To: vim-dev@vim.org Subject: Patch 6.1.010 Fcc: outbox From: Bram Moolenaar MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.1.010 Problem: Searching backwards for a question mark with "?\?" doesn't work. (Alan Isaac) Same problem in ":s?\??" and ":g?\??". Solution: Change the "\?" in a pattern to "?" when using "?" as delimiter. Files: src/ex_cmds.c, src/ex_docmd.c, src/proto/regexp.pro, src/regexp.c, src/search.c, src/syntax.c, src/tag.c *** ../vim61.009/src/ex_cmds.c Fri Mar 22 19:29:46 2002 --- src/ex_cmds.c Mon Apr 8 21:54:17 2002 *************** *** 3408,3414 **** which_pat = RE_LAST; /* use last used regexp */ delimiter = *cmd++; /* remember delimiter character */ pat = cmd; /* remember start of search pat */ ! cmd = skip_regexp(cmd, delimiter, p_magic); if (cmd[0] == delimiter) /* end delimiter found */ *cmd++ = NUL; /* replace it with a NUL */ } --- 3408,3414 ---- which_pat = RE_LAST; /* use last used regexp */ delimiter = *cmd++; /* remember delimiter character */ pat = cmd; /* remember start of search pat */ ! cmd = skip_regexp(cmd, delimiter, p_magic, &eap->arg); if (cmd[0] == delimiter) /* end delimiter found */ *cmd++ = NUL; /* replace it with a NUL */ } *************** *** 4195,4201 **** if (delim) ++cmd; /* skip delimiter if there is one */ pat = cmd; /* remember start of pattern */ ! cmd = skip_regexp(cmd, delim, p_magic); if (cmd[0] == delim) /* end delimiter found */ *cmd++ = NUL; /* replace it with a NUL */ } --- 4195,4201 ---- if (delim) ++cmd; /* skip delimiter if there is one */ pat = cmd; /* remember start of pattern */ ! cmd = skip_regexp(cmd, delim, p_magic, &eap->arg); if (cmd[0] == delim) /* end delimiter found */ *cmd++ = NUL; /* replace it with a NUL */ } *** ../vim61.009/src/ex_docmd.c Fri Mar 22 20:30:29 2002 --- src/ex_docmd.c Mon Apr 8 21:13:43 2002 *************** *** 2552,2558 **** if (*arg != NUL) { xp->xp_context = EXPAND_NOTHING; ! arg = skip_regexp(arg + 1, *arg, p_magic); } } return find_nextcmd(arg); --- 2552,2558 ---- if (*arg != NUL) { xp->xp_context = EXPAND_NOTHING; ! arg = skip_regexp(arg + 1, *arg, p_magic, NULL); } } return find_nextcmd(arg); *************** *** 2642,2648 **** { /* skip "from" part */ ++arg; ! arg = skip_regexp(arg, delim, p_magic); } /* skip "to" part */ while (arg[0] != NUL && arg[0] != delim) --- 2642,2648 ---- { /* skip "from" part */ ++arg; ! arg = skip_regexp(arg, delim, p_magic, NULL); } /* skip "to" part */ while (arg[0] != NUL && arg[0] != delim) *************** *** 2968,2974 **** c = *cmd++; if (skip) /* skip "/pat/" */ { ! cmd = skip_regexp(cmd, c, (int)p_magic); if (*cmd == c) ++cmd; } --- 2968,2974 ---- c = *cmd++; if (skip) /* skip "/pat/" */ { ! cmd = skip_regexp(cmd, c, (int)p_magic, NULL); if (*cmd == c) ++cmd; } *************** *** 7063,7069 **** { whole = FALSE; ++eap->arg; ! p = skip_regexp(eap->arg, '/', p_magic); if (*p) { *p++ = NUL; --- 7063,7069 ---- { whole = FALSE; ++eap->arg; ! p = skip_regexp(eap->arg, '/', p_magic, NULL); if (*p) { *p++ = NUL; *************** *** 8898,8904 **** EMSG2(_(e_invarg2), eap->arg); return; } ! end = skip_regexp(p + 1, *p, TRUE); if (!eap->skip) { c = *end; --- 8898,8904 ---- EMSG2(_(e_invarg2), eap->arg); return; } ! end = skip_regexp(p + 1, *p, TRUE, NULL); if (!eap->skip) { c = *end; *** ../vim61.009/src/proto/regexp.pro Fri Mar 22 21:41:20 2002 --- src/proto/regexp.pro Mon Apr 8 21:26:55 2002 *************** *** 1,6 **** /* regexp.c */ int re_multiline __ARGS((regprog_T *prog)); ! char_u *skip_regexp __ARGS((char_u *p, int dirc, int magic)); regprog_T *vim_regcomp __ARGS((char_u *expr, int magic)); int vim_regcomp_had_eol __ARGS((void)); int vim_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col)); --- 1,6 ---- /* regexp.c */ int re_multiline __ARGS((regprog_T *prog)); ! char_u *skip_regexp __ARGS((char_u *startp, int dirc, int magic, char_u **newp)); regprog_T *vim_regcomp __ARGS((char_u *expr, int magic)); int vim_regcomp_had_eol __ARGS((void)); int vim_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col)); *** ../vim61.009/src/regexp.c Mon Mar 11 21:39:06 2002 --- src/regexp.c Mon Apr 8 21:50:54 2002 *************** *** 712,725 **** * Stop at end of 'p' of where 'dirc' is found ('/', '?', etc). * Take care of characters with a backslash in front of it. * Skip strings inside [ and ]. */ char_u * ! skip_regexp(p, dirc, magic) ! char_u *p; int dirc; int magic; { int mymagic; if (magic) mymagic = MAGIC_ON; --- 712,730 ---- * Stop at end of 'p' of where 'dirc' is found ('/', '?', etc). * Take care of characters with a backslash in front of it. * Skip strings inside [ and ]. + * When "newp" is not NULL and "dirc" is '?', make an allocated copy of the + * expression and change "\?" to "?". If "*newp" is not NULL the expression + * is changed in-place. */ char_u * ! skip_regexp(startp, dirc, magic, newp) ! char_u *startp; int dirc; int magic; + char_u **newp; { int mymagic; + char_u *p = startp; if (magic) mymagic = MAGIC_ON; *************** *** 739,745 **** } else if (p[0] == '\\' && p[1] != NUL) { ! ++p; /* skip next character */ if (*p == 'v') mymagic = MAGIC_ALL; else if (*p == 'V') --- 744,765 ---- } else if (p[0] == '\\' && p[1] != NUL) { ! if (dirc == '?' && newp != NULL && p[1] == '?') ! { ! /* change "\?" to "?", make a copy first. */ ! if (*newp == NULL) ! { ! *newp = vim_strsave(startp); ! if (*newp != NULL) ! p = *newp + (p - startp); ! } ! if (*newp != NULL) ! mch_memmove(p, p + 1, STRLEN(p)); ! else ! ++p; ! } ! else ! ++p; /* skip next character */ if (*p == 'v') mymagic = MAGIC_ALL; else if (*p == 'V') *** ../vim61.009/src/search.c Fri Apr 5 20:13:03 2002 --- src/search.c Mon Apr 8 21:40:30 2002 *************** *** 849,854 **** --- 849,856 ---- char_u *p; long c; char_u *dircp; + char_u *strcopy = NULL; + char_u *ps; /* * A line offset is not remembered, this is vi compatible. *************** *** 940,946 **** * Find end of regular expression. * If there is a matching '/' or '?', toss it. */ ! p = skip_regexp(str, dirc, (int)p_magic); if (*p == dirc) { dircp = p; /* remember where we put the NUL */ --- 942,956 ---- * Find end of regular expression. * If there is a matching '/' or '?', toss it. */ ! ps = strcopy; ! p = skip_regexp(str, dirc, (int)p_magic, &strcopy); ! if (strcopy != ps) ! { ! /* made a copy of "str" to change "\?" to "?" */ ! searchcmdlen += STRLEN(str) - STRLEN(strcopy); ! str = strcopy; ! searchstr = strcopy; ! } if (*p == dirc) { dircp = p; /* remember where we put the NUL */ *************** *** 977,984 **** while (isdigit(*p)) /* skip number */ ++p; } ! searchcmdlen = (int)(p - str); /* compute length of search command ! for get_address() */ str = p; /* put str after search command */ } --- 987,996 ---- while (isdigit(*p)) /* skip number */ ++p; } ! ! /* compute length of search command for get_address() */ ! searchcmdlen += (int)(p - searchstr); ! str = p; /* put str after search command */ } *************** *** 1074,1079 **** --- 1086,1092 ---- + SEARCH_MSG + SEARCH_START + ((str != NULL && *str == ';') ? 0 : SEARCH_NOOF))), RE_LAST); + if (dircp != NULL) *dircp = dirc; /* restore second '/' or '?' for normal_cmd() */ if (c == FAIL) *************** *** 1155,1160 **** --- 1168,1175 ---- end_do_search: if (options & SEARCH_KEEP) spats[0].off = old_off; + vim_free(strcopy); + return retval; } *** ../vim61.009/src/syntax.c Thu Feb 21 21:11:38 2002 --- src/syntax.c Mon Apr 8 21:13:54 2002 *************** *** 5077,5083 **** if (arg == NULL || arg[1] == NUL || arg[2] == NUL) return NULL; ! end = skip_regexp(arg + 1, *arg, TRUE); if (*end != *arg) /* end delimiter not found */ { EMSG2(_("E401: Pattern delimiter not found: %s"), arg); --- 5077,5083 ---- if (arg == NULL || arg[1] == NUL || arg[2] == NUL) return NULL; ! end = skip_regexp(arg + 1, *arg, TRUE, NULL); if (*end != *arg) /* end delimiter not found */ { EMSG2(_("E401: Pattern delimiter not found: %s"), arg); *************** *** 5246,5252 **** finished = TRUE; break; } ! arg_end = skip_regexp(next_arg + 1, *next_arg, TRUE); if (*arg_end != *next_arg) /* end delimiter not found */ { illegal = TRUE; --- 5246,5252 ---- finished = TRUE; break; } ! arg_end = skip_regexp(next_arg + 1, *next_arg, TRUE, NULL); if (*arg_end != *next_arg) /* end delimiter not found */ { illegal = TRUE; *** ../vim61.009/src/tag.c Mon Feb 4 20:34:11 2002 --- src/tag.c Mon Apr 8 21:14:05 2002 *************** *** 2528,2534 **** */ str = pbuf; if (pbuf[0] == '/' || pbuf[0] == '?') ! str = skip_regexp(pbuf + 1, pbuf[0], FALSE) + 1; if (str > pbuf_end - 1) /* search command with nothing following */ { save_p_ws = p_ws; --- 2528,2534 ---- */ str = pbuf; if (pbuf[0] == '/' || pbuf[0] == '?') ! str = skip_regexp(pbuf + 1, pbuf[0], FALSE, NULL) + 1; if (str > pbuf_end - 1) /* search command with nothing following */ { save_p_ws = p_ws; *************** *** 2914,2920 **** str = skipdigits(str); else if (*str == '/' || *str == '?') { ! str = skip_regexp(str + 1, *str, FALSE); if (*str != **pp) str = NULL; else --- 2914,2920 ---- str = skipdigits(str); else if (*str == '/' || *str == '?') { ! str = skip_regexp(str + 1, *str, FALSE, NULL); if (*str != **pp) str = NULL; else *** ../vim61.009/src/version.c Sun Apr 7 22:34:13 2002 --- src/version.c Mon Apr 8 22:03:34 2002 *************** *** 608,609 **** --- 608,611 ---- { /* Add new patch number below this line */ + /**/ + 10, /**/ -- hundred-and-one symptoms of being an internet addict: 93. New mail alarm on your palmtop annoys other churchgoers. /// Bram Moolenaar -- Bram@moolenaar.net -- http://www.moolenaar.net \\\ /// Creator of Vim -- http://vim.sf.net -- ftp://ftp.vim.org/pub/vim \\\ \\\ Project leader for A-A-P -- http://www.a-a-p.org /// \\\ Help me helping AIDS orphans in Uganda - http://iccf-holland.org ///