mc/99_regexp-replace-fixed.patch

313 lines
7.5 KiB
Diff

--- 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: