--- mc-4.6.2~git20080311/edit/editcmd.c.orig 2008-06-22 14:47:49.000000000 +0200 +++ mc-4.6.2~git20080311/edit/editcmd.c 2008-06-22 14:47:41.000000000 +0200 @@ -2076,6 +2076,33 @@ edit_error_dialog (_("Error"), _(" Invalid regular expression, or scanf expression with too many conversions ")); } +int mc_isdigit(mc_wchar_t c) +{ +#ifndef UTF8 + return isdigit(c); +#else /* UTF8 */ + return iswdigit(c); +#endif /* UTF8 */ +} + +mc_wchar_t * mc_memmove(mc_wchar_t *to, mc_wchar_t *from, size_t size) +{ +#ifndef UTF8 + return memmove(to, from, size); +#else /* UTF8 */ + return wmemmove(to, from, size); +#endif /* UTF8 */ +} + +mc_wchar_t * mc_strchr(mc_wchar_t *str, mc_wchar_t c) +{ +#ifndef UTF8 + return strchr(str, c); +#else /* UTF8 */ + return wcschr(str, c); +#endif /* UTF8 */ +} + /* call with edit = 0 before shutdown to close memory leaks */ void edit_replace_cmd (WEdit *edit, int again) @@ -2092,6 +2119,8 @@ int replace_continue; int treplace_prompt = 0; long times_replaced = 0, last_search; + mc_wchar_t *repl_templ; + mc_wchar_t *repl_str; int argord[NUM_REPL_ARGS]; if (!edit) { @@ -2145,7 +2174,68 @@ } - { +#ifndef UTF8 + repl_templ = g_strdup(input2); +#else /* UTF8 */ + repl_templ = mbstr_to_wchar(input2); +#endif /* UTF8 */ + + if (replace_regexp) { + /* + * edit replace template - convert subpattern references (\1) to + * snprintf_p arguments (%s) and fill "argord" array to match captured + * subpatterns + */ + int ao; + int ord; + mc_wchar_t *s; + mc_wchar_t *param; + mc_wchar_t *endptr; +#ifndef UTF8 +#define MC_CHAR(c) ((mc_wchar_t) c) +#else /* UTF8 */ +#define MC_CHAR(c) (L##c) +#endif /* UTF8 */ + + endptr = mc_strchr(repl_templ, MC_CHAR('\0')); + s = repl_templ; + ao = 0; + while ((s = mc_strchr(s, MC_CHAR('\\')))) { + param = s; + s++; + if (!s) break; + /* implement \n \r and \t escape sequences in replace string */ + if (*s == MC_CHAR('n')) { + *s = MC_CHAR('\n'); + } else if (*s == MC_CHAR('r')) { + *s = MC_CHAR('\r'); + } else if (*s == MC_CHAR('t')) { + *s = MC_CHAR('\t'); + } + if (!mc_isdigit(*s)) { + mc_memmove(param, s, endptr - s + 1); + continue; + } + ord = 0; + while (mc_isdigit(*s)) { + ord *= 10; + ord += *s - MC_CHAR('0'); + s++; + } + if ((ord > 0) && (ord <= NUM_REPL_ARGS)) { + argord[ao++] = ord - 1; + *param++ = MC_CHAR('%'); + *param++ = MC_CHAR('s'); + mc_memmove(param, s, endptr - s + 1); + s = param; + } + } + while (ao < NUM_REPL_ARGS) { + argord[ao] = ao; + ao++; + } + + } else { const char *s; int ord; size_t i; @@ -2176,6 +2266,12 @@ && !replace_backwards) edit->search_start++; + if (replace_scanf || replace_regexp) { + repl_str = g_malloc(((MAX_REPL_LEN + 2)+1) * sizeof(mc_wchar_t)); + } else { + repl_str = repl_templ; + } + do { int len = 0; long new_start; @@ -2200,8 +2296,47 @@ replace_yes = 1; + if (replace_scanf || replace_regexp) { + int ret = 0; + + /* we need to fill in sargs just like with scanf */ + if (replace_regexp) { + int k, j; + for (k = 1; k < NUM_REPL_ARGS && pmatch[k].rm_eo >= 0; + k++) { + mc_wchar_t *t; + + if (pmatch[k].rm_eo - pmatch[k].rm_so > 255) { + ret = -1; + break; + } + t = (mc_wchar_t *) &sargs[k - 1][0]; + for (j = 0; j < pmatch[k].rm_eo - pmatch[k].rm_so && + j < 255; j++, t++) + *t = edit_get_byte (edit, edit->search_start - + pmatch[0].rm_so + pmatch[k].rm_so + j); + *t = '\0'; + } + for (; k <= NUM_REPL_ARGS; k++) + sargs[k - 1][0] = 0; + } + if (ret >= 0) + ret = snprintf_p (repl_str, MAX_REPL_LEN + 2, repl_templ, + PRINTF_ARGS); + if (ret < 0) { + edit_error_dialog (_(" Replace "), + ret == -2 + ? _(" Error in replacement format string. ") + : _(" Replacement too long. ")); + treplace_prompt = 0; + replace_yes = 0; + replace_continue = 0; + } + } + if (treplace_prompt) { int l; + char *displ_repl_str; l = edit->curs_row - edit->num_widget_lines / 3; if (l > 0) edit_scroll_downward (edit, l); @@ -2215,7 +2350,15 @@ /*so that undo stops at each query */ edit_push_key_press (edit); - switch (edit_replace_prompt (edit, input2, /* and prompt 2/3 down */ +#ifndef UTF8 + displ_repl_str = g_strdup(repl_str); +#else /* UTF8 */ + displ_repl_str = wchar_to_mbstr(repl_str); + /* wchar_to_mbstr(str) returns NULL when length of str == 0 */ + if (!displ_repl_str) displ_repl_str = g_strdup(""); +#endif /* UTF8 */ + convert_to_display (displ_repl_str); + switch (edit_replace_prompt (edit, displ_repl_str, /* and prompt 2/3 down */ (edit->num_widget_columns - CONFIRM_DLG_WIDTH) / 2, edit->num_widget_lines * 2 / @@ -2237,99 +2380,15 @@ replace_continue = 0; break; } + g_free(displ_repl_str); } if (replace_yes) { /* delete then insert new */ -#ifdef UTF8 - mc_wchar_t *winput2 = mbstr_to_wchar(input2); -#endif /* UTF8 */ - if (replace_scanf) { - mc_wchar_t repl_str[MAX_REPL_LEN + 2]; - int ret = 0; - - /* we need to fill in sargs just like with scanf */ - if (replace_regexp) { - int k, j; - for (k = 1; - k < NUM_REPL_ARGS && pmatch[k].rm_eo >= 0; - k++) { -#ifndef UTF8 - unsigned char *t; -#else /* UTF8 */ - mc_wchar_t *t; -#endif - - if (pmatch[k].rm_eo - pmatch[k].rm_so > 255) { - ret = -1; - break; - } -#ifndef UTF8 - t = (unsigned char *) &sargs[k - 1][0]; -#else /* UTF8 */ - t = (mc_wchar_t *) &sargs[k - 1][0]; -#endif /* UTF8 */ - for (j = 0; - j < pmatch[k].rm_eo - pmatch[k].rm_so - && j < 255; j++, t++) - *t = edit_get_byte (edit, - edit-> - search_start - - - pmatch - [0]. - rm_so + - pmatch - [k]. - rm_so + - j); - *t = '\0'; - } - for (; k <= NUM_REPL_ARGS; k++) - sargs[k - 1][0] = 0; - } - if (!ret) - ret = -#ifndef UTF8 - snprintf_p (repl_str, MAX_REPL_LEN + 2, input2, -#else /* UTF8 */ - snprintf_p (repl_str, MAX_REPL_LEN + 2, winput2, -#endif /* UTF8 */ - PRINTF_ARGS); - if (ret >= 0) { - times_replaced++; - while (i--) - edit_delete (edit); -#ifndef UTF8 - while (repl_str[++i]) - edit_insert (edit, repl_str[i]); -#else /* UTF8 */ - while (winput2[++i]) - edit_insert (edit, winput2[i]); -#endif /* UTF8 */ - } else { - edit_error_dialog (_(" Replace "), - ret == - -2 ? - _ - (" Error in replacement format string. ") - : _(" Replacement too long. ")); - replace_continue = 0; - } - } else { - times_replaced++; - while (i--) - edit_delete (edit); -#ifndef UTF8 - while (input2[++i]) - edit_insert (edit, input2[i]); -#else /* UTF8 */ - while (winput2[++i]) - edit_insert (edit, winput2[i]); -#endif /* UTF8 */ - } + times_replaced++; + while (i--) + edit_delete (edit); + while (repl_str[++i]) + edit_insert (edit, repl_str[i]); edit->found_len = i; -#ifdef UTF8 - g_free (winput2); -#endif /* UTF8 */ } /* so that we don't find the same string again */ if (replace_backwards) { @@ -2358,6 +2417,12 @@ } } while (replace_continue); + /* cleanup */ + if (replace_scanf || replace_regexp) { + g_free(repl_str); + } + g_free(repl_templ); + edit->force = REDRAW_COMPLETELY; edit_scroll_screen_over_cursor (edit); cleanup: