summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/fe.h2
-rw-r--r--src/common/outbound.c53
-rw-r--r--src/common/xchat.c2
-rw-r--r--src/common/xchat.h11
-rw-r--r--src/fe-gtk/fe-gtk.c60
-rw-r--r--src/fe-gtk/menu.c2
-rw-r--r--src/fe-gtk/xtext.c57
-rw-r--r--src/fe-gtk/xtext.h9
8 files changed, 124 insertions, 72 deletions
diff --git a/src/common/fe.h b/src/common/fe.h
index e330ef3e..3fa4e2bc 100644
--- a/src/common/fe.h
+++ b/src/common/fe.h
@@ -98,7 +98,7 @@ void fe_set_nonchannel (struct session *sess, int state);
 void fe_set_nick (struct server *serv, char *newnick);
 void fe_ignore_update (int level);
 void fe_beep (void);
-void fe_lastlog (session *sess, session *lastlog_sess, char *sstr, gboolean regexp);
+void fe_lastlog (session *sess, session *lastlog_sess, char *sstr, gtk_xtext_search_flags flags);
 void fe_set_lag (server *serv, int lag);
 void fe_set_throttle (server *serv);
 void fe_set_away (server *serv);
diff --git a/src/common/outbound.c b/src/common/outbound.c
index 060c6742..2e79d59e 100644
--- a/src/common/outbound.c
+++ b/src/common/outbound.c
@@ -2362,7 +2362,7 @@ cmd_lagcheck (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 }
 
 static void
-lastlog (session *sess, char *search, gboolean regexp)
+lastlog (session *sess, char *search, gtk_xtext_search_flags flags)
 {
 	session *lastlog_sess;
 
@@ -2374,29 +2374,50 @@ lastlog (session *sess, char *search, gboolean regexp)
 		lastlog_sess = new_ircwindow (sess->server, "(lastlog)", SESS_DIALOG, 0);
 
 	lastlog_sess->lastlog_sess = sess;
-	lastlog_sess->lastlog_regexp = regexp;	/* remember the search type */
+	lastlog_sess->lastlog_flags = flags;
 
 	fe_text_clear (lastlog_sess, 0);
-	fe_lastlog (sess, lastlog_sess, search, regexp);
+	fe_lastlog (sess, lastlog_sess, search, flags);
 }
 
 static int
 cmd_lastlog (struct session *sess, char *tbuf, char *word[], char *word_eol[])
 {
-	if (*word_eol[2])
+	int j = 2;
+	gtk_xtext_search_flags flags = 0;
+	gboolean doublehyphen = FALSE;
+
+	while (word_eol[j] != NULL && word_eol [j][0] == '-' && !doublehyphen)
 	{
-		if (!strcmp (word[2], "-r"))
-		{
-			lastlog (sess, word_eol[3], TRUE);
-		}
-		else
+		switch (word_eol [j][1])
 		{
-			lastlog (sess, word_eol[2], FALSE);
+			case 'r':
+				flags |= regexp;
+				break;
+			case 'm':
+				flags |= case_match;
+				break;
+			case 'h':
+				flags |= highlight;
+				break;
+			case '-':
+				doublehyphen = TRUE;
+				break;
+			default:
+				break;
+				/* O dear whatever shall we do here? */
 		}
+		j++;
+	}
+	if (*word_eol[j])
+	{
+		lastlog (sess, word_eol[j], flags);
 		return TRUE;
 	}
-
-	return FALSE;
+	else
+	{	
+		return FALSE;
+	}
 }
 
 static int
@@ -3602,7 +3623,11 @@ const struct commands xc_cmds[] = {
 	{"LAGCHECK", cmd_lagcheck, 0, 0, 1,
 	 N_("LAGCHECK, forces a new lag check")},
 	{"LASTLOG", cmd_lastlog, 0, 0, 1,
-	 N_("LASTLOG [-r] <string>, searches for a string in the buffer")},
+	 N_("LASTLOG [-h] [-m] [-r] [--] <string>, searches for a string in the buffer\n"
+	 "    Use -h to highlight the found string(s)\n"
+	 "    Use -m to match case\n"
+	 "    Use -r when string is a Regular Expression\n"
+	 "    Use -- (double hyphen) to end options when searching for, say, the string '-r'")},
 	{"LIST", cmd_list, 1, 0, 1, 0},
 	{"LOAD", cmd_load, 0, 0, 1, N_("LOAD [-e] <file>, loads a plugin or script")},
 
