From 135b410607f008d3709a7b1374f3f37924eb9fe4 Mon Sep 17 00:00:00 2001 From: Sam Bingner Date: Fri, 3 Aug 2018 15:06:38 -1000 Subject: Update vim --- data/vim/patches/8.1.0192 | 4274 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 4274 insertions(+) create mode 100644 data/vim/patches/8.1.0192 (limited to 'data/vim/patches/8.1.0192') diff --git a/data/vim/patches/8.1.0192 b/data/vim/patches/8.1.0192 new file mode 100644 index 000000000..8dfbf381c --- /dev/null +++ b/data/vim/patches/8.1.0192 @@ -0,0 +1,4274 @@ +To: vim_dev@googlegroups.com +Subject: Patch 8.1.0192 +Fcc: outbox +From: Bram Moolenaar +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 8.1.0192 +Problem: Executing regexp recursively fails with a crash. +Solution: Move global variables into "rex". +Files: src/regexp.c, src/regexp.h, src/regexp_nfa.c + + +*** ../vim-8.1.0191/src/regexp.c 2018-06-23 15:09:02.351412460 +0200 +--- src/regexp.c 2018-07-17 05:32:30.971441868 +0200 +*************** +*** 344,350 **** + + #define MAX_LIMIT (32767L << 16L) + +- static int re_multi_type(int); + static int cstrncmp(char_u *s1, char_u *s2, int *n); + static char_u *cstrchr(char_u *, int); + +--- 344,349 ---- +*************** +*** 371,376 **** +--- 370,377 ---- + #endif + static char_u e_missing_sb[] = N_("E69: Missing ] after %s%%["); + static char_u e_empty_sb[] = N_("E70: Empty %s%%[]"); ++ static char_u e_recursive[] = N_("E956: Cannot use pattern recursively"); ++ + #define NOT_MULTI 0 + #define MULTI_ONE 1 + #define MULTI_MULT 2 +*************** +*** 426,439 **** + static char_u REGEXP_INRANGE[] = "]^-n\\"; + static char_u REGEXP_ABBR[] = "nrtebdoxuU"; + +- static int backslash_trans(int c); +- static int get_char_class(char_u **pp); +- static int get_equi_class(char_u **pp); +- static void reg_equi_class(int c); +- static int get_coll_element(char_u **pp); +- static char_u *skip_anyof(char_u *p); +- static void init_class_tab(void); +- + /* + * Translate '\x' to its control character, except "\n", which is Magic. + */ +--- 427,432 ---- +*************** +*** 688,695 **** + * Forward declarations for vim_regcomp()'s friends. + */ + static void initchr(char_u *); +- static void save_parse_state(parse_state_T *ps); +- static void restore_parse_state(parse_state_T *ps); + static int getchr(void); + static void skipchr_keepstart(void); + static int peekchr(void); +--- 681,686 ---- +*************** +*** 1171,1177 **** + return 0; + } + +- static void get_cpo_flags(void); + static int reg_cpo_lit; /* 'cpoptions' contains 'l' flag */ + static int reg_cpo_bsl; /* 'cpoptions' contains '\' flag */ + +--- 1162,1167 ---- +*************** +*** 1322,1330 **** + return TRUE; + } + +- static regprog_T *bt_regcomp(char_u *expr, int re_flags); +- static void bt_regfree(regprog_T *prog); +- + /* + * bt_regcomp() - compile a regular expression into internal code for the + * traditional back track matcher. +--- 1312,1317 ---- +*************** +*** 1373,1378 **** +--- 1360,1366 ---- + r = (bt_regprog_T *)lalloc(sizeof(bt_regprog_T) + regsize, TRUE); + if (r == NULL) + return NULL; ++ r->re_in_use = FALSE; + + /* + * Second pass: emit code. +*************** +*** 1525,1533 **** + } + #endif + +! /* variables for parsing reginput */ +! static int at_start; /* True when on the first character */ +! static int prev_at_start; /* True when on the second character */ + + /* + * Parse regular expression, i.e. main body or parenthesized thing. +--- 1513,1521 ---- + } + #endif + +! // variables used for parsing +! static int at_start; // True when on the first character +! static int prev_at_start; // True when on the second character + + /* + * Parse regular expression, i.e. main body or parenthesized thing. +*************** +*** 3443,3460 **** + * Global work variables for vim_regexec(). + */ + +- /* The current match-position is remembered with these variables: */ +- static linenr_T reglnum; /* line number, relative to first line */ +- static char_u *regline; /* start of current line */ +- static char_u *reginput; /* current input, points into "regline" */ +- +- static int need_clear_subexpr; /* subexpressions still need to be +- * cleared */ +- #ifdef FEAT_SYN_HL +- static int need_clear_zsubexpr = FALSE; /* extmatch subexpressions +- * still need to be cleared */ +- #endif +- + /* + * Structure used to save the current input state, when it needs to be + * restored after trying a match. Used by reg_save() and reg_restore(). +--- 3431,3436 ---- +*************** +*** 3464,3471 **** + { + union + { +! char_u *ptr; /* reginput pointer, for single-line regexp */ +! lpos_T pos; /* reginput pos, for multi-line regexp */ + } rs_u; + int rs_len; + } regsave_T; +--- 3440,3447 ---- + { + union + { +! char_u *ptr; /* rex.input pointer, for single-line regexp */ +! lpos_T pos; /* rex.input pos, for multi-line regexp */ + } rs_u; + int rs_len; + } regsave_T; +*************** +*** 3564,3576 **** + linenr_T reg_maxline; + int reg_line_lbr; /* "\n" in string is line break */ + + /* Internal copy of 'ignorecase'. It is set at each call to vim_regexec(). + * Normally it gets the value of "rm_ic" or "rmm_ic", but when the pattern + * contains '\c' or '\C' the value is overruled. */ + int reg_ic; + + #ifdef FEAT_MBYTE +! /* Similar to rex.reg_ic, but only for 'combining' characters. Set with \Z + * flag in the regexp. Defaults to false, always. */ + int reg_icombine; + #endif +--- 3540,3563 ---- + linenr_T reg_maxline; + int reg_line_lbr; /* "\n" in string is line break */ + ++ // The current match-position is stord in these variables: ++ linenr_T lnum; // line number, relative to first line ++ char_u *line; // start of current line ++ char_u *input; // current input, points into "regline" ++ ++ int need_clear_subexpr; // subexpressions still need to be cleared ++ #ifdef FEAT_SYN_HL ++ int need_clear_zsubexpr; // extmatch subexpressions still need to be ++ // cleared ++ #endif ++ + /* Internal copy of 'ignorecase'. It is set at each call to vim_regexec(). + * Normally it gets the value of "rm_ic" or "rmm_ic", but when the pattern + * contains '\c' or '\C' the value is overruled. */ + int reg_ic; + + #ifdef FEAT_MBYTE +! /* Similar to "reg_ic", but only for 'combining' characters. Set with \Z + * flag in the regexp. Defaults to false, always. */ + int reg_icombine; + #endif +*************** +*** 3578,3583 **** +--- 3565,3586 ---- + /* Copy of "rmm_maxcol": maximum column to search for a match. Zero when + * there is no maximum. */ + colnr_T reg_maxcol; ++ ++ // State for the NFA engine regexec. ++ int nfa_has_zend; // NFA regexp \ze operator encountered. ++ int nfa_has_backref; // NFA regexp \1 .. \9 encountered. ++ int nfa_nsubexpr; // Number of sub expressions actually being used ++ // during execution. 1 if only the whole match ++ // (subexpr 0) is used. ++ // listid is global, so that it increases on recursive calls to ++ // nfa_regmatch(), which means we don't have to clear the lastlist field of ++ // all the states. ++ int nfa_listid; ++ int nfa_alt_listid; ++ ++ #ifdef FEAT_SYN_HL ++ int nfa_has_zsubexpr; // NFA regexp has \z( ), set zsubexpr. ++ #endif + } regexec_T; + + static regexec_T rex; +*************** +*** 3619,3625 **** + { + save_se_T sesave; + regsave_T regsave; +! } rs_un; /* room for saving reginput */ + short rs_no; /* submatch nr or BEHIND/NOBEHIND */ + } regitem_T; + +--- 3622,3628 ---- + { + save_se_T sesave; + regsave_T regsave; +! } rs_un; /* room for saving rex.input */ + short rs_no; /* submatch nr or BEHIND/NOBEHIND */ + } regitem_T; + +*************** +*** 3896,3903 **** + goto theend; + } + +! regline = line; +! reglnum = 0; + reg_toolong = FALSE; + + /* Simplest case: Anchored match need be tried only once. */ +--- 3899,3906 ---- + goto theend; + } + +! rex.line = line; +! rex.lnum = 0; + reg_toolong = FALSE; + + /* Simplest case: Anchored match need be tried only once. */ +*************** +*** 3907,3916 **** + + #ifdef FEAT_MBYTE + if (has_mbyte) +! c = (*mb_ptr2char)(regline + col); + else + #endif +! c = regline[col]; + if (prog->regstart == NUL + || prog->regstart == c + || (rex.reg_ic && (( +--- 3910,3919 ---- + + #ifdef FEAT_MBYTE + if (has_mbyte) +! c = (*mb_ptr2char)(rex.line + col); + else + #endif +! c = rex.line[col]; + if (prog->regstart == NUL + || prog->regstart == c + || (rex.reg_ic && (( +*************** +*** 3940,3954 **** + && !has_mbyte + #endif + ) +! s = vim_strbyte(regline + col, prog->regstart); + else +! s = cstrchr(regline + col, prog->regstart); + if (s == NULL) + { + retval = 0; + break; + } +! col = (int)(s - regline); + } + + /* Check for maximum column to try. */ +--- 3943,3957 ---- + && !has_mbyte + #endif + ) +! s = vim_strbyte(rex.line + col, prog->regstart); + else +! s = cstrchr(rex.line + col, prog->regstart); + if (s == NULL) + { + retval = 0; + break; + } +! col = (int)(s - rex.line); + } + + /* Check for maximum column to try. */ +*************** +*** 3963,3978 **** + break; + + /* if not currently on the first line, get it again */ +! if (reglnum != 0) + { +! reglnum = 0; +! regline = reg_getline((linenr_T)0); + } +! if (regline[col] == NUL) + break; + #ifdef FEAT_MBYTE + if (has_mbyte) +! col += (*mb_ptr2len)(regline + col); + else + #endif + ++col; +--- 3966,3981 ---- + break; + + /* if not currently on the first line, get it again */ +! if (rex.lnum != 0) + { +! rex.lnum = 0; +! rex.line = reg_getline((linenr_T)0); + } +! if (rex.line[col] == NUL) + break; + #ifdef FEAT_MBYTE + if (has_mbyte) +! col += (*mb_ptr2len)(rex.line + col); + else + #endif + ++col; +*************** +*** 4052,4058 **** + #endif + + /* +! * regtry - try match of "prog" with at regline["col"]. + * Returns 0 for failure, number of lines contained in the match otherwise. + */ + static long +--- 4055,4061 ---- + #endif + + /* +! * regtry - try match of "prog" with at rex.line["col"]. + * Returns 0 for failure, number of lines contained in the match otherwise. + */ + static long +*************** +*** 4062,4073 **** + proftime_T *tm, /* timeout limit or NULL */ + int *timed_out) /* flag set on timeout or NULL */ + { +! reginput = regline + col; +! need_clear_subexpr = TRUE; + #ifdef FEAT_SYN_HL +! /* Clear the external match subpointers if necessary. */ +! if (prog->reghasz == REX_SET) +! need_clear_zsubexpr = TRUE; + #endif + + if (regmatch(prog->program + 1, tm, timed_out) == 0) +--- 4065,4075 ---- + proftime_T *tm, /* timeout limit or NULL */ + int *timed_out) /* flag set on timeout or NULL */ + { +! rex.input = rex.line + col; +! rex.need_clear_subexpr = TRUE; + #ifdef FEAT_SYN_HL +! // Clear the external match subpointers if necessary. +! rex.need_clear_zsubexpr = (prog->reghasz == REX_SET); + #endif + + if (regmatch(prog->program + 1, tm, timed_out) == 0) +*************** +*** 4083,4101 **** + } + if (rex.reg_endpos[0].lnum < 0) + { +! rex.reg_endpos[0].lnum = reglnum; +! rex.reg_endpos[0].col = (int)(reginput - regline); + } + else + /* Use line number of "\ze". */ +! reglnum = rex.reg_endpos[0].lnum; + } + else + { + if (rex.reg_startp[0] == NULL) +! rex.reg_startp[0] = regline + col; + if (rex.reg_endp[0] == NULL) +! rex.reg_endp[0] = reginput; + } + #ifdef FEAT_SYN_HL + /* Package any found \z(...\) matches for export. Default is none. */ +--- 4085,4103 ---- + } + if (rex.reg_endpos[0].lnum < 0) + { +! rex.reg_endpos[0].lnum = rex.lnum; +! rex.reg_endpos[0].col = (int)(rex.input - rex.line); + } + else + /* Use line number of "\ze". */ +! rex.lnum = rex.reg_endpos[0].lnum; + } + else + { + if (rex.reg_startp[0] == NULL) +! rex.reg_startp[0] = rex.line + col; + if (rex.reg_endp[0] == NULL) +! rex.reg_endp[0] = rex.input; + } + #ifdef FEAT_SYN_HL + /* Package any found \z(...\) matches for export. Default is none. */ +*************** +*** 4131,4137 **** + } + } + #endif +! return 1 + reglnum; + } + + #ifdef FEAT_MBYTE +--- 4133,4139 ---- + } + } + #endif +! return 1 + rex.lnum; + } + + #ifdef FEAT_MBYTE +*************** +*** 4143,4151 **** + static int + reg_prev_class(void) + { +! if (reginput > regline) +! return mb_get_class_buf(reginput - 1 +! - (*mb_head_off)(regline, reginput - 1), rex.reg_buf); + return -1; + } + #endif +--- 4145,4153 ---- + static int + reg_prev_class(void) + { +! if (rex.input > rex.line) +! return mb_get_class_buf(rex.input - 1 +! - (*mb_head_off)(rex.line, rex.input - 1), rex.reg_buf); + return -1; + } + #endif +*************** +*** 4153,4159 **** + static int reg_match_visual(void); + + /* +! * Return TRUE if the current reginput position matches the Visual area. + */ + static int + reg_match_visual(void) +--- 4155,4161 ---- + static int reg_match_visual(void); + + /* +! * Return TRUE if the current rex.input position matches the Visual area. + */ + static int + reg_match_visual(void) +*************** +*** 4199,4211 **** + } + mode = curbuf->b_visual.vi_mode; + } +! lnum = reglnum + rex.reg_firstlnum; + if (lnum < top.lnum || lnum > bot.lnum) + return FALSE; + + if (mode == 'v') + { +! col = (colnr_T)(reginput - regline); + if ((lnum == top.lnum && col < top.col) + || (lnum == bot.lnum && col >= bot.col + (*p_sel != 'e'))) + return FALSE; +--- 4201,4213 ---- + } + mode = curbuf->b_visual.vi_mode; + } +! lnum = rex.lnum + rex.reg_firstlnum; + if (lnum < top.lnum || lnum > bot.lnum) + return FALSE; + + if (mode == 'v') + { +! col = (colnr_T)(rex.input - rex.line); + if ((lnum == top.lnum && col < top.col) + || (lnum == bot.lnum && col >= bot.col + (*p_sel != 'e'))) + return FALSE; +*************** +*** 4220,4233 **** + end = end2; + if (top.col == MAXCOL || bot.col == MAXCOL) + end = MAXCOL; +! cols = win_linetabsize(wp, regline, (colnr_T)(reginput - regline)); + if (cols < start || cols > end - (*p_sel == 'e')) + return FALSE; + } + return TRUE; + } + +! #define ADVANCE_REGINPUT() MB_PTR_ADV(reginput) + + /* + * The arguments from BRACE_LIMITS are stored here. They are actually local +--- 4222,4235 ---- + end = end2; + if (top.col == MAXCOL || bot.col == MAXCOL) + end = MAXCOL; +! cols = win_linetabsize(wp, rex.line, (colnr_T)(rex.input - rex.line)); + if (cols < start || cols > end - (*p_sel == 'e')) + return FALSE; + } + return TRUE; + } + +! #define ADVANCE_REGINPUT() MB_PTR_ADV(rex.input) + + /* + * The arguments from BRACE_LIMITS are stored here. They are actually local +*************** +*** 4247,4255 **** + * (that don't need to know whether the rest of the match failed) by a nested + * loop. + * +! * Returns TRUE when there is a match. Leaves reginput and reglnum just after + * the last matched character. +! * Returns FALSE when there is no match. Leaves reginput and reglnum in an + * undefined state! + */ + static int +--- 4249,4257 ---- + * (that don't need to know whether the rest of the match failed) by a nested + * loop. + * +! * Returns TRUE when there is a match. Leaves rex.input and rex.lnum just after + * the last matched character. +! * Returns FALSE when there is no match. Leaves rex.input and rex.lnum in an + * undefined state! + */ + static int +*************** +*** 4349,4359 **** + op = OP(scan); + /* Check for character class with NL added. */ + if (!rex.reg_line_lbr && WITH_NL(op) && REG_MULTI +! && *reginput == NUL && reglnum <= rex.reg_maxline) + { + reg_nextline(); + } +! else if (rex.reg_line_lbr && WITH_NL(op) && *reginput == '\n') + { + ADVANCE_REGINPUT(); + } +--- 4351,4361 ---- + op = OP(scan); + /* Check for character class with NL added. */ + if (!rex.reg_line_lbr && WITH_NL(op) && REG_MULTI +! && *rex.input == NUL && rex.lnum <= rex.reg_maxline) + { + reg_nextline(); + } +! else if (rex.reg_line_lbr && WITH_NL(op) && *rex.input == '\n') + { + ADVANCE_REGINPUT(); + } +*************** +*** 4363,4376 **** + op -= ADD_NL; + #ifdef FEAT_MBYTE + if (has_mbyte) +! c = (*mb_ptr2char)(reginput); + else + #endif +! c = *reginput; + switch (op) + { + case BOL: +! if (reginput != regline) + status = RA_NOMATCH; + break; + +--- 4365,4378 ---- + op -= ADD_NL; + #ifdef FEAT_MBYTE + if (has_mbyte) +! c = (*mb_ptr2char)(rex.input); + else + #endif +! c = *rex.input; + switch (op) + { + case BOL: +! if (rex.input != rex.line) + status = RA_NOMATCH; + break; + +*************** +*** 4383,4395 **** + /* We're not at the beginning of the file when below the first + * line where we started, not at the start of the line or we + * didn't start at the first line of the buffer. */ +! if (reglnum != 0 || reginput != regline + || (REG_MULTI && rex.reg_firstlnum > 1)) + status = RA_NOMATCH; + break; + + case RE_EOF: +! if (reglnum != rex.reg_maxline || c != NUL) + status = RA_NOMATCH; + break; + +--- 4385,4397 ---- + /* We're not at the beginning of the file when below the first + * line where we started, not at the start of the line or we + * didn't start at the first line of the buffer. */ +! if (rex.lnum != 0 || rex.input != rex.line + || (REG_MULTI && rex.reg_firstlnum > 1)) + status = RA_NOMATCH; + break; + + case RE_EOF: +! if (rex.lnum != rex.reg_maxline || c != NUL) + status = RA_NOMATCH; + break; + +*************** +*** 4397,4405 **** + /* Check if the buffer is in a window and compare the + * rex.reg_win->w_cursor position to the match position. */ + if (rex.reg_win == NULL +! || (reglnum + rex.reg_firstlnum + != rex.reg_win->w_cursor.lnum) +! || ((colnr_T)(reginput - regline) + != rex.reg_win->w_cursor.col)) + status = RA_NOMATCH; + break; +--- 4399,4407 ---- + /* Check if the buffer is in a window and compare the + * rex.reg_win->w_cursor position to the match position. */ + if (rex.reg_win == NULL +! || (rex.lnum + rex.reg_firstlnum + != rex.reg_win->w_cursor.lnum) +! || ((colnr_T)(rex.input - rex.line) + != rex.reg_win->w_cursor.col)) + status = RA_NOMATCH; + break; +*************** +*** 4414,4426 **** + pos = getmark_buf(rex.reg_buf, mark, FALSE); + if (pos == NULL /* mark doesn't exist */ + || pos->lnum <= 0 /* mark isn't set in reg_buf */ +! || (pos->lnum == reglnum + rex.reg_firstlnum +! ? (pos->col == (colnr_T)(reginput - regline) + ? (cmp == '<' || cmp == '>') +! : (pos->col < (colnr_T)(reginput - regline) + ? cmp != '>' + : cmp != '<')) +! : (pos->lnum < reglnum + rex.reg_firstlnum + ? cmp != '>' + : cmp != '<'))) + status = RA_NOMATCH; +--- 4416,4428 ---- + pos = getmark_buf(rex.reg_buf, mark, FALSE); + if (pos == NULL /* mark doesn't exist */ + || pos->lnum <= 0 /* mark isn't set in reg_buf */ +! || (pos->lnum == rex.lnum + rex.reg_firstlnum +! ? (pos->col == (colnr_T)(rex.input - rex.line) + ? (cmp == '<' || cmp == '>') +! : (pos->col < (colnr_T)(rex.input - rex.line) + ? cmp != '>' + : cmp != '<')) +! : (pos->lnum < rex.lnum + rex.reg_firstlnum + ? cmp != '>' + : cmp != '<'))) + status = RA_NOMATCH; +*************** +*** 4433,4456 **** + break; + + case RE_LNUM: +! if (!REG_MULTI || !re_num_cmp((long_u)(reglnum + rex.reg_firstlnum), + scan)) + status = RA_NOMATCH; + break; + + case RE_COL: +! if (!re_num_cmp((long_u)(reginput - regline) + 1, scan)) + status = RA_NOMATCH; + break; + + case RE_VCOL: + if (!re_num_cmp((long_u)win_linetabsize( + rex.reg_win == NULL ? curwin : rex.reg_win, +! regline, (colnr_T)(reginput - regline)) + 1, scan)) + status = RA_NOMATCH; + break; + +! case BOW: /* \ regline +! && vim_iswordc_buf(reginput[-1], rex.reg_buf))) + status = RA_NOMATCH; + } + break; + +! case EOW: /* word\>; reginput points after d */ +! if (reginput == regline) /* Can't match at start of line */ + status = RA_NOMATCH; + #ifdef FEAT_MBYTE + else if (has_mbyte) +--- 4470,4483 ---- + #endif + else + { +! if (!vim_iswordc_buf(c, rex.reg_buf) || (rex.input > rex.line +! && vim_iswordc_buf(rex.input[-1], rex.reg_buf))) + status = RA_NOMATCH; + } + break; + +! case EOW: /* word\>; rex.input points after d */ +! if (rex.input == rex.line) /* Can't match at start of line */ + status = RA_NOMATCH; + #ifdef FEAT_MBYTE + else if (has_mbyte) +*************** +*** 4483,4489 **** + int this_class, prev_class; + + /* Get class of current and previous char (if it exists). */ +! this_class = mb_get_class_buf(reginput, rex.reg_buf); + prev_class = reg_prev_class(); + if (this_class == prev_class + || prev_class == 0 || prev_class == 1) +--- 4485,4491 ---- + int this_class, prev_class; + + /* Get class of current and previous char (if it exists). */ +! this_class = mb_get_class_buf(rex.input, rex.reg_buf); + prev_class = reg_prev_class(); + if (this_class == prev_class + || prev_class == 0 || prev_class == 1) +*************** +*** 4492,4499 **** + #endif + else + { +! if (!vim_iswordc_buf(reginput[-1], rex.reg_buf) +! || (reginput[0] != NUL + && vim_iswordc_buf(c, rex.reg_buf))) + status = RA_NOMATCH; + } +--- 4494,4501 ---- + #endif + else + { +! if (!vim_iswordc_buf(rex.input[-1], rex.reg_buf) +! || (rex.input[0] != NUL + && vim_iswordc_buf(c, rex.reg_buf))) + status = RA_NOMATCH; + } +*************** +*** 4515,4536 **** + break; + + case SIDENT: +! if (VIM_ISDIGIT(*reginput) || !vim_isIDc(c)) + status = RA_NOMATCH; + else + ADVANCE_REGINPUT(); + break; + + case KWORD: +! if (!vim_iswordp_buf(reginput, rex.reg_buf)) + status = RA_NOMATCH; + else + ADVANCE_REGINPUT(); + break; + + case SKWORD: +! if (VIM_ISDIGIT(*reginput) +! || !vim_iswordp_buf(reginput, rex.reg_buf)) + status = RA_NOMATCH; + else + ADVANCE_REGINPUT(); +--- 4517,4538 ---- + break; + + case SIDENT: +! if (VIM_ISDIGIT(*rex.input) || !vim_isIDc(c)) + status = RA_NOMATCH; + else + ADVANCE_REGINPUT(); + break; + + case KWORD: +! if (!vim_iswordp_buf(rex.input, rex.reg_buf)) + status = RA_NOMATCH; + else + ADVANCE_REGINPUT(); + break; + + case SKWORD: +! if (VIM_ISDIGIT(*rex.input) +! || !vim_iswordp_buf(rex.input, rex.reg_buf)) + status = RA_NOMATCH; + else + ADVANCE_REGINPUT(); +*************** +*** 4544,4564 **** + break; + + case SFNAME: +! if (VIM_ISDIGIT(*reginput) || !vim_isfilec(c)) + status = RA_NOMATCH; + else + ADVANCE_REGINPUT(); + break; + + case PRINT: +! if (!vim_isprintc(PTR2CHAR(reginput))) + status = RA_NOMATCH; + else + ADVANCE_REGINPUT(); + break; + + case SPRINT: +! if (VIM_ISDIGIT(*reginput) || !vim_isprintc(PTR2CHAR(reginput))) + status = RA_NOMATCH; + else + ADVANCE_REGINPUT(); +--- 4546,4566 ---- + break; + + case SFNAME: +! if (VIM_ISDIGIT(*rex.input) || !vim_isfilec(c)) + status = RA_NOMATCH; + else + ADVANCE_REGINPUT(); + break; + + case PRINT: +! if (!vim_isprintc(PTR2CHAR(rex.input))) + status = RA_NOMATCH; + else + ADVANCE_REGINPUT(); + break; + + case SPRINT: +! if (VIM_ISDIGIT(*rex.input) || !vim_isprintc(PTR2CHAR(rex.input))) + status = RA_NOMATCH; + else + ADVANCE_REGINPUT(); +*************** +*** 4697,4708 **** + + opnd = OPERAND(scan); + /* Inline the first byte, for speed. */ +! if (*opnd != *reginput + && (!rex.reg_ic || ( + #ifdef FEAT_MBYTE + !enc_utf8 && + #endif +! MB_TOLOWER(*opnd) != MB_TOLOWER(*reginput)))) + status = RA_NOMATCH; + else if (*opnd == NUL) + { +--- 4699,4710 ---- + + opnd = OPERAND(scan); + /* Inline the first byte, for speed. */ +! if (*opnd != *rex.input + && (!rex.reg_ic || ( + #ifdef FEAT_MBYTE + !enc_utf8 && + #endif +! MB_TOLOWER(*opnd) != MB_TOLOWER(*rex.input)))) + status = RA_NOMATCH; + else if (*opnd == NUL) + { +*************** +*** 4723,4729 **** + { + /* Need to match first byte again for multi-byte. */ + len = (int)STRLEN(opnd); +! if (cstrncmp(opnd, reginput, &len) != 0) + status = RA_NOMATCH; + } + #ifdef FEAT_MBYTE +--- 4725,4731 ---- + { + /* Need to match first byte again for multi-byte. */ + len = (int)STRLEN(opnd); +! if (cstrncmp(opnd, rex.input, &len) != 0) + status = RA_NOMATCH; + } + #ifdef FEAT_MBYTE +*************** +*** 4731,4737 **** + * follows (skips over all composing chars). */ + if (status != RA_NOMATCH + && enc_utf8 +! && UTF_COMPOSINGLIKE(reginput, reginput + len) + && !rex.reg_icombine + && OP(next) != RE_COMPOSING) + { +--- 4733,4739 ---- + * follows (skips over all composing chars). */ + if (status != RA_NOMATCH + && enc_utf8 +! && UTF_COMPOSINGLIKE(rex.input, rex.input + len) + && !rex.reg_icombine + && OP(next) != RE_COMPOSING) + { +*************** +*** 4742,4748 **** + } + #endif + if (status != RA_NOMATCH) +! reginput += len; + } + } + break; +--- 4744,4750 ---- + } + #endif + if (status != RA_NOMATCH) +! rex.input += len; + } + } + break; +*************** +*** 4780,4789 **** + /* When only a composing char is given match at any + * position where that composing char appears. */ + status = RA_NOMATCH; +! for (i = 0; reginput[i] != NUL; +! i += utf_ptr2len(reginput + i)) + { +! inpc = utf_ptr2char(reginput + i); + if (!utf_iscomposing(inpc)) + { + if (i > 0) +--- 4782,4791 ---- + /* When only a composing char is given match at any + * position where that composing char appears. */ + status = RA_NOMATCH; +! for (i = 0; rex.input[i] != NUL; +! i += utf_ptr2len(rex.input + i)) + { +! inpc = utf_ptr2char(rex.input + i); + if (!utf_iscomposing(inpc)) + { + if (i > 0) +*************** +*** 4792,4798 **** + else if (opndc == inpc) + { + /* Include all following composing chars. */ +! len = i + utfc_ptr2len(reginput + i); + status = RA_MATCH; + break; + } +--- 4794,4800 ---- + else if (opndc == inpc) + { + /* Include all following composing chars. */ +! len = i + utfc_ptr2len(rex.input + i); + status = RA_MATCH; + break; + } +*************** +*** 4800,4811 **** + } + else + for (i = 0; i < len; ++i) +! if (opnd[i] != reginput[i]) + { + status = RA_NOMATCH; + break; + } +! reginput += len; + } + else + status = RA_NOMATCH; +--- 4802,4813 ---- + } + else + for (i = 0; i < len; ++i) +! if (opnd[i] != rex.input[i]) + { + status = RA_NOMATCH; + break; + } +! rex.input += len; + } + else + status = RA_NOMATCH; +*************** +*** 4816,4823 **** + if (enc_utf8) + { + /* Skip composing characters. */ +! while (utf_iscomposing(utf_ptr2char(reginput))) +! MB_CPTR_ADV(reginput); + } + #endif + break; +--- 4818,4825 ---- + if (enc_utf8) + { + /* Skip composing characters. */ +! while (utf_iscomposing(utf_ptr2char(rex.input))) +! MB_CPTR_ADV(rex.input); + } + #endif + break; +*************** +*** 5003,5009 **** + /* Compare current input with back-ref in the same + * line. */ + len = (int)(rex.reg_endp[no] - rex.reg_startp[no]); +! if (cstrncmp(rex.reg_startp[no], reginput, &len) != 0) + status = RA_NOMATCH; + } + } +--- 5005,5011 ---- + /* Compare current input with back-ref in the same + * line. */ + len = (int)(rex.reg_endp[no] - rex.reg_startp[no]); +! if (cstrncmp(rex.reg_startp[no], rex.input, &len) != 0) + status = RA_NOMATCH; + } + } +*************** +*** 5017,5030 **** + } + else + { +! if (rex.reg_startpos[no].lnum == reglnum +! && rex.reg_endpos[no].lnum == reglnum) + { + /* Compare back-ref within the current line. */ + len = rex.reg_endpos[no].col + - rex.reg_startpos[no].col; +! if (cstrncmp(regline + rex.reg_startpos[no].col, +! reginput, &len) != 0) + status = RA_NOMATCH; + } + else +--- 5019,5032 ---- + } + else + { +! if (rex.reg_startpos[no].lnum == rex.lnum +! && rex.reg_endpos[no].lnum == rex.lnum) + { + /* Compare back-ref within the current line. */ + len = rex.reg_endpos[no].col + - rex.reg_startpos[no].col; +! if (cstrncmp(rex.line + rex.reg_startpos[no].col, +! rex.input, &len) != 0) + status = RA_NOMATCH; + } + else +*************** +*** 5045,5051 **** + } + + /* Matched the backref, skip over it. */ +! reginput += len; + } + break; + +--- 5047,5053 ---- + } + + /* Matched the backref, skip over it. */ +! rex.input += len; + } + break; + +*************** +*** 5069,5078 **** + { + len = (int)STRLEN(re_extmatch_in->matches[no]); + if (cstrncmp(re_extmatch_in->matches[no], +! reginput, &len) != 0) + status = RA_NOMATCH; + else +! reginput += len; + } + else + { +--- 5071,5080 ---- + { + len = (int)STRLEN(re_extmatch_in->matches[no]); + if (cstrncmp(re_extmatch_in->matches[no], +! rex.input, &len) != 0) + status = RA_NOMATCH; + else +! rex.input += len; + } + else + { +*************** +*** 5319,5334 **** + case BHPOS: + if (REG_MULTI) + { +! if (behind_pos.rs_u.pos.col != (colnr_T)(reginput - regline) +! || behind_pos.rs_u.pos.lnum != reglnum) + status = RA_NOMATCH; + } +! else if (behind_pos.rs_u.ptr != reginput) + status = RA_NOMATCH; + break; + + case NEWL: +! if ((c != NUL || !REG_MULTI || reglnum > rex.reg_maxline + || rex.reg_line_lbr) + && (c != '\n' || !rex.reg_line_lbr)) + status = RA_NOMATCH; +--- 5321,5336 ---- + case BHPOS: + if (REG_MULTI) + { +! if (behind_pos.rs_u.pos.col != (colnr_T)(rex.input - rex.line) +! || behind_pos.rs_u.pos.lnum != rex.lnum) + status = RA_NOMATCH; + } +! else if (behind_pos.rs_u.ptr != rex.input) + status = RA_NOMATCH; + break; + + case NEWL: +! if ((c != NUL || !REG_MULTI || rex.lnum > rex.reg_maxline + || rex.reg_line_lbr) + && (c != '\n' || !rex.reg_line_lbr)) + status = RA_NOMATCH; +*************** +*** 5562,5568 **** + if (limit > 0 + && ((rp->rs_un.regsave.rs_u.pos.lnum + < behind_pos.rs_u.pos.lnum +! ? (colnr_T)STRLEN(regline) + : behind_pos.rs_u.pos.col) + - rp->rs_un.regsave.rs_u.pos.col >= limit)) + no = FAIL; +--- 5564,5570 ---- + if (limit > 0 + && ((rp->rs_un.regsave.rs_u.pos.lnum + < behind_pos.rs_u.pos.lnum +! ? (colnr_T)STRLEN(rex.line) + : behind_pos.rs_u.pos.col) + - rp->rs_un.regsave.rs_u.pos.col >= limit)) + no = FAIL; +*************** +*** 5578,5584 **** + { + reg_restore(&rp->rs_un.regsave, &backpos); + rp->rs_un.regsave.rs_u.pos.col = +! (colnr_T)STRLEN(regline); + } + } + else +--- 5580,5586 ---- + { + reg_restore(&rp->rs_un.regsave, &backpos); + rp->rs_un.regsave.rs_u.pos.col = +! (colnr_T)STRLEN(rex.line); + } + } + else +*************** +*** 5600,5610 **** + } + else + { +! if (rp->rs_un.regsave.rs_u.ptr == regline) + no = FAIL; + else + { +! MB_PTR_BACK(regline, rp->rs_un.regsave.rs_u.ptr); + if (limit > 0 && (long)(behind_pos.rs_u.ptr + - rp->rs_un.regsave.rs_u.ptr) > limit) + no = FAIL; +--- 5602,5612 ---- + } + else + { +! if (rp->rs_un.regsave.rs_u.ptr == rex.line) + no = FAIL; + else + { +! MB_PTR_BACK(rex.line, rp->rs_un.regsave.rs_u.ptr); + if (limit > 0 && (long)(behind_pos.rs_u.ptr + - rp->rs_un.regsave.rs_u.ptr) > limit) + no = FAIL; +*************** +*** 5678,5697 **** + * didn't match -- back up one char. */ + if (--rst->count < rst->minval) + break; +! if (reginput == regline) + { + /* backup to last char of previous line */ +! --reglnum; +! regline = reg_getline(reglnum); + /* Just in case regrepeat() didn't count + * right. */ +! if (regline == NULL) + break; +! reginput = regline + STRLEN(regline); + fast_breakcheck(); + } + else +! MB_PTR_BACK(regline, reginput); + } + else + { +--- 5680,5699 ---- + * didn't match -- back up one char. */ + if (--rst->count < rst->minval) + break; +! if (rex.input == rex.line) + { + /* backup to last char of previous line */ +! --rex.lnum; +! rex.line = reg_getline(rex.lnum); + /* Just in case regrepeat() didn't count + * right. */ +! if (rex.line == NULL) + break; +! rex.input = rex.line + STRLEN(rex.line); + fast_breakcheck(); + } + else +! MB_PTR_BACK(rex.line, rex.input); + } + else + { +*************** +*** 5711,5718 **** + status = RA_NOMATCH; + + /* If it could match, try it. */ +! if (rst->nextb == NUL || *reginput == rst->nextb +! || *reginput == rst->nextb_ic) + { + reg_save(&rp->rs_un.regsave, &backpos); + scan = regnext(rp->rs_scan); +--- 5713,5720 ---- + status = RA_NOMATCH; + + /* If it could match, try it. */ +! if (rst->nextb == NUL || *rex.input == rst->nextb +! || *rex.input == rst->nextb_ic) + { + reg_save(&rp->rs_un.regsave, &backpos); + scan = regnext(rp->rs_scan); +*************** +*** 5807,5813 **** + + /* + * regrepeat - repeatedly match something simple, return how many. +! * Advances reginput (and reglnum) to just after the matched chars. + */ + static int + regrepeat( +--- 5809,5815 ---- + + /* + * regrepeat - repeatedly match something simple, return how many. +! * Advances rex.input (and rex.lnum) to just after the matched chars. + */ + static int + regrepeat( +*************** +*** 5820,5826 **** + int mask; + int testval = 0; + +! scan = reginput; /* Make local copy of reginput for speed. */ + opnd = OPERAND(p); + switch (OP(p)) + { +--- 5822,5828 ---- + int mask; + int testval = 0; + +! scan = rex.input; /* Make local copy of rex.input for speed. */ + opnd = OPERAND(p); + switch (OP(p)) + { +*************** +*** 5835,5846 **** + ++count; + MB_PTR_ADV(scan); + } +! if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline + || rex.reg_line_lbr || count == maxcount) + break; + ++count; /* count the line-break */ + reg_nextline(); +! scan = reginput; + if (got_int) + break; + } +--- 5837,5848 ---- + ++count; + MB_PTR_ADV(scan); + } +! if (!REG_MULTI || !WITH_NL(OP(p)) || rex.lnum > rex.reg_maxline + || rex.reg_line_lbr || count == maxcount) + break; + ++count; /* count the line-break */ + reg_nextline(); +! scan = rex.input; + if (got_int) + break; + } +*************** +*** 5860,5870 **** + } + else if (*scan == NUL) + { +! if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline + || rex.reg_line_lbr) + break; + reg_nextline(); +! scan = reginput; + if (got_int) + break; + } +--- 5862,5872 ---- + } + else if (*scan == NUL) + { +! if (!REG_MULTI || !WITH_NL(OP(p)) || rex.lnum > rex.reg_maxline + || rex.reg_line_lbr) + break; + reg_nextline(); +! scan = rex.input; + if (got_int) + break; + } +*************** +*** 5891,5901 **** + } + else if (*scan == NUL) + { +! if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline + || rex.reg_line_lbr) + break; + reg_nextline(); +! scan = reginput; + if (got_int) + break; + } +--- 5893,5903 ---- + } + else if (*scan == NUL) + { +! if (!REG_MULTI || !WITH_NL(OP(p)) || rex.lnum > rex.reg_maxline + || rex.reg_line_lbr) + break; + reg_nextline(); +! scan = rex.input; + if (got_int) + break; + } +*************** +*** 5921,5931 **** + } + else if (*scan == NUL) + { +! if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline + || rex.reg_line_lbr) + break; + reg_nextline(); +! scan = reginput; + if (got_int) + break; + } +--- 5923,5933 ---- + } + else if (*scan == NUL) + { +! if (!REG_MULTI || !WITH_NL(OP(p)) || rex.lnum > rex.reg_maxline + || rex.reg_line_lbr) + break; + reg_nextline(); +! scan = rex.input; + if (got_int) + break; + } +*************** +*** 5947,5957 **** + { + if (*scan == NUL) + { +! if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline + || rex.reg_line_lbr) + break; + reg_nextline(); +! scan = reginput; + if (got_int) + break; + } +--- 5949,5959 ---- + { + if (*scan == NUL) + { +! if (!REG_MULTI || !WITH_NL(OP(p)) || rex.lnum > rex.reg_maxline + || rex.reg_line_lbr) + break; + reg_nextline(); +! scan = rex.input; + if (got_int) + break; + } +*************** +*** 5979,5989 **** + #endif + if (*scan == NUL) + { +! if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline + || rex.reg_line_lbr) + break; + reg_nextline(); +! scan = reginput; + if (got_int) + break; + } +--- 5981,5991 ---- + #endif + if (*scan == NUL) + { +! if (!REG_MULTI || !WITH_NL(OP(p)) || rex.lnum > rex.reg_maxline + || rex.reg_line_lbr) + break; + reg_nextline(); +! scan = rex.input; + if (got_int) + break; + } +*************** +*** 6144,6154 **** + #endif + if (*scan == NUL) + { +! if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline + || rex.reg_line_lbr) + break; + reg_nextline(); +! scan = reginput; + if (got_int) + break; + } +--- 6146,6156 ---- + #endif + if (*scan == NUL) + { +! if (!REG_MULTI || !WITH_NL(OP(p)) || rex.lnum > rex.reg_maxline + || rex.reg_line_lbr) + break; + reg_nextline(); +! scan = rex.input; + if (got_int) + break; + } +*************** +*** 6174,6180 **** + + case NEWL: + while (count < maxcount +! && ((*scan == NUL && reglnum <= rex.reg_maxline + && !rex.reg_line_lbr && REG_MULTI) + || (*scan == '\n' && rex.reg_line_lbr))) + { +--- 6176,6182 ---- + + case NEWL: + while (count < maxcount +! && ((*scan == NUL && rex.lnum <= rex.reg_maxline + && !rex.reg_line_lbr && REG_MULTI) + || (*scan == '\n' && rex.reg_line_lbr))) + { +*************** +*** 6183,6189 **** + ADVANCE_REGINPUT(); + else + reg_nextline(); +! scan = reginput; + if (got_int) + break; + } +--- 6185,6191 ---- + ADVANCE_REGINPUT(); + else + reg_nextline(); +! scan = rex.input; + if (got_int) + break; + } +*************** +*** 6197,6203 **** + break; + } + +! reginput = scan; + + return (int)count; + } +--- 6199,6205 ---- + break; + } + +! rex.input = scan; + + return (int)count; + } +*************** +*** 6255,6261 **** + static void + cleanup_subexpr(void) + { +! if (need_clear_subexpr) + { + if (REG_MULTI) + { +--- 6257,6263 ---- + static void + cleanup_subexpr(void) + { +! if (rex.need_clear_subexpr) + { + if (REG_MULTI) + { +*************** +*** 6268,6274 **** + vim_memset(rex.reg_startp, 0, sizeof(char_u *) * NSUBEXP); + vim_memset(rex.reg_endp, 0, sizeof(char_u *) * NSUBEXP); + } +! need_clear_subexpr = FALSE; + } + } + +--- 6270,6276 ---- + vim_memset(rex.reg_startp, 0, sizeof(char_u *) * NSUBEXP); + vim_memset(rex.reg_endp, 0, sizeof(char_u *) * NSUBEXP); + } +! rex.need_clear_subexpr = FALSE; + } + } + +*************** +*** 6276,6282 **** + static void + cleanup_zsubexpr(void) + { +! if (need_clear_zsubexpr) + { + if (REG_MULTI) + { +--- 6278,6284 ---- + static void + cleanup_zsubexpr(void) + { +! if (rex.need_clear_zsubexpr) + { + if (REG_MULTI) + { +*************** +*** 6289,6295 **** + vim_memset(reg_startzp, 0, sizeof(char_u *) * NSUBEXP); + vim_memset(reg_endzp, 0, sizeof(char_u *) * NSUBEXP); + } +! need_clear_zsubexpr = FALSE; + } + } + #endif +--- 6291,6297 ---- + vim_memset(reg_startzp, 0, sizeof(char_u *) * NSUBEXP); + vim_memset(reg_endzp, 0, sizeof(char_u *) * NSUBEXP); + } +! rex.need_clear_zsubexpr = FALSE; + } + } + #endif +*************** +*** 6303,6312 **** + { + int i; + +! /* When "need_clear_subexpr" is set we don't need to save the values, only + * remember that this flag needs to be set again when restoring. */ +! bp->save_need_clear_subexpr = need_clear_subexpr; +! if (!need_clear_subexpr) + { + for (i = 0; i < NSUBEXP; ++i) + { +--- 6305,6314 ---- + { + int i; + +! /* When "rex.need_clear_subexpr" is set we don't need to save the values, only + * remember that this flag needs to be set again when restoring. */ +! bp->save_need_clear_subexpr = rex.need_clear_subexpr; +! if (!rex.need_clear_subexpr) + { + for (i = 0; i < NSUBEXP; ++i) + { +*************** +*** 6333,6340 **** + int i; + + /* Only need to restore saved values when they are not to be cleared. */ +! need_clear_subexpr = bp->save_need_clear_subexpr; +! if (!need_clear_subexpr) + { + for (i = 0; i < NSUBEXP; ++i) + { +--- 6335,6342 ---- + int i; + + /* Only need to restore saved values when they are not to be cleared. */ +! rex.need_clear_subexpr = bp->save_need_clear_subexpr; +! if (!rex.need_clear_subexpr) + { + for (i = 0; i < NSUBEXP; ++i) + { +*************** +*** 6353,6365 **** + } + + /* +! * Advance reglnum, regline and reginput to the next line. + */ + static void + reg_nextline(void) + { +! regline = reg_getline(++reglnum); +! reginput = regline; + fast_breakcheck(); + } + +--- 6355,6367 ---- + } + + /* +! * Advance rex.lnum, rex.line and rex.input to the next line. + */ + static void + reg_nextline(void) + { +! rex.line = reg_getline(++rex.lnum); +! rex.input = rex.line; + fast_breakcheck(); + } + +*************** +*** 6371,6381 **** + { + if (REG_MULTI) + { +! save->rs_u.pos.col = (colnr_T)(reginput - regline); +! save->rs_u.pos.lnum = reglnum; + } + else +! save->rs_u.ptr = reginput; + save->rs_len = gap->ga_len; + } + +--- 6373,6383 ---- + { + if (REG_MULTI) + { +! save->rs_u.pos.col = (colnr_T)(rex.input - rex.line); +! save->rs_u.pos.lnum = rex.lnum; + } + else +! save->rs_u.ptr = rex.input; + save->rs_len = gap->ga_len; + } + +*************** +*** 6387,6403 **** + { + if (REG_MULTI) + { +! if (reglnum != save->rs_u.pos.lnum) + { + /* only call reg_getline() when the line number changed to save + * a bit of time */ +! reglnum = save->rs_u.pos.lnum; +! regline = reg_getline(reglnum); + } +! reginput = regline + save->rs_u.pos.col; + } + else +! reginput = save->rs_u.ptr; + gap->ga_len = save->rs_len; + } + +--- 6389,6405 ---- + { + if (REG_MULTI) + { +! if (rex.lnum != save->rs_u.pos.lnum) + { + /* only call reg_getline() when the line number changed to save + * a bit of time */ +! rex.lnum = save->rs_u.pos.lnum; +! rex.line = reg_getline(rex.lnum); + } +! rex.input = rex.line + save->rs_u.pos.col; + } + else +! rex.input = save->rs_u.ptr; + gap->ga_len = save->rs_len; + } + +*************** +*** 6408,6416 **** + reg_save_equal(regsave_T *save) + { + if (REG_MULTI) +! return reglnum == save->rs_u.pos.lnum +! && reginput == regline + save->rs_u.pos.col; +! return reginput == save->rs_u.ptr; + } + + /* +--- 6410,6418 ---- + reg_save_equal(regsave_T *save) + { + if (REG_MULTI) +! return rex.lnum == save->rs_u.pos.lnum +! && rex.input == rex.line + save->rs_u.pos.col; +! return rex.input == save->rs_u.ptr; + } + + /* +*************** +*** 6424,6438 **** + save_se_multi(save_se_T *savep, lpos_T *posp) + { + savep->se_u.pos = *posp; +! posp->lnum = reglnum; +! posp->col = (colnr_T)(reginput - regline); + } + + static void + save_se_one(save_se_T *savep, char_u **pp) + { + savep->se_u.ptr = *pp; +! *pp = reginput; + } + + /* +--- 6426,6440 ---- + save_se_multi(save_se_T *savep, lpos_T *posp) + { + savep->se_u.pos = *posp; +! posp->lnum = rex.lnum; +! posp->col = (colnr_T)(rex.input - rex.line); + } + + static void + save_se_one(save_se_T *savep, char_u **pp) + { + savep->se_u.ptr = *pp; +! *pp = rex.input; + } + + /* +*************** +*** 6475,6483 **** + { + /* Since getting one line may invalidate the other, need to make copy. + * Slow! */ +! if (regline != reg_tofree) + { +! len = (int)STRLEN(regline); + if (reg_tofree == NULL || len >= (int)reg_tofreelen) + { + len += 50; /* get some extra */ +--- 6477,6485 ---- + { + /* Since getting one line may invalidate the other, need to make copy. + * Slow! */ +! if (rex.line != reg_tofree) + { +! len = (int)STRLEN(rex.line); + if (reg_tofree == NULL || len >= (int)reg_tofreelen) + { + len += 50; /* get some extra */ +*************** +*** 6487,6495 **** + return RA_FAIL; /* out of memory!*/ + reg_tofreelen = len; + } +! STRCPY(reg_tofree, regline); +! reginput = reg_tofree + (reginput - regline); +! regline = reg_tofree; + } + + /* Get the line to compare with. */ +--- 6489,6497 ---- + return RA_FAIL; /* out of memory!*/ + reg_tofreelen = len; + } +! STRCPY(reg_tofree, rex.line); +! rex.input = reg_tofree + (rex.input - rex.line); +! rex.line = reg_tofree; + } + + /* Get the line to compare with. */ +*************** +*** 6499,6511 **** + else + len = (int)STRLEN(p + ccol); + +! if (cstrncmp(p + ccol, reginput, &len) != 0) + return RA_NOMATCH; /* doesn't match */ + if (bytelen != NULL) + *bytelen += len; + if (clnum == end_lnum) + break; /* match and at end! */ +! if (reglnum >= rex.reg_maxline) + return RA_NOMATCH; /* text too short */ + + /* Advance to next line. */ +--- 6501,6513 ---- + else + len = (int)STRLEN(p + ccol); + +! if (cstrncmp(p + ccol, rex.input, &len) != 0) + return RA_NOMATCH; /* doesn't match */ + if (bytelen != NULL) + *bytelen += len; + if (clnum == end_lnum) + break; /* match and at end! */ +! if (rex.lnum >= rex.reg_maxline) + return RA_NOMATCH; /* text too short */ + + /* Advance to next line. */ +*************** +*** 6518,6524 **** + return RA_FAIL; + } + +! /* found a match! Note that regline may now point to a copy of the line, + * that should not matter. */ + return RA_MATCH; + } +--- 6520,6526 ---- + return RA_FAIL; + } + +! /* found a match! Note that rex.line may now point to a copy of the line, + * that should not matter. */ + return RA_MATCH; + } +*************** +*** 8144,8151 **** +--- 8146,8155 ---- + regexp_engine = AUTOMATIC_ENGINE; + } + } ++ #ifdef DEBUG + bt_regengine.expr = expr; + nfa_regengine.expr = expr; ++ #endif + + /* + * First try the NFA engine, unless backtracking was requested. +*************** +*** 8243,8252 **** + regexec_T rex_save; + int rex_in_use_save = rex_in_use; + + if (rex_in_use) +! /* Being called recursively, save the state. */ + rex_save = rex; + rex_in_use = TRUE; + rex.reg_startp = NULL; + rex.reg_endp = NULL; + rex.reg_startpos = NULL; +--- 8247,8265 ---- + regexec_T rex_save; + int rex_in_use_save = rex_in_use; + ++ // Cannot use the same prog recursively, it contains state. ++ if (rmp->regprog->re_in_use) ++ { ++ EMSG(_(e_recursive)); ++ return FALSE; ++ } ++ rmp->regprog->re_in_use = TRUE; ++ + if (rex_in_use) +! // Being called recursively, save the state. + rex_save = rex; + rex_in_use = TRUE; ++ + rex.reg_startp = NULL; + rex.reg_endp = NULL; + rex.reg_startpos = NULL; +*************** +*** 8281,8286 **** +--- 8294,8300 ---- + rex_in_use = rex_in_use_save; + if (rex_in_use) + rex = rex_save; ++ rmp->regprog->re_in_use = FALSE; + + return result > 0; + } +*************** +*** 8353,8358 **** +--- 8367,8380 ---- + regexec_T rex_save; + int rex_in_use_save = rex_in_use; + ++ // Cannot use the same prog recursively, it contains state. ++ if (rmp->regprog->re_in_use) ++ { ++ EMSG(_(e_recursive)); ++ return FALSE; ++ } ++ rmp->regprog->re_in_use = TRUE; ++ + if (rex_in_use) + /* Being called recursively, save the state. */ + rex_save = rex; +*************** +*** 8397,8402 **** +--- 8419,8425 ---- + rex_in_use = rex_in_use_save; + if (rex_in_use) + rex = rex_save; ++ rmp->regprog->re_in_use = FALSE; + + return result <= 0 ? 0 : result; + } +*** ../vim-8.1.0191/src/regexp.h 2017-06-17 17:52:18.000000000 +0200 +--- src/regexp.h 2018-07-17 05:08:49.564483204 +0200 +*************** +*** 50,57 **** + { + regengine_T *engine; + unsigned regflags; +! unsigned re_engine; /* automatic, backtracking or nfa engine */ +! unsigned re_flags; /* second argument for vim_regcomp() */ + } regprog_T; + + /* +--- 50,58 ---- + { + regengine_T *engine; + unsigned regflags; +! unsigned re_engine; // automatic, backtracking or nfa engine +! unsigned re_flags; // second argument for vim_regcomp() +! int re_in_use; // prog is being executed + } regprog_T; + + /* +*************** +*** 65,71 **** + regengine_T *engine; + unsigned regflags; + unsigned re_engine; +! unsigned re_flags; /* second argument for vim_regcomp() */ + + int regstart; + char_u reganch; +--- 66,73 ---- + regengine_T *engine; + unsigned regflags; + unsigned re_engine; +! unsigned re_flags; +! int re_in_use; + + int regstart; + char_u reganch; +*************** +*** 101,107 **** + regengine_T *engine; + unsigned regflags; + unsigned re_engine; +! unsigned re_flags; /* second argument for vim_regcomp() */ + + nfa_state_T *start; /* points into state[] */ + +--- 103,110 ---- + regengine_T *engine; + unsigned regflags; + unsigned re_engine; +! unsigned re_flags; +! int re_in_use; + + nfa_state_T *start; /* points into state[] */ + +*** ../vim-8.1.0191/src/regexp_nfa.c 2018-07-08 19:07:16.159415508 +0200 +--- src/regexp_nfa.c 2018-07-17 05:08:49.568483181 +0200 +*************** +*** 244,284 **** + static char_u e_misplaced[] = N_("E866: (NFA regexp) Misplaced %c"); + static char_u e_ill_char_class[] = N_("E877: (NFA regexp) Invalid character class: %ld"); + +! /* re_flags passed to nfa_regcomp() */ +! static int nfa_re_flags; +! +! /* NFA regexp \ze operator encountered. */ +! static int nfa_has_zend; +! +! /* NFA regexp \1 .. \9 encountered. */ +! static int nfa_has_backref; +! +! #ifdef FEAT_SYN_HL +! /* NFA regexp has \z( ), set zsubexpr. */ +! static int nfa_has_zsubexpr; +! #endif +! +! /* Number of sub expressions actually being used during execution. 1 if only +! * the whole match (subexpr 0) is used. */ +! static int nfa_nsubexpr; +! +! static int *post_start; /* holds the postfix form of r.e. */ + static int *post_end; + static int *post_ptr; +! +! static int nstate; /* Number of states in the NFA. Also used when +! * executing. */ +! static int istate; /* Index in the state vector, used in alloc_state() */ + + /* If not NULL match must end at this position */ + static save_se_T *nfa_endp = NULL; + +- /* listid is global, so that it increases on recursive calls to +- * nfa_regmatch(), which means we don't have to clear the lastlist field of +- * all the states. */ +- static int nfa_listid; +- static int nfa_alt_listid; +- + /* 0 for first call to nfa_regmatch(), 1 for recursive call. */ + static int nfa_ll_index = 0; + +--- 244,260 ---- + static char_u e_misplaced[] = N_("E866: (NFA regexp) Misplaced %c"); + static char_u e_ill_char_class[] = N_("E877: (NFA regexp) Invalid character class: %ld"); + +! // Variables only used in nfa_regcomp() and descendants. +! static int nfa_re_flags; // re_flags passed to nfa_regcomp() +! static int *post_start; // holds the postfix form of r.e. + static int *post_end; + static int *post_ptr; +! static int nstate; // Number of states in the NFA. +! static int istate; // Index in the state vector, used in alloc_state() + + /* If not NULL match must end at this position */ + static save_se_T *nfa_endp = NULL; + + /* 0 for first call to nfa_regmatch(), 1 for recursive call. */ + static int nfa_ll_index = 0; + +*************** +*** 326,333 **** + return FAIL; + post_ptr = post_start; + post_end = post_start + nstate_max; +! nfa_has_zend = FALSE; +! nfa_has_backref = FALSE; + + /* shared with BT engine */ + regcomp_start(expr, re_flags); +--- 302,309 ---- + return FAIL; + post_ptr = post_start; + post_end = post_start + nstate_max; +! rex.nfa_has_zend = FALSE; +! rex.nfa_has_backref = FALSE; + + /* shared with BT engine */ + regcomp_start(expr, re_flags); +*************** +*** 1422,1428 **** + if (!seen_endbrace(refnum + 1)) + return FAIL; + EMIT(NFA_BACKREF1 + refnum); +! nfa_has_backref = TRUE; + } + break; + +--- 1398,1404 ---- + if (!seen_endbrace(refnum + 1)) + return FAIL; + EMIT(NFA_BACKREF1 + refnum); +! rex.nfa_has_backref = TRUE; + } + break; + +*************** +*** 1437,1443 **** + break; + case 'e': + EMIT(NFA_ZEND); +! nfa_has_zend = TRUE; + if (re_mult_next("\\ze") == FAIL) + return FAIL; + break; +--- 1413,1419 ---- + break; + case 'e': + EMIT(NFA_ZEND); +! rex.nfa_has_zend = TRUE; + if (re_mult_next("\\ze") == FAIL) + return FAIL; + break; +*************** +*** 1455,1461 **** + if ((reg_do_extmatch & REX_USE) == 0) + EMSG_RET_FAIL(_(e_z1_not_allowed)); + EMIT(NFA_ZREF1 + (no_Magic(c) - '1')); +! /* No need to set nfa_has_backref, the sub-matches don't + * change when \z1 .. \z9 matches or not. */ + re_has_z = REX_USE; + break; +--- 1431,1437 ---- + if ((reg_do_extmatch & REX_USE) == 0) + EMSG_RET_FAIL(_(e_z1_not_allowed)); + EMIT(NFA_ZREF1 + (no_Magic(c) - '1')); +! /* No need to set rex.nfa_has_backref, the sub-matches don't + * change when \z1 .. \z9 matches or not. */ + re_has_z = REX_USE; + break; +*************** +*** 2920,2930 **** + if (df) + { + fprintf(df, "Error popping the stack!\n"); +! #ifdef DEBUG + fprintf(df, "Current regexp is \"%s\"\n", nfa_regengine.expr); +! #endif + fprintf(df, "Postfix form is: "); +! #ifdef DEBUG + for (p2 = postfix; p2 < end; p2++) + { + nfa_set_code(*p2); +--- 2896,2906 ---- + if (df) + { + fprintf(df, "Error popping the stack!\n"); +! # ifdef DEBUG + fprintf(df, "Current regexp is \"%s\"\n", nfa_regengine.expr); +! # endif + fprintf(df, "Postfix form is: "); +! # ifdef DEBUG + for (p2 = postfix; p2 < end; p2++) + { + nfa_set_code(*p2); +*************** +*** 2937,2943 **** + nfa_set_code(*p2); + fprintf(df, "%s, ", code); + } +! #else + for (p2 = postfix; p2 < end; p2++) + { + fprintf(df, "%d, ", *p2); +--- 2913,2919 ---- + nfa_set_code(*p2); + fprintf(df, "%s, ", code); + } +! # else + for (p2 = postfix; p2 < end; p2++) + { + fprintf(df, "%d, ", *p2); +*************** +*** 2947,2953 **** + { + fprintf(df, "%d, ", *p2); + } +! #endif + fprintf(df, "\n--------------------------\n"); + fclose(df); + } +--- 2923,2929 ---- + { + fprintf(df, "%d, ", *p2); + } +! # endif + fprintf(df, "\n--------------------------\n"); + fclose(df); + } +*************** +*** 3887,3893 **** + { + log_subexpr(&subs->norm); + # ifdef FEAT_SYN_HL +! if (nfa_has_zsubexpr) + log_subexpr(&subs->synt); + # endif + } +--- 3863,3869 ---- + { + log_subexpr(&subs->norm); + # ifdef FEAT_SYN_HL +! if (rex.nfa_has_zsubexpr) + log_subexpr(&subs->synt); + # endif + } +*************** +*** 3927,3933 **** + else + { + sprintf(buf, " PIM col %d", REG_MULTI ? (int)pim->end.pos.col +! : (int)(pim->end.ptr - reginput)); + } + return buf; + } +--- 3903,3909 ---- + else + { + sprintf(buf, " PIM col %d", REG_MULTI ? (int)pim->end.pos.col +! : (int)(pim->end.ptr - rex.input)); + } + return buf; + } +*************** +*** 3955,3961 **** + to->state = from->state; + copy_sub(&to->subs.norm, &from->subs.norm); + #ifdef FEAT_SYN_HL +! if (nfa_has_zsubexpr) + copy_sub(&to->subs.synt, &from->subs.synt); + #endif + to->end = from->end; +--- 3931,3937 ---- + to->state = from->state; + copy_sub(&to->subs.norm, &from->subs.norm); + #ifdef FEAT_SYN_HL +! if (rex.nfa_has_zsubexpr) + copy_sub(&to->subs.synt, &from->subs.synt); + #endif + to->end = from->end; +*************** +*** 3967,3975 **** + if (REG_MULTI) + /* Use 0xff to set lnum to -1 */ + vim_memset(sub->list.multi, 0xff, +! sizeof(struct multipos) * nfa_nsubexpr); + else +! vim_memset(sub->list.line, 0, sizeof(struct linepos) * nfa_nsubexpr); + sub->in_use = 0; + } + +--- 3943,3952 ---- + if (REG_MULTI) + /* Use 0xff to set lnum to -1 */ + vim_memset(sub->list.multi, 0xff, +! sizeof(struct multipos) * rex.nfa_nsubexpr); + else +! vim_memset(sub->list.line, 0, +! sizeof(struct linepos) * rex.nfa_nsubexpr); + sub->in_use = 0; + } + +*************** +*** 4022,4028 **** + static void + copy_ze_off(regsub_T *to, regsub_T *from) + { +! if (nfa_has_zend) + { + if (REG_MULTI) + { +--- 3999,4005 ---- + static void + copy_ze_off(regsub_T *to, regsub_T *from) + { +! if (rex.nfa_has_zend) + { + if (REG_MULTI) + { +*************** +*** 4073,4079 **** + != sub2->list.multi[i].start_col) + return FALSE; + +! if (nfa_has_backref) + { + if (i < sub1->in_use) + s1 = sub1->list.multi[i].end_lnum; +--- 4050,4056 ---- + != sub2->list.multi[i].start_col) + return FALSE; + +! if (rex.nfa_has_backref) + { + if (i < sub1->in_use) + s1 = sub1->list.multi[i].end_lnum; +*************** +*** 4105,4111 **** + sp2 = NULL; + if (sp1 != sp2) + return FALSE; +! if (nfa_has_backref) + { + if (i < sub1->in_use) + sp1 = sub1->list.line[i].end; +--- 4082,4088 ---- + sp2 = NULL; + if (sp1 != sp2) + return FALSE; +! if (rex.nfa_has_backref) + { + if (i < sub1->in_use) + sp1 = sub1->list.line[i].end; +*************** +*** 4139,4145 **** + else if (REG_MULTI) + col = sub->list.multi[0].start_col; + else +! col = (int)(sub->list.line[0].start - regline); + nfa_set_code(state->c); + fprintf(log_fd, "> %s state %d to list %d. char %d: %s (start col %d)%s\n", + action, abs(state->id), lid, state->c, code, col, +--- 4116,4122 ---- + else if (REG_MULTI) + col = sub->list.multi[0].start_col; + else +! col = (int)(sub->list.line[0].start - rex.line); + nfa_set_code(state->c); + fprintf(log_fd, "> %s state %d to list %d. char %d: %s (start col %d)%s\n", + action, abs(state->id), lid, state->c, code, col, +*************** +*** 4167,4173 **** + if (thread->state->id == state->id + && sub_equal(&thread->subs.norm, &subs->norm) + #ifdef FEAT_SYN_HL +! && (!nfa_has_zsubexpr + || sub_equal(&thread->subs.synt, &subs->synt)) + #endif + && pim_equal(&thread->pim, pim)) +--- 4144,4150 ---- + if (thread->state->id == state->id + && sub_equal(&thread->subs.norm, &subs->norm) + #ifdef FEAT_SYN_HL +! && (!rex.nfa_has_zsubexpr + || sub_equal(&thread->subs.synt, &subs->synt)) + #endif + && pim_equal(&thread->pim, pim)) +*************** +*** 4306,4312 **** + { + if (state->lastlist[nfa_ll_index] == l->id) + { +! if (!nfa_has_backref || has_state_with_pos(l, state, subs, NULL)) + return TRUE; + } + return FALSE; +--- 4283,4289 ---- + { + if (state->lastlist[nfa_ll_index] == l->id) + { +! if (!rex.nfa_has_backref || has_state_with_pos(l, state, subs, NULL)) + return TRUE; + } + return FALSE; +*************** +*** 4390,4400 **** + /* "^" won't match past end-of-line, don't bother trying. + * Except when at the end of the line, or when we are going to the + * next line for a look-behind match. */ +! if (reginput > regline +! && *reginput != NUL + && (nfa_endp == NULL + || !REG_MULTI +! || reglnum == nfa_endp->se_u.pos.lnum)) + goto skip_add; + /* FALLTHROUGH */ + +--- 4367,4377 ---- + /* "^" won't match past end-of-line, don't bother trying. + * Except when at the end of the line, or when we are going to the + * next line for a look-behind match. */ +! if (rex.input > rex.line +! && *rex.input != NUL + && (nfa_endp == NULL + || !REG_MULTI +! || rex.lnum == nfa_endp->se_u.pos.lnum)) + goto skip_add; + /* FALLTHROUGH */ + +*************** +*** 4432,4438 **** + * unless it is an MOPEN that is used for a backreference or + * when there is a PIM. For NFA_MATCH check the position, + * lower position is preferred. */ +! if (!nfa_has_backref && pim == NULL && !l->has_pim + && state->c != NFA_MATCH) + { + /* When called from addstate_here() do insert before +--- 4409,4415 ---- + * unless it is an MOPEN that is used for a backreference or + * when there is a PIM. For NFA_MATCH check the position, + * lower position is preferred. */ +! if (!rex.nfa_has_backref && pim == NULL && !l->has_pim + && state->c != NFA_MATCH) + { + /* When called from addstate_here() do insert before +*************** +*** 4477,4483 **** + * copy before it becomes invalid. */ + copy_sub(&temp_subs.norm, &subs->norm); + #ifdef FEAT_SYN_HL +! if (nfa_has_zsubexpr) + copy_sub(&temp_subs.synt, &subs->synt); + #endif + subs = &temp_subs; +--- 4454,4460 ---- + * copy before it becomes invalid. */ + copy_sub(&temp_subs.norm, &subs->norm); + #ifdef FEAT_SYN_HL +! if (rex.nfa_has_zsubexpr) + copy_sub(&temp_subs.synt, &subs->synt); + #endif + subs = &temp_subs; +*************** +*** 4501,4507 **** + } + copy_sub(&thread->subs.norm, &subs->norm); + #ifdef FEAT_SYN_HL +! if (nfa_has_zsubexpr) + copy_sub(&thread->subs.synt, &subs->synt); + #endif + #ifdef ENABLE_LOG +--- 4478,4484 ---- + } + copy_sub(&thread->subs.norm, &subs->norm); + #ifdef FEAT_SYN_HL +! if (rex.nfa_has_zsubexpr) + copy_sub(&thread->subs.synt, &subs->synt); + #endif + #ifdef ENABLE_LOG +*************** +*** 4597,4610 **** + } + if (off == -1) + { +! sub->list.multi[subidx].start_lnum = reglnum + 1; + sub->list.multi[subidx].start_col = 0; + } + else + { +! sub->list.multi[subidx].start_lnum = reglnum; + sub->list.multi[subidx].start_col = +! (colnr_T)(reginput - regline + off); + } + sub->list.multi[subidx].end_lnum = -1; + } +--- 4574,4587 ---- + } + if (off == -1) + { +! sub->list.multi[subidx].start_lnum = rex.lnum + 1; + sub->list.multi[subidx].start_col = 0; + } + else + { +! sub->list.multi[subidx].start_lnum = rex.lnum; + sub->list.multi[subidx].start_col = +! (colnr_T)(rex.input - rex.line + off); + } + sub->list.multi[subidx].end_lnum = -1; + } +*************** +*** 4625,4631 **** + } + sub->in_use = subidx + 1; + } +! sub->list.line[subidx].start = reginput + off; + } + + subs = addstate(l, state->out, subs, pim, off_arg); +--- 4602,4608 ---- + } + sub->in_use = subidx + 1; + } +! sub->list.line[subidx].start = rex.input + off; + } + + subs = addstate(l, state->out, subs, pim, off_arg); +*************** +*** 4649,4655 **** + break; + + case NFA_MCLOSE: +! if (nfa_has_zend && (REG_MULTI + ? subs->norm.list.multi[0].end_lnum >= 0 + : subs->norm.list.line[0].end != NULL)) + { +--- 4626,4632 ---- + break; + + case NFA_MCLOSE: +! if (rex.nfa_has_zend && (REG_MULTI + ? subs->norm.list.multi[0].end_lnum >= 0 + : subs->norm.list.line[0].end != NULL)) + { +*************** +*** 4708,4721 **** + save_multipos = sub->list.multi[subidx]; + if (off == -1) + { +! sub->list.multi[subidx].end_lnum = reglnum + 1; + sub->list.multi[subidx].end_col = 0; + } + else + { +! sub->list.multi[subidx].end_lnum = reglnum; + sub->list.multi[subidx].end_col = +! (colnr_T)(reginput - regline + off); + } + /* avoid compiler warnings */ + save_ptr = NULL; +--- 4685,4698 ---- + save_multipos = sub->list.multi[subidx]; + if (off == -1) + { +! sub->list.multi[subidx].end_lnum = rex.lnum + 1; + sub->list.multi[subidx].end_col = 0; + } + else + { +! sub->list.multi[subidx].end_lnum = rex.lnum; + sub->list.multi[subidx].end_col = +! (colnr_T)(rex.input - rex.line + off); + } + /* avoid compiler warnings */ + save_ptr = NULL; +*************** +*** 4723,4729 **** + else + { + save_ptr = sub->list.line[subidx].end; +! sub->list.line[subidx].end = reginput + off; + /* avoid compiler warnings */ + vim_memset(&save_multipos, 0, sizeof(save_multipos)); + } +--- 4700,4706 ---- + else + { + save_ptr = sub->list.line[subidx].end; +! sub->list.line[subidx].end = rex.input + off; + /* avoid compiler warnings */ + vim_memset(&save_multipos, 0, sizeof(save_multipos)); + } +*************** +*** 4929,4941 **** + if (sub->list.multi[subidx].start_lnum < 0 + || sub->list.multi[subidx].end_lnum < 0) + goto retempty; +! if (sub->list.multi[subidx].start_lnum == reglnum +! && sub->list.multi[subidx].end_lnum == reglnum) + { + len = sub->list.multi[subidx].end_col + - sub->list.multi[subidx].start_col; +! if (cstrncmp(regline + sub->list.multi[subidx].start_col, +! reginput, &len) == 0) + { + *bytelen = len; + return TRUE; +--- 4906,4918 ---- + if (sub->list.multi[subidx].start_lnum < 0 + || sub->list.multi[subidx].end_lnum < 0) + goto retempty; +! if (sub->list.multi[subidx].start_lnum == rex.lnum +! && sub->list.multi[subidx].end_lnum == rex.lnum) + { + len = sub->list.multi[subidx].end_col + - sub->list.multi[subidx].start_col; +! if (cstrncmp(rex.line + sub->list.multi[subidx].start_col, +! rex.input, &len) == 0) + { + *bytelen = len; + return TRUE; +*************** +*** 4958,4964 **** + || sub->list.line[subidx].end == NULL) + goto retempty; + len = (int)(sub->list.line[subidx].end - sub->list.line[subidx].start); +! if (cstrncmp(sub->list.line[subidx].start, reginput, &len) == 0) + { + *bytelen = len; + return TRUE; +--- 4935,4941 ---- + || sub->list.line[subidx].end == NULL) + goto retempty; + len = (int)(sub->list.line[subidx].end - sub->list.line[subidx].start); +! if (cstrncmp(sub->list.line[subidx].start, rex.input, &len) == 0) + { + *bytelen = len; + return TRUE; +*************** +*** 4989,4995 **** + } + + len = (int)STRLEN(re_extmatch_in->matches[subidx]); +! if (cstrncmp(re_extmatch_in->matches[subidx], reginput, &len) == 0) + { + *bytelen = len; + return TRUE; +--- 4966,4972 ---- + } + + len = (int)STRLEN(re_extmatch_in->matches[subidx]); +! if (cstrncmp(re_extmatch_in->matches[subidx], rex.input, &len) == 0) + { + *bytelen = len; + return TRUE; +*************** +*** 5061,5070 **** + int **listids, + int *listids_len) + { +! int save_reginput_col = (int)(reginput - regline); +! int save_reglnum = reglnum; + int save_nfa_match = nfa_match; +! int save_nfa_listid = nfa_listid; + save_se_T *save_nfa_endp = nfa_endp; + save_se_T endpos; + save_se_T *endposp = NULL; +--- 5038,5047 ---- + int **listids, + int *listids_len) + { +! int save_reginput_col = (int)(rex.input - rex.line); +! int save_reglnum = rex.lnum; + int save_nfa_match = nfa_match; +! int save_nfa_listid = rex.nfa_listid; + save_se_T *save_nfa_endp = nfa_endp; + save_se_T endpos; + save_se_T *endposp = NULL; +*************** +*** 5075,5083 **** + { + /* start at the position where the postponed match was */ + if (REG_MULTI) +! reginput = regline + pim->end.pos.col; + else +! reginput = pim->end.ptr; + } + + if (state->c == NFA_START_INVISIBLE_BEFORE +--- 5052,5060 ---- + { + /* start at the position where the postponed match was */ + if (REG_MULTI) +! rex.input = rex.line + pim->end.pos.col; + else +! rex.input = pim->end.ptr; + } + + if (state->c == NFA_START_INVISIBLE_BEFORE +*************** +*** 5092,5099 **** + { + if (pim == NULL) + { +! endpos.se_u.pos.col = (int)(reginput - regline); +! endpos.se_u.pos.lnum = reglnum; + } + else + endpos.se_u.pos = pim->end.pos; +--- 5069,5076 ---- + { + if (pim == NULL) + { +! endpos.se_u.pos.col = (int)(rex.input - rex.line); +! endpos.se_u.pos.lnum = rex.lnum; + } + else + endpos.se_u.pos = pim->end.pos; +*************** +*** 5101,5107 **** + else + { + if (pim == NULL) +! endpos.se_u.ptr = reginput; + else + endpos.se_u.ptr = pim->end.ptr; + } +--- 5078,5084 ---- + else + { + if (pim == NULL) +! endpos.se_u.ptr = rex.input; + else + endpos.se_u.ptr = pim->end.ptr; + } +*************** +*** 5114,5152 **** + { + if (REG_MULTI) + { +! regline = reg_getline(--reglnum); +! if (regline == NULL) + /* can't go before the first line */ +! regline = reg_getline(++reglnum); + } +! reginput = regline; + } + else + { +! if (REG_MULTI && (int)(reginput - regline) < state->val) + { + /* Not enough bytes in this line, go to end of + * previous line. */ +! regline = reg_getline(--reglnum); +! if (regline == NULL) + { + /* can't go before the first line */ +! regline = reg_getline(++reglnum); +! reginput = regline; + } + else +! reginput = regline + STRLEN(regline); + } +! if ((int)(reginput - regline) >= state->val) + { +! reginput -= state->val; + #ifdef FEAT_MBYTE + if (has_mbyte) +! reginput -= mb_head_off(regline, reginput); + #endif + } + else +! reginput = regline; + } + } + +--- 5091,5129 ---- + { + if (REG_MULTI) + { +! rex.line = reg_getline(--rex.lnum); +! if (rex.line == NULL) + /* can't go before the first line */ +! rex.line = reg_getline(++rex.lnum); + } +! rex.input = rex.line; + } + else + { +! if (REG_MULTI && (int)(rex.input - rex.line) < state->val) + { + /* Not enough bytes in this line, go to end of + * previous line. */ +! rex.line = reg_getline(--rex.lnum); +! if (rex.line == NULL) + { + /* can't go before the first line */ +! rex.line = reg_getline(++rex.lnum); +! rex.input = rex.line; + } + else +! rex.input = rex.line + STRLEN(rex.line); + } +! if ((int)(rex.input - rex.line) >= state->val) + { +! rex.input -= state->val; + #ifdef FEAT_MBYTE + if (has_mbyte) +! rex.input -= mb_head_off(rex.line, rex.input); + #endif + } + else +! rex.input = rex.line; + } + } + +*************** +*** 5161,5189 **** + { + /* Already calling nfa_regmatch() recursively. Save the lastlist[1] + * values and clear them. */ +! if (*listids == NULL || *listids_len < nstate) + { + vim_free(*listids); +! *listids = (int *)lalloc(sizeof(int) * nstate, TRUE); + if (*listids == NULL) + { + EMSG(_("E878: (NFA) Could not allocate memory for branch traversal!")); + return 0; + } +! *listids_len = nstate; + } + nfa_save_listids(prog, *listids); + need_restore = TRUE; +! /* any value of nfa_listid will do */ + } + else + { + /* First recursive nfa_regmatch() call, switch to the second lastlist +! * entry. Make sure nfa_listid is different from a previous recursive +! * call, because some states may still have this ID. */ + ++nfa_ll_index; +! if (nfa_listid <= nfa_alt_listid) +! nfa_listid = nfa_alt_listid; + } + + /* Call nfa_regmatch() to check if the current concat matches at this +--- 5138,5166 ---- + { + /* Already calling nfa_regmatch() recursively. Save the lastlist[1] + * values and clear them. */ +! if (*listids == NULL || *listids_len < prog->nstate) + { + vim_free(*listids); +! *listids = (int *)lalloc(sizeof(int) * prog->nstate, TRUE); + if (*listids == NULL) + { + EMSG(_("E878: (NFA) Could not allocate memory for branch traversal!")); + return 0; + } +! *listids_len = prog->nstate; + } + nfa_save_listids(prog, *listids); + need_restore = TRUE; +! /* any value of rex.nfa_listid will do */ + } + else + { + /* First recursive nfa_regmatch() call, switch to the second lastlist +! * entry. Make sure rex.nfa_listid is different from a previous +! * recursive call, because some states may still have this ID. */ + ++nfa_ll_index; +! if (rex.nfa_listid <= rex.nfa_alt_listid) +! rex.nfa_listid = rex.nfa_alt_listid; + } + + /* Call nfa_regmatch() to check if the current concat matches at this +*************** +*** 5196,5213 **** + else + { + --nfa_ll_index; +! nfa_alt_listid = nfa_listid; + } + + /* restore position in input text */ +! reglnum = save_reglnum; + if (REG_MULTI) +! regline = reg_getline(reglnum); +! reginput = regline + save_reginput_col; + if (result != NFA_TOO_EXPENSIVE) + { + nfa_match = save_nfa_match; +! nfa_listid = save_nfa_listid; + } + nfa_endp = save_nfa_endp; + +--- 5173,5190 ---- + else + { + --nfa_ll_index; +! rex.nfa_alt_listid = rex.nfa_listid; + } + + /* restore position in input text */ +! rex.lnum = save_reglnum; + if (REG_MULTI) +! rex.line = reg_getline(rex.lnum); +! rex.input = rex.line + save_reginput_col; + if (result != NFA_TOO_EXPENSIVE) + { + nfa_match = save_nfa_match; +! rex.nfa_listid = save_nfa_listid; + } + nfa_endp = save_nfa_endp; + +*************** +*** 5407,5418 **** + && !has_mbyte + #endif + ) +! s = vim_strbyte(regline + *colp, c); + else +! s = cstrchr(regline + *colp, c); + if (s == NULL) + return FAIL; +! *colp = (int)(s - regline); + return OK; + } + +--- 5384,5395 ---- + && !has_mbyte + #endif + ) +! s = vim_strbyte(rex.line + *colp, c); + else +! s = cstrchr(rex.line + *colp, c); + if (s == NULL) + return FAIL; +! *colp = (int)(s - rex.line); + return OK; + } + +*************** +*** 5436,5442 **** + for (len1 = 0; match_text[len1] != NUL; len1 += MB_CHAR2LEN(c1)) + { + c1 = PTR2CHAR(match_text + len1); +! c2 = PTR2CHAR(regline + col + len2); + if (c1 != c2 && (!rex.reg_ic || MB_TOLOWER(c1) != MB_TOLOWER(c2))) + { + match = FALSE; +--- 5413,5419 ---- + for (len1 = 0; match_text[len1] != NUL; len1 += MB_CHAR2LEN(c1)) + { + c1 = PTR2CHAR(match_text + len1); +! c2 = PTR2CHAR(rex.line + col + len2); + if (c1 != c2 && (!rex.reg_ic || MB_TOLOWER(c1) != MB_TOLOWER(c2))) + { + match = FALSE; +*************** +*** 5448,5469 **** + #ifdef FEAT_MBYTE + /* check that no composing char follows */ + && !(enc_utf8 +! && utf_iscomposing(PTR2CHAR(regline + col + len2))) + #endif + ) + { + cleanup_subexpr(); + if (REG_MULTI) + { +! rex.reg_startpos[0].lnum = reglnum; + rex.reg_startpos[0].col = col; +! rex.reg_endpos[0].lnum = reglnum; + rex.reg_endpos[0].col = col + len2; + } + else + { +! rex.reg_startp[0] = regline + col; +! rex.reg_endp[0] = regline + col + len2; + } + return 1L; + } +--- 5425,5446 ---- + #ifdef FEAT_MBYTE + /* check that no composing char follows */ + && !(enc_utf8 +! && utf_iscomposing(PTR2CHAR(rex.line + col + len2))) + #endif + ) + { + cleanup_subexpr(); + if (REG_MULTI) + { +! rex.reg_startpos[0].lnum = rex.lnum; + rex.reg_startpos[0].col = col; +! rex.reg_endpos[0].lnum = rex.lnum; + rex.reg_endpos[0].col = col + len2; + } + else + { +! rex.reg_startp[0] = rex.line + col; +! rex.reg_endp[0] = rex.line + col + len2; + } + return 1L; + } +*************** +*** 5493,5499 **** + /* + * Main matching routine. + * +! * Run NFA to determine whether it matches reginput. + * + * When "nfa_endp" is not NULL it is a required end-of-match position. + * +--- 5470,5476 ---- + /* + * Main matching routine. + * +! * Run NFA to determine whether it matches rex.input. + * + * When "nfa_endp" is not NULL it is a required end-of-match position. + * +*************** +*** 5549,5560 **** + nfa_match = FALSE; + + /* Allocate memory for the lists of nodes. */ +! size = (nstate + 1) * sizeof(nfa_thread_T); + + list[0].t = (nfa_thread_T *)lalloc(size, TRUE); +! list[0].len = nstate + 1; + list[1].t = (nfa_thread_T *)lalloc(size, TRUE); +! list[1].len = nstate + 1; + if (list[0].t == NULL || list[1].t == NULL) + goto theend; + +--- 5526,5537 ---- + nfa_match = FALSE; + + /* Allocate memory for the lists of nodes. */ +! size = (prog->nstate + 1) * sizeof(nfa_thread_T); + + list[0].t = (nfa_thread_T *)lalloc(size, TRUE); +! list[0].len = prog->nstate + 1; + list[1].t = (nfa_thread_T *)lalloc(size, TRUE); +! list[1].len = prog->nstate + 1; + if (list[0].t == NULL || list[1].t == NULL) + goto theend; + +*************** +*** 5584,5590 **** + #ifdef ENABLE_LOG + fprintf(log_fd, "(---) STARTSTATE first\n"); + #endif +! thislist->id = nfa_listid + 1; + + /* Inline optimized code for addstate(thislist, start, m, 0) if we know + * it's the first MOPEN. */ +--- 5561,5567 ---- + #ifdef ENABLE_LOG + fprintf(log_fd, "(---) STARTSTATE first\n"); + #endif +! thislist->id = rex.nfa_listid + 1; + + /* Inline optimized code for addstate(thislist, start, m, 0) if we know + * it's the first MOPEN. */ +*************** +*** 5592,5602 **** + { + if (REG_MULTI) + { +! m->norm.list.multi[0].start_lnum = reglnum; +! m->norm.list.multi[0].start_col = (colnr_T)(reginput - regline); + } + else +! m->norm.list.line[0].start = reginput; + m->norm.in_use = 1; + addstate(thislist, start->out, m, NULL, 0); + } +--- 5569,5579 ---- + { + if (REG_MULTI) + { +! m->norm.list.multi[0].start_lnum = rex.lnum; +! m->norm.list.multi[0].start_col = (colnr_T)(rex.input - rex.line); + } + else +! m->norm.list.line[0].start = rex.input; + m->norm.in_use = 1; + addstate(thislist, start->out, m, NULL, 0); + } +*************** +*** 5620,5632 **** + #ifdef FEAT_MBYTE + if (has_mbyte) + { +! curc = (*mb_ptr2char)(reginput); +! clen = (*mb_ptr2len)(reginput); + } + else + #endif + { +! curc = *reginput; + clen = 1; + } + if (curc == NUL) +--- 5597,5609 ---- + #ifdef FEAT_MBYTE + if (has_mbyte) + { +! curc = (*mb_ptr2char)(rex.input); +! clen = (*mb_ptr2len)(rex.input); + } + else + #endif + { +! curc = *rex.input; + clen = 1; + } + if (curc == NUL) +*************** +*** 5640,5648 **** + nextlist = &list[flag ^= 1]; + nextlist->n = 0; /* clear nextlist */ + nextlist->has_pim = FALSE; +! ++nfa_listid; + if (prog->re_engine == AUTOMATIC_ENGINE +! && (nfa_listid >= NFA_MAX_STATES + # ifdef FEAT_EVAL + || nfa_fail_for_testing + # endif +--- 5617,5625 ---- + nextlist = &list[flag ^= 1]; + nextlist->n = 0; /* clear nextlist */ + nextlist->has_pim = FALSE; +! ++rex.nfa_listid; + if (prog->re_engine == AUTOMATIC_ENGINE +! && (rex.nfa_listid >= NFA_MAX_STATES + # ifdef FEAT_EVAL + || nfa_fail_for_testing + # endif +*************** +*** 5653,5664 **** + goto theend; + } + +! thislist->id = nfa_listid; +! nextlist->id = nfa_listid + 1; + + #ifdef ENABLE_LOG + fprintf(log_fd, "------------------------------------------\n"); +! fprintf(log_fd, ">>> Reginput is \"%s\"\n", reginput); + fprintf(log_fd, ">>> Advanced one character... Current char is %c (code %d) \n", curc, (int)curc); + fprintf(log_fd, ">>> Thislist has %d states available: ", thislist->n); + { +--- 5630,5641 ---- + goto theend; + } + +! thislist->id = rex.nfa_listid; +! nextlist->id = rex.nfa_listid + 1; + + #ifdef ENABLE_LOG + fprintf(log_fd, "------------------------------------------\n"); +! fprintf(log_fd, ">>> Reginput is \"%s\"\n", rex.input); + fprintf(log_fd, ">>> Advanced one character... Current char is %c (code %d) \n", curc, (int)curc); + fprintf(log_fd, ">>> Thislist has %d states available: ", thislist->n); + { +*************** +*** 5710,5716 **** + else if (REG_MULTI) + col = t->subs.norm.list.multi[0].start_col; + else +! col = (int)(t->subs.norm.list.line[0].start - regline); + nfa_set_code(t->state->c); + fprintf(log_fd, "(%d) char %d %s (start col %d)%s... \n", + abs(t->state->id), (int)t->state->c, code, col, +--- 5687,5693 ---- + else if (REG_MULTI) + col = t->subs.norm.list.multi[0].start_col; + else +! col = (int)(t->subs.norm.list.line[0].start - rex.line); + nfa_set_code(t->state->c); + fprintf(log_fd, "(%d) char %d %s (start col %d)%s... \n", + abs(t->state->id), (int)t->state->c, code, col, +*************** +*** 5738,5744 **** + nfa_match = TRUE; + copy_sub(&submatch->norm, &t->subs.norm); + #ifdef FEAT_SYN_HL +! if (nfa_has_zsubexpr) + copy_sub(&submatch->synt, &t->subs.synt); + #endif + #ifdef ENABLE_LOG +--- 5715,5721 ---- + nfa_match = TRUE; + copy_sub(&submatch->norm, &t->subs.norm); + #ifdef FEAT_SYN_HL +! if (rex.nfa_has_zsubexpr) + copy_sub(&submatch->synt, &t->subs.synt); + #endif + #ifdef ENABLE_LOG +*************** +*** 5746,5752 **** + #endif + /* Found the left-most longest match, do not look at any other + * states at this position. When the list of states is going +! * to be empty quit without advancing, so that "reginput" is + * correct. */ + if (nextlist->n == 0) + clen = 0; +--- 5723,5729 ---- + #endif + /* Found the left-most longest match, do not look at any other + * states at this position. When the list of states is going +! * to be empty quit without advancing, so that "rex.input" is + * correct. */ + if (nextlist->n == 0) + clen = 0; +*************** +*** 5772,5794 **** + { + if (REG_MULTI) + fprintf(log_fd, "Current lnum: %d, endp lnum: %d; current col: %d, endp col: %d\n", +! (int)reglnum, + (int)nfa_endp->se_u.pos.lnum, +! (int)(reginput - regline), + nfa_endp->se_u.pos.col); + else + fprintf(log_fd, "Current col: %d, endp col: %d\n", +! (int)(reginput - regline), +! (int)(nfa_endp->se_u.ptr - reginput)); + } + #endif + /* If "nfa_endp" is set it's only a match if it ends at + * "nfa_endp" */ + if (nfa_endp != NULL && (REG_MULTI +! ? (reglnum != nfa_endp->se_u.pos.lnum +! || (int)(reginput - regline) + != nfa_endp->se_u.pos.col) +! : reginput != nfa_endp->se_u.ptr)) + break; + + /* do not set submatches for \@! */ +--- 5749,5771 ---- + { + if (REG_MULTI) + fprintf(log_fd, "Current lnum: %d, endp lnum: %d; current col: %d, endp col: %d\n", +! (int)rex.lnum, + (int)nfa_endp->se_u.pos.lnum, +! (int)(rex.input - rex.line), + nfa_endp->se_u.pos.col); + else + fprintf(log_fd, "Current col: %d, endp col: %d\n", +! (int)(rex.input - rex.line), +! (int)(nfa_endp->se_u.ptr - rex.input)); + } + #endif + /* If "nfa_endp" is set it's only a match if it ends at + * "nfa_endp" */ + if (nfa_endp != NULL && (REG_MULTI +! ? (rex.lnum != nfa_endp->se_u.pos.lnum +! || (int)(rex.input - rex.line) + != nfa_endp->se_u.pos.col) +! : rex.input != nfa_endp->se_u.ptr)) + break; + + /* do not set submatches for \@! */ +*************** +*** 5796,5802 **** + { + copy_sub(&m->norm, &t->subs.norm); + #ifdef FEAT_SYN_HL +! if (nfa_has_zsubexpr) + copy_sub(&m->synt, &t->subs.synt); + #endif + } +--- 5773,5779 ---- + { + copy_sub(&m->norm, &t->subs.norm); + #ifdef FEAT_SYN_HL +! if (rex.nfa_has_zsubexpr) + copy_sub(&m->synt, &t->subs.synt); + #endif + } +*************** +*** 5838,5844 **** + * of what happens on success below. */ + copy_sub_off(&m->norm, &t->subs.norm); + #ifdef FEAT_SYN_HL +! if (nfa_has_zsubexpr) + copy_sub_off(&m->synt, &t->subs.synt); + #endif + +--- 5815,5821 ---- + * of what happens on success below. */ + copy_sub_off(&m->norm, &t->subs.norm); + #ifdef FEAT_SYN_HL +! if (rex.nfa_has_zsubexpr) + copy_sub_off(&m->synt, &t->subs.synt); + #endif + +*************** +*** 5866,5872 **** + /* Copy submatch info from the recursive call */ + copy_sub_off(&t->subs.norm, &m->norm); + #ifdef FEAT_SYN_HL +! if (nfa_has_zsubexpr) + copy_sub_off(&t->subs.synt, &m->synt); + #endif + /* If the pattern has \ze and it matched in the +--- 5843,5849 ---- + /* Copy submatch info from the recursive call */ + copy_sub_off(&t->subs.norm, &m->norm); + #ifdef FEAT_SYN_HL +! if (rex.nfa_has_zsubexpr) + copy_sub_off(&t->subs.synt, &m->synt); + #endif + /* If the pattern has \ze and it matched in the +*************** +*** 5899,5909 **** + #endif + if (REG_MULTI) + { +! pim.end.pos.col = (int)(reginput - regline); +! pim.end.pos.lnum = reglnum; + } + else +! pim.end.ptr = reginput; + + /* t->state->out1 is the corresponding END_INVISIBLE + * node; Add its out to the current list (zero-width +--- 5876,5886 ---- + #endif + if (REG_MULTI) + { +! pim.end.pos.col = (int)(rex.input - rex.line); +! pim.end.pos.lnum = rex.lnum; + } + else +! pim.end.ptr = rex.input; + + /* t->state->out1 is the corresponding END_INVISIBLE + * node; Add its out to the current list (zero-width +*************** +*** 5959,5965 **** + * happens afterwards. */ + copy_sub_off(&m->norm, &t->subs.norm); + #ifdef FEAT_SYN_HL +! if (nfa_has_zsubexpr) + copy_sub_off(&m->synt, &t->subs.synt); + #endif + +--- 5936,5942 ---- + * happens afterwards. */ + copy_sub_off(&m->norm, &t->subs.norm); + #ifdef FEAT_SYN_HL +! if (rex.nfa_has_zsubexpr) + copy_sub_off(&m->synt, &t->subs.synt); + #endif + +*************** +*** 5982,5988 **** + /* Copy submatch info from the recursive call */ + copy_sub_off(&t->subs.norm, &m->norm); + #ifdef FEAT_SYN_HL +! if (nfa_has_zsubexpr) + copy_sub_off(&t->subs.synt, &m->synt); + #endif + /* Now we need to skip over the matched text and then +--- 5959,5965 ---- + /* Copy submatch info from the recursive call */ + copy_sub_off(&t->subs.norm, &m->norm); + #ifdef FEAT_SYN_HL +! if (rex.nfa_has_zsubexpr) + copy_sub_off(&t->subs.synt, &m->synt); + #endif + /* Now we need to skip over the matched text and then +*************** +*** 5990,5998 **** + if (REG_MULTI) + /* TODO: multi-line match */ + bytelen = m->norm.list.multi[0].end_col +! - (int)(reginput - regline); + else +! bytelen = (int)(m->norm.list.line[0].end - reginput); + + #ifdef ENABLE_LOG + fprintf(log_fd, "NFA_START_PATTERN length: %d\n", bytelen); +--- 5967,5975 ---- + if (REG_MULTI) + /* TODO: multi-line match */ + bytelen = m->norm.list.multi[0].end_col +! - (int)(rex.input - rex.line); + else +! bytelen = (int)(m->norm.list.line[0].end - rex.input); + + #ifdef ENABLE_LOG + fprintf(log_fd, "NFA_START_PATTERN length: %d\n", bytelen); +*************** +*** 6025,6031 **** + } + + case NFA_BOL: +! if (reginput == regline) + { + add_here = TRUE; + add_state = t->state->out; +--- 6002,6008 ---- + } + + case NFA_BOL: +! if (rex.input == rex.line) + { + add_here = TRUE; + add_state = t->state->out; +*************** +*** 6051,6057 **** + int this_class; + + /* Get class of current and previous char (if it exists). */ +! this_class = mb_get_class_buf(reginput, rex.reg_buf); + if (this_class <= 1) + result = FALSE; + else if (reg_prev_class() == this_class) +--- 6028,6034 ---- + int this_class; + + /* Get class of current and previous char (if it exists). */ +! this_class = mb_get_class_buf(rex.input, rex.reg_buf); + if (this_class <= 1) + result = FALSE; + else if (reg_prev_class() == this_class) +*************** +*** 6059,6066 **** + } + #endif + else if (!vim_iswordc_buf(curc, rex.reg_buf) +! || (reginput > regline +! && vim_iswordc_buf(reginput[-1], rex.reg_buf))) + result = FALSE; + if (result) + { +--- 6036,6043 ---- + } + #endif + else if (!vim_iswordc_buf(curc, rex.reg_buf) +! || (rex.input > rex.line +! && vim_iswordc_buf(rex.input[-1], rex.reg_buf))) + result = FALSE; + if (result) + { +*************** +*** 6071,6077 **** + + case NFA_EOW: + result = TRUE; +! if (reginput == regline) + result = FALSE; + #ifdef FEAT_MBYTE + else if (has_mbyte) +--- 6048,6054 ---- + + case NFA_EOW: + result = TRUE; +! if (rex.input == rex.line) + result = FALSE; + #ifdef FEAT_MBYTE + else if (has_mbyte) +*************** +*** 6079,6093 **** + int this_class, prev_class; + + /* Get class of current and previous char (if it exists). */ +! this_class = mb_get_class_buf(reginput, rex.reg_buf); + prev_class = reg_prev_class(); + if (this_class == prev_class + || prev_class == 0 || prev_class == 1) + result = FALSE; + } + #endif +! else if (!vim_iswordc_buf(reginput[-1], rex.reg_buf) +! || (reginput[0] != NUL + && vim_iswordc_buf(curc, rex.reg_buf))) + result = FALSE; + if (result) +--- 6056,6070 ---- + int this_class, prev_class; + + /* Get class of current and previous char (if it exists). */ +! this_class = mb_get_class_buf(rex.input, rex.reg_buf); + prev_class = reg_prev_class(); + if (this_class == prev_class + || prev_class == 0 || prev_class == 1) + result = FALSE; + } + #endif +! else if (!vim_iswordc_buf(rex.input[-1], rex.reg_buf) +! || (rex.input[0] != NUL + && vim_iswordc_buf(curc, rex.reg_buf))) + result = FALSE; + if (result) +*************** +*** 6098,6104 **** + break; + + case NFA_BOF: +! if (reglnum == 0 && reginput == regline + && (!REG_MULTI || rex.reg_firstlnum == 1)) + { + add_here = TRUE; +--- 6075,6081 ---- + break; + + case NFA_BOF: +! if (rex.lnum == 0 && rex.input == rex.line + && (!REG_MULTI || rex.reg_firstlnum == 1)) + { + add_here = TRUE; +*************** +*** 6107,6113 **** + break; + + case NFA_EOF: +! if (reglnum == rex.reg_maxline && curc == NUL) + { + add_here = TRUE; + add_state = t->state->out; +--- 6084,6090 ---- + break; + + case NFA_EOF: +! if (rex.lnum == rex.reg_maxline && curc == NUL) + { + add_here = TRUE; + add_state = t->state->out; +*************** +*** 6159,6165 **** + * Get them into cchars[] first. */ + while (len < clen) + { +! mc = mb_ptr2char(reginput + len); + cchars[ccount++] = mc; + len += mb_char2len(mc); + if (ccount == MAX_MCO) +--- 6136,6142 ---- + * Get them into cchars[] first. */ + while (len < clen) + { +! mc = mb_ptr2char(rex.input + len); + cchars[ccount++] = mc; + len += mb_char2len(mc); + if (ccount == MAX_MCO) +*************** +*** 6194,6200 **** + + case NFA_NEWL: + if (curc == NUL && !rex.reg_line_lbr && REG_MULTI +! && reglnum <= rex.reg_maxline) + { + go_to_nextline = TRUE; + /* Pass -1 for the offset, which means taking the position +--- 6171,6177 ---- + + case NFA_NEWL: + if (curc == NUL && !rex.reg_line_lbr && REG_MULTI +! && rex.lnum <= rex.reg_maxline) + { + go_to_nextline = TRUE; + /* Pass -1 for the offset, which means taking the position +*************** +*** 6323,6335 **** + break; + + case NFA_KWORD: /* \k */ +! result = vim_iswordp_buf(reginput, rex.reg_buf); + ADD_STATE_IF_MATCH(t->state); + break; + + case NFA_SKWORD: /* \K */ + result = !VIM_ISDIGIT(curc) +! && vim_iswordp_buf(reginput, rex.reg_buf); + ADD_STATE_IF_MATCH(t->state); + break; + +--- 6300,6312 ---- + break; + + case NFA_KWORD: /* \k */ +! result = vim_iswordp_buf(rex.input, rex.reg_buf); + ADD_STATE_IF_MATCH(t->state); + break; + + case NFA_SKWORD: /* \K */ + result = !VIM_ISDIGIT(curc) +! && vim_iswordp_buf(rex.input, rex.reg_buf); + ADD_STATE_IF_MATCH(t->state); + break; + +*************** +*** 6344,6355 **** + break; + + case NFA_PRINT: /* \p */ +! result = vim_isprintc(PTR2CHAR(reginput)); + ADD_STATE_IF_MATCH(t->state); + break; + + case NFA_SPRINT: /* \P */ +! result = !VIM_ISDIGIT(curc) && vim_isprintc(PTR2CHAR(reginput)); + ADD_STATE_IF_MATCH(t->state); + break; + +--- 6321,6332 ---- + break; + + case NFA_PRINT: /* \p */ +! result = vim_isprintc(PTR2CHAR(rex.input)); + ADD_STATE_IF_MATCH(t->state); + break; + + case NFA_SPRINT: /* \P */ +! result = !VIM_ISDIGIT(curc) && vim_isprintc(PTR2CHAR(rex.input)); + ADD_STATE_IF_MATCH(t->state); + break; + +*************** +*** 6552,6558 **** + case NFA_LNUM_LT: + result = (REG_MULTI && + nfa_re_num_cmp(t->state->val, t->state->c - NFA_LNUM, +! (long_u)(reglnum + rex.reg_firstlnum))); + if (result) + { + add_here = TRUE; +--- 6529,6535 ---- + case NFA_LNUM_LT: + result = (REG_MULTI && + nfa_re_num_cmp(t->state->val, t->state->c - NFA_LNUM, +! (long_u)(rex.lnum + rex.reg_firstlnum))); + if (result) + { + add_here = TRUE; +*************** +*** 6564,6570 **** + case NFA_COL_GT: + case NFA_COL_LT: + result = nfa_re_num_cmp(t->state->val, t->state->c - NFA_COL, +! (long_u)(reginput - regline) + 1); + if (result) + { + add_here = TRUE; +--- 6541,6547 ---- + case NFA_COL_GT: + case NFA_COL_LT: + result = nfa_re_num_cmp(t->state->val, t->state->c - NFA_COL, +! (long_u)(rex.input - rex.line) + 1); + if (result) + { + add_here = TRUE; +*************** +*** 6577,6583 **** + case NFA_VCOL_LT: + { + int op = t->state->c - NFA_VCOL; +! colnr_T col = (colnr_T)(reginput - regline); + win_T *wp = rex.reg_win == NULL ? curwin : rex.reg_win; + + /* Bail out quickly when there can't be a match, avoid the +--- 6554,6560 ---- + case NFA_VCOL_LT: + { + int op = t->state->c - NFA_VCOL; +! colnr_T col = (colnr_T)(rex.input - rex.line); + win_T *wp = rex.reg_win == NULL ? curwin : rex.reg_win; + + /* Bail out quickly when there can't be a match, avoid the +*************** +*** 6601,6607 **** + } + if (!result) + result = nfa_re_num_cmp(t->state->val, op, +! (long_u)win_linetabsize(wp, regline, col) + 1); + if (result) + { + add_here = TRUE; +--- 6578,6584 ---- + } + if (!result) + result = nfa_re_num_cmp(t->state->val, op, +! (long_u)win_linetabsize(wp, rex.line, col) + 1); + if (result) + { + add_here = TRUE; +*************** +*** 6619,6631 **** + /* Compare the mark position to the match position. */ + result = (pos != NULL /* mark doesn't exist */ + && pos->lnum > 0 /* mark isn't set in reg_buf */ +! && (pos->lnum == reglnum + rex.reg_firstlnum +! ? (pos->col == (colnr_T)(reginput - regline) + ? t->state->c == NFA_MARK +! : (pos->col < (colnr_T)(reginput - regline) + ? t->state->c == NFA_MARK_GT + : t->state->c == NFA_MARK_LT)) +! : (pos->lnum < reglnum + rex.reg_firstlnum + ? t->state->c == NFA_MARK_GT + : t->state->c == NFA_MARK_LT))); + if (result) +--- 6596,6608 ---- + /* Compare the mark position to the match position. */ + result = (pos != NULL /* mark doesn't exist */ + && pos->lnum > 0 /* mark isn't set in reg_buf */ +! && (pos->lnum == rex.lnum + rex.reg_firstlnum +! ? (pos->col == (colnr_T)(rex.input - rex.line) + ? t->state->c == NFA_MARK +! : (pos->col < (colnr_T)(rex.input - rex.line) + ? t->state->c == NFA_MARK_GT + : t->state->c == NFA_MARK_LT)) +! : (pos->lnum < rex.lnum + rex.reg_firstlnum + ? t->state->c == NFA_MARK_GT + : t->state->c == NFA_MARK_LT))); + if (result) +*************** +*** 6638,6646 **** + + case NFA_CURSOR: + result = (rex.reg_win != NULL +! && (reglnum + rex.reg_firstlnum + == rex.reg_win->w_cursor.lnum) +! && ((colnr_T)(reginput - regline) + == rex.reg_win->w_cursor.col)); + if (result) + { +--- 6615,6623 ---- + + case NFA_CURSOR: + result = (rex.reg_win != NULL +! && (rex.lnum + rex.reg_firstlnum + == rex.reg_win->w_cursor.lnum) +! && ((colnr_T)(rex.input - rex.line) + == rex.reg_win->w_cursor.col)); + if (result) + { +*************** +*** 6701,6707 **** + /* If rex.reg_icombine is not set only skip over the character + * itself. When it is set skip over composing characters. */ + if (result && enc_utf8 && !rex.reg_icombine) +! clen = utf_ptr2len(reginput); + #endif + ADD_STATE_IF_MATCH(t->state); + break; +--- 6678,6684 ---- + /* If rex.reg_icombine is not set only skip over the character + * itself. When it is set skip over composing characters. */ + if (result && enc_utf8 && !rex.reg_icombine) +! clen = utf_ptr2len(rex.input); + #endif + ADD_STATE_IF_MATCH(t->state); + break; +*************** +*** 6746,6752 **** + /* Copy submatch info from the recursive call */ + copy_sub_off(&pim->subs.norm, &m->norm); + #ifdef FEAT_SYN_HL +! if (nfa_has_zsubexpr) + copy_sub_off(&pim->subs.synt, &m->synt); + #endif + } +--- 6723,6729 ---- + /* Copy submatch info from the recursive call */ + copy_sub_off(&pim->subs.norm, &m->norm); + #ifdef FEAT_SYN_HL +! if (rex.nfa_has_zsubexpr) + copy_sub_off(&pim->subs.synt, &m->synt); + #endif + } +*************** +*** 6773,6779 **** + /* Copy submatch info from the recursive call */ + copy_sub_off(&t->subs.norm, &pim->subs.norm); + #ifdef FEAT_SYN_HL +! if (nfa_has_zsubexpr) + copy_sub_off(&t->subs.synt, &pim->subs.synt); + #endif + } +--- 6750,6756 ---- + /* Copy submatch info from the recursive call */ + copy_sub_off(&t->subs.norm, &pim->subs.norm); + #ifdef FEAT_SYN_HL +! if (rex.nfa_has_zsubexpr) + copy_sub_off(&t->subs.synt, &pim->subs.synt); + #endif + } +*************** +*** 6817,6833 **** + * Also don't start a match past the first line. */ + if (nfa_match == FALSE + && ((toplevel +! && reglnum == 0 + && clen != 0 + && (rex.reg_maxcol == 0 +! || (colnr_T)(reginput - regline) < rex.reg_maxcol)) + || (nfa_endp != NULL + && (REG_MULTI +! ? (reglnum < nfa_endp->se_u.pos.lnum +! || (reglnum == nfa_endp->se_u.pos.lnum +! && (int)(reginput - regline) + < nfa_endp->se_u.pos.col)) +! : reginput < nfa_endp->se_u.ptr)))) + { + #ifdef ENABLE_LOG + fprintf(log_fd, "(---) STARTSTATE\n"); +--- 6794,6810 ---- + * Also don't start a match past the first line. */ + if (nfa_match == FALSE + && ((toplevel +! && rex.lnum == 0 + && clen != 0 + && (rex.reg_maxcol == 0 +! || (colnr_T)(rex.input - rex.line) < rex.reg_maxcol)) + || (nfa_endp != NULL + && (REG_MULTI +! ? (rex.lnum < nfa_endp->se_u.pos.lnum +! || (rex.lnum == nfa_endp->se_u.pos.lnum +! && (int)(rex.input - rex.line) + < nfa_endp->se_u.pos.col)) +! : rex.input < nfa_endp->se_u.ptr)))) + { + #ifdef ENABLE_LOG + fprintf(log_fd, "(---) STARTSTATE\n"); +*************** +*** 6843,6849 **** + { + if (nextlist->n == 0) + { +! colnr_T col = (colnr_T)(reginput - regline) + clen; + + /* Nextlist is empty, we can skip ahead to the + * character that must appear at the start. */ +--- 6820,6826 ---- + { + if (nextlist->n == 0) + { +! colnr_T col = (colnr_T)(rex.input - rex.line) + clen; + + /* Nextlist is empty, we can skip ahead to the + * character that must appear at the start. */ +*************** +*** 6851,6865 **** + break; + #ifdef ENABLE_LOG + fprintf(log_fd, " Skipping ahead %d bytes to regstart\n", +! col - ((colnr_T)(reginput - regline) + clen)); + #endif +! reginput = regline + col - clen; + } + else + { + /* Checking if the required start character matches is + * cheaper than adding a state that won't match. */ +! c = PTR2CHAR(reginput + clen); + if (c != prog->regstart && (!rex.reg_ic + || MB_TOLOWER(c) != MB_TOLOWER(prog->regstart))) + { +--- 6828,6842 ---- + break; + #ifdef ENABLE_LOG + fprintf(log_fd, " Skipping ahead %d bytes to regstart\n", +! col - ((colnr_T)(rex.input - rex.line) + clen)); + #endif +! rex.input = rex.line + col - clen; + } + else + { + /* Checking if the required start character matches is + * cheaper than adding a state that won't match. */ +! c = PTR2CHAR(rex.input + clen); + if (c != prog->regstart && (!rex.reg_ic + || MB_TOLOWER(c) != MB_TOLOWER(prog->regstart))) + { +*************** +*** 6875,6883 **** + { + if (REG_MULTI) + m->norm.list.multi[0].start_col = +! (colnr_T)(reginput - regline) + clen; + else +! m->norm.list.line[0].start = reginput + clen; + addstate(nextlist, start->out, m, NULL, clen); + } + } +--- 6852,6860 ---- + { + if (REG_MULTI) + m->norm.list.multi[0].start_col = +! (colnr_T)(rex.input - rex.line) + clen; + else +! m->norm.list.line[0].start = rex.input + clen; + addstate(nextlist, start->out, m, NULL, clen); + } + } +*************** +*** 6900,6908 **** + /* Advance to the next character, or advance to the next line, or + * finish. */ + if (clen != 0) +! reginput += clen; + else if (go_to_nextline || (nfa_endp != NULL && REG_MULTI +! && reglnum < nfa_endp->se_u.pos.lnum)) + reg_nextline(); + else + break; +--- 6877,6885 ---- + /* Advance to the next character, or advance to the next line, or + * finish. */ + if (clen != 0) +! rex.input += clen; + else if (go_to_nextline || (nfa_endp != NULL && REG_MULTI +! && rex.lnum < nfa_endp->se_u.pos.lnum)) + reg_nextline(); + else + break; +*************** +*** 6942,6948 **** + } + + /* +! * Try match of "prog" with at regline["col"]. + * Returns <= 0 for failure, number of lines contained in the match otherwise. + */ + static long +--- 6919,6925 ---- + } + + /* +! * Try match of "prog" with at rex.line["col"]. + * Returns <= 0 for failure, number of lines contained in the match otherwise. + */ + static long +*************** +*** 6960,6966 **** + FILE *f; + #endif + +! reginput = regline + col; + #ifdef FEAT_RELTIME + nfa_time_limit = tm; + nfa_timed_out = timed_out; +--- 6937,6943 ---- + FILE *f; + #endif + +! rex.input = rex.line + col; + #ifdef FEAT_RELTIME + nfa_time_limit = tm; + nfa_timed_out = timed_out; +*************** +*** 6975,6981 **** + #ifdef DEBUG + fprintf(f, "\tRegexp is \"%s\"\n", nfa_regengine.expr); + #endif +! fprintf(f, "\tInput text is \"%s\" \n", reginput); + fprintf(f, "\t=======================================================\n\n"); + nfa_print_state(f, start); + fprintf(f, "\n\n"); +--- 6952,6958 ---- + #ifdef DEBUG + fprintf(f, "\tRegexp is \"%s\"\n", nfa_regengine.expr); + #endif +! fprintf(f, "\tInput text is \"%s\" \n", rex.input); + fprintf(f, "\t=======================================================\n\n"); + nfa_print_state(f, start); + fprintf(f, "\n\n"); +*************** +*** 7018,7029 **** + if (rex.reg_endpos[0].lnum < 0) + { + /* pattern has a \ze but it didn't match, use current end */ +! rex.reg_endpos[0].lnum = reglnum; +! rex.reg_endpos[0].col = (int)(reginput - regline); + } + else + /* Use line number of "\ze". */ +! reglnum = rex.reg_endpos[0].lnum; + } + else + { +--- 6995,7006 ---- + if (rex.reg_endpos[0].lnum < 0) + { + /* pattern has a \ze but it didn't match, use current end */ +! rex.reg_endpos[0].lnum = rex.lnum; +! rex.reg_endpos[0].col = (int)(rex.input - rex.line); + } + else + /* Use line number of "\ze". */ +! rex.lnum = rex.reg_endpos[0].lnum; + } + else + { +*************** +*** 7034,7042 **** + } + + if (rex.reg_startp[0] == NULL) +! rex.reg_startp[0] = regline + col; + if (rex.reg_endp[0] == NULL) +! rex.reg_endp[0] = reginput; + } + + #ifdef FEAT_SYN_HL +--- 7011,7019 ---- + } + + if (rex.reg_startp[0] == NULL) +! rex.reg_startp[0] = rex.line + col; + if (rex.reg_endp[0] == NULL) +! rex.reg_endp[0] = rex.input; + } + + #ifdef FEAT_SYN_HL +*************** +*** 7077,7083 **** + } + #endif + +! return 1 + reglnum; + } + + /* +--- 7054,7060 ---- + } + #endif + +! return 1 + rex.lnum; + } + + /* +*************** +*** 7131,7159 **** + rex.reg_icombine = TRUE; + #endif + +! regline = line; +! reglnum = 0; /* relative to line */ + +! nfa_has_zend = prog->has_zend; +! nfa_has_backref = prog->has_backref; +! nfa_nsubexpr = prog->nsubexp; +! nfa_listid = 1; +! nfa_alt_listid = 2; + nfa_regengine.expr = prog->pattern; + + if (prog->reganch && col > 0) + return 0L; + +! need_clear_subexpr = TRUE; + #ifdef FEAT_SYN_HL + /* Clear the external match subpointers if necessary. */ + if (prog->reghasz == REX_SET) + { +! nfa_has_zsubexpr = TRUE; +! need_clear_zsubexpr = TRUE; + } + else +! nfa_has_zsubexpr = FALSE; + #endif + + if (prog->regstart != NUL) +--- 7108,7141 ---- + rex.reg_icombine = TRUE; + #endif + +! rex.line = line; +! rex.lnum = 0; /* relative to line */ + +! rex.nfa_has_zend = prog->has_zend; +! rex.nfa_has_backref = prog->has_backref; +! rex.nfa_nsubexpr = prog->nsubexp; +! rex.nfa_listid = 1; +! rex.nfa_alt_listid = 2; +! #ifdef DEBUG + nfa_regengine.expr = prog->pattern; ++ #endif + + if (prog->reganch && col > 0) + return 0L; + +! rex.need_clear_subexpr = TRUE; + #ifdef FEAT_SYN_HL + /* Clear the external match subpointers if necessary. */ + if (prog->reghasz == REX_SET) + { +! rex.nfa_has_zsubexpr = TRUE; +! rex.need_clear_zsubexpr = TRUE; + } + else +! { +! rex.nfa_has_zsubexpr = FALSE; +! rex.need_clear_zsubexpr = FALSE; +! } + #endif + + if (prog->regstart != NUL) +*************** +*** 7177,7184 **** + if (rex.reg_maxcol > 0 && col >= rex.reg_maxcol) + goto theend; + +! nstate = prog->nstate; +! for (i = 0; i < nstate; ++i) + { + prog->state[i].id = i; + prog->state[i].lastlist[0] = 0; +--- 7159,7168 ---- + if (rex.reg_maxcol > 0 && col >= rex.reg_maxcol) + goto theend; + +! // Set the "nstate" used by nfa_regcomp() to zero to trigger an error when +! // it's accidentally used during execution. +! nstate = 0; +! for (i = 0; i < prog->nstate; ++i) + { + prog->state[i].id = i; + prog->state[i].lastlist[0] = 0; +*************** +*** 7187,7193 **** +--- 7171,7179 ---- + + retval = nfa_regtry(prog, col, tm, timed_out); + ++ #ifdef DEBUG + nfa_regengine.expr = NULL; ++ #endif + + theend: + return retval; +*************** +*** 7207,7213 **** +--- 7193,7201 ---- + if (expr == NULL) + return NULL; + ++ #ifdef DEBUG + nfa_regengine.expr = expr; ++ #endif + nfa_re_flags = re_flags; + + init_class_tab(); +*************** +*** 7255,7260 **** +--- 7243,7249 ---- + if (prog == NULL) + goto fail; + state_ptr = prog->state; ++ prog->re_in_use = FALSE; + + /* + * PASS 2 +*************** +*** 7267,7274 **** + prog->regflags = regflags; + prog->engine = &nfa_regengine; + prog->nstate = nstate; +! prog->has_zend = nfa_has_zend; +! prog->has_backref = nfa_has_backref; + prog->nsubexp = regnpar; + + nfa_postprocess(prog); +--- 7256,7263 ---- + prog->regflags = regflags; + prog->engine = &nfa_regengine; + prog->nstate = nstate; +! prog->has_zend = rex.nfa_has_zend; +! prog->has_backref = rex.nfa_has_backref; + prog->nsubexp = regnpar; + + nfa_postprocess(prog); +*************** +*** 7286,7292 **** +--- 7275,7283 ---- + prog->reghasz = re_has_z; + #endif + prog->pattern = vim_strsave(expr); ++ #ifdef DEBUG + nfa_regengine.expr = NULL; ++ #endif + + out: + VIM_CLEAR(post_start); +*************** +*** 7299,7305 **** +--- 7290,7298 ---- + #ifdef ENABLE_LOG + nfa_postfix_dump(expr, FAIL); + #endif ++ #ifdef DEBUG + nfa_regengine.expr = NULL; ++ #endif + goto out; + } + +*** ../vim-8.1.0191/src/version.c 2018-07-16 18:08:56.326109917 +0200 +--- src/version.c 2018-07-17 05:10:12.956018803 +0200 +*************** +*** 791,792 **** +--- 791,794 ---- + { /* Add new patch number below this line */ ++ /**/ ++ 192, + /**/ + +-- +hundred-and-one symptoms of being an internet addict: +262. Your computer has it's own phone line - but your daughter doesn't. + + /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ +/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ +\\\ an exciting new programming language -- http://www.Zimbu.org /// + \\\ help me help AIDS victims -- http://ICCF-Holland.org /// -- cgit v1.2.3