]> git.0d.be Git - empathy.git/commitdiff
string-parser: move everything except for _match_smiley(), to tp-aw
authorMarco Barisione <marco.barisione@collabora.co.uk>
Mon, 29 Jul 2013 13:01:56 +0000 (14:01 +0100)
committerMarco Barisione <marco.barisione@collabora.co.uk>
Tue, 20 Aug 2013 10:03:05 +0000 (11:03 +0100)
empathy_string_match_smiley() depends on other files and it's not needed
by tp-account-widgets, so we can leave it in libempathy-gtk.

https://bugzilla.gnome.org/show_bug.cgi?id=699492

14 files changed:
libempathy-gtk/empathy-chat.c
libempathy-gtk/empathy-contact-widget.c
libempathy-gtk/empathy-contactinfo-utils.c
libempathy-gtk/empathy-individual-widget.c
libempathy-gtk/empathy-log-window.c
libempathy-gtk/empathy-string-parser.c
libempathy-gtk/empathy-string-parser.h
libempathy-gtk/empathy-theme-adium.c
libempathy-gtk/empathy-webkit-utils.c
libempathy-gtk/empathy-webkit-utils.h
tests/empathy-parser-test.c
tp-account-widgets/Makefile.am
tp-account-widgets/tpaw-string-parser.c [new file with mode: 0644]
tp-account-widgets/tpaw-string-parser.h [new file with mode: 0644]

index dd6208b4843da8fb773d1658023898750825ae98..d8ea5e3ee1f8ad42d01f85952a1716bef3c0b7b4 100644 (file)
@@ -1680,7 +1680,7 @@ chat_subject_changed_cb (EmpathyChat *chat)
                        gchar *markup_topic;
                        gchar *markup_text;
 
-                       markup_topic = empathy_add_link_markup (priv->subject);
+                       markup_topic = tpaw_add_link_markup (priv->subject);
                        markup_text = g_strdup_printf ("<span weight=\"bold\">%s</span> %s",
                                _("Topic:"), markup_topic);
 
index be0b745f2979ba1e12d0358f69c064f278916c65..d6ce3e193279d5bc830c64e658406f3919836aeb 100644 (file)
 
 #include <glib/gi18n-lib.h>
 #include <tp-account-widgets/tpaw-builder.h>
+#include <tp-account-widgets/tpaw-string-parser.h>
 
 #include "empathy-avatar-image.h"
 #include "empathy-client-factory.h"
 #include "empathy-groups-widget.h"
-#include "empathy-string-parser.h"
 #include "empathy-ui-utils.h"
 #include "empathy-utils.h"
 
@@ -359,7 +359,7 @@ contact_widget_presence_notify_cb (EmpathyContactWidget *self)
 
   status = empathy_contact_get_status (self->priv->contact);
   if (status != NULL)
-    markup_text = empathy_add_link_markup (status);
+    markup_text = tpaw_add_link_markup (status);
   gtk_label_set_markup (GTK_LABEL (self->priv->label_status), markup_text);
   g_free (markup_text);
 
index 010580254748efc08f76900cf022a23bec5226ae..0389e61d0e4a7033c3876156ff372d676681b0d5 100644 (file)
 
 #include <glib/gi18n-lib.h>
 #include <tp-account-widgets/tpaw-time.h>
+#include <tp-account-widgets/tpaw-string-parser.h>
 
-#include "empathy-string-parser.h"
 #include "empathy-ui-utils.h"
 
 static gchar *
 linkify_first_value (GStrv values)
 {
-  return empathy_add_link_markup (values[0]);
+  return tpaw_add_link_markup (values[0]);
 }
 
 static gchar *
index 8910954f70788ae971c9759737204f021266e982..728f4143aff4b3fbf27926bc34d83edc249a102e 100644 (file)
@@ -1302,7 +1302,7 @@ notify_presence_cb (gpointer folks_object,
     }
 
   if (message != NULL)
-    markup_text = empathy_add_link_markup (message);
+    markup_text = tpaw_add_link_markup (message);
   gtk_label_set_markup (GTK_LABEL (status_label), markup_text);
   g_free (markup_text);
 
