changeset 30986:bedc5715ab5f

Use GRegex where available. Fixes #12601. committer: John Bailey <rekkanoryo@rekkanoryo.org>
author eion@robbmob.com
date Sat, 18 Sep 2010 00:20:35 +0000
parents 274e691dd5f4
children d84d306b5610
files pidgin/gtkdebug.c
diffstat 1 files changed, 101 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin/gtkdebug.c	Fri Sep 17 18:40:46 2010 +0000
+++ b/pidgin/gtkdebug.c	Sat Sep 18 00:20:35 2010 +0000
@@ -39,6 +39,11 @@
 
 #ifdef HAVE_REGEX_H
 # include <regex.h>
+#	define USE_REGEX 1
+#else
+#if GLIB_CHECK_VERSION(2,14,0)
+#	define USE_REGEX 1
+#endif
 #endif /* HAVE_REGEX_H */
 
 #include <gdk/gdkkeysyms.h>
@@ -52,7 +57,7 @@
 
 	gboolean paused;
 
-#ifdef HAVE_REGEX_H
+#ifdef USE_REGEX
 	GtkWidget *filter;
 	GtkWidget *expression;
 
@@ -60,11 +65,14 @@
 	gboolean highlight;
 
 	guint timer;
-
+#	ifdef HAVE_REGEX_H
 	regex_t regex;
+#	else
+	GRegex *regex;
+#	endif /* HAVE_REGEX_H */
 #else
 	GtkWidget *find;
-#endif /* HAVE_REGEX_H */
+#endif /* USE_REGEX */
 	GtkWidget *filterlevel;
 } DebugWindow;
 
@@ -80,17 +88,17 @@
 static DebugWindow *debug_win = NULL;
 static guint debug_enabled_timer = 0;
 
-#ifdef HAVE_REGEX_H
+#ifdef USE_REGEX
 static void regex_filter_all(DebugWindow *win);
 static void regex_show_all(DebugWindow *win);
-#endif /* HAVE_REGEX_H */
+#endif /* USE_REGEX */
 
 static gint
 debug_window_destroy(GtkWidget *w, GdkEvent *event, void *unused)
 {
 	purple_prefs_disconnect_by_handle(pidgin_debug_get_handle());
 
-#ifdef HAVE_REGEX_H
+#ifdef USE_REGEX
 	if(debug_win->timer != 0) {
 		const gchar *text;
 
@@ -99,9 +107,12 @@
 		text = gtk_entry_get_text(GTK_ENTRY(debug_win->expression));
 		purple_prefs_set_string(PIDGIN_PREFS_ROOT "/debug/regex", text);
 	}
-
+#ifdef HAVE_REGEX_H
 	regfree(&debug_win->regex);
-#endif
+#else
+	g_regex_unref(debug_win->regex);
+#endif /* HAVE_REGEX_H */
+#endif /* USE_REGEX */
 
 	/* If the "Save Log" dialog is open then close it */
 	purple_request_close_with_handle(debug_win);
@@ -125,7 +136,7 @@
 	return FALSE;
 }
 
-#ifndef HAVE_REGEX_H
+#ifndef USE_REGEX
 struct _find {
 	DebugWindow *window;
 	GtkWidget *entry;
@@ -206,7 +217,7 @@
 	gtk_widget_show_all(win->find);
 	gtk_widget_grab_focus(f->entry);
 }
-#endif /* HAVE_REGEX_H */
+#endif /* USE_REGEX */
 
 static void
 save_writefile_cb(void *user_data, const char *filename)
@@ -242,9 +253,9 @@
 {
 	gtk_imhtml_clear(GTK_IMHTML(win->text));
 
-#ifdef HAVE_REGEX_H
+#ifdef USE_REGEX
 	gtk_list_store_clear(win->store);
-#endif /* HAVE_REGEX_H */
+#endif /* USE_REGEX */
 }
 
 static void
@@ -252,20 +263,20 @@
 {
 	win->paused = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(w));
 
-#ifdef HAVE_REGEX_H
+#ifdef USE_REGEX
 	if(!win->paused) {
 		if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter)))
 			regex_filter_all(win);
 		else
 			regex_show_all(win);
 	}
-#endif /* HAVE_REGEX_H */
+#endif /* USE_REGEX */
 }
 
 /******************************************************************************
  * regex stuff
  *****************************************************************************/
