To: vim-dev@vim.org Subject: Patch 6.0.238 Fcc: outbox From: Bram Moolenaar MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.0.238 Problem: Using a ":subsitute" command with a substitute() call in the substitution expression causes errors. (Srinath Avadhanula) Solution: Save and restore pointers when doing substitution recursively. Files: src/regexp.c *** ../vim60.237/src/regexp.c Mon Feb 18 12:38:04 2002 --- src/regexp.c Tue Feb 19 21:20:51 2002 *************** *** 5338,5343 **** --- 5338,5349 ---- #ifdef FEAT_EVAL static int can_f_submatch = FALSE; /* TRUE when submatch() can be used */ + + /* These pointers are used instead of reg_match and reg_mmatch for + * reg_submatch(). Needed for when the substitution string is an expression + * that contains a call to substitute() and submatch(). */ + static regmatch_T *submatch_match; + static regmmatch_T *submatch_mmatch; #endif #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) *************** *** 5431,5437 **** /* * When the substitute part starts with "\=" evaluate it as an expression. */ ! if (source[0] == '\\' && source[1] == '=') { #ifdef FEAT_EVAL /* To make sure that the length doesn't change between checking the --- 5437,5447 ---- /* * When the substitute part starts with "\=" evaluate it as an expression. */ ! if (source[0] == '\\' && source[1] == '=' ! #ifdef FEAT_EVAL ! && !can_f_submatch /* can't do this recursively */ ! #endif ! ) { #ifdef FEAT_EVAL /* To make sure that the length doesn't change between checking the *************** *** 5450,5461 **** } else { vim_free(eval_result); can_f_submatch = TRUE; eval_result = eval_to_string(source + 2, NULL); - can_f_submatch = FALSE; if (eval_result != NULL) dst += STRLEN(eval_result); } #endif } --- 5460,5493 ---- } else { + linenr_T save_reg_maxline; + win_T *save_reg_win; + int save_ireg_ic; + vim_free(eval_result); + + /* The expression may contain substitute(), which calls us + * recursively. Make sure submatch() gets the text from the first + * level. Don't need to save "reg_buf", because + * vim_regexec_multi() can't be called recursively. */ + submatch_match = reg_match; + submatch_mmatch = reg_mmatch; + save_reg_maxline = reg_maxline; + save_reg_win = reg_win; + save_ireg_ic = ireg_ic; can_f_submatch = TRUE; + eval_result = eval_to_string(source + 2, NULL); if (eval_result != NULL) dst += STRLEN(eval_result); + + reg_match = submatch_match; + reg_mmatch = submatch_mmatch; + reg_maxline = save_reg_maxline; + reg_win = save_reg_win; + ireg_ic = save_ireg_ic; + can_f_submatch = FALSE; + } #endif } *************** *** 5672,5678 **** if (!can_f_submatch) return NULL; ! if (REG_MULTI) { /* * First round: compute the length and allocate memory. --- 5704,5710 ---- if (!can_f_submatch) return NULL; ! if (submatch_match == NULL) { /* * First round: compute the length and allocate memory. *************** *** 5680,5694 **** */ for (round = 1; round <= 2; ++round) { ! lnum = reg_mmatch->startpos[no].lnum; ! if (lnum < 0 || reg_mmatch->endpos[no].lnum < 0) return NULL; ! s = reg_getline(lnum) + reg_mmatch->startpos[no].col; ! if (reg_mmatch->endpos[no].lnum == lnum) { /* Within one line: take form start to end col. */ ! len = reg_mmatch->endpos[no].col - reg_mmatch->startpos[no].col; if (round == 2) { STRNCPY(retval, s, len); --- 5712,5729 ---- */ for (round = 1; round <= 2; ++round) { ! lnum = submatch_mmatch->startpos[no].lnum; ! if (lnum < 0 || submatch_mmatch->endpos[no].lnum < 0) return NULL; ! s = reg_getline(lnum) + submatch_mmatch->startpos[no].col; ! if (s == NULL) /* anti-crash check, cannot happen? */ ! break; ! if (submatch_mmatch->endpos[no].lnum == lnum) { /* Within one line: take form start to end col. */ ! len = submatch_mmatch->endpos[no].col ! - submatch_mmatch->startpos[no].col; if (round == 2) { STRNCPY(retval, s, len); *************** *** 5708,5714 **** } ++len; ++lnum; ! while (lnum < reg_mmatch->endpos[no].lnum) { s = reg_getline(lnum++); if (round == 2) --- 5743,5749 ---- } ++len; ++lnum; ! while (lnum < submatch_mmatch->endpos[no].lnum) { s = reg_getline(lnum++); if (round == 2) *************** *** 5720,5727 **** } if (round == 2) STRNCPY(retval + len, reg_getline(lnum), ! reg_mmatch->endpos[no].col); ! len += reg_mmatch->endpos[no].col; if (round == 2) retval[len] = NUL; ++len; --- 5755,5762 ---- } if (round == 2) STRNCPY(retval + len, reg_getline(lnum), ! submatch_mmatch->endpos[no].col); ! len += submatch_mmatch->endpos[no].col; if (round == 2) retval[len] = NUL; ++len; *************** *** 5737,5748 **** } else { ! if (reg_match->endp[no] == NULL) retval = NULL; else { ! s = reg_match->startp[no]; ! retval = vim_strnsave(s, (int)(reg_match->endp[no] - s)); } } --- 5772,5783 ---- } else { ! if (submatch_match->endp[no] == NULL) retval = NULL; else { ! s = submatch_match->startp[no]; ! retval = vim_strnsave(s, (int)(submatch_match->endp[no] - s)); } } *** ../vim60.237/src/version.c Mon Feb 18 17:18:18 2002 --- src/version.c Tue Feb 19 21:13:02 2002 *************** *** 608,609 **** --- 608,611 ---- { /* Add new patch number below this line */ + /**/ + 238, /**/ -- CART DRIVER: Bring out your dead! We follow the cart through a wretched, impoverished plague-ridden village. A few starved mongrels run about in the mud scavenging. In the open doorway of one house perhaps we jug glimpse a pair of legs dangling from the ceiling. In another doorway an OLD WOMAN is beating a cat against a wall rather like one does with a mat. The cart passes round a dead donkey or cow in the mud. And a MAN tied to a cart is being hammered to death by four NUNS with huge mallets. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// 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 ///