@@ -4099,7 +4124,7 @@ handle_say (session *sess, char *text, int check_spch)
 
 	if (strcmp (sess->channel, "(lastlog)") == 0)
 	{
-		lastlog (sess->lastlog_sess, text, sess->lastlog_regexp);
+		lastlog (sess->lastlog_sess, text, sess->lastlog_flags);
 		return;
 	}
 
diff --git a/src/common/xchat.c b/src/common/xchat.c
index f90a6291..21e2bd9e 100644
--- a/src/common/xchat.c
+++ b/src/common/xchat.c
@@ -591,7 +591,7 @@ static char defaultconf_commands[] =
 	"NAME DIALOG\n"		"CMD query %2\n\n"\
 	"NAME DMSG\n"			"CMD msg =%2 &3\n\n"\
 	"NAME EXIT\n"			"CMD quit\n\n"\
-	"NAME GREP\n"			"CMD lastlog -r &2\n\n"\
+	"NAME GREP\n"			"CMD lastlog -r -- &2\n\n"\
 	"NAME IGNALL\n"			"CMD ignore %2!*@* ALL\n\n"\
 	"NAME J\n"				"CMD join &2\n\n"\
 	"NAME KILL\n"			"CMD quote KILL %2 :&3\n\n"\
diff --git a/src/common/xchat.h b/src/common/xchat.h
index 66f43522..0ebe83cf 100644
--- a/src/common/xchat.h
+++ b/src/common/xchat.h
@@ -346,6 +346,15 @@ struct xchatprefs
 #define SET_ON 1
 #define SET_DEFAULT 2 /* use global setting */
 
+/* Moved from fe-gtk for use in outbound.c as well -- */
+typedef enum gtk_xtext_search_flags_e {
+	case_match = 1,
+	backward = 2,
+	highlight = 4,
+	follow = 8,
+	regexp = 16
+} gtk_xtext_search_flags;
+
 typedef struct session
 {
 	/* Per-Channel Alerts */
@@ -405,7 +414,7 @@ typedef struct session
 	int end_of_names:1;
 	int doing_who:1;		/* /who sent on this channel */
 	int done_away_check:1;	/* done checking for away status changes */
-	unsigned int lastlog_regexp:1;	/* this is a lastlog and using regexp */
+	gtk_xtext_search_flags lastlog_flags;
 } session;
 
 struct msproxy_state_t
diff --git a/src/fe-gtk/fe-gtk.c b/src/fe-gtk/fe-gtk.c
index 706ab776..8a7ce283 100644
--- a/src/fe-gtk/fe-gtk.c
+++ b/src/fe-gtk/fe-gtk.c
@@ -700,50 +700,48 @@ fe_beep (void)
 	gdk_beep ();
 }
 
-static int
-lastlog_regex_cmp (char *a, GRegex *reg)
-{
-	GMatchInfo *gmi;
-	int ret;
-
-	g_regex_match (reg, a, 0, &gmi);
-	ret = (g_match_info_matches (gmi))? TRUE: FALSE;
-	g_match_info_free (gmi);
-	return ret;
-}
-
 void
-fe_lastlog (session *sess, session *lastlog_sess, char *sstr, gboolean regexp)
+fe_lastlog (session *sess, session *lastlog_sess, char *sstr, gtk_xtext_search_flags flags)
 {
-	GRegex *search_re = NULL;
 	GError *err = NULL;
+	xtext_buffer *buf, *lbuf;
 
-	if (gtk_xtext_is_empty (sess->res->buffer))
+	buf = sess->res->buffer;
+
+	if (gtk_xtext_is_empty (buf))
 	{
 		PrintText (lastlog_sess, _("Search buffer is empty.\n"));
 		return;
 	}
 
-	if (!regexp)
+	lbuf = lastlog_sess->res->buffer;
+	if (flags & regexp)
 	{
-		gtk_xtext_lastlog (lastlog_sess->res->buffer, sess->res->buffer,
-								 (void *) nocasestrstr, sstr);
-		return;
-	}
+		GRegexCompileFlags gcf = (flags & case_match)? 0: G_REGEX_CASELESS;
 
-	/* TODO:  add arg 'match' and if it's TRUE don't use G_REGEX_CASELESS
-	 * and for that matter don't use nocasesetrstr() above either */
-	search_re = g_regex_new (sstr, G_REGEX_CASELESS, 0, &err);
-	if (err)
+		lbuf->search_re = g_regex_new (sstr, gcf, 0, &err);
+		if (err)
+		{
+			PrintText (lastlog_sess, _(err->message));
+			g_error_free (err);
+			return;
+		}
+	}
+	else
 	{
-		PrintText (lastlog_sess, _(err->message));
-		g_error_free (err);
-		return;
+		if (flags & case_match)
+		{
+			lbuf->search_nee = g_strdup (sstr);
+		}
+		else
+		{
+			lbuf->search_nee = g_utf8_casefold (sstr, strlen (sstr));
+		}
+		lbuf->search_lnee = strlen (lbuf->search_nee);
 	}