-#ifdef HAVE_REGEX_H
+#ifdef USE_REGEX
 static void
 regex_clear_color(GtkWidget *w) {
 	gtk_widget_modify_base(w, GTK_STATE_NORMAL, NULL);
@@ -295,16 +306,18 @@
 static void
 regex_match(DebugWindow *win, const gchar *text) {
 	GtkIMHtml *imhtml = GTK_IMHTML(win->text);
+#ifdef HAVE_REGEX_H
 	regmatch_t matches[4]; /* adjust if necessary */
 	size_t n_matches = sizeof(matches) / sizeof(matches[0]);
+	gint inverted;
+#else
+	GMatchInfo *match_info;
+#endif /* HAVE_REGEX_H */
 	gchar *plaintext;
-	gint inverted;
 
 	if(!text)
 		return;
 
-	inverted = (win->invert) ? REG_NOMATCH : 0;
-
 	/* I don't like having to do this, but we need it for highlighting.  Plus
 	 * it makes the ^ and $ operators work :)
 	 */
@@ -313,9 +326,14 @@
 	/* we do a first pass to see if it matches at all.  If it does we append
 	 * it, and work out the offsets to highlight.
 	 */
+#ifdef HAVE_REGEX_H
+	inverted = (win->invert) ? REG_NOMATCH : 0;
 	if(regexec(&win->regex, plaintext, n_matches, matches, 0) == inverted) {
+#else
+	if(g_regex_match(win->regex, plaintext, 0, &match_info) != win->invert) {
+#endif /* HAVE_REGEX_H */
+		gchar *p = plaintext;
 		GtkTextIter ins;
-		gchar *p = plaintext;
 		gint i, offset = 0;
 
 		gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &ins,
@@ -327,14 +345,18 @@
 		/* If we're not highlighting or the expression is inverted, we're
 		 * done and move on.
 		 */
-		if(!win->highlight || inverted == REG_NOMATCH) {
+		if(!win->highlight || win->invert) {
 			g_free(plaintext);
+#ifndef HAVE_REGEX_H
+			g_match_info_free(match_info);
+#endif
 			return;
 		}
 
 		/* we use a do-while to highlight the first match, and then continue
 		 * if necessary...
 		 */
+#ifdef HAVE_REGEX_H
 		do {
 			size_t m;
 
@@ -357,6 +379,41 @@
 
 			p += offset;
 		} while(regexec(&win->regex, p, n_matches, matches, REG_NOTBOL) == inverted);
+#else
+		do
+		{
+			gint m;
+			gint start_pos, end_pos;
+			GtkTextIter ms, me;
+			
+			if (!g_match_info_matches(match_info))
+				break;
+			
+			for (m = 0; m < g_match_info_get_match_count(match_info); m++)
+			{
+				if (m == 1)
+					continue;
+				
+				g_match_info_fetch_pos(match_info, m, &start_pos, &end_pos);
+				
+				if (end_pos == -1)
+					break;
+				
+				gtk_text_buffer_get_iter_at_offset(imhtml->text_buffer, &ms,
+													i + start_pos);
+				gtk_text_buffer_get_iter_at_offset(imhtml->text_buffer, &me,
+													i + end_pos);
+				gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "regex",
+												  &ms, &me);
+				offset = end_pos;
+			}
+			
+			g_match_info_free(match_info);
+			p += offset;
+			i += offset;
+		} while (g_regex_match(win->regex, p, G_REGEX_MATCH_NOTBOL, &match_info) != win->invert);
+		g_match_info_free(match_info);
+#endif /* HAVE_REGEX_H */
 	}
 
 	g_free(plaintext);
@@ -430,9 +487,15 @@
 		return;
 	}
 
+#ifdef HAVE_REGEX_H
 	regfree(&win->regex);
-
 	if(regcomp(&win->regex, text, REG_EXTENDED | REG_ICASE) != 0) {
+#else
+	if (win->regex)
+		g_regex_unref(win->regex);
+	win->regex = g_regex_new(text, G_REGEX_EXTENDED | G_REGEX_CASELESS, 0, NULL);
+	if(win->regex == NULL) {
+#endif
 		/* failed to compile */
 		regex_change_color(win->expression, 0xFFFF, 0xAFFF, 0xAFFF);
 		gtk_widget_set_sensitive(win->filter, FALSE);
@@ -616,7 +679,7 @@
 	else
 		regex_show_all(win);
 }
-#endif /* HAVE_REGEX_H */
+#endif /* USE_REGEX */
 
 static void
 filter_level_changed_cb(GtkWidget *combo, gpointer null)
@@ -702,7 +765,7 @@
 
 	handle = pidgin_debug_get_handle();
 
-#ifdef HAVE_REGEX_H
+#ifdef USE_REGEX
 	/* the list store for all the messages */
 	win->store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
 
@@ -714,7 +777,7 @@
 	g_signal_connect(G_OBJECT(win->store), "row-changed",
 					 G_CALLBACK(regex_row_changed_cb), win);
 
-#endif /* HAVE_REGEX_H */
+#endif /* USE_REGEX */
 
 	/* Setup the vbox */
 	vbox = gtk_vbox_new(FALSE, 0);
@@ -741,7 +804,7 @@
 
 		gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
 
-#ifndef HAVE_REGEX_H
+#ifndef USE_REGEX
 		/* Find button */
 		item = gtk_tool_button_new_from_stock(GTK_STOCK_FIND);
 		gtk_tool_item_set_is_important(item, TRUE);
@@ -752,7 +815,7 @@
 #endif
 		g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(find_cb), win);
 		gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
-#endif /* HAVE_REGEX_H */
+#endif /* USE_REGEX */
 
 		/* Save */
 		item = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE);
@@ -790,7 +853,7 @@
 		g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(pause_cb), win);
 		gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
 
