From def581b24de9af132f284ee20d6771ad7a1343f1 Mon Sep 17 00:00:00 2001
From: Slava Zanko <slavazanko@gmail.com>
Date: Wed, 29 Apr 2009 18:45:21 +0300
Subject: [PATCH] Search engine:  * add function for prepare replacement string

edit/editcmd.c:
 * changes for correct replace

WARNING! replace don't fully works!
---
 edit/editcmd.c        | 34 +++++++++++++++++-----------------
 src/search/internal.h |  2 ++
 src/search/regex.c    | 28 ++++++++++++++++++++++++++++
 src/search/search.c   | 24 ++++++++++++++++++++++++
 src/search/search.h   |  3 +++
 5 files changed, 74 insertions(+), 17 deletions(-)

diff --git a/edit/editcmd.c b/edit/editcmd.c
index 8db26af59..3b82453d3 100644
--- a/edit/editcmd.c
+++ b/edit/editcmd.c
@@ -1176,13 +1176,6 @@ edit_replace_prompt (WEdit * edit, char *replace_text, int xpos, int ypos)
 
 #define is_digit(x) ((x) >= '0' && (x) <= '9')
 
-/*
-static void regexp_error (WEdit *edit)
-{
-    (void) edit;
-    edit_error_dialog (_("Error"), _(" Invalid regular expression, or scanf expression with too many conversions "));
-}
-*/
 static char *
 edit_replace_cmd__conv_to_display(char *str)
 {
@@ -1358,17 +1351,24 @@ edit_replace_cmd (WEdit *edit, int again)
 		}
 	    }
 	    if (replace_yes) {	/* delete then insert new */
-/*
-		if (replace_scanf) {
-// REGEX!!!!!!!!!!!11 
-		} else {
-		    times_replaced++;
-		    while (i--)
-			edit_delete (edit, 1);
-		    while (input2[++i])
-			edit_insert (edit, input2[i]);
+		GString *repl_str, *tmp_str;
+		tmp_str = g_string_new(input2);
+		
+		repl_str = mc_search_prepare_replace_str (edit->search, tmp_str);
+		g_string_free(tmp_str, TRUE);
+		if (edit->search->error != MC_SEARCH_E_OK)
+		{
+		    edit_error_dialog (_ ("Replace"), edit->search->error_str);
+		    break;
 		}
-*/
+
+		while (i--)
+		    edit_delete (edit, 1);
+
+		while (++i < repl_str->len)
+			edit_insert (edit, repl_str->str[i]);
+		
+		g_string_free(repl_str, TRUE);
 		edit->found_len = i;
 	    }
 	    /* so that we don't find the same string again */
diff --git a/src/search/internal.h b/src/search/internal.h
index 8bcdadabf..3d6fc1f3d 100644
--- a/src/search/internal.h
+++ b/src/search/internal.h
@@ -57,6 +57,8 @@ void mc_search__cond_struct_new_init_regex (const char *, mc_search_t *, mc_sear
 
 gboolean mc_search__run_regex (mc_search_t *, const void *, gsize, gsize, gsize *);
 
+GString *mc_search_regex_prepare_replace_str (mc_search_t *, GString *);
+
 /* search/normal.c : */
 
 void mc_search__cond_struct_new_init_normal (const char *, mc_search_t *, mc_search_cond_t *);
diff --git a/src/search/regex.c b/src/search/regex.c
index 638769488..15467aa6c 100644
--- a/src/search/regex.c
+++ b/src/search/regex.c
@@ -357,3 +357,31 @@ mc_search__run_regex (mc_search_t * mc_search, const void *user_data,
     mc_search->error_str = g_strdup (_(STR_E_NOTFOUND));
     return FALSE;
 }
+
+/* --------------------------------------------------------------------------------------------- */
+GString *
+mc_search_regex_prepare_replace_str (mc_search_t * mc_search, GString * replace_str)
+{
+#if GLIB_CHECK_VERSION (2, 14, 0)
+    GString *ret;
+    gchar *tmp_str;
+    GError *error = NULL;
+
+
+    tmp_str = g_match_info_expand_references (mc_search->regex_match_info,
+                                           replace_str->str, &error);
+
+    if (error){
+        mc_search->error = MC_SEARCH_E_REGEX_REPLACE;
+        mc_search->error_str = g_strdup (error->message);
+        g_error_free (error);
+        return NULL;
+    }
+
+    ret = g_string_new (tmp_str);
+    g_free(tmp_str);
+    return ret;
+#else
+    return g_string_new_len (replace_str->str, replace_str->len);
+#endif
+}
diff --git a/src/search/search.c b/src/search/search.c
index bac0adf65..6a0b46d79 100644
--- a/src/search/search.c
+++ b/src/search/search.c
@@ -291,3 +291,27 @@ mc_search_types_list_get (void)
 }
 
 /* --------------------------------------------------------------------------------------------- */
+
+GString *
+mc_search_prepare_replace_str (mc_search_t * mc_search, GString *replace_str)
+{
+    GString *ret;
+
+    if (mc_search == NULL)
+	return g_string_new_len(replace_str->str,replace_str->len);
+
+    switch (mc_search->search_type) {
+    case MC_SEARCH_T_REGEX:
+	ret = mc_search_regex_prepare_replace_str (mc_search, replace_str);
+    break;
+    case MC_SEARCH_T_NORMAL:
+    case MC_SEARCH_T_HEX:
+    case MC_SEARCH_T_GLOB:
+    default:
+	ret = g_string_new_len(replace_str->str,replace_str->len);
+        break;
+    }
+    return ret;
+}
+
+/* --------------------------------------------------------------------------------------------- */
diff --git a/src/search/search.h b/src/search/search.h
index 38d36d206..c5214fca2 100644
--- a/src/search/search.h
+++ b/src/search/search.h
@@ -19,6 +19,7 @@ typedef enum {
     MC_SEARCH_E_INPUT,
     MC_SEARCH_E_REGEX_COMPILE,
     MC_SEARCH_E_REGEX,
+    MC_SEARCH_E_REGEX_REPLACE,
     MC_SEARCH_E_NOTFOUND
 } mc_search_error_t;
 
@@ -104,4 +105,6 @@ gboolean mc_search_is_type_avail (mc_search_type_t);
 
 mc_search_type_str_t *mc_search_types_list_get (void);
 
+GString *mc_search_prepare_replace_str (mc_search_t * mc_search, GString *replace_str);
+
 #endif