aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libempathy-gtk/empathy-theme.c104
-rw-r--r--libempathy/empathy-utils.c126
-rw-r--r--libempathy/empathy-utils.h19
3 files changed, 53 insertions, 196 deletions
diff --git a/libempathy-gtk/empathy-theme.c b/libempathy-gtk/empathy-theme.c
index e2da4e494..d68b72f02 100644
--- a/libempathy-gtk/empathy-theme.c
+++ b/libempathy-gtk/empathy-theme.c
@@ -34,7 +34,17 @@
/* Number of seconds between timestamps when using normal mode, 5 minutes. */
#define TIMESTAMP_INTERVAL 300
+#define SHEMES "(https?|ftps?|nntp|news|javascript|about|ghelp|apt|telnet|"\
+ "file|webcal|mailto)"
+#define SEPARATOR "([^,;\?><()\\ ])"
+#define BODY "([^\\ ]*(\\\\ )?)+"
+#define URI_REGEX "("SHEMES"://"BODY SEPARATOR")" \
+ "|((mailto:)?"BODY"@"BODY"."BODY SEPARATOR")"\
+ "|((www|ftp)."BODY SEPARATOR")"
+static GRegex *uri_regex = NULL;
+
#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyTheme)
+
typedef struct {
EmpathySmileyManager *smiley_manager;
gboolean show_avatars;
@@ -254,8 +264,11 @@ empathy_theme_append_text (EmpathyTheme *theme,
GtkTextIter start_iter, end_iter;
GtkTextMark *mark;
GtkTextIter iter;
- gint num_matches, i;
- GArray *start, *end;
+ GMatchInfo *match_info;
+ gboolean match;
+ gint last = 0;
+ gint s = 0, e = 0;
+ gchar *tmp;
priv = GET_PRIV (theme);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
@@ -263,57 +276,17 @@ empathy_theme_append_text (EmpathyTheme *theme,
gtk_text_buffer_get_end_iter (buffer, &start_iter);
mark = gtk_text_buffer_create_mark (buffer, NULL, &start_iter, TRUE);
- start = g_array_new (FALSE, FALSE, sizeof (gint));
- end = g_array_new (FALSE, FALSE, sizeof (gint));
-
- num_matches = empathy_regex_match (EMPATHY_REGEX_ALL, body, start, end);
-
- if (num_matches == 0) {
- gtk_text_buffer_get_end_iter (buffer, &iter);
- theme_insert_text_with_emoticons (buffer, &iter, body, priv->smiley_manager);
- } else {
- gint last = 0;
- gint s = 0, e = 0;
- gchar *tmp;
-
- for (i = 0; i < num_matches; i++) {
- s = g_array_index (start, gint, i);
- e = g_array_index (end, gint, i);
-
- if (s > last) {
- tmp = empathy_substring (body, last, s);
-
- gtk_text_buffer_get_end_iter (buffer, &iter);
- theme_insert_text_with_emoticons (buffer,
- &iter,
- tmp,
- priv->smiley_manager);
- g_free (tmp);
- }
-
- tmp = empathy_substring (body, s, e);
-
- gtk_text_buffer_get_end_iter (buffer, &iter);
- if (!link_tag) {
- gtk_text_buffer_insert (buffer, &iter,
- tmp, -1);
- } {
- gtk_text_buffer_insert_with_tags_by_name (buffer,
- &iter,
- tmp,
- -1,
- link_tag,
- "link",
- NULL);
- }
-
- g_free (tmp);
+ if (!uri_regex) {
+ uri_regex = g_regex_new (URI_REGEX, 0, 0, NULL);
+ }
- last = e;
- }
+ for (match = g_regex_match (uri_regex, body, 0, &match_info); match;
+ match = g_match_info_next (match_info, NULL)) {
+ if (!g_match_info_fetch_pos (match_info, 0, &s, &e))
+ continue;
- if (e < strlen (body)) {
- tmp = empathy_substring (body, e, strlen (body));
+ if (s > last) {
+ tmp = empathy_substring (body, last, s);
gtk_text_buffer_get_end_iter (buffer, &iter);
theme_insert_text_with_emoticons (buffer,
@@ -322,10 +295,35 @@ empathy_theme_append_text (EmpathyTheme *theme,
priv->smiley_manager);
g_free (tmp);
}
+
+ tmp = empathy_substring (body, s, e);
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ if (!link_tag) {
+ gtk_text_buffer_insert (buffer, &iter,
+ tmp, -1);
+ } else {
+ gtk_text_buffer_insert_with_tags_by_name (buffer,
+ &iter,
+ tmp,
+ -1,
+ link_tag,
+ "link",
+ NULL);
+ }
+
+ g_free (tmp);
+ last = e;
}
+ g_match_info_free (match_info);
- g_array_free (start, TRUE);
- g_array_free (end, TRUE);
+ if (last < strlen (body)) {
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ theme_insert_text_with_emoticons (buffer,
+ &iter,
+ body + last,
+ priv->smiley_manager);
+ }
gtk_text_buffer_get_end_iter (buffer, &iter);
gtk_text_buffer_insert (buffer, &iter, "\n", 1);
diff --git a/libempathy/empathy-utils.c b/libempathy/empathy-utils.c
index b5bdb9ff7..671595e68 100644
--- a/libempathy/empathy-utils.c
+++ b/libempathy/empathy-utils.c
@@ -28,7 +28,6 @@
#include <string.h>
#include <time.h>
#include <sys/types.h>
-#include <regex.h>
#include <glib/gi18n.h>
@@ -44,8 +43,6 @@
#define DEBUG_FLAG EMPATHY_DEBUG_OTHER
#include "empathy-debug.h"
-static void regex_init (void);
-
gchar *
empathy_substring (const gchar *str,
gint start,
@@ -54,129 +51,6 @@ empathy_substring (const gchar *str,
return g_strndup (str + start, end - start);
}
-/*
- * Regular Expression code to match urls.
- */
-#define APTCHARS "-A-Za-z0-9,-."
-#define USERCHARS "-A-Za-z0-9"
-#define PASSCHARS "-A-Za-z0-9,?;.:/!%$^*&~\"#'"
-#define HOSTCHARS "-A-Za-z0-9_"
-#define PATHCHARS "-A-Za-z0-9_$.+!*(),;:@&=?/~#%"
-#define SCHEME "(news:|telnet:|nntp:|file:/|https?:|ftps?:|webcal:)"
-#define USER "[" USERCHARS "]+(:["PASSCHARS "]+)?"
-#define URLPATH "/[" PATHCHARS "]*[^]'.}>) \t\r\n,\\\"]"
-
-static regex_t dingus[EMPATHY_REGEX_ALL];
-
-static void
-regex_init (void)
-{
- static gboolean inited = FALSE;
- const gchar *expression;
- gint i;
-
- if (inited) {
- return;
- }
-
- for (i = 0; i < EMPATHY_REGEX_ALL; i++) {
- switch (i) {
- case EMPATHY_REGEX_AS_IS:
- expression =
- SCHEME "//(" USER "@)?[" HOSTCHARS ".]+"
- "(:[0-9]+)?(" URLPATH ")?";
- break;
- case EMPATHY_REGEX_BROWSER:
- expression =
- "(www|ftp)[" HOSTCHARS "]*\\.[" HOSTCHARS ".]+"
- "(:[0-9]+)?(" URLPATH ")?";
- break;
- case EMPATHY_REGEX_APT:
- expression =
- "apt://[" APTCHARS "]*";
- break;
- case EMPATHY_REGEX_EMAIL:
- expression =
- "(mailto:)?[a-z0-9][a-z0-9._-]*@[a-z0-9]"
- "[a-z0-9-]*(\\.[a-z0-9][a-z0-9-]*)+";
- break;
- case EMPATHY_REGEX_OTHER:
- expression =
- "news:[-A-Z\\^_a-z{|}~!\"#$%&'()*+,./0-9;:=?`]+"
- "@[" HOSTCHARS ".]+(:[0-9]+)?";
- break;
- default:
- /* Silence the compiler. */
- expression = NULL;
- continue;
- }
-
- memset (&dingus[i], 0, sizeof (regex_t));
- regcomp (&dingus[i], expression, REG_EXTENDED | REG_ICASE);
- }
-
- inited = TRUE;
-}
-
-gint
-empathy_regex_match (EmpathyRegExType type,
- const gchar *msg,
- GArray *start,
- GArray *end)
-{
- regmatch_t matches[1];
- gint ret = 0;
- gint num_matches = 0;
- gint offset = 0;
- gint i;
-
- g_return_val_if_fail (type >= 0 || type <= EMPATHY_REGEX_ALL, 0);
-
- regex_init ();
-
- while (!ret && type != EMPATHY_REGEX_ALL) {
- ret = regexec (&dingus[type], msg + offset, 1, matches, 0);
- if (ret == 0) {
- gint s;
-
- num_matches++;
-
- s = matches[0].rm_so + offset;
- offset = matches[0].rm_eo + offset;
-
- g_array_append_val (start, s);
- g_array_append_val (end, offset);
- }
- }
-
- if (type != EMPATHY_REGEX_ALL) {
- DEBUG ("Found %d matches for regex type:%d", num_matches, type);
- return num_matches;
- }
-
- /* If EMPATHY_REGEX_ALL then we run ALL regex's on the string. */
- for (i = 0; i < EMPATHY_REGEX_ALL; i++, ret = 0) {
- while (!ret) {
- ret = regexec (&dingus[i], msg + offset, 1, matches, 0);
- if (ret == 0) {
- gint s;
-
- num_matches++;
-
- s = matches[0].rm_so + offset;
- offset = matches[0].rm_eo + offset;
-
- g_array_append_val (start, s);
- g_array_append_val (end, offset);
- }
- }
- }
-
- DEBUG ("Found %d matches for ALL regex types", num_matches);
-
- return num_matches;
-}
-
gint
empathy_strcasecmp (const gchar *s1,
const gchar *s2)
diff --git a/libempathy/empathy-utils.h b/libempathy/empathy-utils.h
index a320c6246..51ddd231f 100644
--- a/libempathy/empathy-utils.h
+++ b/libempathy/empathy-utils.h
@@ -37,30 +37,15 @@
#include "empathy-contact.h"
-G_BEGIN_DECLS
-
#define EMPATHY_GET_PRIV(obj,type) ((type##Priv*) ((type*)obj)->priv)
#define G_STR_EMPTY(x) ((x) == NULL || (x)[0] == '\0')
-typedef enum {
- EMPATHY_REGEX_AS_IS,
- EMPATHY_REGEX_BROWSER,
- EMPATHY_REGEX_APT,
- EMPATHY_REGEX_EMAIL,
- EMPATHY_REGEX_OTHER,
- EMPATHY_REGEX_ALL,
-} EmpathyRegExType;
+G_BEGIN_DECLS
-/* Regular expressions */
+/* Strings */
gchar * empathy_substring (const gchar *str,
gint start,
gint end);
-gint empathy_regex_match (EmpathyRegExType type,
- const gchar *msg,
- GArray *start,
- GArray *end);
-
-/* Strings */
gint empathy_strcasecmp (const gchar *s1,
const gchar *s2);
gint empathy_strncasecmp (const gchar *s1,