-#ifdef HAVE_REGEX_H
+#ifdef USE_REGEX
 		/* regex stuff */
 		item = gtk_separator_tool_item_new();
 		gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
@@ -853,7 +916,7 @@
 		purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/debug/highlight",
 									regex_pref_highlight_cb, win);
 
-#endif /* HAVE_REGEX_H */
+#endif /* USE_REGEX */
 
 		item = gtk_separator_tool_item_new();
 		gtk_container_add(GTK_CONTAINER(toolbar), GTK_WIDGET(item));
@@ -880,7 +943,7 @@
 		gtk_combo_box_append_text(GTK_COMBO_BOX(win->filterlevel), _("Fatal Error"));
 		gtk_combo_box_set_active(GTK_COMBO_BOX(win->filterlevel),
 					purple_prefs_get_int(PIDGIN_PREFS_ROOT "/debug/filterlevel"));
-#ifdef HAVE_REGEX_H
+#ifdef USE_REGEX
 		purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/debug/filterlevel",
 						filter_level_pref_changed, win);
 #endif
@@ -895,13 +958,13 @@
 	gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
 	gtk_widget_show(frame);
 
-#ifdef HAVE_REGEX_H
+#ifdef USE_REGEX
 	/* add the tag for regex highlighting */
 	gtk_text_buffer_create_tag(GTK_IMHTML(win->text)->text_buffer, "regex",
 							   "background", "#FFAFAF",
 							   "weight", "bold",
 							   NULL);
-#endif /* HAVE_REGEX_H */
+#endif /* USE_REGEX */
 
 	gtk_widget_show_all(win->window);
 
@@ -1002,13 +1065,13 @@
 	purple_prefs_add_int(PIDGIN_PREFS_ROOT "/debug/width",  450);
 	purple_prefs_add_int(PIDGIN_PREFS_ROOT "/debug/height", 250);
 
-#ifdef HAVE_REGEX_H
+#ifdef USE_REGEX
 	purple_prefs_add_string(PIDGIN_PREFS_ROOT "/debug/regex", "");
 	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/debug/filter", FALSE);
 	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/debug/invert", FALSE);
 	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/debug/case_insensitive", FALSE);
 	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/debug/highlight", FALSE);
-#endif /* HAVE_REGEX_H */
+#endif /* USE_REGEX */
 
 	purple_prefs_connect_callback(NULL, PIDGIN_PREFS_ROOT "/debug/enabled",
 								debug_enabled_cb, NULL);
@@ -1070,9 +1133,9 @@
 pidgin_debug_print(PurpleDebugLevel level, const char *category,
 					 const char *arg_s)
 {
-#ifdef HAVE_REGEX_H
+#ifdef USE_REGEX
 	GtkTreeIter iter;
-#endif /* HAVE_REGEX_H */
+#endif /* USE_REGEX */
 	gchar *ts_s;
 	gchar *esc_s, *cat_s, *tmp, *s;
 	const char *mdate;
@@ -1111,14 +1174,14 @@
 		s = tmp;
 	}
 
-#ifdef HAVE_REGEX_H
+#ifdef USE_REGEX
 	/* add the text to the list store */
 	gtk_list_store_append(debug_win->store, &iter);
 	gtk_list_store_set(debug_win->store, &iter, 0, s, 1, level, -1);
-#else /* HAVE_REGEX_H */
+#else /* USE_REGEX */
 	if(!debug_win->paused && level >= purple_prefs_get_int(PIDGIN_PREFS_ROOT "/debug/filterlevel"))
 		gtk_imhtml_append_text(GTK_IMHTML(debug_win->text), s, 0);
-#endif /* !HAVE_REGEX_H */
+#endif /* !USE_REGEX */
 
 	g_free(s);
 }