-
-	gtk_xtext_lastlog (lastlog_sess->res->buffer, sess->res->buffer,
-							 (void *) lastlog_regex_cmp, search_re);
-	g_regex_unref (search_re);
+	lbuf->search_flags = flags;
+	lbuf->search_text = strdup (sstr);
+	gtk_xtext_lastlog (lbuf, buf);
 }
 
 void
diff --git a/src/fe-gtk/menu.c b/src/fe-gtk/menu.c
index 2bca63c8..a02ec284 100644
--- a/src/fe-gtk/menu.c
+++ b/src/fe-gtk/menu.c
@@ -1235,7 +1235,7 @@ menu_search_prev ()
 	xtext_buffer *buf = xtext->buffer;
 
 	if (!gtk_xtext_search(xtext, buf->search_text,
-		(buf->search_flags & (case_match | follow | regexp) | backward), NULL))
+		(buf->search_flags & (case_match | follow | regexp)) | backward, NULL))
 	{
 		fe_message (_("Search hit end, not found."), FE_MSG_ERROR);
 	}
diff --git a/src/fe-gtk/xtext.c b/src/fe-gtk/xtext.c
index 38ae2a89..585555b1 100644
--- a/src/fe-gtk/xtext.c
+++ b/src/fe-gtk/xtext.c
@@ -183,7 +183,8 @@ gtk_xtext_strip_color (unsigned char *text, int len, unsigned char *outbuf,
 static gboolean gtk_xtext_check_ent_visibility (GtkXText * xtext, textentry *find_ent, int add);
 static int gtk_xtext_render_page_timeout (GtkXText * xtext);
 static int gtk_xtext_search_offset (xtext_buffer *buf, textentry *ent, unsigned int off);
-static void gtk_xtext_search_textentry (xtext_buffer *, textentry *, int);
+static GList * gtk_xtext_search_textentry (xtext_buffer *, textentry *);
+static void gtk_xtext_search_textentry_add (xtext_buffer *, textentry *, GList *, gboolean);
 static void gtk_xtext_search_textentry_del (xtext_buffer *, textentry *);
 static void gtk_xtext_search_textentry_fini (gpointer, gpointer);
 static void gtk_xtext_search_fini (xtext_buffer *);
@@ -5226,8 +5227,8 @@ gtk_xtext_unstrip_color (gint start, gint end, GSList *slp, GList **gl, gint max
 }
 
 /* Search a single textentry for occurrence(s) of search arg string */
-static void
-gtk_xtext_search_textentry (xtext_buffer *buf, textentry *ent, int pre)
+static GList *
+gtk_xtext_search_textentry (xtext_buffer *buf, textentry *ent)
 {
 	gchar *str;								/* text string to be searched */
 	GList *gl = NULL;
@@ -5236,7 +5237,7 @@ gtk_xtext_search_textentry (xtext_buffer *buf, textentry *ent, int pre)
 
 	if (buf->search_text == NULL)
 	{
-		return;
+		return gl;
 	}
 
 	str = gtk_xtext_strip_color (ent->str, ent->str_len, buf->xtext->scratch_buffer,
@@ -5250,7 +5251,7 @@ gtk_xtext_search_textentry (xtext_buffer *buf, textentry *ent, int pre)
 
 		if (buf->search_re == NULL)
 		{
-			return;
+			return gl;
 		}
 		g_regex_match (buf->search_re, str, 0, &gmi);
 		while (g_match_info_matches (gmi))
@@ -5289,6 +5290,13 @@ gtk_xtext_search_textentry (xtext_buffer *buf, textentry *ent, int pre)
 
 	/* Common processing --- */
 	g_slist_free (slp);
+	return gl;
+}
+
+/* Add a list of found search results to an entry, maybe NULL */
+static void
+gtk_xtext_search_textentry_add (xtext_buffer *buf, textentry *ent, GList *gl, gboolean pre)
+{
 	ent->marks = gl;
 	if (gl)
 	{
@@ -5298,7 +5306,6 @@ gtk_xtext_search_textentry (xtext_buffer *buf, textentry *ent, int pre)
 			buf->hintsearch = ent;
 		}
 	}
-	return;
 }
 
 /* Free all search information for a textentry */
@@ -5424,7 +5431,10 @@ gtk_xtext_search (GtkXText * xtext, const gchar *text, gtk_xtext_search_flags fl
 			ent = gl? gl->data: buf->text_first;
 			for (; ent; ent = ent->next)
 			{
-				gtk_xtext_search_textentry (buf, ent, FALSE);
+				GList *gl;
+
+				gl = gtk_xtext_search_textentry (buf, ent);
+				gtk_xtext_search_textentry_add (buf, ent, gl, FALSE);
 			}
 		}
 		buf->search_flags = flags;
@@ -5448,7 +5458,10 @@ gtk_xtext_search (GtkXText * xtext, const gchar *text, gtk_xtext_search_flags fl
 			}
 			for (ent = buf->text_first; ent; ent = ent->next)
 			{
-				gtk_xtext_search_textentry (buf, ent, TRUE);
+				GList *gl;
+
+				gl = gtk_xtext_search_textentry (buf, ent);
+				gtk_xtext_search_textentry_add (buf, ent, gl, TRUE);
 			}
 			buf->search_found = g_list_reverse (buf->search_found);
 		}
