To: vim_dev@googlegroups.com Subject: Patch 8.1.2010 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.2010 Problem: New file uses old style comments. Solution: Change to new style comments. (Yegappan Lakshmanan, closes #4910) Files: src/regexp_bt.c *** ../vim-8.1.2009/src/regexp_bt.c 2019-09-07 23:16:16.830370948 +0200 --- src/regexp_bt.c 2019-09-08 17:19:06.810320699 +0200 *************** *** 134,257 **** * The opcodes are: */ ! /* definition number opnd? meaning */ ! #define END 0 /* End of program or NOMATCH operand. */ ! #define BOL 1 /* Match "" at beginning of line. */ ! #define EOL 2 /* Match "" at end of line. */ ! #define BRANCH 3 /* node Match this alternative, or the ! * next... */ ! #define BACK 4 /* Match "", "next" ptr points backward. */ ! #define EXACTLY 5 /* str Match this string. */ ! #define NOTHING 6 /* Match empty string. */ ! #define STAR 7 /* node Match this (simple) thing 0 or more ! * times. */ ! #define PLUS 8 /* node Match this (simple) thing 1 or more ! * times. */ ! #define MATCH 9 /* node match the operand zero-width */ ! #define NOMATCH 10 /* node check for no match with operand */ ! #define BEHIND 11 /* node look behind for a match with operand */ ! #define NOBEHIND 12 /* node look behind for no match with operand */ ! #define SUBPAT 13 /* node match the operand here */ ! #define BRACE_SIMPLE 14 /* node Match this (simple) thing between m and ! * n times (\{m,n\}). */ ! #define BOW 15 /* Match "" after [^a-zA-Z0-9_] */ ! #define EOW 16 /* Match "" at [^a-zA-Z0-9_] */ ! #define BRACE_LIMITS 17 /* nr nr define the min & max for BRACE_SIMPLE ! * and BRACE_COMPLEX. */ ! #define NEWL 18 /* Match line-break */ ! #define BHPOS 19 /* End position for BEHIND or NOBEHIND */ ! /* character classes: 20-48 normal, 50-78 include a line-break */ #define ADD_NL 30 #define FIRST_NL ANY + ADD_NL ! #define ANY 20 /* Match any one character. */ ! #define ANYOF 21 /* str Match any character in this string. */ ! #define ANYBUT 22 /* str Match any character not in this ! * string. */ ! #define IDENT 23 /* Match identifier char */ ! #define SIDENT 24 /* Match identifier char but no digit */ ! #define KWORD 25 /* Match keyword char */ ! #define SKWORD 26 /* Match word char but no digit */ ! #define FNAME 27 /* Match file name char */ ! #define SFNAME 28 /* Match file name char but no digit */ ! #define PRINT 29 /* Match printable char */ ! #define SPRINT 30 /* Match printable char but no digit */ ! #define WHITE 31 /* Match whitespace char */ ! #define NWHITE 32 /* Match non-whitespace char */ ! #define DIGIT 33 /* Match digit char */ ! #define NDIGIT 34 /* Match non-digit char */ ! #define HEX 35 /* Match hex char */ ! #define NHEX 36 /* Match non-hex char */ ! #define OCTAL 37 /* Match octal char */ ! #define NOCTAL 38 /* Match non-octal char */ ! #define WORD 39 /* Match word char */ ! #define NWORD 40 /* Match non-word char */ ! #define HEAD 41 /* Match head char */ ! #define NHEAD 42 /* Match non-head char */ ! #define ALPHA 43 /* Match alpha char */ ! #define NALPHA 44 /* Match non-alpha char */ ! #define LOWER 45 /* Match lowercase char */ ! #define NLOWER 46 /* Match non-lowercase char */ ! #define UPPER 47 /* Match uppercase char */ ! #define NUPPER 48 /* Match non-uppercase char */ #define LAST_NL NUPPER + ADD_NL #define WITH_NL(op) ((op) >= FIRST_NL && (op) <= LAST_NL) ! #define MOPEN 80 /* -89 Mark this point in input as start of ! * \( subexpr. MOPEN + 0 marks start of ! * match. */ ! #define MCLOSE 90 /* -99 Analogous to MOPEN. MCLOSE + 0 marks ! * end of match. */ ! #define BACKREF 100 /* -109 node Match same string again \1-\9 */ #ifdef FEAT_SYN_HL ! # define ZOPEN 110 /* -119 Mark this point in input as start of ! * \z( subexpr. */ ! # define ZCLOSE 120 /* -129 Analogous to ZOPEN. */ ! # define ZREF 130 /* -139 node Match external submatch \z1-\z9 */ #endif ! #define BRACE_COMPLEX 140 /* -149 node Match nodes between m & n times */ ! #define NOPEN 150 /* Mark this point in input as start of ! \%( subexpr. */ ! #define NCLOSE 151 /* Analogous to NOPEN. */ ! ! #define MULTIBYTECODE 200 /* mbc Match one multi-byte character */ ! #define RE_BOF 201 /* Match "" at beginning of file. */ ! #define RE_EOF 202 /* Match "" at end of file. */ ! #define CURSOR 203 /* Match location of cursor. */ ! ! #define RE_LNUM 204 /* nr cmp Match line number */ ! #define RE_COL 205 /* nr cmp Match column number */ ! #define RE_VCOL 206 /* nr cmp Match virtual column number */ ! ! #define RE_MARK 207 /* mark cmp Match mark position */ ! #define RE_VISUAL 208 /* Match Visual area */ ! #define RE_COMPOSING 209 /* any composing characters */ /* * Flags to be passed up and down. */ ! #define HASWIDTH 0x1 /* Known never to match null string. */ ! #define SIMPLE 0x2 /* Simple enough to be STAR/PLUS operand. */ ! #define SPSTART 0x4 /* Starts with * or +. */ ! #define HASNL 0x8 /* Contains some \n. */ ! #define HASLOOKBH 0x10 /* Contains "\@<=" or "\@= FIRST_NL && (op) <= LAST_NL) ! #define MOPEN 80 // -89 Mark this point in input as start of ! // \( subexpr. MOPEN + 0 marks start of ! // match. ! #define MCLOSE 90 // -99 Analogous to MOPEN. MCLOSE + 0 marks ! // end of match. ! #define BACKREF 100 // -109 node Match same string again \1-\9 #ifdef FEAT_SYN_HL ! # define ZOPEN 110 // -119 Mark this point in input as start of ! // \z( subexpr. ! # define ZCLOSE 120 // -129 Analogous to ZOPEN. ! # define ZREF 130 // -139 node Match external submatch \z1-\z9 #endif ! #define BRACE_COMPLEX 140 // -149 node Match nodes between m & n times ! #define NOPEN 150 // Mark this point in input as start of ! // \%( subexpr. ! #define NCLOSE 151 // Analogous to NOPEN. ! ! #define MULTIBYTECODE 200 // mbc Match one multi-byte character ! #define RE_BOF 201 // Match "" at beginning of file. ! #define RE_EOF 202 // Match "" at end of file. ! #define CURSOR 203 // Match location of cursor. ! ! #define RE_LNUM 204 // nr cmp Match line number ! #define RE_COL 205 // nr cmp Match column number ! #define RE_VCOL 206 // nr cmp Match virtual column number ! ! #define RE_MARK 207 // mark cmp Match mark position ! #define RE_VISUAL 208 // Match Visual area ! #define RE_COMPOSING 209 // any composing characters /* * Flags to be passed up and down. */ ! #define HASWIDTH 0x1 // Known never to match null string. ! #define SIMPLE 0x2 // Simple enough to be STAR/PLUS operand. ! #define SPSTART 0x4 // Starts with * or +. ! #define HASNL 0x8 // Contains some \n. ! #define HASLOOKBH 0x10 // Contains "\@<=" or "\@ 0xffff) reg_toolong = TRUE; else --- 935,943 ---- offset = (int)(scan - val); else offset = (int)(val - scan); ! // When the offset uses more than 16 bits it can no longer fit in the two ! // bytes available. Use a global flag to avoid having to check return ! // values in too many places. if (offset > 0xffff) reg_toolong = TRUE; else *************** *** 953,959 **** static void regoptail(char_u *p, char_u *val) { ! /* When op is neither BRANCH nor BRACE_COMPLEX0-9, it is "operandless" */ if (p == NULL || p == JUST_CALC_SIZE || (OP(p) != BRANCH && (OP(p) < BRACE_COMPLEX || OP(p) > BRACE_COMPLEX + 9))) --- 953,959 ---- static void regoptail(char_u *p, char_u *val) { ! // When op is neither BRANCH nor BRACE_COMPLEX0-9, it is "operandless" if (p == NULL || p == JUST_CALC_SIZE || (OP(p) != BRANCH && (OP(p) < BRACE_COMPLEX || OP(p) > BRACE_COMPLEX + 9))) *************** *** 984,990 **** while (src > opnd) *--dst = *--src; ! place = opnd; /* Op node, where operand used to be. */ *place++ = op; *place++ = NUL; *place = NUL; --- 984,990 ---- while (src > opnd) *--dst = *--src; ! place = opnd; // Op node, where operand used to be. *place++ = op; *place++ = NUL; *place = NUL; *************** *** 1012,1018 **** while (src > opnd) *--dst = *--src; ! place = opnd; /* Op node, where operand used to be. */ *place++ = op; *place++ = NUL; *place++ = NUL; --- 1012,1018 ---- while (src > opnd) *--dst = *--src; ! place = opnd; // Op node, where operand used to be. *place++ = op; *place++ = NUL; *place++ = NUL; *************** *** 1047,1053 **** while (src > opnd) *--dst = *--src; ! place = opnd; /* Op node, where operand used to be. */ *place++ = op; *place++ = NUL; *place++ = NUL; --- 1047,1053 ---- while (src > opnd) *--dst = *--src; ! place = opnd; // Op node, where operand used to be. *place++ = op; *place++ = NUL; *place++ = NUL; *************** *** 1069,1076 **** { char_u *p; ! /* Trick: check if "@<=" or "@= MAGIC_ON : reg_magic == MAGIC_ALL), c); ! /* NOTREACHED */ ! case Magic('~'): /* previous substitute pattern */ if (reg_prev_sub != NULL) { char_u *lp; --- 1238,1246 ---- c = no_Magic(c); EMSG3_RET_NULL(_("E64: %s%c follows nothing"), (c == '*' ? reg_magic >= MAGIC_ON : reg_magic == MAGIC_ALL), c); ! // NOTREACHED ! case Magic('~'): // previous substitute pattern if (reg_prev_sub != NULL) { char_u *lp; *************** *** 1334,1340 **** c = no_Magic(getchr()); switch (c) { ! /* () without a back reference */ case '(': if (one_exactly) EMSG_ONE_RET_NULL; --- 1332,1338 ---- c = no_Magic(getchr()); switch (c) { ! // () without a back reference case '(': if (one_exactly) EMSG_ONE_RET_NULL; *************** *** 1344,1351 **** *flagp |= flags & (HASWIDTH | SPSTART | HASNL | HASLOOKBH); break; ! /* Catch \%^ and \%$ regardless of where they appear in the ! * pattern -- regardless of whether or not it makes sense. */ case '^': ret = regnode(RE_BOF); break; --- 1342,1349 ---- *flagp |= flags & (HASWIDTH | SPSTART | HASNL | HASLOOKBH); break; ! // Catch \%^ and \%$ regardless of where they appear in the ! // pattern -- regardless of whether or not it makes sense. case '^': ret = regnode(RE_BOF); break; *************** *** 1366,1375 **** ret = regnode(RE_COMPOSING); break; ! /* \%[abc]: Emit as a list of branches, all ending at the last ! * branch which matches nothing. */ case '[': ! if (one_exactly) /* doesn't nest */ EMSG_ONE_RET_NULL; { char_u *lastbranch; --- 1364,1373 ---- ret = regnode(RE_COMPOSING); break; ! // \%[abc]: Emit as a list of branches, all ending at the last ! // branch which matches nothing. case '[': ! if (one_exactly) // doesn't nest EMSG_ONE_RET_NULL; { char_u *lastbranch; *************** *** 1408,1415 **** { regtail(lastnode, br); regtail(lastbranch, br); ! /* connect all branches to the NOTHING ! * branch at the end */ for (br = ret; br != lastnode; ) { if (OP(br) == BRANCH) --- 1406,1413 ---- { regtail(lastnode, br); regtail(lastbranch, br); ! // connect all branches to the NOTHING ! // branch at the end for (br = ret; br != lastnode; ) { if (OP(br) == BRANCH) *************** *** 1427,1437 **** break; } ! case 'd': /* %d123 decimal */ ! case 'o': /* %o123 octal */ ! case 'x': /* %xab hex 2 */ ! case 'u': /* %uabcd hex 4 */ ! case 'U': /* %U1234abcd hex 8 */ { long i; --- 1425,1435 ---- break; } ! case 'd': // %d123 decimal ! case 'o': // %o123 octal ! case 'x': // %xab hex 2 ! case 'u': // %uabcd hex 4 ! case 'U': // %U1234abcd hex 8 { long i; *************** *** 1479,1485 **** } if (c == '\'' && n == 0) { ! /* "\%'m", "\%<'m" and "\%>'m": Mark */ c = getchr(); ret = regnode(RE_MARK); if (ret == JUST_CALC_SIZE) --- 1477,1483 ---- } if (c == '\'' && n == 0) { ! // "\%'m", "\%<'m" and "\%>'m": Mark c = getchr(); ret = regnode(RE_MARK); if (ret == JUST_CALC_SIZE) *************** *** 1507,1514 **** regsize += 5; else { ! /* put the number and the optional ! * comparator after the opcode */ regcode = re_put_long(regcode, n); *regcode++ = cmp; } --- 1505,1512 ---- regsize += 5; else { ! // put the number and the optional ! // comparator after the opcode regcode = re_put_long(regcode, n); *regcode++ = cmp; } *************** *** 1527,1547 **** { char_u *lp; ! /* ! * If there is no matching ']', we assume the '[' is a normal ! * character. This makes 'incsearch' and ":help [" work. ! */ lp = skip_anyof(regparse); ! if (*lp == ']') /* there is a matching ']' */ { ! int startc = -1; /* > 0 when next '-' is a range */ int endc; ! /* ! * In a character class, different parsing rules apply. ! * Not even \ is special anymore, nothing is. ! */ ! if (*regparse == '^') /* Complement of range. */ { ret = regnode(ANYBUT + extra); regparse++; --- 1525,1541 ---- { char_u *lp; ! // If there is no matching ']', we assume the '[' is a normal ! // character. This makes 'incsearch' and ":help [" work. lp = skip_anyof(regparse); ! if (*lp == ']') // there is a matching ']' { ! int startc = -1; // > 0 when next '-' is a range int endc; ! // In a character class, different parsing rules apply. ! // Not even \ is special anymore, nothing is. ! if (*regparse == '^') // Complement of range. { ret = regnode(ANYBUT + extra); regparse++; *************** *** 1549,1555 **** else ret = regnode(ANYOF + extra); ! /* At the start ']' and '-' mean the literal character. */ if (*regparse == ']' || *regparse == '-') { startc = *regparse; --- 1543,1549 ---- else ret = regnode(ANYOF + extra); ! // At the start ']' and '-' mean the literal character. if (*regparse == ']' || *regparse == '-') { startc = *regparse; *************** *** 1561,1578 **** if (*regparse == '-') { ++regparse; ! /* The '-' is not used for a range at the end and ! * after or before a '\n'. */ if (*regparse == ']' || *regparse == NUL || startc == -1 || (regparse[0] == '\\' && regparse[1] == 'n')) { regc('-'); ! startc = '-'; /* [--x] is a range */ } else { ! /* Also accept "a-[.z.]" */ endc = 0; if (*regparse == '[') endc = get_coll_element(®parse); --- 1555,1572 ---- if (*regparse == '-') { ++regparse; ! // The '-' is not used for a range at the end and ! // after or before a '\n'. if (*regparse == ']' || *regparse == NUL || startc == -1 || (regparse[0] == '\\' && regparse[1] == 'n')) { regc('-'); ! startc = '-'; // [--x] is a range } else { ! // Also accept "a-[.z.]" endc = 0; if (*regparse == '[') endc = get_coll_element(®parse); *************** *** 1584,1590 **** endc = *regparse++; } ! /* Handle \o40, \x20 and \u20AC style sequences */ if (endc == '\\' && !reg_cpo_lit && !reg_cpo_bsl) endc = coll_get_char(); --- 1578,1584 ---- endc = *regparse++; } ! // Handle \o40, \x20 and \u20AC style sequences if (endc == '\\' && !reg_cpo_lit && !reg_cpo_bsl) endc = coll_get_char(); *************** *** 1593,1599 **** if (has_mbyte && ((*mb_char2len)(startc) > 1 || (*mb_char2len)(endc) > 1)) { ! /* Limit to a range of 256 chars. */ if (endc > startc + 256) EMSG_RET_NULL(_(e_large_class)); while (++startc <= endc) --- 1587,1593 ---- if (has_mbyte && ((*mb_char2len)(startc) > 1 || (*mb_char2len)(endc) > 1)) { ! // Limit to a range of 256 chars. if (endc > startc + 256) EMSG_RET_NULL(_(e_large_class)); while (++startc <= endc) *************** *** 1604,1611 **** #ifdef EBCDIC int alpha_only = FALSE; ! /* for alphabetical range skip the gaps ! * 'i'-'j', 'r'-'s', 'I'-'J' and 'R'-'S'. */ if (isalpha(startc) && isalpha(endc)) alpha_only = TRUE; #endif --- 1598,1605 ---- #ifdef EBCDIC int alpha_only = FALSE; ! // for alphabetical range skip the gaps ! // 'i'-'j', 'r'-'s', 'I'-'J' and 'R'-'S'. if (isalpha(startc) && isalpha(endc)) alpha_only = TRUE; #endif *************** *** 1618,1629 **** startc = -1; } } ! /* ! * Only "\]", "\^", "\]" and "\\" are special in Vi. Vim ! * accepts "\t", "\e", etc., but only when the 'l' flag in ! * 'cpoptions' is not included. ! * Posix doesn't recognize backslash at all. ! */ else if (*regparse == '\\' && !reg_cpo_bsl && (vim_strchr(REGEXP_INRANGE, regparse[1]) != NULL --- 1612,1621 ---- startc = -1; } } ! // Only "\]", "\^", "\]" and "\\" are special in Vi. Vim ! // accepts "\t", "\e", etc., but only when the 'l' flag in ! // 'cpoptions' is not included. ! // Posix doesn't recognize backslash at all. else if (*regparse == '\\' && !reg_cpo_bsl && (vim_strchr(REGEXP_INRANGE, regparse[1]) != NULL *************** *** 1634,1650 **** regparse++; if (*regparse == 'n') { ! /* '\n' in range: also match NL */ if (ret != JUST_CALC_SIZE) { ! /* Using \n inside [^] does not change what ! * matches. "[^\n]" is the same as ".". */ if (*ret == ANYOF) { *ret = ANYOF + ADD_NL; *flagp |= HASNL; } ! /* else: must have had a \n already */ } regparse++; startc = -1; --- 1626,1642 ---- regparse++; if (*regparse == 'n') { ! // '\n' in range: also match NL if (ret != JUST_CALC_SIZE) { ! // Using \n inside [^] does not change what ! // matches. "[^\n]" is the same as ".". if (*ret == ANYOF) { *ret = ANYOF + ADD_NL; *flagp |= HASNL; } ! // else: must have had a \n already } regparse++; startc = -1; *************** *** 1674,1698 **** c_class = get_char_class(®parse); startc = -1; ! /* Characters assumed to be 8 bits! */ switch (c_class) { case CLASS_NONE: c_class = get_equi_class(®parse); if (c_class != 0) { ! /* produce equivalence class */ reg_equi_class(c_class); } else if ((c_class = get_coll_element(®parse)) != 0) { ! /* produce a collating element */ regmbc(c_class); } else { ! /* literal '[', allow [[-x] as a range */ startc = *regparse++; regc(startc); } --- 1666,1690 ---- c_class = get_char_class(®parse); startc = -1; ! // Characters assumed to be 8 bits! switch (c_class) { case CLASS_NONE: c_class = get_equi_class(®parse); if (c_class != 0) { ! // produce equivalence class reg_equi_class(c_class); } else if ((c_class = get_coll_element(®parse)) != 0) { ! // produce a collating element regmbc(c_class); } else { ! // literal '[', allow [[-x] as a range startc = *regparse++; regc(startc); } *************** *** 1792,1803 **** { int len; ! /* produce a multibyte character, including any ! * following composing characters */ startc = mb_ptr2char(regparse); len = (*mb_ptr2len)(regparse); if (enc_utf8 && utf_char2len(startc) != len) ! startc = -1; /* composing chars */ while (--len >= 0) regc(*regparse++); } --- 1784,1795 ---- { int len; ! // produce a multibyte character, including any ! // following composing characters startc = mb_ptr2char(regparse); len = (*mb_ptr2len)(regparse); if (enc_utf8 && utf_char2len(startc) != len) ! startc = -1; // composing chars while (--len >= 0) regc(*regparse++); } *************** *** 1809,1832 **** } } regc(NUL); ! prevchr_len = 1; /* last char was the ']' */ if (*regparse != ']') ! EMSG_RET_NULL(_(e_toomsbra)); /* Cannot happen? */ ! skipchr(); /* let's be friends with the lexer again */ *flagp |= HASWIDTH | SIMPLE; break; } else if (reg_strict) EMSG2_RET_NULL(_(e_missingbracket), reg_magic > MAGIC_OFF); } ! /* FALLTHROUGH */ default: { int len; ! /* A multi-byte character is handled as a separate atom if it's ! * before a multi and when it's a composing char. */ if (use_multibytecode(c)) { do_multibyte: --- 1801,1824 ---- } } regc(NUL); ! prevchr_len = 1; // last char was the ']' if (*regparse != ']') ! EMSG_RET_NULL(_(e_toomsbra)); // Cannot happen? ! skipchr(); // let's be friends with the lexer again *flagp |= HASWIDTH | SIMPLE; break; } else if (reg_strict) EMSG2_RET_NULL(_(e_missingbracket), reg_magic > MAGIC_OFF); } ! // FALLTHROUGH default: { int len; ! // A multi-byte character is handled as a separate atom if it's ! // before a multi and when it's a composing char. if (use_multibytecode(c)) { do_multibyte: *************** *** 1838,1852 **** ret = regnode(EXACTLY); ! /* ! * Append characters as long as: ! * - there is no following multi, we then need the character in ! * front of it as a single character operand ! * - not running into a Magic character ! * - "one_exactly" is not set ! * But always emit at least one character. Might be a Multi, ! * e.g., a "[" without matching "]". ! */ for (len = 0; c != NUL && (len == 0 || (re_multi_type(peekchr()) == NOT_MULTI && !one_exactly --- 1830,1842 ---- ret = regnode(EXACTLY); ! // Append characters as long as: ! // - there is no following multi, we then need the character in ! // front of it as a single character operand ! // - not running into a Magic character ! // - "one_exactly" is not set ! // But always emit at least one character. Might be a Multi, ! // e.g., a "[" without matching "]". for (len = 0; c != NUL && (len == 0 || (re_multi_type(peekchr()) == NOT_MULTI && !one_exactly *************** *** 1860,1866 **** { int l; ! /* Need to get composing character too. */ for (;;) { l = utf_ptr2len(regparse); --- 1850,1856 ---- { int l; ! // Need to get composing character too. for (;;) { l = utf_ptr2len(regparse); *************** *** 1917,1923 **** *flagp = flags; return ret; } ! /* default flags */ *flagp = (WORST | SPSTART | (flags & (HASNL | HASLOOKBH))); skipchr(); --- 1907,1913 ---- *flagp = flags; return ret; } ! // default flags *flagp = (WORST | SPSTART | (flags & (HASNL | HASLOOKBH))); skipchr(); *************** *** 1928,1939 **** reginsert(STAR, ret); else { ! /* Emit x* as (x&|), where & means "self". */ ! reginsert(BRANCH, ret); /* Either x */ ! regoptail(ret, regnode(BACK)); /* and loop */ ! regoptail(ret, ret); /* back */ ! regtail(ret, regnode(BRANCH)); /* or */ ! regtail(ret, regnode(NOTHING)); /* null. */ } break; --- 1918,1929 ---- reginsert(STAR, ret); else { ! // Emit x* as (x&|), where & means "self". ! reginsert(BRANCH, ret); // Either x ! regoptail(ret, regnode(BACK)); // and loop ! regoptail(ret, ret); // back ! regtail(ret, regnode(BRANCH)); // or ! regtail(ret, regnode(NOTHING)); // null. } break; *************** *** 1942,1953 **** reginsert(PLUS, ret); else { ! /* Emit x+ as x(&|), where & means "self". */ ! next = regnode(BRANCH); /* Either */ regtail(ret, next); ! regtail(regnode(BACK), ret); /* loop back */ ! regtail(next, regnode(BRANCH)); /* or */ ! regtail(ret, regnode(NOTHING)); /* null. */ } *flagp = (WORST | HASWIDTH | (flags & (HASNL | HASLOOKBH))); break; --- 1932,1943 ---- reginsert(PLUS, ret); else { ! // Emit x+ as x(&|), where & means "self". ! next = regnode(BRANCH); // Either regtail(ret, next); ! regtail(regnode(BACK), ret); // loop back ! regtail(next, regnode(BRANCH)); // or ! regtail(ret, regnode(NOTHING)); // null. } *flagp = (WORST | HASWIDTH | (flags & (HASNL | HASLOOKBH))); break; *************** *** 1960,1988 **** nr = getdecchrs(); switch (no_Magic(getchr())) { ! case '=': lop = MATCH; break; /* \@= */ ! case '!': lop = NOMATCH; break; /* \@! */ ! case '>': lop = SUBPAT; break; /* \@> */ case '<': switch (no_Magic(getchr())) { ! case '=': lop = BEHIND; break; /* \@<= */ ! case '!': lop = NOBEHIND; break; /* \@': lop = SUBPAT; break; // \@> case '<': switch (no_Magic(getchr())) { ! case '=': lop = BEHIND; break; // \@<= ! case '!': lop = NOBEHIND; break; // \@= NSUBEXP) EMSG_RET_NULL(_("E50: Too many \\z(")); parno = regnzpar; --- 2164,2175 ---- int parno = 0; int flags; ! *flagp = HASWIDTH; // Tentatively. #ifdef FEAT_SYN_HL if (paren == REG_ZPAREN) { ! // Make a ZOPEN node. if (regnzpar >= NSUBEXP) EMSG_RET_NULL(_("E50: Too many \\z(")); parno = regnzpar; *************** *** 2190,2196 **** #endif if (paren == REG_PAREN) { ! /* Make a MOPEN node. */ if (regnpar >= NSUBEXP) EMSG2_RET_NULL(_("E51: Too many %s("), reg_magic == MAGIC_ALL); parno = regnpar; --- 2180,2186 ---- #endif if (paren == REG_PAREN) { ! // Make a MOPEN node. if (regnpar >= NSUBEXP) EMSG2_RET_NULL(_("E51: Too many %s("), reg_magic == MAGIC_ALL); parno = regnpar; *************** *** 2199,2221 **** } else if (paren == REG_NPAREN) { ! /* Make a NOPEN node. */ ret = regnode(NOPEN); } else ret = NULL; ! /* Pick up the branches, linking them together. */ br = regbranch(&flags); if (br == NULL) return NULL; if (ret != NULL) ! regtail(ret, br); /* [MZ]OPEN -> first. */ else ret = br; ! /* If one of the branches can be zero-width, the whole thing can. ! * If one of the branches has * at start or matches a line-break, the ! * whole thing can. */ if (!(flags & HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags & (SPSTART | HASNL | HASLOOKBH); --- 2189,2211 ---- } else if (paren == REG_NPAREN) { ! // Make a NOPEN node. ret = regnode(NOPEN); } else ret = NULL; ! // Pick up the branches, linking them together. br = regbranch(&flags); if (br == NULL) return NULL; if (ret != NULL) ! regtail(ret, br); // [MZ]OPEN -> first. else ret = br; ! // If one of the branches can be zero-width, the whole thing can. ! // If one of the branches has * at start or matches a line-break, the ! // whole thing can. if (!(flags & HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags & (SPSTART | HASNL | HASLOOKBH); *************** *** 2225,2237 **** br = regbranch(&flags); if (br == NULL || reg_toolong) return NULL; ! regtail(ret, br); /* BRANCH -> BRANCH. */ if (!(flags & HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags & (SPSTART | HASNL | HASLOOKBH); } ! /* Make a closing node, and hook it on the end. */ ender = regnode( #ifdef FEAT_SYN_HL paren == REG_ZPAREN ? ZCLOSE + parno : --- 2215,2227 ---- br = regbranch(&flags); if (br == NULL || reg_toolong) return NULL; ! regtail(ret, br); // BRANCH -> BRANCH. if (!(flags & HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags & (SPSTART | HASNL | HASLOOKBH); } ! // Make a closing node, and hook it on the end. ender = regnode( #ifdef FEAT_SYN_HL paren == REG_ZPAREN ? ZCLOSE + parno : *************** *** 2240,2250 **** paren == REG_NPAREN ? NCLOSE : END); regtail(ret, ender); ! /* Hook the tails of the branches to the closing node. */ for (br = ret; br != NULL; br = regnext(br)) regoptail(br, ender); ! /* Check for proper termination. */ if (paren != REG_NOPAREN && getchr() != Magic(')')) { #ifdef FEAT_SYN_HL --- 2230,2240 ---- paren == REG_NPAREN ? NCLOSE : END); regtail(ret, ender); ! // Hook the tails of the branches to the closing node. for (br = ret; br != NULL; br = regnext(br)) regoptail(br, ender); ! // Check for proper termination. if (paren != REG_NOPAREN && getchr() != Magic(')')) { #ifdef FEAT_SYN_HL *************** *** 2262,2276 **** if (curchr == Magic(')')) EMSG2_RET_NULL(_(e_unmatchedpar), reg_magic == MAGIC_ALL); else ! EMSG_RET_NULL(_(e_trailing)); /* "Can't happen". */ ! /* NOTREACHED */ } ! /* ! * Here we set the flag allowing back references to this set of ! * parentheses. ! */ if (paren == REG_PAREN) ! had_endbrace[parno] = TRUE; /* have seen the close paren */ return ret; } --- 2252,2264 ---- if (curchr == Magic(')')) EMSG2_RET_NULL(_(e_unmatchedpar), reg_magic == MAGIC_ALL); else ! EMSG_RET_NULL(_(e_trailing)); // "Can't happen". ! // NOTREACHED } ! // Here we set the flag allowing back references to this set of ! // parentheses. if (paren == REG_PAREN) ! had_endbrace[parno] = TRUE; // have seen the close paren return ret; } *************** *** 2442,2449 **** } if (nr < 0 || nr > INT_MAX) { ! /* If getting the number fails be backwards compatible: the character ! * is a backslash. */ --regparse; nr = '\\'; } --- 2430,2437 ---- } if (nr < 0 || nr > INT_MAX) { ! // If getting the number fails be backwards compatible: the character ! // is a backslash. --regparse; nr = '\\'; } *************** *** 2495,2502 **** { 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); } --- 2483,2490 ---- { 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); } *************** *** 2519,2529 **** return rex.input == save->rs_u.ptr; } ! /* Save the sub-expressions before attempting a match. */ #define save_se(savep, posp, pp) \ REG_MULTI ? save_se_multi((savep), (posp)) : save_se_one((savep), (pp)) ! /* After a failed match restore the sub-expressions. */ #define restore_se(savep, posp, pp) { \ if (REG_MULTI) \ *(posp) = (savep)->se_u.pos; \ --- 2507,2517 ---- return rex.input == save->rs_u.ptr; } ! // Save the sub-expressions before attempting a match. #define save_se(savep, posp, pp) \ REG_MULTI ? save_se_multi((savep), (posp)) : save_se_one((savep), (pp)) ! // After a failed match restore the sub-expressions. #define restore_se(savep, posp, pp) { \ if (REG_MULTI) \ *(posp) = (savep)->se_u.pos; \ *************** *** 2559,2565 **** static int regrepeat( char_u *p, ! long maxcount) /* maximum number of matches allowed */ { long count = 0; char_u *scan; --- 2547,2553 ---- static int regrepeat( char_u *p, ! long maxcount) // maximum number of matches allowed { long count = 0; char_u *scan; *************** *** 2567,2573 **** int mask; int testval = 0; ! scan = rex.input; /* Make local copy of rex.input for speed. */ opnd = OPERAND(p); switch (OP(p)) { --- 2555,2561 ---- int mask; int testval = 0; ! scan = rex.input; // Make local copy of rex.input for speed. opnd = OPERAND(p); switch (OP(p)) { *************** *** 2575,2582 **** case ANY + ADD_NL: while (count < maxcount) { ! /* Matching anything means we continue until end-of-line (or ! * end-of-file for ANY + ADD_NL), only limited by maxcount. */ while (*scan != NUL && count < maxcount) { ++count; --- 2563,2570 ---- case ANY + ADD_NL: while (count < maxcount) { ! // Matching anything means we continue until end-of-line (or ! // end-of-file for ANY + ADD_NL), only limited by maxcount. while (*scan != NUL && count < maxcount) { ++count; *************** *** 2585,2591 **** 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) --- 2573,2579 ---- 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) *************** *** 2596,2602 **** case IDENT: case IDENT + ADD_NL: testval = TRUE; ! /* FALLTHROUGH */ case SIDENT: case SIDENT + ADD_NL: while (count < maxcount) --- 2584,2590 ---- case IDENT: case IDENT + ADD_NL: testval = TRUE; ! // FALLTHROUGH case SIDENT: case SIDENT + ADD_NL: while (count < maxcount) *************** *** 2626,2632 **** case KWORD: case KWORD + ADD_NL: testval = TRUE; ! /* FALLTHROUGH */ case SKWORD: case SKWORD + ADD_NL: while (count < maxcount) --- 2614,2620 ---- case KWORD: case KWORD + ADD_NL: testval = TRUE; ! // FALLTHROUGH case SKWORD: case SKWORD + ADD_NL: while (count < maxcount) *************** *** 2657,2663 **** case FNAME: case FNAME + ADD_NL: testval = TRUE; ! /* FALLTHROUGH */ case SFNAME: case SFNAME + ADD_NL: while (count < maxcount) --- 2645,2651 ---- case FNAME: case FNAME + ADD_NL: testval = TRUE; ! // FALLTHROUGH case SFNAME: case SFNAME + ADD_NL: while (count < maxcount) *************** *** 2687,2693 **** case PRINT: case PRINT + ADD_NL: testval = TRUE; ! /* FALLTHROUGH */ case SPRINT: case SPRINT + ADD_NL: while (count < maxcount) --- 2675,2681 ---- case PRINT: case PRINT + ADD_NL: testval = TRUE; ! // FALLTHROUGH case SPRINT: case SPRINT + ADD_NL: while (count < maxcount) *************** *** 2822,2830 **** { int cu, cl; ! /* This doesn't do a multi-byte character, because a MULTIBYTECODE ! * would have been used for it. It does handle single-byte ! * characters, such as latin1. */ if (rex.reg_ic) { cu = MB_TOUPPER(*opnd); --- 2810,2818 ---- { int cu, cl; ! // This doesn't do a multi-byte character, because a MULTIBYTECODE ! // would have been used for it. It does handle single-byte ! // characters, such as latin1. if (rex.reg_ic) { cu = MB_TOUPPER(*opnd); *************** *** 2851,2858 **** { int i, len, cf = 0; ! /* Safety check (just in case 'encoding' was changed since ! * compiling the program). */ if ((len = (*mb_ptr2len)(opnd)) > 1) { if (rex.reg_ic && enc_utf8) --- 2839,2846 ---- { int i, len, cf = 0; ! // Safety check (just in case 'encoding' was changed since ! // compiling the program). if ((len = (*mb_ptr2len)(opnd)) > 1) { if (rex.reg_ic && enc_utf8) *************** *** 2875,2881 **** case ANYOF: case ANYOF + ADD_NL: testval = TRUE; ! /* FALLTHROUGH */ case ANYBUT: case ANYBUT + ADD_NL: --- 2863,2869 ---- case ANYOF: case ANYOF + ADD_NL: testval = TRUE; ! // FALLTHROUGH case ANYBUT: case ANYBUT + ADD_NL: *************** *** 2928,2934 **** } break; ! default: /* Oh dear. Called inappropriately. */ emsg(_(e_re_corr)); #ifdef DEBUG printf("Called regrepeat with op code %d\n", OP(p)); --- 2916,2922 ---- } break; ! default: // Oh dear. Called inappropriately. emsg(_(e_re_corr)); #ifdef DEBUG printf("Called regrepeat with op code %d\n", OP(p)); *************** *** 2989,2996 **** { 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) { --- 2977,2984 ---- { 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) { *************** *** 3018,3024 **** { 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) { --- 3006,3012 ---- { 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) { *************** *** 3055,3086 **** */ static int regmatch( ! char_u *scan, /* Current node. */ ! proftime_T *tm UNUSED, /* timeout limit or NULL */ ! int *timed_out UNUSED) /* flag set on timeout or NULL */ { ! char_u *next; /* Next node. */ int op; int c; regitem_T *rp; int no; ! int status; /* one of the RA_ values: */ #ifdef FEAT_RELTIME int tm_count = 0; #endif ! /* Make "regstack" and "backpos" empty. They are allocated and freed in ! * bt_regexec_both() to reduce malloc()/free() calls. */ regstack.ga_len = 0; backpos.ga_len = 0; ! /* ! * Repeat until "regstack" is empty. ! */ for (;;) { ! /* Some patterns may take a long time to match, e.g., "\([a-z]\+\)\+Q". ! * Allow interrupting them with CTRL-C. */ fast_breakcheck(); #ifdef DEBUG --- 3043,3072 ---- */ static int regmatch( ! char_u *scan, // Current node. ! proftime_T *tm UNUSED, // timeout limit or NULL ! int *timed_out UNUSED) // flag set on timeout or NULL { ! char_u *next; // Next node. int op; int c; regitem_T *rp; int no; ! int status; // one of the RA_ values: #ifdef FEAT_RELTIME int tm_count = 0; #endif ! // Make "regstack" and "backpos" empty. They are allocated and freed in ! // bt_regexec_both() to reduce malloc()/free() calls. regstack.ga_len = 0; backpos.ga_len = 0; ! // Repeat until "regstack" is empty. for (;;) { ! // Some patterns may take a long time to match, e.g., "\([a-z]\+\)\+Q". ! // Allow interrupting them with CTRL-C. fast_breakcheck(); #ifdef DEBUG *************** *** 3091,3100 **** } #endif ! /* ! * Repeat for items that can be matched sequentially, without using the ! * regstack. ! */ for (;;) { if (got_int || scan == NULL) --- 3077,3084 ---- } #endif ! // Repeat for items that can be matched sequentially, without using the ! // regstack. for (;;) { if (got_int || scan == NULL) *************** *** 3103,3109 **** break; } #ifdef FEAT_RELTIME ! /* Check for timeout once in a 100 times to avoid overhead. */ if (tm != NULL && ++tm_count == 100) { tm_count = 0; --- 3087,3093 ---- break; } #ifdef FEAT_RELTIME ! // Check for timeout once in a 100 times to avoid overhead. if (tm != NULL && ++tm_count == 100) { tm_count = 0; *************** *** 3143,3149 **** next = regnext(scan); 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) { --- 3127,3133 ---- next = regnext(scan); 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) { *************** *** 3174,3182 **** break; case RE_BOF: ! /* 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; --- 3158,3166 ---- break; case RE_BOF: ! // 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; *************** *** 3188,3195 **** break; case CURSOR: ! /* 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) --- 3172,3179 ---- break; case CURSOR: ! // 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) *************** *** 3199,3213 **** break; case RE_MARK: ! /* Compare the mark position to the match position. */ { int mark = OPERAND(scan)[0]; int cmp = OPERAND(scan)[1]; pos_T *pos; 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 == '>') --- 3183,3197 ---- break; case RE_MARK: ! // Compare the mark position to the match position. { int mark = OPERAND(scan)[0]; int cmp = OPERAND(scan)[1]; pos_T *pos; 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 == '>') *************** *** 3244,3262 **** status = RA_NOMATCH; break; ! case BOW: /* \; rex.input points after d */ ! if (rex.input == rex.line) /* Can't match at start of line */ status = RA_NOMATCH; else if (has_mbyte) { 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 --- 3250,3263 ---- } break; ! case EOW: // word\>; rex.input points after d ! if (rex.input == rex.line) // Can't match at start of line status = RA_NOMATCH; else if (has_mbyte) { 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 *************** *** 3287,3296 **** && vim_iswordc_buf(c, rex.reg_buf))) status = RA_NOMATCH; } ! break; /* Matched with EOW */ case ANY: ! /* ANY does not match new lines. */ if (c == NUL) status = RA_NOMATCH; else --- 3271,3280 ---- && vim_iswordc_buf(c, rex.reg_buf))) status = RA_NOMATCH; } ! break; // Matched with EOW case ANY: ! // ANY does not match new lines. if (c == NUL) status = RA_NOMATCH; else *************** *** 3486,3492 **** char_u *opnd; opnd = OPERAND(scan); ! /* Inline the first byte, for speed. */ if (*opnd != *rex.input && (!rex.reg_ic || (!enc_utf8 --- 3470,3476 ---- char_u *opnd; opnd = OPERAND(scan); ! // Inline the first byte, for speed. if (*opnd != *rex.input && (!rex.reg_ic || (!enc_utf8 *************** *** 3494,3526 **** status = RA_NOMATCH; else if (*opnd == NUL) { ! /* match empty string always works; happens when "~" is ! * empty. */ } else { if (opnd[1] == NUL && !(enc_utf8 && rex.reg_ic)) { ! len = 1; /* matched a single byte above */ } else { ! /* Need to match first byte again for multi-byte. */ len = (int)STRLEN(opnd); if (cstrncmp(opnd, rex.input, &len) != 0) status = RA_NOMATCH; } ! /* Check for following composing character, unless %C ! * 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) { ! /* raaron: This code makes a composing character get ! * ignored, which is the correct behavior (sometimes) ! * for voweled Hebrew texts. */ status = RA_NOMATCH; } if (status != RA_NOMATCH) --- 3478,3510 ---- status = RA_NOMATCH; else if (*opnd == NUL) { ! // match empty string always works; happens when "~" is ! // empty. } else { if (opnd[1] == NUL && !(enc_utf8 && rex.reg_ic)) { ! len = 1; // matched a single byte above } else { ! // Need to match first byte again for multi-byte. len = (int)STRLEN(opnd); if (cstrncmp(opnd, rex.input, &len) != 0) status = RA_NOMATCH; } ! // Check for following composing character, unless %C ! // 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) { ! // raaron: This code makes a composing character get ! // ignored, which is the correct behavior (sometimes) ! // for voweled Hebrew texts. status = RA_NOMATCH; } if (status != RA_NOMATCH) *************** *** 3547,3554 **** int opndc = 0, inpc; opnd = OPERAND(scan); ! /* Safety check (just in case 'encoding' was changed since ! * compiling the program). */ if ((len = (*mb_ptr2len)(opnd)) < 2) { status = RA_NOMATCH; --- 3531,3538 ---- int opndc = 0, inpc; opnd = OPERAND(scan); ! // Safety check (just in case 'encoding' was changed since ! // compiling the program). if ((len = (*mb_ptr2len)(opnd)) < 2) { status = RA_NOMATCH; *************** *** 3558,3565 **** opndc = utf_ptr2char(opnd); if (enc_utf8 && utf_iscomposing(opndc)) { ! /* 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)) --- 3542,3549 ---- opndc = utf_ptr2char(opnd); if (enc_utf8 && utf_iscomposing(opndc)) { ! // 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)) *************** *** 3572,3578 **** } else if (opndc == inpc) { ! /* Include all following composing chars. */ len = i + utfc_ptr2len(rex.input + i); status = RA_MATCH; break; --- 3556,3562 ---- } else if (opndc == inpc) { ! // Include all following composing chars. len = i + utfc_ptr2len(rex.input + i); status = RA_MATCH; break; *************** *** 3594,3600 **** case RE_COMPOSING: if (enc_utf8) { ! /* Skip composing characters. */ while (utf_iscomposing(utf_ptr2char(rex.input))) MB_CPTR_ADV(rex.input); } --- 3578,3584 ---- case RE_COMPOSING: if (enc_utf8) { ! // Skip composing characters. while (utf_iscomposing(utf_ptr2char(rex.input))) MB_CPTR_ADV(rex.input); } *************** *** 3608,3640 **** int i; backpos_T *bp; ! /* ! * When we run into BACK we need to check if we don't keep ! * looping without matching any input. The second and later ! * times a BACK is encountered it fails if the input is still ! * at the same position as the previous time. ! * The positions are stored in "backpos" and found by the ! * current value of "scan", the position in the RE program. ! */ bp = (backpos_T *)backpos.ga_data; for (i = 0; i < backpos.ga_len; ++i) if (bp[i].bp_scan == scan) break; if (i == backpos.ga_len) { ! /* First time at this BACK, make room to store the pos. */ if (ga_grow(&backpos, 1) == FAIL) status = RA_FAIL; else { ! /* get "ga_data" again, it may have changed */ bp = (backpos_T *)backpos.ga_data; bp[i].bp_scan = scan; ++backpos.ga_len; } } else if (reg_save_equal(&bp[i].bp_pos)) ! /* Still at same position as last time, fail. */ status = RA_NOMATCH; if (status != RA_FAIL && status != RA_NOMATCH) --- 3592,3622 ---- int i; backpos_T *bp; ! // When we run into BACK we need to check if we don't keep ! // looping without matching any input. The second and later ! // times a BACK is encountered it fails if the input is still ! // at the same position as the previous time. ! // The positions are stored in "backpos" and found by the ! // current value of "scan", the position in the RE program. bp = (backpos_T *)backpos.ga_data; for (i = 0; i < backpos.ga_len; ++i) if (bp[i].bp_scan == scan) break; if (i == backpos.ga_len) { ! // First time at this BACK, make room to store the pos. if (ga_grow(&backpos, 1) == FAIL) status = RA_FAIL; else { ! // get "ga_data" again, it may have changed bp = (backpos_T *)backpos.ga_data; bp[i].bp_scan = scan; ++backpos.ga_len; } } else if (reg_save_equal(&bp[i].bp_pos)) ! // Still at same position as last time, fail. status = RA_NOMATCH; if (status != RA_FAIL && status != RA_NOMATCH) *************** *** 3642,3649 **** } break; ! case MOPEN + 0: /* Match start: \zs */ ! case MOPEN + 1: /* \( */ case MOPEN + 2: case MOPEN + 3: case MOPEN + 4: --- 3624,3631 ---- } break; ! case MOPEN + 0: // Match start: \zs ! case MOPEN + 1: // \( case MOPEN + 2: case MOPEN + 3: case MOPEN + 4: *************** *** 3663,3678 **** rp->rs_no = no; save_se(&rp->rs_un.sesave, &rex.reg_startpos[no], &rex.reg_startp[no]); ! /* We simply continue and handle the result when done. */ } } break; ! case NOPEN: /* \%( */ ! case NCLOSE: /* \) after \%( */ if (regstack_push(RS_NOPEN, scan) == NULL) status = RA_FAIL; ! /* We simply continue and handle the result when done. */ break; #ifdef FEAT_SYN_HL --- 3645,3660 ---- rp->rs_no = no; save_se(&rp->rs_un.sesave, &rex.reg_startpos[no], &rex.reg_startp[no]); ! // We simply continue and handle the result when done. } } break; ! case NOPEN: // \%( ! case NCLOSE: // \) after \%( if (regstack_push(RS_NOPEN, scan) == NULL) status = RA_FAIL; ! // We simply continue and handle the result when done. break; #ifdef FEAT_SYN_HL *************** *** 3696,3709 **** rp->rs_no = no; save_se(&rp->rs_un.sesave, ®_startzpos[no], ®_startzp[no]); ! /* We simply continue and handle the result when done. */ } } break; #endif ! case MCLOSE + 0: /* Match end: \ze */ ! case MCLOSE + 1: /* \) */ case MCLOSE + 2: case MCLOSE + 3: case MCLOSE + 4: --- 3678,3691 ---- rp->rs_no = no; save_se(&rp->rs_un.sesave, ®_startzpos[no], ®_startzp[no]); ! // We simply continue and handle the result when done. } } break; #endif ! case MCLOSE + 0: // Match end: \ze ! case MCLOSE + 1: // \) case MCLOSE + 2: case MCLOSE + 3: case MCLOSE + 4: *************** *** 3723,3735 **** rp->rs_no = no; save_se(&rp->rs_un.sesave, &rex.reg_endpos[no], &rex.reg_endp[no]); ! /* We simply continue and handle the result when done. */ } } break; #ifdef FEAT_SYN_HL ! case ZCLOSE + 1: /* \) after \z( */ case ZCLOSE + 2: case ZCLOSE + 3: case ZCLOSE + 4: --- 3705,3717 ---- rp->rs_no = no; save_se(&rp->rs_un.sesave, &rex.reg_endpos[no], &rex.reg_endp[no]); ! // We simply continue and handle the result when done. } } break; #ifdef FEAT_SYN_HL ! case ZCLOSE + 1: // \) after \z( case ZCLOSE + 2: case ZCLOSE + 3: case ZCLOSE + 4: *************** *** 3749,3755 **** rp->rs_no = no; save_se(&rp->rs_un.sesave, ®_endzpos[no], ®_endzp[no]); ! /* We simply continue and handle the result when done. */ } } break; --- 3731,3737 ---- rp->rs_no = no; save_se(&rp->rs_un.sesave, ®_endzpos[no], ®_endzp[no]); ! // We simply continue and handle the result when done. } } break; *************** *** 3769,3796 **** no = op - BACKREF; cleanup_subexpr(); ! if (!REG_MULTI) /* Single-line regexp */ { if (rex.reg_startp[no] == NULL || rex.reg_endp[no] == NULL) { ! /* Backref was not set: Match an empty string. */ len = 0; } else { ! /* 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; } } ! else /* Multi-line regexp */ { if (rex.reg_startpos[no].lnum < 0 || rex.reg_endpos[no].lnum < 0) { ! /* Backref was not set: Match an empty string. */ len = 0; } else --- 3751,3778 ---- no = op - BACKREF; cleanup_subexpr(); ! if (!REG_MULTI) // Single-line regexp { if (rex.reg_startp[no] == NULL || rex.reg_endp[no] == NULL) { ! // Backref was not set: Match an empty string. len = 0; } else { ! // 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; } } ! else // Multi-line regexp { if (rex.reg_startpos[no].lnum < 0 || rex.reg_endpos[no].lnum < 0) { ! // Backref was not set: Match an empty string. len = 0; } else *************** *** 3798,3804 **** 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, --- 3780,3786 ---- 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, *************** *** 3807,3814 **** } else { ! /* Messy situation: Need to compare between two ! * lines. */ int r = match_with_backref( rex.reg_startpos[no].lnum, rex.reg_startpos[no].col, --- 3789,3796 ---- } else { ! // Messy situation: Need to compare between two ! // lines. int r = match_with_backref( rex.reg_startpos[no].lnum, rex.reg_startpos[no].col, *************** *** 3822,3828 **** } } ! /* Matched the backref, skip over it. */ rex.input += len; } break; --- 3804,3810 ---- } } ! // Matched the backref, skip over it. rex.input += len; } break; *************** *** 3854,3860 **** } else { ! /* Backref was not set: Match an empty string. */ } } break; --- 3836,3842 ---- } else { ! // Backref was not set: Match an empty string. } } break; *************** *** 3862,3876 **** case BRANCH: { ! if (OP(next) != BRANCH) /* No choice. */ ! next = OPERAND(scan); /* Avoid recursion. */ else { rp = regstack_push(RS_BRANCH, scan); if (rp == NULL) status = RA_FAIL; else ! status = RA_BREAK; /* rest is below */ } } break; --- 3844,3858 ---- case BRANCH: { ! if (OP(next) != BRANCH) // No choice. ! next = OPERAND(scan); // Avoid recursion. else { rp = regstack_push(RS_BRANCH, scan); if (rp == NULL) status = RA_FAIL; else ! status = RA_BREAK; // rest is below } } break; *************** *** 3912,3918 **** no = op - BRACE_COMPLEX; ++brace_count[no]; ! /* If not matched enough times yet, try one more */ if (brace_count[no] <= (brace_min[no] <= brace_max[no] ? brace_min[no] : brace_max[no])) { --- 3894,3900 ---- no = op - BRACE_COMPLEX; ++brace_count[no]; ! // If not matched enough times yet, try one more if (brace_count[no] <= (brace_min[no] <= brace_max[no] ? brace_min[no] : brace_max[no])) { *************** *** 3924,3938 **** rp->rs_no = no; reg_save(&rp->rs_un.regsave, &backpos); next = OPERAND(scan); ! /* We continue and handle the result when done. */ } break; } ! /* If matched enough times, may try matching some more */ if (brace_min[no] <= brace_max[no]) { ! /* Range is the normal way around, use longest match */ if (brace_count[no] <= brace_max[no]) { rp = regstack_push(RS_BRCPLX_LONG, scan); --- 3906,3920 ---- rp->rs_no = no; reg_save(&rp->rs_un.regsave, &backpos); next = OPERAND(scan); ! // We continue and handle the result when done. } break; } ! // If matched enough times, may try matching some more if (brace_min[no] <= brace_max[no]) { ! // Range is the normal way around, use longest match if (brace_count[no] <= brace_max[no]) { rp = regstack_push(RS_BRCPLX_LONG, scan); *************** *** 3943,3955 **** rp->rs_no = no; reg_save(&rp->rs_un.regsave, &backpos); next = OPERAND(scan); ! /* We continue and handle the result when done. */ } } } else { ! /* Range is backwards, use shortest match first */ if (brace_count[no] <= brace_min[no]) { rp = regstack_push(RS_BRCPLX_SHORT, scan); --- 3925,3937 ---- rp->rs_no = no; reg_save(&rp->rs_un.regsave, &backpos); next = OPERAND(scan); ! // We continue and handle the result when done. } } } else { ! // Range is backwards, use shortest match first if (brace_count[no] <= brace_min[no]) { rp = regstack_push(RS_BRCPLX_SHORT, scan); *************** *** 3958,3964 **** else { reg_save(&rp->rs_un.regsave, &backpos); ! /* We continue and handle the result when done. */ } } } --- 3940,3946 ---- else { reg_save(&rp->rs_un.regsave, &backpos); ! // We continue and handle the result when done. } } } *************** *** 3971,3980 **** { regstar_T rst; ! /* ! * Lookahead to avoid useless match attempts when we know ! * what character comes next. ! */ if (OP(next) == EXACTLY) { rst.nextb = *OPERAND(next); --- 3953,3960 ---- { regstar_T rst; ! // Lookahead to avoid useless match attempts when we know ! // what character comes next. if (OP(next) == EXACTLY) { rst.nextb = *OPERAND(next); *************** *** 4004,4015 **** rst.maxval = bl_maxval; } ! /* ! * When maxval > minval, try matching as much as possible, up ! * to maxval. When maxval < minval, try matching at least the ! * minimal number (since the range is backwards, that's also ! * maxval!). ! */ rst.count = regrepeat(OPERAND(scan), rst.maxval); if (got_int) { --- 3984,3993 ---- rst.maxval = bl_maxval; } ! // When maxval > minval, try matching as much as possible, up ! // to maxval. When maxval < minval, try matching at least the ! // minimal number (since the range is backwards, that's also ! // maxval!). rst.count = regrepeat(OPERAND(scan), rst.maxval); if (got_int) { *************** *** 4019,4027 **** if (rst.minval <= rst.maxval ? rst.count >= rst.minval : rst.count >= rst.maxval) { ! /* It could match. Prepare for trying to match what ! * follows. The code is below. Parameters are stored in ! * a regstar_T on the regstack. */ if ((long)((unsigned)regstack.ga_len >> 10) >= p_mmp) { emsg(_(e_maxmempat)); --- 3997,4005 ---- if (rst.minval <= rst.maxval ? rst.count >= rst.minval : rst.count >= rst.maxval) { ! // It could match. Prepare for trying to match what ! // follows. The code is below. Parameters are stored in ! // a regstar_T on the regstack. if ((long)((unsigned)regstack.ga_len >> 10) >= p_mmp) { emsg(_(e_maxmempat)); *************** *** 4039,4045 **** else { *(((regstar_T *)rp) - 1) = rst; ! status = RA_BREAK; /* skip the restore bits */ } } } --- 4017,4023 ---- else { *(((regstar_T *)rp) - 1) = rst; ! status = RA_BREAK; // skip the restore bits } } } *************** *** 4060,4072 **** rp->rs_no = op; reg_save(&rp->rs_un.regsave, &backpos); next = OPERAND(scan); ! /* We continue and handle the result when done. */ } break; case BEHIND: case NOBEHIND: ! /* Need a bit of room to store extra positions. */ if ((long)((unsigned)regstack.ga_len >> 10) >= p_mmp) { emsg(_(e_maxmempat)); --- 4038,4050 ---- rp->rs_no = op; reg_save(&rp->rs_un.regsave, &backpos); next = OPERAND(scan); ! // We continue and handle the result when done. } break; case BEHIND: case NOBEHIND: ! // Need a bit of room to store extra positions. if ((long)((unsigned)regstack.ga_len >> 10) >= p_mmp) { emsg(_(e_maxmempat)); *************** *** 4082,4095 **** status = RA_FAIL; else { ! /* Need to save the subexpr to be able to restore them ! * when there is a match but we don't use it. */ save_subexpr(((regbehind_T *)rp) - 1); rp->rs_no = op; reg_save(&rp->rs_un.regsave, &backpos); ! /* First try if what follows matches. If it does then we ! * check the behind match by looping. */ } } break; --- 4060,4073 ---- status = RA_FAIL; else { ! // Need to save the subexpr to be able to restore them ! // when there is a match but we don't use it. save_subexpr(((regbehind_T *)rp) - 1); rp->rs_no = op; reg_save(&rp->rs_un.regsave, &backpos); ! // First try if what follows matches. If it does then we ! // check the behind match by looping. } } break; *************** *** 4117,4123 **** break; case END: ! status = RA_MATCH; /* Success! */ break; default: --- 4095,4101 ---- break; case END: ! status = RA_MATCH; // Success! break; default: *************** *** 4130,4160 **** } } ! /* If we can't continue sequentially, break the inner loop. */ if (status != RA_CONT) break; ! /* Continue in inner loop, advance to next item. */ scan = next; ! } /* end of inner loop */ ! /* ! * If there is something on the regstack execute the code for the state. ! * If the state is popped then loop and use the older state. ! */ while (regstack.ga_len > 0 && status != RA_FAIL) { rp = (regitem_T *)((char *)regstack.ga_data + regstack.ga_len) - 1; switch (rp->rs_state) { case RS_NOPEN: ! /* Result is passed on as-is, simply pop the state. */ regstack_pop(&scan); break; case RS_MOPEN: ! /* Pop the state. Restore pointers when there is no match. */ if (status == RA_NOMATCH) restore_se(&rp->rs_un.sesave, &rex.reg_startpos[rp->rs_no], &rex.reg_startp[rp->rs_no]); --- 4108,4136 ---- } } ! // If we can't continue sequentially, break the inner loop. if (status != RA_CONT) break; ! // Continue in inner loop, advance to next item. scan = next; ! } // end of inner loop ! // If there is something on the regstack execute the code for the state. ! // If the state is popped then loop and use the older state. while (regstack.ga_len > 0 && status != RA_FAIL) { rp = (regitem_T *)((char *)regstack.ga_data + regstack.ga_len) - 1; switch (rp->rs_state) { case RS_NOPEN: ! // Result is passed on as-is, simply pop the state. regstack_pop(&scan); break; case RS_MOPEN: ! // Pop the state. Restore pointers when there is no match. if (status == RA_NOMATCH) restore_se(&rp->rs_un.sesave, &rex.reg_startpos[rp->rs_no], &rex.reg_startp[rp->rs_no]); *************** *** 4163,4169 **** #ifdef FEAT_SYN_HL case RS_ZOPEN: ! /* Pop the state. Restore pointers when there is no match. */ if (status == RA_NOMATCH) restore_se(&rp->rs_un.sesave, ®_startzpos[rp->rs_no], ®_startzp[rp->rs_no]); --- 4139,4145 ---- #ifdef FEAT_SYN_HL case RS_ZOPEN: ! // Pop the state. Restore pointers when there is no match. if (status == RA_NOMATCH) restore_se(&rp->rs_un.sesave, ®_startzpos[rp->rs_no], ®_startzp[rp->rs_no]); *************** *** 4172,4178 **** #endif case RS_MCLOSE: ! /* Pop the state. Restore pointers when there is no match. */ if (status == RA_NOMATCH) restore_se(&rp->rs_un.sesave, &rex.reg_endpos[rp->rs_no], &rex.reg_endp[rp->rs_no]); --- 4148,4154 ---- #endif case RS_MCLOSE: ! // Pop the state. Restore pointers when there is no match. if (status == RA_NOMATCH) restore_se(&rp->rs_un.sesave, &rex.reg_endpos[rp->rs_no], &rex.reg_endp[rp->rs_no]); *************** *** 4181,4187 **** #ifdef FEAT_SYN_HL case RS_ZCLOSE: ! /* Pop the state. Restore pointers when there is no match. */ if (status == RA_NOMATCH) restore_se(&rp->rs_un.sesave, ®_endzpos[rp->rs_no], ®_endzp[rp->rs_no]); --- 4157,4163 ---- #ifdef FEAT_SYN_HL case RS_ZCLOSE: ! // Pop the state. Restore pointers when there is no match. if (status == RA_NOMATCH) restore_se(&rp->rs_un.sesave, ®_endzpos[rp->rs_no], ®_endzp[rp->rs_no]); *************** *** 4191,4215 **** case RS_BRANCH: if (status == RA_MATCH) ! /* this branch matched, use it */ regstack_pop(&scan); else { if (status != RA_BREAK) { ! /* After a non-matching branch: try next one. */ reg_restore(&rp->rs_un.regsave, &backpos); scan = rp->rs_scan; } if (scan == NULL || OP(scan) != BRANCH) { ! /* no more branches, didn't find a match */ status = RA_NOMATCH; regstack_pop(&scan); } else { ! /* Prepare to try a branch. */ rp->rs_scan = regnext(scan); reg_save(&rp->rs_un.regsave, &backpos); scan = OPERAND(scan); --- 4167,4191 ---- case RS_BRANCH: if (status == RA_MATCH) ! // this branch matched, use it regstack_pop(&scan); else { if (status != RA_BREAK) { ! // After a non-matching branch: try next one. reg_restore(&rp->rs_un.regsave, &backpos); scan = rp->rs_scan; } if (scan == NULL || OP(scan) != BRANCH) { ! // no more branches, didn't find a match status = RA_NOMATCH; regstack_pop(&scan); } else { ! // Prepare to try a branch. rp->rs_scan = regnext(scan); reg_save(&rp->rs_un.regsave, &backpos); scan = OPERAND(scan); *************** *** 4218,4240 **** break; case RS_BRCPLX_MORE: ! /* Pop the state. Restore pointers when there is no match. */ if (status == RA_NOMATCH) { reg_restore(&rp->rs_un.regsave, &backpos); ! --brace_count[rp->rs_no]; /* decrement match count */ } regstack_pop(&scan); break; case RS_BRCPLX_LONG: ! /* Pop the state. Restore pointers when there is no match. */ if (status == RA_NOMATCH) { ! /* There was no match, but we did find enough matches. */ reg_restore(&rp->rs_un.regsave, &backpos); --brace_count[rp->rs_no]; ! /* continue with the items after "\{}" */ status = RA_CONT; } regstack_pop(&scan); --- 4194,4216 ---- break; case RS_BRCPLX_MORE: ! // Pop the state. Restore pointers when there is no match. if (status == RA_NOMATCH) { reg_restore(&rp->rs_un.regsave, &backpos); ! --brace_count[rp->rs_no]; // decrement match count } regstack_pop(&scan); break; case RS_BRCPLX_LONG: ! // Pop the state. Restore pointers when there is no match. if (status == RA_NOMATCH) { ! // There was no match, but we did find enough matches. reg_restore(&rp->rs_un.regsave, &backpos); --brace_count[rp->rs_no]; ! // continue with the items after "\{}" status = RA_CONT; } regstack_pop(&scan); *************** *** 4243,4251 **** break; case RS_BRCPLX_SHORT: ! /* Pop the state. Restore pointers when there is no match. */ if (status == RA_NOMATCH) ! /* There was no match, try to match one more item. */ reg_restore(&rp->rs_un.regsave, &backpos); regstack_pop(&scan); if (status == RA_NOMATCH) --- 4219,4227 ---- break; case RS_BRCPLX_SHORT: ! // Pop the state. Restore pointers when there is no match. if (status == RA_NOMATCH) ! // There was no match, try to match one more item. reg_restore(&rp->rs_un.regsave, &backpos); regstack_pop(&scan); if (status == RA_NOMATCH) *************** *** 4256,4270 **** break; case RS_NOMATCH: ! /* Pop the state. If the operand matches for NOMATCH or ! * doesn't match for MATCH/SUBPAT, we fail. Otherwise backup, ! * except for SUBPAT, and continue with the next item. */ if (status == (rp->rs_no == NOMATCH ? RA_MATCH : RA_NOMATCH)) status = RA_NOMATCH; else { status = RA_CONT; ! if (rp->rs_no != SUBPAT) /* zero-width */ reg_restore(&rp->rs_un.regsave, &backpos); } regstack_pop(&scan); --- 4232,4246 ---- break; case RS_NOMATCH: ! // Pop the state. If the operand matches for NOMATCH or ! // doesn't match for MATCH/SUBPAT, we fail. Otherwise backup, ! // except for SUBPAT, and continue with the next item. if (status == (rp->rs_no == NOMATCH ? RA_MATCH : RA_NOMATCH)) status = RA_NOMATCH; else { status = RA_CONT; ! if (rp->rs_no != SUBPAT) // zero-width reg_restore(&rp->rs_un.regsave, &backpos); } regstack_pop(&scan); *************** *** 4280,4300 **** } else { ! /* The stuff after BEHIND/NOBEHIND matches. Now try if ! * the behind part does (not) match before the current ! * position in the input. This must be done at every ! * position in the input and checking if the match ends at ! * the current position. */ ! /* save the position after the found match for next */ reg_save(&(((regbehind_T *)rp) - 1)->save_after, &backpos); ! /* Start looking for a match with operand at the current ! * position. Go back one character until we find the ! * result, hitting the start of the line or the previous ! * line (for multi-line matching). ! * Set behind_pos to where the match should end, BHPOS ! * will match it. Save the current value. */ (((regbehind_T *)rp) - 1)->save_behind = behind_pos; behind_pos = rp->rs_un.regsave; --- 4256,4276 ---- } else { ! // The stuff after BEHIND/NOBEHIND matches. Now try if ! // the behind part does (not) match before the current ! // position in the input. This must be done at every ! // position in the input and checking if the match ends at ! // the current position. ! // save the position after the found match for next reg_save(&(((regbehind_T *)rp) - 1)->save_after, &backpos); ! // Start looking for a match with operand at the current ! // position. Go back one character until we find the ! // result, hitting the start of the line or the previous ! // line (for multi-line matching). ! // Set behind_pos to where the match should end, BHPOS ! // will match it. Save the current value. (((regbehind_T *)rp) - 1)->save_behind = behind_pos; behind_pos = rp->rs_un.regsave; *************** *** 4306,4326 **** break; case RS_BEHIND2: ! /* ! * Looping for BEHIND / NOBEHIND match. ! */ if (status == RA_MATCH && reg_save_equal(&behind_pos)) { ! /* found a match that ends where "next" started */ behind_pos = (((regbehind_T *)rp) - 1)->save_behind; if (rp->rs_no == BEHIND) reg_restore(&(((regbehind_T *)rp) - 1)->save_after, &backpos); else { ! /* But we didn't want a match. Need to restore the ! * subexpr, because what follows matched, so they have ! * been set. */ status = RA_NOMATCH; restore_subexpr(((regbehind_T *)rp) - 1); } --- 4282,4300 ---- break; case RS_BEHIND2: ! // Looping for BEHIND / NOBEHIND match. if (status == RA_MATCH && reg_save_equal(&behind_pos)) { ! // found a match that ends where "next" started behind_pos = (((regbehind_T *)rp) - 1)->save_behind; if (rp->rs_no == BEHIND) reg_restore(&(((regbehind_T *)rp) - 1)->save_after, &backpos); else { ! // But we didn't want a match. Need to restore the ! // subexpr, because what follows matched, so they have ! // been set. status = RA_NOMATCH; restore_subexpr(((regbehind_T *)rp) - 1); } *************** *** 4331,4338 **** { long limit; ! /* No match or a match that doesn't end where we want it: Go ! * back one character. May go to previous line once. */ no = OK; limit = OPERAND_MIN(rp->rs_scan); if (REG_MULTI) --- 4305,4312 ---- { long limit; ! // No match or a match that doesn't end where we want it: Go ! // back one character. May go to previous line once. no = OK; limit = OPERAND_MIN(rp->rs_scan); if (REG_MULTI) *************** *** 4388,4407 **** } if (no == OK) { ! /* Advanced, prepare for finding match again. */ reg_restore(&rp->rs_un.regsave, &backpos); scan = OPERAND(rp->rs_scan) + 4; if (status == RA_MATCH) { ! /* We did match, so subexpr may have been changed, ! * need to restore them for the next try. */ status = RA_NOMATCH; restore_subexpr(((regbehind_T *)rp) - 1); } } else { ! /* Can't advance. For NOBEHIND that's a match. */ behind_pos = (((regbehind_T *)rp) - 1)->save_behind; if (rp->rs_no == NOBEHIND) { --- 4362,4381 ---- } if (no == OK) { ! // Advanced, prepare for finding match again. reg_restore(&rp->rs_un.regsave, &backpos); scan = OPERAND(rp->rs_scan) + 4; if (status == RA_MATCH) { ! // We did match, so subexpr may have been changed, ! // need to restore them for the next try. status = RA_NOMATCH; restore_subexpr(((regbehind_T *)rp) - 1); } } else { ! // Can't advance. For NOBEHIND that's a match. behind_pos = (((regbehind_T *)rp) - 1)->save_behind; if (rp->rs_no == NOBEHIND) { *************** *** 4411,4419 **** } else { ! /* We do want a proper match. Need to restore the ! * subexpr if we had a match, because they may have ! * been set. */ if (status == RA_MATCH) { status = RA_NOMATCH; --- 4385,4393 ---- } else { ! // We do want a proper match. Need to restore the ! // subexpr if we had a match, because they may have ! // been set. if (status == RA_MATCH) { status = RA_NOMATCH; *************** *** 4438,4466 **** break; } ! /* Tried once already, restore input pointers. */ if (status != RA_BREAK) reg_restore(&rp->rs_un.regsave, &backpos); ! /* Repeat until we found a position where it could match. */ for (;;) { if (status != RA_BREAK) { ! /* Tried first position already, advance. */ if (rp->rs_state == RS_STAR_LONG) { ! /* Trying for longest match, but couldn't or ! * 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); --- 4412,4440 ---- break; } ! // Tried once already, restore input pointers. if (status != RA_BREAK) reg_restore(&rp->rs_un.regsave, &backpos); ! // Repeat until we found a position where it could match. for (;;) { if (status != RA_BREAK) { ! // Tried first position already, advance. if (rp->rs_state == RS_STAR_LONG) { ! // Trying for longest match, but couldn't or ! // 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); *************** *** 4471,4480 **** } else { ! /* Range is backwards, use shortest match first. ! * Careful: maxval and minval are exchanged! ! * Couldn't or didn't match: try advancing one ! * char. */ if (rst->count == rst->minval || regrepeat(OPERAND(rp->rs_scan), 1L) == 0) break; --- 4445,4454 ---- } else { ! // Range is backwards, use shortest match first. ! // Careful: maxval and minval are exchanged! ! // Couldn't or didn't match: try advancing one ! // char. if (rst->count == rst->minval || regrepeat(OPERAND(rp->rs_scan), 1L) == 0) break; *************** *** 4486,4492 **** else status = RA_NOMATCH; ! /* If it could match, try it. */ if (rst->nextb == NUL || *rex.input == rst->nextb || *rex.input == rst->nextb_ic) { --- 4460,4466 ---- else status = RA_NOMATCH; ! // If it could match, try it. if (rst->nextb == NUL || *rex.input == rst->nextb || *rex.input == rst->nextb_ic) { *************** *** 4498,4504 **** } if (status != RA_CONT) { ! /* Failed. */ regstack_pop(&scan); regstack.ga_len -= sizeof(regstar_T); status = RA_NOMATCH; --- 4472,4478 ---- } if (status != RA_CONT) { ! // Failed. regstack_pop(&scan); regstack.ga_len -= sizeof(regstar_T); status = RA_NOMATCH; *************** *** 4507,4534 **** break; } ! /* If we want to continue the inner loop or didn't pop a state ! * continue matching loop */ if (status == RA_CONT || rp == (regitem_T *) ((char *)regstack.ga_data + regstack.ga_len) - 1) break; } ! /* May need to continue with the inner loop, starting at "scan". */ if (status == RA_CONT) continue; ! /* ! * If the regstack is empty or something failed we are done. ! */ if (regstack.ga_len == 0 || status == RA_FAIL) { if (scan == NULL) { ! /* ! * We get here only if there's trouble -- normally "case END" is ! * the terminating point. ! */ emsg(_(e_re_corr)); #ifdef DEBUG printf("Premature EOL\n"); --- 4481,4504 ---- break; } ! // If we want to continue the inner loop or didn't pop a state ! // continue matching loop if (status == RA_CONT || rp == (regitem_T *) ((char *)regstack.ga_data + regstack.ga_len) - 1) break; } ! // May need to continue with the inner loop, starting at "scan". if (status == RA_CONT) continue; ! // If the regstack is empty or something failed we are done. if (regstack.ga_len == 0 || status == RA_FAIL) { if (scan == NULL) { ! // We get here only if there's trouble -- normally "case END" is ! // the terminating point. emsg(_(e_re_corr)); #ifdef DEBUG printf("Premature EOL\n"); *************** *** 4537,4545 **** return (status == RA_MATCH); } ! } /* End of loop until the regstack is empty. */ ! /* NOTREACHED */ } /* --- 4507,4515 ---- return (status == RA_MATCH); } ! } // End of loop until the regstack is empty. ! // NOTREACHED } /* *** ../vim-8.1.2009/src/version.c 2019-09-08 17:11:39.350869449 +0200 --- src/version.c 2019-09-08 17:19:49.150237614 +0200 *************** *** 759,760 **** --- 759,762 ---- { /* Add new patch number below this line */ + /**/ + 2010, /**/ -- How do I set the laser printer to stun? /// 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 ///