summaryrefslogtreecommitdiff
path: root/data/vim/patches/8.1.0192
diff options
context:
space:
mode:
authorSam Bingner <sam@bingner.com>2018-08-03 15:06:38 -1000
committerSam Bingner <sam@bingner.com>2018-08-03 15:06:38 -1000
commit135b410607f008d3709a7b1374f3f37924eb9fe4 (patch)
treef4756ef3a354f6001360db894db010df85177f76 /data/vim/patches/8.1.0192
parentbd1eb51da0d3f250793e1868d73babdf495c921f (diff)
Update vim
Diffstat (limited to 'data/vim/patches/8.1.0192')
-rw-r--r--data/vim/patches/8.1.01924274
1 files changed, 4274 insertions, 0 deletions
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 <Bram@moolenaar.net>
+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: /* \<word; reginput points to w */
+ if (c == NUL) /* Can't match at end of line */
+ status = RA_NOMATCH;
+ #ifdef FEAT_MBYTE
+--- 4435,4458 ----
+ break;
+
+ case RE_LNUM:
+! if (!REG_MULTI || !re_num_cmp((long_u)(rex.lnum + rex.reg_firstlnum),
+ scan))
+ status = RA_NOMATCH;
+ break;
+
+ case RE_COL:
+! if (!re_num_cmp((long_u)(rex.input - rex.line) + 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,
+! rex.line, (colnr_T)(rex.input - rex.line)) + 1, scan))
+ status = RA_NOMATCH;
+ break;
+
+! case BOW: /* \<word; rex.input points to w */
+ if (c == NUL) /* Can't match at end of line */
+ status = RA_NOMATCH;
+ #ifdef FEAT_MBYTE
+***************
+*** 4459,4465 ****
+ 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)
+ status = RA_NOMATCH; /* not on a word at all */
+ else if (reg_prev_class() == this_class)
+--- 4461,4467 ----
+ 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)
+ status = RA_NOMATCH; /* not on a word at all */
+ else if (reg_prev_class() == this_class)
+***************
+*** 4468,4481 ****
+ #endif
+ else
+ {
+! if (!vim_iswordc_buf(c, rex.reg_buf) || (reginput > 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 ///