[geany/geany] c2481c: Use GRegex matching for Find & Replace commands
Nick Treleaven
git-noreply at xxxxx
Thu Jul 26 00:02:25 UTC 2012
Branch: refs/heads/document-messages
Author: Nick Treleaven <nick.treleaven at btinternet.com>
Committer: Nick Treleaven <nick.treleaven at btinternet.com>
Date: Sun, 25 Dec 2011 13:23:06
Commit: c2481ccb9544c22258278dcb1b503c2e26baecd1
https://github.com/geany/geany/commit/c2481ccb9544c22258278dcb1b503c2e26baecd1
Log Message:
-----------
Use GRegex matching for Find & Replace commands
Modified Paths:
--------------
src/search.c
Modified: src/search.c
106 files changed, 61 insertions(+), 45 deletions(-)
===================================================================
@@ -51,12 +51,6 @@
# include <sys/wait.h>
#endif
-#ifdef HAVE_REGEX_H
-# include <regex.h>
-#else
-# include "gnuregex.h"
-#endif
-
enum
{
@@ -1822,84 +1816,106 @@ static void search_close_pid(GPid child_pid, gint status, gpointer user_data)
}
-static gboolean compile_regex(regex_t *regex, const gchar *str, gint sflags)
+static GRegex *compile_regex(const gchar *str, gint sflags)
{
- gint err;
- gint rflags = REG_EXTENDED | REG_NEWLINE;
+ GRegex *regex;
+ GError *error = NULL;
+ gint rflags = G_REGEX_MULTILINE;
if (~sflags & SCFIND_MATCHCASE)
- rflags |= REG_ICASE;
+ rflags |= G_REGEX_CASELESS;
if (sflags & (SCFIND_WHOLEWORD | SCFIND_WORDSTART))
{
geany_debug("%s: Unsupported regex flags found!", G_STRFUNC);
}
- err = regcomp(regex, str, rflags);
- if (err != 0)
+ regex = g_regex_new(str, rflags, 0, &error);
+ if (!regex)
{
- gchar buf[256];
-
- regerror(err, regex, buf, sizeof buf);
- ui_set_statusbar(FALSE, _("Bad regex: %s"), buf);
- return FALSE;
+ ui_set_statusbar(FALSE, _("Bad regex: %s"), error->message);
+ g_error_free(error);
}
- return TRUE;
+ return regex;
}
+typedef struct CharOffsets
+{
+ gint start, end;
+} CharOffsets;
+
+static CharOffsets regex_matches[10];
+
/* groups that don't exist are handled OK as len = end - start = (-1) - (-1) = 0 */
-static gchar *get_regex_match_string(const gchar *text, regmatch_t *pmatch, gint match_idx)
+static gchar *get_regex_match_string(const gchar *text, CharOffsets *match)
{
- return g_strndup(&text[pmatch[match_idx].rm_so],
- pmatch[match_idx].rm_eo - pmatch[match_idx].rm_so);
+ return g_strndup(&text[match->start], match->end - match->start);
}
-static regmatch_t regex_matches[10];
-/* All matching text from regex_matches[0].rm_so to regex_matches[0].rm_eo */
+/* All matching text from regex_matches[0].start to regex_matches[0].end */
static gchar *regex_match_text = NULL;
-static gint find_regex(ScintillaObject *sci, guint pos, regex_t *regex)
+static gint find_regex(ScintillaObject *sci, guint pos, GRegex *regex)
{
const gchar *text;
gint flags = 0;
+ GMatchInfo *minfo;
+ gint ret = -1;
g_return_val_if_fail(pos <= (guint)sci_get_length(sci), FALSE);
+ /* clear old match */
+ setptr(regex_match_text, NULL);
+
if (sci_get_col_from_position(sci, pos) != 0)
- flags = REG_NOTBOL;
+ flags = G_REGEX_MATCH_NOTBOL;
/* Warning: any SCI calls will invalidate 'text' after calling SCI_GETCHARACTERPOINTER */
text = (void*)scintilla_send_message(sci, SCI_GETCHARACTERPOINTER, 0, 0);
text += pos;
- if (regexec(regex, text, G_N_ELEMENTS(regex_matches), regex_matches, flags) == 0)
+ /* Warning: minfo will become invalid when 'text' does! */
+ if (g_regex_match(regex, text, flags, &minfo))
{
- setptr(regex_match_text, get_regex_match_string(text, regex_matches, 0));
- return regex_matches[0].rm_so + pos;
+ gint i;
+
+ /* copy whole match text and offsets before they become invalid */
+ regex_match_text = g_match_info_fetch(minfo, 0);
+
+ foreach_range(i, G_N_ELEMENTS(regex_matches))
+ {
+ gint start = -1, end = -1;
+
+ g_match_info_fetch_pos(minfo, i, &start, &end);
+ regex_matches[i].start = start;
+ regex_matches[i].end = end;
+ }
+ ret = regex_matches[0].start + pos;
}
- setptr(regex_match_text, NULL);
- return -1;
+ g_match_info_free(minfo);
+ return ret;
}
gint search_find_next(ScintillaObject *sci, const gchar *str, gint flags)
{
- regex_t regex;
+ GRegex *regex;
gint ret = -1;
gint pos;
if (~flags & SCFIND_REGEXP)
return sci_search_next(sci, flags, str);
- if (!compile_regex(®ex, str, flags))
+ regex = compile_regex(str, flags);
+ if (!regex)
return -1;
pos = sci_get_current_position(sci);
- ret = find_regex(sci, pos, ®ex);
+ ret = find_regex(sci, pos, regex);
if (ret >= 0)
- sci_set_selection(sci, ret, regex_matches[0].rm_eo + pos);
+ sci_set_selection(sci, ret, regex_matches[0].end + pos);
- regfree(®ex);
+ g_regex_unref(regex);
return ret;
}
@@ -1937,8 +1953,8 @@ gint search_replace_target(ScintillaObject *sci, const gchar *replace_text,
/* digit escape */
g_string_erase(str, i, 2);
/* fix match offsets by subtracting index of whole match start from the string */
- grp = get_regex_match_string(regex_match_text - regex_matches[0].rm_so,
- regex_matches, c - '0');
+ grp = get_regex_match_string(regex_match_text - regex_matches[0].start,
+ ®ex_matches[c - '0']);
g_string_insert(str, i, grp);
i += strlen(grp);
g_free(grp);
@@ -1951,27 +1967,27 @@ gint search_replace_target(ScintillaObject *sci, const gchar *replace_text,
gint search_find_text(ScintillaObject *sci, gint flags, struct Sci_TextToFind *ttf)
{
- regex_t regex;
+ GRegex *regex;
gint pos;
gint ret;
if (~flags & SCFIND_REGEXP)
return sci_find_text(sci, flags, ttf);
- if (!compile_regex(®ex, ttf->lpstrText, flags))
+ regex = compile_regex(ttf->lpstrText, flags);
+ if (!regex)
return -1;
pos = ttf->chrg.cpMin;
- ret = find_regex(sci, pos, ®ex);
- regfree(®ex);
+ ret = find_regex(sci, pos, regex);
if (ret >= 0 && ret < ttf->chrg.cpMax)
{
- ttf->chrgText.cpMin = regex_matches[0].rm_so + pos;
- ttf->chrgText.cpMax = regex_matches[0].rm_eo + pos;
- return ret;
+ ttf->chrgText.cpMin = regex_matches[0].start + pos;
+ ttf->chrgText.cpMax = regex_matches[0].end + pos;
}
- return -1;
+ g_regex_unref(regex);
+ return ret;
}
@@ Diff output truncated at 100000 characters. @@
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: TBD).
More information about the Commits
mailing list