grim/glibre

fdbe88e20076
Parents cb3562372609
Children 340c7313e3eb
Remove the old original code that we're no longer using
  • +0 -946
    src/glibre.c
  • --- a/src/glibre.c Tue Mar 29 01:47:58 2022 -0500
    +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
    @@ -1,946 +0,0 @@
    -/*
    - * GlibRe - The glib regex tester
    - * Copyright (C) 2010 Gary Kramlich <grim@reaperworld.com>
    - *
    - * This program is free software: you can redistribute it and/or modify
    - * it under the terms of the GNU General Public License as published by
    - * the Free Software Foundation, either version 3 of the License, or
    - * (at your option) any later version.
    - *
    - * This program is distributed in the hope that it will be useful,
    - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    - * GNU General Public License for more details.
    - *
    - * You should have received a copy of the GNU General Public License
    - * along with this program. If not, see <http://www.gnu.org/licenses/>.
    - */
    -#include <glib.h>
    -#include <gdk/gdk.h>
    -#include <gtk/gtk.h>
    -
    -#include "glibre.h"
    -
    -typedef struct {
    - GtkWidget *window;
    -
    - GtkWidget *dock;
    - GtkWidget *dockbar;
    -
    - GRegex *regex;
    - GtkWidget *regex_entry;
    -
    - GtkWidget *method_one;
    - GtkWidget *method_all;
    - GtkWidget *method_split;
    -
    - GtkWidget *c_caseless;
    - GtkWidget *c_multiline;
    - GtkWidget *c_dotall;
    - GtkWidget *c_extended;
    - GtkWidget *c_anchored;
    - GtkWidget *c_dollar_endonly;
    - GtkWidget *c_ungreedy;
    - GtkWidget *c_raw;
    - GtkWidget *c_no_auto_capture;
    - GtkWidget *c_optimize;
    - GtkWidget *c_dupnames;
    - GtkWidget *c_newline_cr;
    - GtkWidget *c_newline_lf;
    -
    - GtkWidget *m_anchored;
    - GtkWidget *m_notbol;
    - GtkWidget *m_noteol;
    - GtkWidget *m_notempty;
    - GtkWidget *m_partial;
    - GtkWidget *m_newline_cr;
    - GtkWidget *m_newline_lf;
    - GtkWidget *m_newline_any;
    -
    - GtkWidget *replace_entry;
    -
    - GtkWidget *data_entry;
    -
    - GtkTreeStore *groups_store;
    - GtkWidget *groups_tree;
    -
    - GtkWidget *results_entry;
    -} GlibReWindow;
    -
    -typedef enum {
    - GLIBRE_REGEX_STATUS_NONE,
    - GLIBRE_REGEX_STATUS_GOOD,
    - GLIBRE_REGEX_STATUS_ERROR,
    -} GlibReRegexStatus;
    -
    -/******************************************************************************
    - * Globals
    - *****************************************************************************/
    -#define GLIBRE_ENTRIES_GROUP "inputs"
    -#define GLIBRE_REGEX "regex"
    -#define GLIBRE_METHOD "method"
    -#define GLIBRE_REPLACE_WITH "replace with"
    -#define GLIBRE_DATA "data"
    -
    -#define GLIBRE_COMPILE_GROUP "compile options"
    -#define GLIBRE_COMPILE_CASELESS "caseless"
    -#define GLIBRE_COMPILE_MULTILINE "multiline"
    -#define GLIBRE_COMPILE_DOTALL "dotall"
    -#define GLIBRE_COMPILE_EXTENDED "extended"
    -#define GLIBRE_COMPILE_ANCHORED "anchored"
    -#define GLIBRE_COMPILE_DOLLAR_ENDONLY "dollar endonly"
    -#define GLIBRE_COMPILE_UNGREEDY "ungreedy"
    -#define GLIBRE_COMPILE_RAW "raw"
    -#define GLIBRE_COMPILE_NO_AUTO_CAPTURE "no auto capture"
    -#define GLIBRE_COMPILE_OPTIMIZE "optimize"
    -#define GLIBRE_COMPILE_DUPNAMES "dupnames"
    -#define GLIBRE_COMPILE_NEWLINE_CR "newline cr"
    -#define GLIBRE_COMPILE_NEWLINE_LF "newline lf"
    -
    -#define GLIBRE_MATCH_GROUP "match options"
    -#define GLIBRE_MATCH_ALL "all"
    -#define GLIBRE_MATCH_ANCHORED "anchored"
    -#define GLIBRE_MATCH_NOTBOL "notbol"
    -#define GLIBRE_MATCH_NOTEOL "noteol"
    -#define GLIBRE_MATCH_NOTEMPTY "notempty"
    -#define GLIBRE_MATCH_PARTIAL "partial"
    -#define GLIBRE_MATCH_NEWLINE_CR "newline cr"
    -#define GLIBRE_MATCH_NEWLINE_LF "newline lf"
    -#define GLIBRE_MATCH_NEWLINE_ANY "newline any"
    -
    -static GlibReWindow window;
    -static gboolean loaded = FALSE;
    -
    -/******************************************************************************
    - * Prototypes
    - *
    - * Gross, but sometimes they're necessary and make life easier :)
    - *****************************************************************************/
    -static void glibre_update(void);
    -
    -/******************************************************************************
    - * Helpers
    - *****************************************************************************/
    -static void
    -glibre_regex_update_status(GlibReRegexStatus status) {
    - GdkColor good_default_bg_color = { 0, 0xafff, 0xffff, 0xafff };
    - GdkColor error_default_bg_color = { 0, 0xffff, 0xafff, 0xafff };
    - GdkColor themed;
    - GdkColor *real = NULL;
    - GtkStyle *style;
    - const gchar *bg_color_name[] = {
    - "",
    - "good_bg_color",
    - "error_bg_color"
    - };
    -
    - style = gtk_widget_get_style(window.regex_entry);
    -
    - if(gtk_style_lookup_color(style, bg_color_name[status], &themed)) {
    - real = &themed;
    - printf("Found a themed color...\n");
    - } else {
    - switch(status) {
    - case GLIBRE_REGEX_STATUS_GOOD:
    - real = &good_default_bg_color;
    - break;
    - case GLIBRE_REGEX_STATUS_ERROR:
    - real = &error_default_bg_color;
    - break;
    - default:
    - real = NULL;
    - break;
    - }
    - }
    -
    - if(!real) {
    - gtk_widget_set_style(window.regex_entry, NULL);
    - } else {
    - gtk_widget_modify_base(window.regex_entry, GTK_STATE_NORMAL, real);
    - }
    -}
    -
    -static inline gchar *
    -glibre_get_entry_text(GtkWidget *w) {
    - GtkTextBuffer *buffer = NULL;
    - GtkTextIter start, end;
    - gchar *text = NULL;
    -
    - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w));
    -
    - gtk_text_buffer_get_start_iter(buffer, &start);
    - gtk_text_buffer_get_end_iter(buffer, &end);
    -
    - text = gtk_text_buffer_get_text(buffer, &start, &end, TRUE);
    -
    - return text;
    -}
    -
    -static inline void
    -glibre_set_entry_text(GtkWidget *w, const gchar *text) {
    - GtkTextBuffer *buffer = NULL;
    -
    - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w));
    -
    - gtk_text_buffer_set_text(buffer, text, -1);
    -}
    -
    -static inline gboolean
    -glibre_get_toggle(GtkWidget *w) {
    - return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
    -}
    -
    -static inline void
    -glibre_set_toggle(GtkWidget *w, gboolean v) {
    - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), v);
    -}
    -
    -static inline gchar *
    -glibre_config_file(const gchar *filename) {
    - return g_build_filename(g_get_user_config_dir(), "glibre", filename, NULL);
    -}
    -
    -static void
    -glibre_load_config(void) {
    - GKeyFile *key_file = NULL;
    - gchar *conf_file = NULL;
    - gint width, height;
    -
    - conf_file = glibre_config_file("glibre.conf");
    -
    - #define glibre_load_entry(group, key, widget) { \
    - gchar *string = g_key_file_get_string(key_file, (group), (key), NULL); \
    - glibre_set_entry_text(widget, string); \
    - g_free(string); \
    - }
    -
    - #define glibre_load_toggle(group, key, widget) \
    - glibre_set_toggle((widget), g_key_file_get_boolean(key_file, (group), (key), NULL))
    -
    - #define glibre_load_radio(group, key, widget, value) { \
    - gint v = g_key_file_get_integer(key_file, (group), (key), NULL); \
    - if(v == (value)) \
    - glibre_set_toggle((widget), TRUE); \
    - }
    -
    - key_file = g_key_file_new();
    -
    - /* load the file */
    - if(!g_key_file_load_from_file(key_file, conf_file, 0, NULL)) {
    - g_free(conf_file);
    - g_key_file_free(key_file);
    -
    - loaded = TRUE;
    -
    - return;
    - }
    -
    - /* main window */
    - width = g_key_file_get_integer(key_file, "window", "width", NULL);
    - height = g_key_file_get_integer(key_file, "window", "height", NULL);
    -
    - width = (width > 0) ? width : -1;
    - height = (height > 0) ? height : -1;
    -
    - gtk_window_set_default_size(GTK_WINDOW(window.window), width, height);
    -
    - /* entries */
    - glibre_load_entry(GLIBRE_ENTRIES_GROUP, GLIBRE_REGEX, window.regex_entry);
    - glibre_load_entry(GLIBRE_ENTRIES_GROUP, GLIBRE_REPLACE_WITH, window.replace_entry);
    - glibre_load_entry(GLIBRE_ENTRIES_GROUP, GLIBRE_DATA, window.data_entry);
    -
    - glibre_load_radio(GLIBRE_ENTRIES_GROUP, GLIBRE_METHOD, window.method_one, 0);
    - glibre_load_radio(GLIBRE_ENTRIES_GROUP, GLIBRE_METHOD, window.method_all, 1);
    - glibre_load_radio(GLIBRE_ENTRIES_GROUP, GLIBRE_METHOD, window.method_split, 2);
    -
    - /* compile options */
    - glibre_load_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_CASELESS,
    - window.c_caseless);
    - glibre_load_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_MULTILINE,
    - window.c_multiline);
    - glibre_load_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_DOTALL,
    - window.c_dotall);
    - glibre_load_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_EXTENDED,
    - window.c_extended);
    - glibre_load_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_ANCHORED,
    - window.c_anchored);
    - glibre_load_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_DOLLAR_ENDONLY,
    - window.c_dollar_endonly);
    - glibre_load_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_UNGREEDY,
    - window.c_ungreedy);
    - glibre_load_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_RAW,
    - window.c_raw);
    - glibre_load_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_NO_AUTO_CAPTURE,
    - window.c_no_auto_capture);
    - glibre_load_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_OPTIMIZE,
    - window.c_optimize);
    - glibre_load_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_DUPNAMES,
    - window.c_dupnames);
    - glibre_load_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_NEWLINE_CR,
    - window.c_newline_cr);
    - glibre_load_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_NEWLINE_LF,
    - window.c_newline_lf);
    -
    - /* match options */
    - glibre_load_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_ANCHORED,
    - window.m_anchored);
    - glibre_load_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_NOTBOL,
    - window.m_notbol);
    - glibre_load_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_NOTEOL,
    - window.m_noteol);
    - glibre_load_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_NOTEMPTY,
    - window.m_notempty);
    - glibre_load_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_PARTIAL,
    - window.m_partial);
    - glibre_load_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_NEWLINE_CR,
    - window.m_newline_cr);
    - glibre_load_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_NEWLINE_LF,
    - window.m_newline_lf);
    - glibre_load_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_NEWLINE_ANY,
    - window.m_newline_any);
    -
    - /* cleanup */
    - g_key_file_free(key_file);
    - g_free(conf_file);
    -
    - glibre_update();
    - loaded = TRUE;
    -}
    -
    -static void
    -glibre_save_config(void) {
    - GKeyFile *key_file = NULL;
    - gchar *data = NULL;
    - gchar *conf_dir = NULL, *conf_file = NULL;
    - gint width, height;
    -
    - conf_dir = glibre_config_file(NULL);
    - if(g_mkdir_with_parents(conf_dir, 0755) != 0) {
    - printf("Failed to create directory '%s': aborting save\n", conf_dir);
    - g_free(conf_dir);
    -
    - return;
    - }
    -
    - g_free(conf_dir);
    -
    - #define glibre_save_entry(group, key, value) \
    - g_key_file_set_string(key_file, (group), (key), \
    - glibre_get_entry_text((value)))
    -
    - #define glibre_save_toggle(group, key, widget) \
    - g_key_file_set_boolean(key_file, (group), (key), \
    - glibre_get_toggle((widget)))
    -
    - #define glibre_save_radio(group, key, widget, value) { \
    - if(glibre_get_toggle((widget))) \
    - g_key_file_set_integer(key_file, (group), (key), (value)); \
    - }
    -
    - key_file = g_key_file_new();
    -
    - /* main window */
    - gtk_window_get_size(GTK_WINDOW(window.window), &width, &height);
    - g_key_file_set_integer(key_file, "window", "width", width);
    - g_key_file_set_integer(key_file, "window", "height", height);
    -
    - /* entries */
    - glibre_save_entry(GLIBRE_ENTRIES_GROUP, GLIBRE_REGEX, window.regex_entry);
    - glibre_save_entry(GLIBRE_ENTRIES_GROUP, GLIBRE_REPLACE_WITH, window.replace_entry);
    - glibre_save_entry(GLIBRE_ENTRIES_GROUP, GLIBRE_DATA, window.data_entry);
    -
    - glibre_save_radio(GLIBRE_ENTRIES_GROUP, GLIBRE_METHOD, window.method_one, 0);
    - glibre_save_radio(GLIBRE_ENTRIES_GROUP, GLIBRE_METHOD, window.method_all, 1);
    - glibre_save_radio(GLIBRE_ENTRIES_GROUP, GLIBRE_METHOD, window.method_split, 2);
    -
    - /* compile options */
    - glibre_save_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_CASELESS,
    - window.c_caseless);
    - glibre_save_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_MULTILINE,
    - window.c_multiline);
    - glibre_save_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_DOTALL,
    - window.c_dotall);
    - glibre_save_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_EXTENDED,
    - window.c_extended);
    - glibre_save_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_ANCHORED,
    - window.c_anchored);
    - glibre_save_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_DOLLAR_ENDONLY,
    - window.c_dollar_endonly);
    - glibre_save_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_UNGREEDY,
    - window.c_ungreedy);
    - glibre_save_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_RAW,
    - window.c_raw);
    - glibre_save_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_NO_AUTO_CAPTURE,
    - window.c_no_auto_capture);
    - glibre_save_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_OPTIMIZE,
    - window.c_optimize);
    - glibre_save_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_DUPNAMES,
    - window.c_dupnames);
    - glibre_save_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_NEWLINE_CR,
    - window.c_newline_cr);
    - glibre_save_toggle(GLIBRE_COMPILE_GROUP, GLIBRE_COMPILE_NEWLINE_LF,
    - window.c_newline_lf);
    -
    - /* match options */
    - glibre_save_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_ANCHORED,
    - window.m_anchored);
    - glibre_save_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_NOTBOL,
    - window.m_notbol);
    - glibre_save_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_NOTEOL,
    - window.m_noteol);
    - glibre_save_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_NOTEMPTY,
    - window.m_notempty);
    - glibre_save_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_PARTIAL,
    - window.m_partial);
    - glibre_save_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_NEWLINE_CR,
    - window.m_newline_cr);
    - glibre_save_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_NEWLINE_LF,
    - window.m_newline_lf);
    - glibre_save_toggle(GLIBRE_MATCH_GROUP, GLIBRE_MATCH_NEWLINE_ANY,
    - window.m_newline_any);
    -
    - /* store the settings */
    - data = g_key_file_to_data(key_file, NULL, NULL);
    -
    - /* free the keyfile */
    - g_key_file_free(key_file);
    -
    - /* if we didn't get any data, we don't want to overwrite the existing file
    - * so we exit.
    - */
    - if(!data)
    - return;
    -
    - /* write the date to the file and free the data */
    - conf_file = glibre_config_file("glibre.conf");
    - g_file_set_contents(conf_file, data, -1, NULL);
    - g_free(conf_file);
    -
    - g_free(data);
    -}
    -
    -#define glibre_check_flag(widget, value) { \
    - if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON((widget)))) { \
    - flags |= (value); \
    - } \
    -}
    -
    -static GRegexCompileFlags
    -glibre_compile_flags_to_int(void) {
    - GRegexCompileFlags flags = 0;
    -
    - glibre_check_flag(window.c_caseless, G_REGEX_CASELESS);
    - glibre_check_flag(window.c_multiline, G_REGEX_MULTILINE);
    - glibre_check_flag(window.c_dotall, G_REGEX_DOTALL);
    - glibre_check_flag(window.c_extended, G_REGEX_EXTENDED);
    - glibre_check_flag(window.c_anchored, G_REGEX_ANCHORED);
    - glibre_check_flag(window.c_dollar_endonly, G_REGEX_DOLLAR_ENDONLY);
    - glibre_check_flag(window.c_ungreedy, G_REGEX_UNGREEDY);
    - glibre_check_flag(window.c_raw, G_REGEX_RAW);
    - glibre_check_flag(window.c_no_auto_capture, G_REGEX_NO_AUTO_CAPTURE);
    - glibre_check_flag(window.c_optimize, G_REGEX_OPTIMIZE);
    - glibre_check_flag(window.c_dupnames, G_REGEX_DUPNAMES);
    - glibre_check_flag(window.c_newline_cr, G_REGEX_NEWLINE_CR);
    - glibre_check_flag(window.c_newline_lf, G_REGEX_NEWLINE_LF);
    -
    - return flags;
    -}
    -
    -static GRegexMatchFlags
    -glibre_match_flags_to_int(void) {
    - GRegexMatchFlags flags = 0;
    -
    - glibre_check_flag(window.m_anchored, G_REGEX_MATCH_ANCHORED);
    - glibre_check_flag(window.m_notbol, G_REGEX_MATCH_NOTBOL);
    - glibre_check_flag(window.m_noteol, G_REGEX_MATCH_NOTEOL);
    - glibre_check_flag(window.m_notempty, G_REGEX_MATCH_NOTEMPTY);
    - glibre_check_flag(window.m_partial, G_REGEX_MATCH_PARTIAL);
    - glibre_check_flag(window.m_newline_cr, G_REGEX_MATCH_NEWLINE_CR);
    - glibre_check_flag(window.m_newline_lf, G_REGEX_MATCH_NEWLINE_LF);
    - glibre_check_flag(window.m_newline_any, G_REGEX_MATCH_NEWLINE_ANY);
    -
    - return flags;
    -}
    -
    -static inline void
    -glibre_add_groups(GtkTreeIter *parent, gchar **groups) {
    - gint i = 0;
    -
    - for(i = 0; groups[i]; i++) {
    - GtkTreeIter iter;
    - gchar *title = g_strdup_printf("Group %d", i);
    -
    - gtk_tree_store_append(window.groups_store, &iter, parent);
    - gtk_tree_store_set(window.groups_store, &iter,
    - 0, title,
    - 1, groups[i],
    - -1);
    - g_free(title);
    - }
    -}
    -
    -static void
    -glibre_update(void) {
    - GError *error = NULL;
    - GRegexCompileFlags compile_flags = 0;
    - GRegexMatchFlags match_flags = 0;
    - GMatchInfo *mi = NULL;
    - gchar *pattern = NULL, *data = NULL, *replaced = NULL;
    - const gchar *stock_id = NULL;
    - gboolean good = FALSE;
    - const gchar *replacement = NULL;
    - gchar **groups = NULL;
    -
    - /* grab the pattern and try to compile the it */
    - pattern = glibre_get_entry_text(window.regex_entry);
    -
    - if(window.regex) {
    - g_regex_unref(window.regex);
    - window.regex = NULL;
    - }
    -
    - if(!*pattern) {
    - glibre_regex_update_status(GLIBRE_REGEX_STATUS_NONE);
    -
    - return;
    - }
    -
    - compile_flags = glibre_compile_flags_to_int();
    - match_flags = glibre_match_flags_to_int();
    -
    - window.regex = g_regex_new(pattern, compile_flags, match_flags, &error);
    - g_free(pattern);
    -
    - if(error) {
    - glibre_regex_update_status(GLIBRE_REGEX_STATUS_ERROR);
    - g_error_free(error);
    - } else {
    - glibre_regex_update_status(GLIBRE_REGEX_STATUS_GOOD);
    - good = TRUE;
    - }
    -
    - /* clear the groups list */
    - gtk_tree_store_clear(window.groups_store);
    -
    - /* jump out if the regex failed to compile */
    - if(!good)
    - return;
    -
    - /* grab the data */
    - data = glibre_get_entry_text(window.data_entry);
    -
    - /* now actually run the regex against the data and figure out the gruops */
    - if(glibre_get_toggle(window.method_split)) {
    - groups = g_regex_split(window.regex, data, match_flags);
    -
    - glibre_add_groups(NULL, groups);
    -
    - g_strfreev(groups);
    - } else {
    - gboolean matched = FALSE;
    -
    - if(glibre_get_toggle(window.method_one))
    - matched = g_regex_match(window.regex, data, match_flags, &mi);
    - else if(glibre_get_toggle(window.method_all))
    - matched = g_regex_match_all(window.regex, data, match_flags, &mi);
    -
    - if(matched) {
    - gint match = 0;
    -
    - do {
    - GtkTreeIter parent;
    - gchar *title;
    -
    - title = g_strdup_printf("Match %d", match++);
    - gtk_tree_store_append(window.groups_store, &parent, NULL);
    - gtk_tree_store_set(window.groups_store, &parent, 0, title, -1);
    - g_free(title);
    -
    - groups = g_match_info_fetch_all(mi);
    -
    - glibre_add_groups(&parent, groups);
    -
    - g_strfreev(groups);
    - } while (g_match_info_next(mi, NULL));
    - }
    -
    - g_match_info_free(mi);
    - }
    -
    - /* expand all of the tree view nodes */
    - gtk_tree_view_expand_all(GTK_TREE_VIEW(window.groups_tree));
    -
    - /* now run the regex again, and this time do the replacements */
    - replacement = glibre_get_entry_text(window.replace_entry);
    - replaced = g_regex_replace(window.regex, data, -1, 0, replacement, match_flags, NULL);
    - glibre_set_entry_text(window.results_entry, (replaced) ? replaced : "");
    - g_free(replaced);
    -
    - /* cleanup */
    - g_free(data);
    -}
    -
    -/******************************************************************************
    - * Helpers
    - *****************************************************************************/
    -static void
    -glibre_quit(void) {
    - glibre_save_config();
    -
    - gtk_main_quit();
    -}
    -
    -/******************************************************************************
    - * Callbacks
    - *****************************************************************************/
    -static gboolean
    -glibre_window_delete(GtkWidget *w, GdkEvent *e, gpointer d) {
    - glibre_quit();
    -
    - return FALSE;
    -}
    -
    -static void
    -glibre_clear_cb(GtkMenuItem *w, gpointer d) {
    - glibre_set_entry_text(window.regex_entry, "");
    - glibre_set_entry_text(window.data_entry, "");
    - glibre_set_entry_text(window.replace_entry, "");
    -
    - glibre_set_toggle(window.c_caseless, FALSE);
    - glibre_set_toggle(window.c_multiline, FALSE);
    - glibre_set_toggle(window.c_dotall, FALSE);
    - glibre_set_toggle(window.c_extended, FALSE);
    - glibre_set_toggle(window.c_anchored, FALSE);
    - glibre_set_toggle(window.c_dollar_endonly, FALSE);
    - glibre_set_toggle(window.c_ungreedy, FALSE);
    - glibre_set_toggle(window.c_raw, FALSE);
    - glibre_set_toggle(window.c_no_auto_capture, FALSE);
    - glibre_set_toggle(window.c_optimize, FALSE);
    - glibre_set_toggle(window.c_dupnames, FALSE);
    - glibre_set_toggle(window.c_newline_cr, FALSE);
    - glibre_set_toggle(window.c_newline_lf, FALSE);
    -
    - glibre_set_toggle(window.m_anchored, FALSE);
    - glibre_set_toggle(window.m_notbol, FALSE);
    - glibre_set_toggle(window.m_noteol, FALSE);
    - glibre_set_toggle(window.m_notempty, FALSE);
    - glibre_set_toggle(window.m_partial, FALSE);
    - glibre_set_toggle(window.m_newline_cr, FALSE);
    - glibre_set_toggle(window.m_newline_lf, FALSE);
    - glibre_set_toggle(window.m_newline_any, FALSE);
    -}
    -
    -static void
    -glibre_entry_changed_cb(GtkTextBuffer *buffer, gpointer d) {
    - if(loaded)
    - glibre_update();
    -}
    -
    -static void
    -glibre_toggle_toggled_cb(GtkToggleButton *button, gpointer d) {
    - if(loaded)
    - glibre_update();
    -}
    -
    -/******************************************************************************
    - * UI Building
    - *****************************************************************************/
    -static inline GtkWidget *
    -glibre_create_scrolled_window(void) {
    - GtkWidget *sw = NULL;
    -
    - sw = gtk_scrolled_window_new(NULL, NULL);
    - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
    - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
    - GTK_SHADOW_IN);
    -
    - return sw;
    -}
    -
    -static void
    -glibre_build_window(void) {
    - GtkAccelGroup *ag = NULL;
    - GtkWidget *ovbox = NULL, *vbox = NULL, *sw = NULL;
    - GtkWidget *menubar = NULL, *menu = NULL, *item = NULL;
    - GtkTreeViewColumn *col = NULL;
    -
    - ag = gtk_accel_group_new();
    -
    - window.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    - gtk_window_set_title(GTK_WINDOW(window.window), "GlibRe");
    - g_signal_connect(window.window, "delete-event",
    - G_CALLBACK(glibre_window_delete), NULL);
    -
    - /* create our vbox */
    - ovbox = gtk_vbox_new(FALSE, 4);
    - gtk_container_add(GTK_CONTAINER(window.window), ovbox);
    -
    - /**************************************************************************
    - * Menus
    - *************************************************************************/
    - /* create the menubar */
    - menubar = gtk_menu_bar_new();
    - gtk_box_pack_start(GTK_BOX(ovbox), menubar, FALSE, FALSE, 0);
    -
    - /* file menu */
    - item = gtk_menu_item_new_with_mnemonic("_File");
    - gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item);
    -
    - menu = gtk_menu_new();
    - gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
    -
    - item = gtk_menu_item_new_with_mnemonic("_Quit");
    - gtk_actionable_set_action_name(GTK_ACTIONABLE(item), "app.quit");
    - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
    -
    - /* Edit Menu */
    - item = gtk_menu_item_new_with_mnemonic("_Edit");
    - gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item);
    -
    - menu = gtk_menu_new();
    - gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
    -
    - item = gtk_menu_item_new_with_mnemonic("_Clear");
    - gtk_actionable_set_action_name(GTK_ACTIONABLE(item), "win.clear");
    - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
    -
    - /* Help Menu */
    - item = gtk_menu_item_new_with_mnemonic("_Help");
    - gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item);
    -
    - menu = gtk_menu_new();
    - gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
    -
    - item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, ag);
    - gtk_actionable_set_action_name(GTK_ACTIONABLE(item), "app.about");
    - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
    -
    - /**************************************************************************
    - * create the regex text view
    - *************************************************************************/
    - sw = glibre_create_scrolled_window();
    - gtk_box_pack_start(GTK_BOX(ovbox), sw, TRUE, TRUE, 0);
    -
    - window.regex_entry = gtk_text_view_new();
    - g_signal_connect(gtk_text_view_get_buffer(GTK_TEXT_VIEW(window.regex_entry)),
    - "changed", G_CALLBACK(glibre_entry_changed_cb), NULL);
    - gtk_container_add(GTK_CONTAINER(sw), window.regex_entry);
    -
    - /**************************************************************************
    - * build the method dock and it's children
    - **************************************************************************/
    - vbox = gtk_vbox_new(FALSE, 0);
    - gtk_box_pack_start(GTK_BOX(ovbox), vbox, TRUE, TRUE, 0);
    -
    - window.method_one = gtk_radio_button_new_with_label(NULL, "Match One");
    - g_signal_connect(window.method_one, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.method_one, FALSE, FALSE, 0);
    -
    - window.method_all =
    - gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(window.method_one),
    - "Match All");
    - g_signal_connect(window.method_all, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.method_all, FALSE, FALSE, 0);
    -
    - window.method_split =
    - gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(window.method_one),
    - "Split");
    - g_signal_connect(window.method_split, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.method_split, FALSE, FALSE, 0);
    -
    - /**************************************************************************
    - * build the compile option dock and it's children
    - **************************************************************************/
    - vbox = gtk_vbox_new(FALSE, 0);
    - gtk_box_pack_start(GTK_BOX(ovbox), vbox, TRUE, TRUE, 0);
    -
    - window.c_caseless = gtk_check_button_new_with_label("Caseless");
    - g_signal_connect(window.c_caseless, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.c_caseless, FALSE, FALSE, 0);
    -
    - window.c_multiline = gtk_check_button_new_with_label("Multiline");
    - g_signal_connect(window.c_multiline, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.c_multiline, FALSE, FALSE, 0);
    -
    - window.c_dotall = gtk_check_button_new_with_label("Dot All");
    - g_signal_connect(window.c_dotall, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.c_dotall, FALSE, FALSE, 0);
    -
    - window.c_extended = gtk_check_button_new_with_label("Extended");
    - g_signal_connect(window.c_extended, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.c_extended, FALSE, FALSE, 0);
    -
    - window.c_anchored = gtk_check_button_new_with_label("Anchored");
    - g_signal_connect(window.c_anchored, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.c_anchored, FALSE, FALSE, 0);
    -
    - window.c_dollar_endonly = gtk_check_button_new_with_label("Dollar Endonly");
    - g_signal_connect(window.c_dollar_endonly, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.c_dollar_endonly, FALSE, FALSE, 0);
    -
    - window.c_ungreedy = gtk_check_button_new_with_label("Ungreedy");
    - g_signal_connect(window.c_ungreedy, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.c_ungreedy, FALSE, FALSE, 0);
    -
    - window.c_raw = gtk_check_button_new_with_label("Raw");
    - g_signal_connect(window.c_raw, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.c_raw, FALSE, FALSE, 0);
    -
    - window.c_no_auto_capture = gtk_check_button_new_with_label("No Auto Capture");
    - g_signal_connect(window.c_no_auto_capture, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.c_no_auto_capture, FALSE, FALSE, 0);
    -
    - window.c_optimize = gtk_check_button_new_with_label("Optimize");
    - g_signal_connect(window.c_optimize, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.c_optimize, FALSE, FALSE, 0);
    -
    - window.c_dupnames = gtk_check_button_new_with_label("Dup Names");
    - g_signal_connect(window.c_dupnames, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.c_dupnames, FALSE, FALSE, 0);
    -
    - window.c_newline_cr = gtk_check_button_new_with_label("Newline CR");
    - g_signal_connect(window.c_newline_cr, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.c_newline_cr, FALSE, FALSE, 0);
    -
    - window.c_newline_lf = gtk_check_button_new_with_label("Newline LF");
    - g_signal_connect(window.c_newline_lf, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.c_newline_lf, FALSE, FALSE, 0);
    -
    - /**************************************************************************
    - * build the match option dock and it's children
    - **************************************************************************/
    - vbox = gtk_vbox_new(FALSE, 0);
    - gtk_box_pack_start(GTK_BOX(ovbox), vbox, TRUE, TRUE, 0);
    -
    - window.m_anchored = gtk_check_button_new_with_label("Anchored");
    - g_signal_connect(window.m_anchored, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.m_anchored, FALSE, FALSE, 0);
    -
    - window.m_notbol = gtk_check_button_new_with_label("Not BOL");
    - g_signal_connect(window.m_notbol, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.m_notbol, FALSE, FALSE, 0);
    -
    - window.m_noteol = gtk_check_button_new_with_label("Not EOL");
    - g_signal_connect(window.m_noteol, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.m_noteol, FALSE, FALSE, 0);
    -
    - window.m_notempty = gtk_check_button_new_with_label("Not Empty");
    - g_signal_connect(window.m_notempty, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.m_notempty, FALSE, FALSE, 0);
    -
    - window.m_partial = gtk_check_button_new_with_label("Partial");
    - g_signal_connect(window.m_partial, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.m_partial, FALSE, FALSE, 0);
    -
    - window.m_newline_cr = gtk_check_button_new_with_label("Newline CR");
    - g_signal_connect(window.m_newline_cr, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.m_newline_cr, FALSE, FALSE, 0);
    -
    - window.m_newline_lf = gtk_check_button_new_with_label("Newline LF");
    - g_signal_connect(window.m_newline_lf, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.m_newline_lf, FALSE, FALSE, 0);
    -
    - window.m_newline_any = gtk_check_button_new_with_label("Newline Any");
    - g_signal_connect(window.m_newline_any, "toggled",
    - G_CALLBACK(glibre_toggle_toggled_cb), NULL);
    - gtk_box_pack_start(GTK_BOX(vbox), window.m_newline_any, FALSE, FALSE, 0);
    -
    - /**************************************************************************
    - * Replacement
    - *************************************************************************/
    - sw = glibre_create_scrolled_window();
    - gtk_box_pack_start(GTK_BOX(ovbox), sw, TRUE, TRUE, 0);
    -
    - window.replace_entry = gtk_text_view_new();
    - g_signal_connect(gtk_text_view_get_buffer(GTK_TEXT_VIEW(window.replace_entry)),
    - "changed", G_CALLBACK(glibre_entry_changed_cb), NULL);
    - gtk_container_add(GTK_CONTAINER(sw), window.replace_entry);
    -
    - /**************************************************************************
    - * Data
    - *************************************************************************/
    - sw = glibre_create_scrolled_window();
    - gtk_box_pack_start(GTK_BOX(ovbox), sw, TRUE, TRUE, 0);
    -
    - window.data_entry = gtk_text_view_new();
    - g_signal_connect(gtk_text_view_get_buffer(GTK_TEXT_VIEW(window.data_entry)),
    - "changed", G_CALLBACK(glibre_entry_changed_cb), NULL);
    - gtk_container_add(GTK_CONTAINER(sw), window.data_entry);
    -
    - /**************************************************************************
    - * Groups
    - *************************************************************************/
    - sw = glibre_create_scrolled_window();
    - gtk_box_pack_start(GTK_BOX(ovbox), sw, TRUE, TRUE, 0);
    -
    - window.groups_store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
    -
    - window.groups_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(window.groups_store));
    - gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(window.groups_tree), FALSE);
    - gtk_container_add(GTK_CONTAINER(sw), window.groups_tree);
    -
    - col = gtk_tree_view_column_new_with_attributes("Group",
    - gtk_cell_renderer_text_new(),
    - "text", 0,
    - NULL);
    - gtk_tree_view_append_column(GTK_TREE_VIEW(window.groups_tree), col);
    -
    - col = gtk_tree_view_column_new_with_attributes("Data",
    - gtk_cell_renderer_text_new(),
    - "text", 1,
    - NULL);
    - gtk_tree_view_append_column(GTK_TREE_VIEW(window.groups_tree), col);
    -
    - /**************************************************************************
    - * Results
    - *************************************************************************/
    - sw = glibre_create_scrolled_window();
    - gtk_box_pack_start(GTK_BOX(ovbox), sw, TRUE, TRUE, 0);
    -
    - window.results_entry = gtk_text_view_new();
    - gtk_text_view_set_editable(GTK_TEXT_VIEW(window.results_entry), FALSE);
    - gtk_container_add(GTK_CONTAINER(sw), window.results_entry);
    -}
    -
    -/******************************************************************************
    - * mizain
    - *****************************************************************************/
    -void
    -glibre_main(void) {
    - glibre_build_window();
    -
    - /* this is kind of a hack, but i need regex to be null, and since i'm not
    - * allocating the structure, this becomes necessary.
    - */
    - window.regex = NULL;
    -
    - glibre_load_config();
    -
    - gtk_widget_show_all(window.window);
    - gtk_window_set_application(GTK_WINDOW(window.window), g_application_get_default());
    -}
    -