@@ -5661,7 +5674,10 @@ gtk_xtext_append_entry (xtext_buffer *buf, textentry * ent, time_t stamp)
 	}
 	if (buf->search_flags & follow)
 	{
-		gtk_xtext_search_textentry (buf, ent, FALSE);
+		GList *gl;
+
+		gl = gtk_xtext_search_textentry (buf, ent);
+		gtk_xtext_search_textentry_add (buf, ent, gl, FALSE);
 	}
 }
 
@@ -5764,30 +5780,41 @@ gtk_xtext_is_empty (xtext_buffer *buf)
 	return buf->text_first == NULL;
 }
 
+
 int
-gtk_xtext_lastlog (xtext_buffer *out, xtext_buffer *search_area,
-						 int (*cmp_func) (char *, void *), void *userdata)
+gtk_xtext_lastlog (xtext_buffer *out, xtext_buffer *search_area)
 {
-	textentry *ent = search_area->text_first;
-	int matches = 0;
+	textentry *ent;
+	int matches;
+	GList *gl;
+
+	ent = search_area->text_first;
+	matches = 0;
 
 	while (ent)
 	{
-		if (cmp_func (ent->str, userdata))
+		gl = gtk_xtext_search_textentry (out, ent);
+		if (gl)
 		{
 			matches++;
 			/* copy the text over */
 			if (search_area->xtext->auto_indent)
+			{
 				gtk_xtext_append_indent (out, ent->str, ent->left_len,
 												 ent->str + ent->left_len + 1,
 												 ent->str_len - ent->left_len - 1, 0);
+			}
 			else
+			{
 				gtk_xtext_append (out, ent->str, ent->str_len);
-			/* copy the timestamp over */
+			}
+
 			out->text_last->stamp = ent->stamp;
+			gtk_xtext_search_textentry_add (out, out->text_last, gl, TRUE);
 		}
 		ent = ent->next;
 	}
+	out->search_found = g_list_reverse (out->search_found);
 
 	return matches;
 }
diff --git a/src/fe-gtk/xtext.h b/src/fe-gtk/xtext.h
index 6c126346..48c71d0c 100644
--- a/src/fe-gtk/xtext.h
+++ b/src/fe-gtk/xtext.h
@@ -43,13 +43,6 @@
 typedef struct _GtkXText GtkXText;
 typedef struct _GtkXTextClass GtkXTextClass;
 typedef struct textentry textentry;
-typedef enum gtk_xtext_search_flags_e {
-	case_match = 1,
-	backward = 2,
-	highlight = 4,
-	follow = 8,
-	regexp = 16
-} gtk_xtext_search_flags;
 
 typedef struct {
 	GtkXText *xtext;					/* attached to this widget */
@@ -263,7 +256,7 @@ void gtk_xtext_set_palette (GtkXText * xtext, GdkColor palette[]);
 void gtk_xtext_clear (xtext_buffer *buf, int lines);
 void gtk_xtext_save (GtkXText * xtext, int fh);
 void gtk_xtext_refresh (GtkXText * xtext, int do_trans);
-int gtk_xtext_lastlog (xtext_buffer *out, xtext_buffer *search_area, int (*cmp_func) (char *, void *userdata), void *userdata);
+int gtk_xtext_lastlog (xtext_buffer *out, xtext_buffer *search_area);
 textentry *gtk_xtext_search (GtkXText * xtext, const gchar *text, gtk_xtext_search_flags flags, GError **err);
 void gtk_xtext_reset_marker_pos (GtkXText *xtext);
 void gtk_xtext_check_marker_visibility(GtkXText *xtext);