Revision: 4720 http://geany.svn.sourceforge.net/geany/?rev=4720&view=rev Author: ntrel Date: 2010-03-02 13:21:41 +0000 (Tue, 02 Mar 2010)
Log Message: ----------- Move new regex code to search.c: search_find_next(), search_replace_target().
Modified Paths: -------------- branches/gnu-regex/ChangeLog branches/gnu-regex/src/document.c branches/gnu-regex/src/search.c branches/gnu-regex/src/search.h
Modified: branches/gnu-regex/ChangeLog =================================================================== --- branches/gnu-regex/ChangeLog 2010-03-02 04:22:22 UTC (rev 4719) +++ branches/gnu-regex/ChangeLog 2010-03-02 13:21:41 UTC (rev 4720) @@ -1,3 +1,10 @@ +2010-03-02 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com> + + * src/search.c, src/search.h, src/document.c: + Move new regex code to search.c: search_find_next(), + search_replace_target(). + + 2010-03-01 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
* src/search.c:
Modified: branches/gnu-regex/src/document.c =================================================================== --- branches/gnu-regex/src/document.c 2010-03-02 04:22:22 UTC (rev 4719) +++ branches/gnu-regex/src/document.c 2010-03-02 13:21:41 UTC (rev 4720) @@ -41,7 +41,6 @@ # include <sys/types.h> #endif
-#include <ctype.h> #include <stdlib.h>
/* gstdio.h also includes sys/stat.h */ @@ -1924,86 +1923,6 @@ }
-/* TODO: fix building when HAVE_REGCOMP is not defined? */ -# ifdef HAVE_REGEX_H -# include <regex.h> -# else -# include "gnuregex.h" -# endif - -static gboolean compile_regex(regex_t *regex, const gchar *str, gint sflags) -{ - gint err; - gint rflags = REG_EXTENDED | REG_NEWLINE; - - if (~sflags & SCFIND_MATCHCASE) - rflags |= REG_ICASE; - - err = regcomp(regex, str, rflags); - if (err != 0) - { - gchar buf[256]; - - regerror(err, regex, buf, sizeof buf); - ui_set_statusbar(FALSE, _("Bad regex: %s"), buf); - return FALSE; - } - return TRUE; -} - - -/* 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) -{ - return g_strndup(&text[pmatch[match_idx].rm_so], - pmatch[match_idx].rm_eo - pmatch[match_idx].rm_so); -} - - -static regmatch_t regex_matches[10]; -/* All matching text from regex_matches[0].rm_so to regex_matches[0].rm_eo */ -static gchar *regex_match_text = NULL; - -static gint find_regex(ScintillaObject *sci, guint pos, regex_t *regex) -{ - const gchar *text; - - g_return_val_if_fail(pos <= (guint)sci_get_length(sci), FALSE); - - text = (void*)scintilla_send_message(sci, SCI_GETCHARACTERPOINTER, 0, 0); - text += pos; - if (regexec(regex, text, G_N_ELEMENTS(regex_matches), regex_matches, 0) == 0) - { - setptr(regex_match_text, get_regex_match_string(text, regex_matches, 0)); - return regex_matches[0].rm_so + pos; - } - setptr(regex_match_text, NULL); - return -1; -} - - -static gint geany_search_next(ScintillaObject *sci, const gchar *str, gint flags) -{ - regex_t regex; - gint ret = -1; - gint pos; - - if (~flags & SCFIND_REGEXP) - return sci_search_next(sci, flags, str); - - if (!compile_regex(®ex, str, flags)) - return -1; - - pos = sci_get_current_position(sci); - ret = find_regex(sci, pos, ®ex); - if (ret >= 0) - sci_set_selection(sci, ret, regex_matches[0].rm_eo + pos); - - regfree(®ex); - return ret; -} - - /* General search function, used from the find dialog. * Returns -1 on failure or the start position of the matching text. * Will skip past any selection, ignoring it. */ @@ -2034,7 +1953,7 @@ if (search_backwards) search_pos = sci_search_prev(doc->editor->sci, flags, text); else - search_pos = geany_search_next(doc->editor->sci, text, flags); + search_pos = search_find_next(doc->editor->sci, text, flags);
if (search_pos != -1) { @@ -2077,51 +1996,6 @@ }
-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; - } - c = ptr[1]; - /* backslash or unnecessary escape */ - if (c == '\' || !isdigit(c)) - { - g_string_erase(str, i, 1); - i++; - continue; - } - /* 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'); - g_string_insert(str, i, grp); - i += strlen(grp); - g_free(grp); - } - 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, @@ -2163,7 +2037,7 @@ 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 = geany_replace_target(doc->editor->sci, replace_text, flags & SCFIND_REGEXP); + replace_len = search_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);
Modified: branches/gnu-regex/src/search.c =================================================================== --- branches/gnu-regex/src/search.c 2010-03-02 04:22:22 UTC (rev 4719) +++ branches/gnu-regex/src/search.c 2010-03-02 13:21:41 UTC (rev 4720) @@ -45,13 +45,20 @@
#include <unistd.h> #include <string.h> +#include <ctype.h>
#ifdef G_OS_UNIX # include <sys/types.h> # include <sys/wait.h> #endif
+#ifdef HAVE_REGEX_H +# include <regex.h> +#else +# include "gnuregex.h" +#endif
+ enum { GEANY_RESPONSE_FIND = 1, @@ -1633,6 +1640,124 @@ }
+static gboolean compile_regex(regex_t *regex, const gchar *str, gint sflags) +{ + gint err; + gint rflags = REG_EXTENDED | REG_NEWLINE; + + if (~sflags & SCFIND_MATCHCASE) + rflags |= REG_ICASE; + + err = regcomp(regex, str, rflags); + if (err != 0) + { + gchar buf[256]; + + regerror(err, regex, buf, sizeof buf); + ui_set_statusbar(FALSE, _("Bad regex: %s"), buf); + return FALSE; + } + return TRUE; +} + + +/* 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) +{ + return g_strndup(&text[pmatch[match_idx].rm_so], + pmatch[match_idx].rm_eo - pmatch[match_idx].rm_so); +} + + +static regmatch_t regex_matches[10]; +/* All matching text from regex_matches[0].rm_so to regex_matches[0].rm_eo */ +static gchar *regex_match_text = NULL; + +static gint find_regex(ScintillaObject *sci, guint pos, regex_t *regex) +{ + const gchar *text; + + g_return_val_if_fail(pos <= (guint)sci_get_length(sci), FALSE); + + text = (void*)scintilla_send_message(sci, SCI_GETCHARACTERPOINTER, 0, 0); + text += pos; + if (regexec(regex, text, G_N_ELEMENTS(regex_matches), regex_matches, 0) == 0) + { + setptr(regex_match_text, get_regex_match_string(text, regex_matches, 0)); + return regex_matches[0].rm_so + pos; + } + setptr(regex_match_text, NULL); + return -1; +} + + +gint search_find_next(ScintillaObject *sci, const gchar *str, gint flags) +{ + regex_t regex; + gint ret = -1; + gint pos; + + if (~flags & SCFIND_REGEXP) + return sci_search_next(sci, flags, str); + + if (!compile_regex(®ex, str, flags)) + return -1; + + pos = sci_get_current_position(sci); + ret = find_regex(sci, pos, ®ex); + if (ret >= 0) + sci_set_selection(sci, ret, regex_matches[0].rm_eo + pos); + + regfree(®ex); + return ret; +} + + +gint search_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; + } + c = ptr[1]; + /* backslash or unnecessary escape */ + if (c == '\' || !isdigit(c)) + { + g_string_erase(str, i, 1); + i++; + continue; + } + /* 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'); + g_string_insert(str, i, grp); + i += strlen(grp); + g_free(grp); + } + ret = sci_replace_target(sci, str->str, FALSE); + g_string_free(str, TRUE); + return ret; +} + + static gint find_document_usage(GeanyDocument *doc, const gchar *search_text, gint flags) { gchar *buffer, *short_file_name;
Modified: branches/gnu-regex/src/search.h =================================================================== --- branches/gnu-regex/src/search.h 2010-03-02 04:22:22 UTC (rev 4719) +++ branches/gnu-regex/src/search.h 2010-03-02 13:21:41 UTC (rev 4720) @@ -67,10 +67,17 @@
void search_show_find_in_files_dialog(const gchar *dir);
+struct _ScintillaObject; + +gint search_find_next(struct _ScintillaObject *sci, const gchar *str, gint flags); + void search_find_usage(const gchar *search_text, gint flags, gboolean in_session);
void search_find_selection(GeanyDocument *doc, gboolean search_backwards);
gint search_mark_all(GeanyDocument *doc, const gchar *search_text, gint flags);
+gint search_replace_target(struct _ScintillaObject *sci, const gchar *replace_text, + gboolean regex); + #endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.