index fa7753e281488d6571163ec4b9ce39e349a55186..9f9dfcbc06a0466d5b8bc68af8ec6fe4dab65029 100644 (file)
@@ -1266,7 +1266,7 @@ log_window_append_chat_message (TplEvent *event,
   GtkTreeIter iter, parent;
   gchar *pretty_date, *alias, *body;
   GDateTime *date;
-  EmpathyStringParser *parsers;
+  TpawStringParser *parsers;
   GString *msg;
 
   date = g_date_time_new_from_unix_local (
@@ -1285,7 +1285,7 @@ log_window_append_chat_message (TplEvent *event,
         EMPATHY_PREFS_CHAT_SHOW_SMILEYS));
   msg = g_string_new ("");
 
-  empathy_string_parser_substr (empathy_message_get_body (message), -1,
+  tpaw_string_parser_substr (empathy_message_get_body (message), -1,
       parsers, msg);
 
   if (tpl_text_event_get_message_type (TPL_TEXT_EVENT (event))
index 7cbd290f3ee34a593b7ea1aee5a05fd277e7a76c..f17fc9c03dd961759027b5177fca5b00e4788398 100644 (file)
 #include "empathy-string-parser.h"
 
 #include "empathy-smiley-manager.h"
-#include "empathy-ui-utils.h"
-
-#define SCHEMES           "([a-zA-Z\\+]+)"
-#define INVALID_CHARS     "\\s\"<>"
-#define INVALID_CHARS_EXT INVALID_CHARS "\\[\\](){},;:"
-#define INVALID_CHARS_FULL INVALID_CHARS_EXT "?'"
-#define BODY              "([^"INVALID_CHARS_FULL"])([^"INVALID_CHARS_EXT"]*)"
-#define BODY_END          "([^"INVALID_CHARS"]*)[^"INVALID_CHARS_FULL".]"
-#define URI_REGEX         "("SCHEMES"://"BODY_END")" \
-                         "|((www|ftp)\\."BODY_END")" \
-                         "|((mailto:)?"BODY"@"BODY"\\."BODY_END")"
-
-static GRegex *
-uri_regex_dup_singleton (void)
-{
-       static GRegex *uri_regex = NULL;
-
-       /* We intentionally leak the regex so it's not recomputed */
-       if (!uri_regex) {
-               GError *error = NULL;
-
-               uri_regex = g_regex_new (URI_REGEX, 0, 0, &error);
-               if (uri_regex == NULL) {
-                       g_warning ("Failed to create reg exp: %s", error->message);
-                       g_error_free (error);
-                       return NULL;
-               }
-       }
-
-       return g_regex_ref (uri_regex);
-}
-
-void
-empathy_string_parser_substr (const gchar *text,
-                             gssize len,
-                             EmpathyStringParser *parsers,
-                             gpointer user_data)
-{
-       if (parsers != NULL && parsers[0].match_func != NULL) {
-               parsers[0].match_func (text, len,
-                                      parsers[0].replace_func, parsers + 1,
-                                      user_data);
-       }
-}
-
-void
-empathy_string_match_link (const gchar *text,
-                          gssize len,
-                          EmpathyStringReplace replace_func,
-                          EmpathyStringParser *sub_parsers,
-                          gpointer user_data)
-{
-       GRegex     *uri_regex;
-       GMatchInfo *match_info;
-       gboolean    match;
-       gint        last = 0;
-
-       uri_regex = uri_regex_dup_singleton ();
-       if (uri_regex == NULL) {
-               empathy_string_parser_substr (text, len, sub_parsers, user_data);
-               return;
-       }
-
-       match = g_regex_match_full (uri_regex, text, len, 0, 0, &match_info, NULL);
-       if (match) {
-               gint s = 0, e = 0;
-
-               do {
-                       g_match_info_fetch_pos (match_info, 0, &s, &e);
-
-                       if (s > last) {
-                               /* Append the text between last link (or the
-                                * start of the message) and this link */
-                               empathy_string_parser_substr (text + last,
-                                                             s - last,
-                                                             sub_parsers,
-                                                             user_data);
-                       }
-
-                       replace_func (text + s, e - s, NULL, user_data);
-
-                       last = e;
-               } while (g_match_info_next (match_info, NULL));
-       }
-
-       empathy_string_parser_substr (text + last, len - last,
-                                     sub_parsers, user_data);
-
-       g_match_info_free (match_info);
-       g_regex_unref (uri_regex);
-}
 
 void
 empathy_string_match_smiley (const gchar *text,
                             gssize len,
-                            EmpathyStringReplace replace_func,
-                            EmpathyStringParser *sub_parsers,
+                            TpawStringReplace replace_func,
+                            TpawStringParser *sub_parsers,
                             gpointer user_data)
 {
        guint last = 0;
@@ -134,9 +43,9 @@ empathy_string_match_smiley (const gchar *text,
                if (hit->start > last) {
                        /* Append the text between last smiley (or the
                         * start of the message) and this smiley */
-                       empathy_string_parser_substr (text + last,
-                                                     hit->start - last,
-                                                     sub_parsers, user_data);
+                       tpaw_string_parser_substr (text + last,
+                                                  hit->start - last,
+                                                  sub_parsers, user_data);
                }
 
                replace_func (text + hit->start, hit->end - hit->start,
@@ -149,91 +58,6 @@ empathy_string_match_smiley (const gchar *text,
        g_slist_free (hits);
        g_object_unref (smiley_manager);
 
-       empathy_string_parser_substr (text + last, len - last,
-                                     sub_parsers, user_data);
+       tpaw_string_parser_substr (text + last, len - last,
+                                  sub_parsers, user_data);
 }
-
-void
-empathy_string_match_all (const gchar *text,
-                         gssize len,
-                         EmpathyStringReplace replace_func,
-                         EmpathyStringParser *sub_parsers,
-                         gpointer user_data)
-{
-       replace_func (text, len, NULL, user_data);
-}
-
-void
-empathy_string_replace_link (const gchar *text,
-                             gssize len,
-                             gpointer match_data,
-                             gpointer user_data)
-{
-       GString *string = user_data;
-       gchar *real_url;
-       gchar *title;
-       gchar *markup;
-
-       real_url = empathy_make_absolute_url_len (text, len);
-
-       /* Need to copy manually, because g_markup_printf_escaped does not work
-        * with string precision pitfalls. */
-       title = g_strndup (text, len);
-
-       /* Append the link inside <a href=""></a> tag */
-       markup = g_markup_printf_escaped ("<a href=\"%s\">%s</a>",
-                       real_url, title);
-
-       g_string_append (string, markup);
-
-       g_free (real_url);
-       g_free (title);
-       g_free (markup);
-}
-
-void
-empathy_string_replace_escaped (const gchar *text,
-                               gssize len,
-                               gpointer match_data,
-                               gpointer user_data)
-{
-       GString *string = user_data;
-       gchar *escaped;
-       guint i;
-       gsize escaped_len, old_len;
-
-       escaped = g_markup_escape_text (text, len);
-       escaped_len = strlen (escaped);
-
-       /* Allocate more space to string (we really need a g_string_extend...) */
-       old_len = string->len;
-       g_string_set_size (string, old_len + escaped_len);
-       g_string_truncate (string, old_len);
-
-       /* Remove '\r' */
-       for (i = 0; i < escaped_len; i++) {
-               if (escaped[i] != '\r')
-                       g_string_append_c (string, escaped[i]);
-       }
-
-       g_free (escaped);
-}
-
-gchar *
-empathy_add_link_markup (const gchar *text)
-{
-       EmpathyStringParser parsers[] = {
-               {empathy_string_match_link, empathy_string_replace_link},
-               {empathy_string_match_all, empathy_string_replace_escaped},
-               {NULL, NULL}
-       };
-       GString *string;
-
-       g_return_val_if_fail (text != NULL, NULL);
-
-       string = g_string_sized_new (strlen (text));
-       empathy_string_parser_substr (text, -1, parsers, string);
-
-       return g_string_free (string, FALSE);
-}
-
index 78a822652a1b6645f80fd9877415f61e93e6b9f4..57b784aebb72c00380fb6ae2aa0ce46870abef9d 100644 (file)
 #define __EMPATHY_STRING_PARSER_H__
 
 #include <glib.h>
+#include <tp-account-widgets/tpaw-string-parser.h>
 
 G_BEGIN_DECLS
 
-typedef struct _EmpathyStringParser EmpathyStringParser;
-
-typedef void (*EmpathyStringReplace) (const gchar *text,
-                                     gssize len,
-                                     gpointer match_data,
-                                     gpointer user_data);
-typedef void (*EmpathyStringMatch) (const gchar *text,
-                                   gssize len,
-                                   EmpathyStringReplace replace_func,
-                                   EmpathyStringParser *sub_parsers,
-                                   gpointer user_data);
-
-struct _EmpathyStringParser {
-       EmpathyStringMatch match_func;
-       EmpathyStringReplace replace_func;
-};
-
-void
-empathy_string_parser_substr (const gchar *text,
-                             gssize len,
-                             EmpathyStringParser *parsers,
-                             gpointer user_data);
-
-void
-empathy_string_match_link (const gchar *text,
-                          gssize len,
-                          EmpathyStringReplace replace_func,
-                          EmpathyStringParser *sub_parsers,
-                          gpointer user_data);
-
 void
 empathy_string_match_smiley (const gchar *text,
                             gssize len,
-                            EmpathyStringReplace replace_func,
-                            EmpathyStringParser *sub_parsers,
+                            TpawStringReplace replace_func,
+                            TpawStringParser *sub_parsers,
                             gpointer user_data);
 
-void
-empathy_string_match_all (const gchar *text,
-                         gssize len,
-                         EmpathyStringReplace replace_func,
-                         EmpathyStringParser *sub_parsers,
-                         gpointer user_data);
-
-/* Replace functions assume user_data is a GString */
-void
-empathy_string_replace_link (const gchar *text,
-                             gssize len,
-                             gpointer match_data,
-                             gpointer user_data);
-
-void
-empathy_string_replace_escaped (const gchar *text,
-                               gssize len,
-                               gpointer match_data,
-                               gpointer user_data);
-
-/* Returns a new string with <a> html tag around links, and escape the rest.
- * To be used with gtk_label_set_markup() for example */
-gchar *
-empathy_add_link_markup (const gchar *text);
-
 G_END_DECLS
 
 #endif /*  __EMPATHY_STRING_PARSER_H__ */
index 05b16618087c71574911c67d416362cce891dda9..721a0b4e583da0d3156d8dffc9f1b3bd4ee0211e 100644 (file)
@@ -249,7 +249,7 @@ theme_adium_parse_body (EmpathyThemeAdium *self,
   const gchar *text,
   const gchar *token)
 {
-  EmpathyStringParser *parsers;
+  TpawStringParser *parsers;
   GString *string;
 
   /* Check if we have to parse smileys */
@@ -269,7 +269,7 @@ theme_adium_parse_body (EmpathyThemeAdium *self,
       "<span id=\"message-token-%s\">",
       token);
 
-  empathy_string_parser_substr (text, -1, parsers, string);
+  tpaw_string_parser_substr (text, -1, parsers, string);
 
   if (!tp_str_empty (token))
     g_string_append (string, "</span>");
index 0fc31908814ab1a3b74fb8da64ca72117197d9ce..90dc28c17344c2fed4a7912afcac21164fd2f972 100644 (file)
@@ -24,6 +24,7 @@
 #include <glib/gi18n-lib.h>
 
 #include "empathy-smiley-manager.h"
+#include "empathy-string-parser.h"
 #include "empathy-theme-adium.h"
 #include "empathy-ui-utils.h"
 
@@ -32,8 +33,8 @@
 static void
 empathy_webkit_match_newline (const gchar *text,
     gssize len,
-    EmpathyStringReplace replace_func,
-    EmpathyStringParser *sub_parsers,
+    TpawStringReplace replace_func,
+    TpawStringParser *sub_parsers,
     gpointer user_data)
 {
   GString *string = user_data;
@@ -48,14 +49,14 @@ empathy_webkit_match_newline (const gchar *text,
     {
       if (text[i] == '\n')
         {
-          empathy_string_parser_substr (text + prev, i - prev,
+          tpaw_string_parser_substr (text + prev, i - prev,
               sub_parsers, user_data);
           g_string_append (string, "<br/>");
           prev = i + 1;
         }
     }
 
-  empathy_string_parser_substr (text + prev, i - prev,
+  tpaw_string_parser_substr (text + prev, i - prev,
               sub_parsers, user_data);
 }
 
@@ -74,22 +75,22 @@ empathy_webkit_replace_smiley (const gchar *text,
       hit->path, (int)len, text, (int)len, text);
 }
 
-static EmpathyStringParser string_parsers[] = {
-  { empathy_string_match_link, empathy_string_replace_link },
+static TpawStringParser string_parsers[] = {
+  { tpaw_string_match_link, tpaw_string_replace_link },
   { empathy_webkit_match_newline, NULL },
-  { empathy_string_match_all, empathy_string_replace_escaped },
+  { tpaw_string_match_all, tpaw_string_replace_escaped },
   { NULL, NULL}
 };
 
-static EmpathyStringParser string_parsers_with_smiley[] = {
-  { empathy_string_match_link, empathy_string_replace_link },
+static TpawStringParser string_parsers_with_smiley[] = {
+  { tpaw_string_match_link, tpaw_string_replace_link },
   { empathy_string_match_smiley, empathy_webkit_replace_smiley },
   { empathy_webkit_match_newline, NULL },
-  { empathy_string_match_all, empathy_string_replace_escaped },
+  { tpaw_string_match_all, tpaw_string_replace_escaped },
   { NULL, NULL }
 };
 
-EmpathyStringParser *
+TpawStringParser *
 empathy_webkit_get_string_parser (gboolean smileys)
 {
   if (smileys)
index 034e3bf55d5ead9310d30d67ab5fde82a4815819..98fdc4dcbe85a74a4935152e1734c9d6c749681e 100644 (file)
 #ifndef _EMPATHY_WEBKIT_UTILS__H_
 #define _EMPATHY_WEBKIT_UTILS__H_
 
+#include <tp-account-widgets/tpaw-string-parser.h>
 #include <webkit/webkit.h>
 
-#include "empathy-string-parser.h"
-
 G_BEGIN_DECLS
 
 typedef enum {
@@ -32,7 +31,7 @@ typedef enum {
     EMPATHY_WEBKIT_MENU_INSPECT = 1 << 1,
 } EmpathyWebKitMenuFlags;
 
-EmpathyStringParser * empathy_webkit_get_string_parser (gboolean smileys);
+TpawStringParser * empathy_webkit_get_string_parser (gboolean smileys);
 
 void empathy_webkit_bind_font_setting (WebKitWebView *webview,
     GSettings *gsettings,
index 0cf0374441116e522819923bf6d0667c3f3a6cec..843bf368cf6ea0b81677d765d1e2d8dc6d0d15e4 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <telepathy-glib/telepathy-glib.h>
+#include <tp-account-widgets/tpaw-string-parser.h>
 
 #include "empathy-string-parser.h"
 #include "test-helper.h"
@@ -95,11 +96,11 @@ test_parsers (void)
 
       NULL, NULL
     };
-  EmpathyStringParser parsers[] =
+  TpawStringParser parsers[] =
     {
-      {empathy_string_match_link, test_replace_match},
+      {tpaw_string_match_link, test_replace_match},
       {empathy_string_match_smiley, test_replace_match},
-      {empathy_string_match_all, empathy_string_replace_escaped},
+      {tpaw_string_match_all, tpaw_string_replace_escaped},
       {NULL, NULL}
     };
   guint i;
@@ -111,7 +112,7 @@ test_parsers (void)
       gboolean ok;
 
       string = g_string_new (NULL);
-      empathy_string_parser_substr (tests[i], -1, parsers, string);
+      tpaw_string_parser_substr (tests[i], -1, parsers, string);
 
       ok = !tp_strdiff (tests[i + 1], string->str);
       DEBUG ("'%s' => '%s': %s", tests[i], string->str, ok ? "OK" : "FAILED");
index 6887ab2ca38032250243574e036927f6bf1d1555..9aee73442a38316f31c3f19a04598ee321a79325 100644 (file)
@@ -31,6 +31,7 @@ libtp_account_widgets_sources =               \
        tpaw-irc-network.c                      \
        tpaw-irc-server.c                       \
        tpaw-live-search.c                      \
+       tpaw-string-parser.c                    \
        tpaw-time.c                             \
        tpaw-utils.c                            \
        totem-subtitle-encoding.c               \
@@ -51,6 +52,7 @@ libtp_account_widgets_headers =                       \
        tpaw-irc-network.h                      \
        tpaw-irc-server.h                       \
        tpaw-live-search.h                      \
+       tpaw-string-parser.h                    \
        tpaw-time.h                             \
        tpaw-utils.h                            \
        totem-subtitle-encoding.h               \
diff --git a/tp-account-widgets/tpaw-string-parser.c b/tp-account-widgets/tpaw-string-parser.c
new file mode 100644 (file)
index 0000000..172a763
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ */
+
+#include "config.h"
+#include "tpaw-string-parser.h"
+
+#include "empathy-ui-utils.h"
+
+#define SCHEMES           "([a-zA-Z\\+]+)"
+#define INVALID_CHARS     "\\s\"<>"
+#define INVALID_CHARS_EXT INVALID_CHARS "\\[\\](){},;:"
+#define INVALID_CHARS_FULL INVALID_CHARS_EXT "?'"
+#define BODY              "([^"INVALID_CHARS_FULL"])([^"INVALID_CHARS_EXT"]*)"
+#define BODY_END          "([^"INVALID_CHARS"]*)[^"INVALID_CHARS_FULL".]"
+#define URI_REGEX         "("SCHEMES"://"BODY_END")" \
+                         "|((www|ftp)\\."BODY_END")" \
+                         "|((mailto:)?"BODY"@"BODY"\\."BODY_END")"
+
+static GRegex *
+uri_regex_dup_singleton (void)
+{
+       static GRegex *uri_regex = NULL;
+
+       /* We intentionally leak the regex so it's not recomputed */
+       if (!uri_regex) {
+               GError *error = NULL;
+
+               uri_regex = g_regex_new (URI_REGEX, 0, 0, &error);
+               if (uri_regex == NULL) {
+                       g_warning ("Failed to create reg exp: %s", error->message);
+                       g_error_free (error);
+                       return NULL;
+               }
+       }
+
+       return g_regex_ref (uri_regex);
+}
+
+void
+tpaw_string_parser_substr (const gchar *text,
+                             gssize len,
+                             TpawStringParser *parsers,
+                             gpointer user_data)
+{
+       if (parsers != NULL && parsers[0].match_func != NULL) {
+               parsers[0].match_func (text, len,
+                                      parsers[0].replace_func, parsers + 1,
+                                      user_data);
+       }
+}
+
+void
+tpaw_string_match_link (const gchar *text,
+                          gssize len,
+                          TpawStringReplace replace_func,
+                          TpawStringParser *sub_parsers,
+                          gpointer user_data)
+{
+       GRegex     *uri_regex;
+       GMatchInfo *match_info;
+       gboolean    match;
+       gint        last = 0;
+
+       uri_regex = uri_regex_dup_singleton ();
+       if (uri_regex == NULL) {
+               tpaw_string_parser_substr (text, len, sub_parsers, user_data);
+               return;
+       }
+
+       match = g_regex_match_full (uri_regex, text, len, 0, 0, &match_info, NULL);
+       if (match) {
+               gint s = 0, e = 0;
+
+               do {
+                       g_match_info_fetch_pos (match_info, 0, &s, &e);
+
+                       if (s > last) {
+                               /* Append the text between last link (or the
+                                * start of the message) and this link */
+                               tpaw_string_parser_substr (text + last,
+                                                             s - last,
+                                                             sub_parsers,
+                                                             user_data);
+                       }
+
+                       replace_func (text + s, e - s, NULL, user_data);
+
+                       last = e;
+               } while (g_match_info_next (match_info, NULL));
+       }
+
+       tpaw_string_parser_substr (text + last, len - last,
+                                     sub_parsers, user_data);
+
+       g_match_info_free (match_info);
+       g_regex_unref (uri_regex);
+}
+
+void
+tpaw_string_match_all (const gchar *text,
+                         gssize len,
+                         TpawStringReplace replace_func,
+                         TpawStringParser *sub_parsers,
+                         gpointer user_data)
+{
+       replace_func (text, len, NULL, user_data);
+}
+
+void
+tpaw_string_replace_link (const gchar *text,
+                             gssize len,
+                             gpointer match_data,
+                             gpointer user_data)
+{
+       GString *string = user_data;
+       gchar *real_url;
+       gchar *title;
+       gchar *markup;
+
+       real_url = empathy_make_absolute_url_len (text, len);
+
+       /* Need to copy manually, because g_markup_printf_escaped does not work
+        * with string precision pitfalls. */
+       title = g_strndup (text, len);
+
+       /* Append the link inside <a href=""></a> tag */
+       markup = g_markup_printf_escaped ("<a href=\"%s\">%s</a>",
+                       real_url, title);
+
+       g_string_append (string, markup);
+
+       g_free (real_url);
+       g_free (title);
+       g_free (markup);
+}
+
+void
+tpaw_string_replace_escaped (const gchar *text,
+                               gssize len,
+                               gpointer match_data,
+                               gpointer user_data)
+{
+       GString *string = user_data;
+       gchar *escaped;
+       guint i;
+       gsize escaped_len, old_len;
+
+       escaped = g_markup_escape_text (text, len);
+       escaped_len = strlen (escaped);
+
+       /* Allocate more space to string (we really need a g_string_extend...) */
+       old_len = string->len;
+       g_string_set_size (string, old_len + escaped_len);
+       g_string_truncate (string, old_len);
+
+       /* Remove '\r' */
+       for (i = 0; i < escaped_len; i++) {
+               if (escaped[i] != '\r')
+                       g_string_append_c (string, escaped[i]);
+       }
+
+       g_free (escaped);
+}
+
+gchar *
+tpaw_add_link_markup (const gchar *text)
+{
+       TpawStringParser parsers[] = {
+               {tpaw_string_match_link, tpaw_string_replace_link},
+               {tpaw_string_match_all, tpaw_string_replace_escaped},
+               {NULL, NULL}
+       };
+       GString *string;
+
+       g_return_val_if_fail (text != NULL, NULL);
+
+       string = g_string_sized_new (strlen (text));
+       tpaw_string_parser_substr (text, -1, parsers, string);
+
+       return g_string_free (string, FALSE);
+}
diff --git a/tp-account-widgets/tpaw-string-parser.h b/tp-account-widgets/tpaw-string-parser.h
new file mode 100644 (file)
index 0000000..629fa41
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ */
+
+#ifndef __TPAW_STRING_PARSER_H__
+#define __TPAW_STRING_PARSER_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpawStringParser TpawStringParser;
+
+typedef void (*TpawStringReplace) (const gchar *text,
+                                  gssize len,
+                                  gpointer match_data,
+                                  gpointer user_data);
+typedef void (*TpawStringMatch) (const gchar *text,
+                                gssize len,
+                                TpawStringReplace replace_func,
+                                TpawStringParser *sub_parsers,
+                                gpointer user_data);
+
+struct _TpawStringParser {
+       TpawStringMatch match_func;
+       TpawStringReplace replace_func;
+};
+
+void
+tpaw_string_parser_substr (const gchar *text,
+                          gssize len,
+                          TpawStringParser *parsers,
+                          gpointer user_data);
+
+void
+tpaw_string_match_link (const gchar *text,
+                       gssize len,
+                       TpawStringReplace replace_func,
+                       TpawStringParser *sub_parsers,
+                       gpointer user_data);
+
+void
+tpaw_string_match_all (const gchar *text,
+                      gssize len,
+                      TpawStringReplace replace_func,
+                      TpawStringParser *sub_parsers,
+                      gpointer user_data);
+
+/* Replace functions assume user_data is a GString */
+void
+tpaw_string_replace_link (const gchar *text,
+                         gssize len,
+                         gpointer match_data,
+                         gpointer user_data);
+
+void
+tpaw_string_replace_escaped (const gchar *text,
+                            gssize len,
+                            gpointer match_data,
+                            gpointer user_data);
+
+/* Returns a new string with <a> html tag around links, and escape the rest.
+ * To be used with gtk_label_set_markup() for example */
+gchar *
+tpaw_add_link_markup (const gchar *text);
+
+G_END_DECLS
+
+#endif /*  __TPAW_STRING_PARSER_H__ */