[Xfce4-commits] r30090 - terminal/trunk/terminal
Nick Schermer
nick at xfce.org
Sat Jun 27 21:27:31 CEST 2009
Author: nick
Date: 2009-06-27 19:27:31 +0000 (Sat, 27 Jun 2009)
New Revision: 30090
Modified:
terminal/trunk/terminal/terminal-widget.c
Log:
Use new regex API for link matching.
Modified: terminal/trunk/terminal/terminal-widget.c
===================================================================
--- terminal/trunk/terminal/terminal-widget.c 2009-06-27 19:27:11 UTC (rev 30089)
+++ terminal/trunk/terminal/terminal-widget.c 2009-06-27 19:27:31 UTC (rev 30090)
@@ -40,19 +40,17 @@
-#define USERCHARS "-A-Za-z0-9"
-#define PASSCHARS "-A-Za-z0-9,?;.:/!%$^*&~\"#'"
-#define HOSTCHARS "-A-Za-z0-9"
-#define USER "[" USERCHARS "]+(:["PASSCHARS "]+)?"
-#define MATCH_BROWSER1 "((file|https?|ftps?)://(" USER "@)?)[" HOSTCHARS ".]+(:[0-9]+)?" \
- "(/[-A-Za-z0-9_$.+!*(),;:@&=?/~#%]*[^]'.}>) \t\r\n,\\\"])?"
-#define MATCH_BROWSER2 "(www|ftp)[" HOSTCHARS "]*\\.[" HOSTCHARS ".]+(:[0-9]+)?" \
- "(/[-A-Za-z0-9_$.+!*(),;:@&=?/~#%]*[^]'.}>) \t\r\n,\\\"])?"
-#if !defined(__GLIBC__)
-#define MATCH_MAILER "(mailto:)?[a-z0-9][a-z0-9.-]*@[a-z0-9][a-z0-9-]*(\\.[a-z0-9][a-z0-9-]*)+"
-#else
-#define MATCH_MAILER "\\<(mailto:)?[a-z0-9][a-z0-9.-]*@[a-z0-9][a-z0-9-]*(\\.[a-z0-9][a-z0-9-]*)+\\>"
-#endif
+#define USERCHARS "-[:alnum:]"
+#define USERCHARS_CLASS "[" USERCHARS "]"
+#define PASSCHARS_CLASS "[-[:alnum:]\\Q,?;.:/!%$^*&~\"#'\\E]"
+#define HOSTCHARS_CLASS "[-[:alnum:]]"
+#define HOST HOSTCHARS_CLASS "+(\\." HOSTCHARS_CLASS "+)*"
+#define PORT "(?:\\:[[:digit:]]{1,5})?"
+#define PATHCHARS_CLASS "[-[:alnum:]\\Q_$.+!*,;@&=?/~#%\\E]"
+#define PATHTERM_CLASS "[^\\Q]'.}>) \t\r\n,\"\\E]"
+#define SCHEME "(?:news:|telnet:|nntp:|file:\\/|https?:|ftps?:|webcal:)"
+#define USERPASS USERCHARS_CLASS "+(?:" PASSCHARS_CLASS "+)?"
+#define URLPATH "(?:(/"PATHCHARS_CLASS"+(?:[(]"PATHCHARS_CLASS"*[)])*"PATHCHARS_CLASS"*)*"PATHTERM_CLASS")?"
@@ -75,8 +73,31 @@
TARGET_GTK_NOTEBOOK_TAB,
};
+enum
+{
+ PATTERN_TYPE_NONE,
+ PATTERN_TYPE_FULL_HTTP,
+ PATTERN_TYPE_HTTP,
+ PATTERN_TYPE_EMAIL
+};
+typedef struct
+{
+ const gchar *pattern;
+ gint type;
+}
+TerminalRegexPattern;
+static const TerminalRegexPattern regex_patterns[] =
+{
+ { SCHEME "//(?:" USERPASS "\\@)?" HOST PORT URLPATH, PATTERN_TYPE_FULL_HTTP },
+ { "(?:www|ftp)" HOSTCHARS_CLASS "*\\." HOST PORT URLPATH, PATTERN_TYPE_HTTP },
+ { "(?:mailto:)?" USERCHARS_CLASS "[" USERCHARS ".]*\\@" HOSTCHARS_CLASS "+\\." HOST, PATTERN_TYPE_EMAIL },
+ { "news:[[:alnum:]\\Q^_{|}~!\"#$%&'()*+,./;:=?`\\E]+", PATTERN_TYPE_FULL_HTTP }
+};
+
+
+
static void terminal_widget_finalize (GObject *object);
static gboolean terminal_widget_button_press_event (GtkWidget *widget,
GdkEventButton *event);
@@ -110,9 +131,7 @@
/*< private >*/
TerminalPreferences *preferences;
- gint tag_browser1;
- gint tag_browser2;
- gint tag_mailer;
+ gint *regex_tags;
};
@@ -172,10 +191,13 @@
static void
terminal_widget_init (TerminalWidget *widget)
{
- widget->tag_browser1 = -1;
- widget->tag_browser2 = -1;
- widget->tag_mailer = -1;
+ guint i;
+ /* initialize regex tag ids */
+ widget->regex_tags = g_new (gint, G_N_ELEMENTS (regex_patterns));
+ for (i = 0; i < G_N_ELEMENTS (regex_patterns); i++)
+ widget->regex_tags[i] = -1;
+
/* query preferences connection */
widget->preferences = terminal_preferences_get ();
@@ -202,6 +224,9 @@
{
TerminalWidget *widget = TERMINAL_WIDGET (object);
+ /* free tag ids */
+ g_free (widget->regex_tags);
+
/* disconnect the misc-highlight-urls watch */
g_signal_handlers_disconnect_by_func (G_OBJECT (widget->preferences), G_CALLBACK (terminal_widget_update_highlight_urls), widget);
@@ -269,8 +294,9 @@
GtkWidget *item_separator = NULL;
GList *children;
gchar *match;
- guint id;
+ guint id, i;
gint tag;
+ gint pattern_type = PATTERN_TYPE_NONE;
g_signal_emit (G_OBJECT (widget), widget_signals[GET_CONTEXT_MENU], 0, &menu);
if (G_UNLIKELY (menu == NULL))
@@ -293,8 +319,17 @@
item_separator = NULL;
g_list_free (children);
+ /* lookup the pattern type */
+ for (i = 0; i < G_N_ELEMENTS (regex_patterns); i++)
+ if (widget->regex_tags[i] == tag)
+ {
+ pattern_type = regex_patterns[i].type;
+ break;
+ }
+ g_return_if_fail (pattern_type != PATTERN_TYPE_NONE);
+
/* create menu items with appriorate labels */
- if (tag == widget->tag_mailer)
+ if (pattern_type == PATTERN_TYPE_EMAIL)
{
item_copy = gtk_menu_item_new_with_label (_("Copy Email Address"));
item_open = gtk_menu_item_new_with_label (_("Compose Email"));
@@ -325,7 +360,7 @@
g_object_ref (G_OBJECT (menu));
gtk_object_sink (GTK_OBJECT (menu));
- if (event_time < 0)
+ if (event_time == 0)
event_time = gtk_get_current_event_time ();
loop = g_main_loop_new (NULL, FALSE);
@@ -641,38 +676,54 @@
{
GError *error = NULL;
gchar *uri;
+ guint i;
- /* parse the URI from the link */
- if (tag == widget->tag_browser1)
+ for (i = 0; i < G_N_ELEMENTS (regex_patterns); i++)
{
- uri = g_strdup (link);
- }
- else if (tag == widget->tag_browser2)
- {
- uri = g_strconcat ("http://", link, NULL);
- }
- else if (tag == widget->tag_mailer)
- {
- if (strncmp (link, "mailto:", 7) == 0)
- uri = g_strdup (link);
- else
- uri = g_strconcat ("mailto:", link, NULL);
- }
- else
- {
- g_warning ("Invalid tag specified while trying to open an URI.");
+ /* lookup the tag in our tags */
+ if (widget->regex_tags[i] != tag)
+ continue;
+
+ /* handle the pattern type */
+ switch (regex_patterns[i].type)
+ {
+ case PATTERN_TYPE_FULL_HTTP:
+ uri = g_strdup (link);
+ break;
+
+ case PATTERN_TYPE_HTTP:
+ uri = g_strconcat ("http://", link, NULL);
+ break;
+
+ case PATTERN_TYPE_EMAIL:
+ if (strncmp (link, "mailto:", 7) == 0)
+ uri = g_strdup (link);
+ else
+ uri = g_strconcat ("mailto:", link, NULL);
+ break;
+
+ default:
+ goto invalid_tag;
+ }
+
+ /* try to open the URI with the responsible application */
+ if (!exo_url_show_on_screen (uri, NULL,
+ gtk_widget_get_screen (GTK_WIDGET (widget)), &error))
+ {
+ /* tell the user that we were unable to open the responsible application */
+ terminal_dialogs_show_error (widget, error, _("Failed to open the URL `%s'"), uri);
+ g_error_free (error);
+ }
+
+ g_free (uri);
+
+ /* done */
return;
}
- /* try to open the URI with the responsible application */
- if (!exo_url_show_on_screen (uri, NULL, gtk_widget_get_screen (GTK_WIDGET (widget)), &error))
- {
- /* tell the user that we were unable to open the responsible application */
- terminal_dialogs_show_error (widget, error, _("Failed to open the URL `%s'"), uri);
- g_error_free (error);
- }
+invalid_tag:
- g_free (uri);
+ g_warning ("Invalid tag specified while trying to open link \"%s\".", link);
}
@@ -680,56 +731,55 @@
static void
terminal_widget_update_highlight_urls (TerminalWidget *widget)
{
- gboolean highlight_urls;
+ guint i;
+ gboolean highlight_urls;
+ GRegex *regex;
+ const TerminalRegexPattern *pattern;
+ GError *error;
- g_object_get (G_OBJECT (widget->preferences), "misc-highlight-urls", &highlight_urls, NULL);
+ g_object_get (G_OBJECT (widget->preferences),
+ "misc-highlight-urls", &highlight_urls, NULL);
+
if (!highlight_urls)
{
- if (widget->tag_browser1 >= 0)
- {
- vte_terminal_match_remove (VTE_TERMINAL (widget), widget->tag_browser1);
- widget->tag_browser1 = -1;
- }
-
- if (widget->tag_browser2 >= 0)
- {
- vte_terminal_match_remove (VTE_TERMINAL (widget), widget->tag_browser2);
- widget->tag_browser2 = -1;
- }
-
- if (widget->tag_mailer >= 0)
- {
- vte_terminal_match_remove (VTE_TERMINAL (widget), widget->tag_mailer);
- widget->tag_mailer = -1;
- }
+ /* remove all our regex tags */
+ for (i = 0; i < G_N_ELEMENTS (regex_patterns); i++)
+ if (widget->regex_tags[i] != -1)
+ {
+ vte_terminal_match_remove (VTE_TERMINAL (widget),
+ widget->regex_tags[i]);
+ widget->regex_tags[i] = -1;
+ }
}
else
{
- if (widget->tag_browser1 < 0)
+ /* set all our patterns */
+ for (i = 0; i < G_N_ELEMENTS (regex_patterns); i++)
{
- widget->tag_browser1 = vte_terminal_match_add (VTE_TERMINAL (widget),
- MATCH_BROWSER1);
- vte_terminal_match_set_cursor_type (VTE_TERMINAL (widget),
- widget->tag_browser1,
- GDK_HAND2);
- }
+ /* get the pattern */
+ pattern = ®ex_patterns[i];
+ g_return_if_fail (widget->regex_tags[i] == -1);
- if (widget->tag_browser2 < 0)
- {
- widget->tag_browser2 = vte_terminal_match_add (VTE_TERMINAL (widget),
- MATCH_BROWSER2);
- vte_terminal_match_set_cursor_type (VTE_TERMINAL (widget),
- widget->tag_browser2,
- GDK_HAND2);
- }
+ /* build the regex */
+ error = NULL;
+ regex = g_regex_new (pattern->pattern,
+ G_REGEX_CASELESS | G_REGEX_OPTIMIZE,
+ 0, &error);
+ if (G_UNLIKELY (error != NULL))
+ {
+ g_critical ("Failed to parse regular expression pattern %d: %s",
+ i, error->message);
+ g_error_free (error);
+ continue;
+ }
- if (widget->tag_mailer < 0)
- {
- widget->tag_mailer = vte_terminal_match_add (VTE_TERMINAL (widget),
- MATCH_MAILER);
+ /* set the new regular expression */
+ widget->regex_tags[i] = vte_terminal_match_add_gregex (VTE_TERMINAL (widget),
+ regex, 0);
vte_terminal_match_set_cursor_type (VTE_TERMINAL (widget),
- widget->tag_mailer,
- GDK_HAND2);
+ widget->regex_tags[i], GDK_HAND2);
+ /* release the regex owned by vte now */
+ g_regex_unref (regex);
}
}
}
More information about the Xfce4-commits
mailing list