From d4dd143357114d7ce7e668659297834061e98fc6 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Thu, 25 Feb 2010 18:30:43 +0000 Subject: [PATCH] Implement single POSIX regex replacement - escape replacements are done with utils_str_replace_escape(). Warning: regex backreference replacement is still to do. Make utils_str_replace_escape() accept unnecessary escapes (e.g. '\e' goes to 'e'). git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/branches/gnu-regex@4705 ea778897-0a13-0410-b9d1-a72fbfd435f5 --- ChangeLog | 10 +++++++++ src/document.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++- src/utils.c | 5 ++++- 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 69b3a628..5f342105 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-02-25 Nick Treleaven + + * src/utils.c, src/document.c: + Implement single POSIX regex replacement - escape replacements are + done with utils_str_replace_escape(). + Warning: regex backreference replacement is still to do. + Make utils_str_replace_escape() accept unnecessary escapes (e.g. + '\e' goes to 'e'). + + 2010-02-24 Nick Treleaven * src/keybindings.c, doc/geany.txt, doc/geany.html: diff --git a/src/document.c b/src/document.c index 2ac1082b..18b8842c 100644 --- a/src/document.c +++ b/src/document.c @@ -2063,6 +2063,59 @@ gint document_find_text(GeanyDocument *doc, const gchar *text, gint flags, gbool } +static gint geany_replace_target(ScintillaObject *sci, const gchar *replace_text, + gboolean regex) +{ + GString *str; + gint ret = 0; + gint i = 0; + + if (!regex) + return sci_replace_target(sci, replace_text, FALSE); + + str = g_string_new(replace_text); + while (str->str[i]) + { + gchar *ptr = &str->str[i]; + gchar *grp; + gchar c; + + if (ptr[0] != '\\') + { + i++; + continue; + } + if (ptr[1] == '\\') + { + /* backslash escape, leave for later */ + i += 2; + continue; + } + c = ptr[1]; + if (!isdigit(c)) + { + /* unnecessary escape */ + i += 2; + continue; + } + /* digit escape */ + g_string_erase(str, i, 2); + grp = "{group}"; + g_string_insert(str, i, grp); + i += strlen(grp); + } + /* now fix backslash, tabs, etc */ + if (!utils_str_replace_escape(str->str)) + { + /* replace_text should already be checked as valid */ + g_assert_not_reached(); + } + ret = sci_replace_target(sci, str->str, FALSE); + g_string_free(str, TRUE); + return ret; +} + + /* Replaces the selection if it matches, otherwise just finds the next match. * Returns: start of replaced text, or -1 if no replacement was made */ gint document_replace_text(GeanyDocument *doc, const gchar *find_text, const gchar *replace_text, @@ -2104,7 +2157,7 @@ gint document_replace_text(GeanyDocument *doc, const gchar *find_text, const gch gint replace_len; /* search next/prev will select matching text, which we use to set the replace target */ sci_target_from_selection(doc->editor->sci); - replace_len = sci_replace_target(doc->editor->sci, replace_text, flags & SCFIND_REGEXP); + replace_len = geany_replace_target(doc->editor->sci, replace_text, flags & SCFIND_REGEXP); /* select the replacement - find text will skip past the selected text */ sci_set_selection_start(doc->editor->sci, search_pos); sci_set_selection_end(doc->editor->sci, search_pos + replace_len); diff --git a/src/utils.c b/src/utils.c index 35974b39..7888fbfb 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1094,6 +1094,7 @@ gboolean utils_str_replace_escape(gchar *string) break; #endif case 'u': + { i += 2; if (i >= strlen(string)) { @@ -1159,8 +1160,10 @@ gboolean utils_str_replace_escape(gchar *string) return FALSE; } break; + } default: - return FALSE; + /* unnecessary escapes are allowed */ + string[j] = string[i]; } } else