fix merge conflict
This commit is contained in:
commit
64ba92593e
224
src/common/url.c
224
src/common/url.c
|
@ -35,6 +35,7 @@ GTree *url_btree = NULL;
|
||||||
static int do_an_re (const char *word, int *start, int *end, int *type);
|
static int do_an_re (const char *word, int *start, int *end, int *type);
|
||||||
static GRegex *re_url (void);
|
static GRegex *re_url (void);
|
||||||
static GRegex *re_host (void);
|
static GRegex *re_host (void);
|
||||||
|
static GRegex *re_host6 (void);
|
||||||
static GRegex *re_email (void);
|
static GRegex *re_email (void);
|
||||||
static GRegex *re_nick (void);
|
static GRegex *re_nick (void);
|
||||||
static GRegex *re_channel (void);
|
static GRegex *re_channel (void);
|
||||||
|
@ -222,6 +223,7 @@ url_check_word (const char *word)
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
case WORD_URL:
|
case WORD_URL:
|
||||||
case WORD_HOST:
|
case WORD_HOST:
|
||||||
|
case WORD_HOST6:
|
||||||
case WORD_CHANNEL:
|
case WORD_CHANNEL:
|
||||||
case WORD_PATH:
|
case WORD_PATH:
|
||||||
return lasttype;
|
return lasttype;
|
||||||
|
@ -314,9 +316,10 @@ do_an_re(const char *word,int *start, int *end, int *type)
|
||||||
} func_t;
|
} func_t;
|
||||||
func_t funcs[] =
|
func_t funcs[] =
|
||||||
{
|
{
|
||||||
{ re_email, WORD_EMAIL },
|
|
||||||
{ re_url, WORD_URL },
|
{ re_url, WORD_URL },
|
||||||
|
{ re_email, WORD_EMAIL },
|
||||||
{ re_channel, WORD_CHANNEL },
|
{ re_channel, WORD_CHANNEL },
|
||||||
|
{ re_host6, WORD_HOST6 },
|
||||||
{ re_host, WORD_HOST },
|
{ re_host, WORD_HOST },
|
||||||
{ re_path, WORD_PATH },
|
{ re_path, WORD_PATH },
|
||||||
{ re_nick, WORD_NICK }
|
{ re_nick, WORD_NICK }
|
||||||
|
@ -349,17 +352,23 @@ do_an_re(const char *word,int *start, int *end, int *type)
|
||||||
/* Miscellaneous description --- */
|
/* Miscellaneous description --- */
|
||||||
#define DOMAIN "[a-z0-9][-a-z0-9]*(\\.[-a-z0-9]+)*\\."
|
#define DOMAIN "[a-z0-9][-a-z0-9]*(\\.[-a-z0-9]+)*\\."
|
||||||
#define TLD "[a-z][-a-z0-9]*[a-z]"
|
#define TLD "[a-z][-a-z0-9]*[a-z]"
|
||||||
#define IPADDR "[0-9]+(\\.[0-9]+){3}"
|
#define IPADDR "[0-9]{1,3}(\\.[0-9]{1,3}){3}"
|
||||||
#define HOST "(" DOMAIN TLD "|" IPADDR ")"
|
#define IPV6GROUP "([0-9a-f]{0,4})"
|
||||||
#define OPT_PORT "(:[1-9][0-9]{0,4})?"
|
#define IPV6ADDR "((" IPV6GROUP "(:" IPV6GROUP "){7})" \
|
||||||
|
"|(" IPV6GROUP "(:" IPV6GROUP ")*:(:" IPV6GROUP ")+))" /* with :: compression */
|
||||||
|
#define HOST "(" DOMAIN TLD "|" IPADDR "|" IPV6ADDR ")"
|
||||||
|
/* In urls the IPv6 must be enclosed in square brackets */
|
||||||
|
#define HOST_URL "(" DOMAIN TLD "|" IPADDR "|" "\\[" IPV6ADDR "\\]" ")"
|
||||||
|
#define PORT "(:[1-9][0-9]{0,4})"
|
||||||
|
#define OPT_PORT "(" PORT ")?"
|
||||||
|
|
||||||
GRegex *
|
GRegex *
|
||||||
make_re(char *grist, char *type)
|
make_re (char *grist)
|
||||||
{
|
{
|
||||||
GRegex *ret;
|
GRegex *ret;
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
|
|
||||||
ret = g_regex_new (grist, G_REGEX_CASELESS + G_REGEX_OPTIMIZE, 0, &err);
|
ret = g_regex_new (grist, G_REGEX_CASELESS | G_REGEX_OPTIMIZE, 0, &err);
|
||||||
g_free (grist);
|
g_free (grist);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -375,78 +384,163 @@ re_host (void)
|
||||||
if (host_ret) return host_ret;
|
if (host_ret) return host_ret;
|
||||||
|
|
||||||
grist = g_strdup_printf (
|
grist = g_strdup_printf (
|
||||||
"(" /* HOST */
|
"("
|
||||||
HOST OPT_PORT
|
"(" HOST_URL PORT ")|(" HOST ")"
|
||||||
")"
|
")"
|
||||||
);
|
);
|
||||||
host_ret = make_re (grist, "re_host");
|
host_ret = make_re (grist);
|
||||||
return host_ret;
|
return host_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GRegex *
|
||||||
|
re_host6 (void)
|
||||||
|
{
|
||||||
|
static GRegex *host6_ret;
|
||||||
|
char *grist;
|
||||||
|
|
||||||
|
if (host6_ret) return host6_ret;
|
||||||
|
|
||||||
|
grist = g_strdup_printf (
|
||||||
|
"("
|
||||||
|
"(" IPV6ADDR ")|(" "\\[" IPV6ADDR "\\]" PORT ")"
|
||||||
|
")"
|
||||||
|
);
|
||||||
|
|
||||||
|
host6_ret = make_re (grist);
|
||||||
|
|
||||||
|
return host6_ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* URL description --- */
|
/* URL description --- */
|
||||||
#define SCHEME "(%s)"
|
#define SCHEME "(%s)"
|
||||||
#define LPAR "\\("
|
#define LPAR "\\("
|
||||||
#define RPAR "\\)"
|
#define RPAR "\\)"
|
||||||
#define NOPARENS "[^() \t]*"
|
#define NOPARENS "[^() \t]*"
|
||||||
|
#define PATH \
|
||||||
|
"(" \
|
||||||
|
"(" LPAR NOPARENS RPAR ")" \
|
||||||
|
"|" \
|
||||||
|
"(" NOPARENS ")" \
|
||||||
|
")*" /* Zero or more occurrences of either of these */ \
|
||||||
|
"(?<![.,?!\\]])" /* Not allowed to end with these */
|
||||||
|
#define USERINFO "([-a-z0-9._~%]+(:[-a-z0-9._~%]*)?@)"
|
||||||
|
|
||||||
char *prefix[] = {
|
/* Flags used to describe URIs (RFC 3986)
|
||||||
"irc\\.",
|
*
|
||||||
"ftp\\.",
|
* Bellow is an example of what the flags match.
|
||||||
"www\\.",
|
*
|
||||||
"irc://",
|
* URI_AUTHORITY - http://example.org:80/foo/bar
|
||||||
"ircs://",
|
* ^^^^^^^^^^^^^^^^
|
||||||
"ftp://",
|
* URI_USERINFO/URI_OPT_USERINFO - http://user@example.org:80/foo/bar
|
||||||
"http://",
|
* ^^^^^
|
||||||
"https://",
|
* URI_PATH - http://example.org:80/foo/bar
|
||||||
"file://",
|
* ^^^^^^^^
|
||||||
"rtsp://",
|
*/
|
||||||
NULL
|
#define URI_AUTHORITY (1 << 0)
|
||||||
|
#define URI_OPT_USERINFO (1 << 1)
|
||||||
|
#define URI_USERINFO (1 << 2)
|
||||||
|
#define URI_PATH (1 << 3)
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
const char *scheme; /* scheme name. e.g. http */
|
||||||
|
const char *path_sep; /* string that begins the path */
|
||||||
|
int flags; /* see above (flag macros) */
|
||||||
|
} uri[] = {
|
||||||
|
{ "irc", "/", URI_PATH },
|
||||||
|
{ "ircs", "/", URI_PATH },
|
||||||
|
{ "rtsp", "/", URI_AUTHORITY | URI_PATH },
|
||||||
|
{ "feed", "/", URI_AUTHORITY | URI_PATH },
|
||||||
|
{ "teamspeak", "?", URI_AUTHORITY | URI_PATH },
|
||||||
|
{ "ftp", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "sftp", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "ftps", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "http", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "https", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "cvs", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "svn", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "git", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "bzr", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "rsync", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "mumble", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "ventrilo", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "xmpp", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "h323", ";", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "imap", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "pop", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "nfs", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "smb", "/", URI_AUTHORITY | URI_OPT_USERINFO | URI_PATH },
|
||||||
|
{ "ssh", "", URI_AUTHORITY | URI_OPT_USERINFO },
|
||||||
|
{ "sip", "", URI_AUTHORITY | URI_USERINFO },
|
||||||
|
{ "sips", "", URI_AUTHORITY | URI_USERINFO },
|
||||||
|
{ "magnet", "?", URI_PATH },
|
||||||
|
{ "mailto", "", URI_PATH },
|
||||||
|
{ "bitcoin", "", URI_PATH },
|
||||||
|
{ "gtalk", "", URI_PATH },
|
||||||
|
{ "steam", "", URI_PATH },
|
||||||
|
{ "file", "/", URI_PATH },
|
||||||
|
{ "callto", "", URI_PATH },
|
||||||
|
{ "skype", "", URI_PATH },
|
||||||
|
{ "geo", "", URI_PATH },
|
||||||
|
{ NULL, "", 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static GRegex *
|
static GRegex *
|
||||||
re_url (void)
|
re_url (void)
|
||||||
{
|
{
|
||||||
static GRegex *url_ret;
|
static GRegex *url_ret = NULL;
|
||||||
|
GString *grist_gstr;
|
||||||
char *grist;
|
char *grist;
|
||||||
char *scheme;
|
int i;
|
||||||
|
|
||||||
if (url_ret) return url_ret;
|
if (url_ret) return url_ret;
|
||||||
|
|
||||||
scheme = g_strjoinv ("|", prefix);
|
grist_gstr = g_string_new (NULL);
|
||||||
grist = g_strdup_printf (
|
|
||||||
"(" /* URL or HOST */
|
/* Add regex "host/path", representing a "schemeless" url */
|
||||||
"("
|
g_string_append (grist_gstr, "(" HOST_URL OPT_PORT "/" "(" PATH ")?" ")");
|
||||||
SCHEME HOST OPT_PORT
|
|
||||||
"(" /* Optional "/path?query_string#fragment_id" */
|
for (i = 0; uri[i].scheme; i++)
|
||||||
"/" /* Must start with slash */
|
{
|
||||||
"("
|
g_string_append (grist_gstr, "|(");
|
||||||
"(" LPAR NOPARENS RPAR ")"
|
g_string_append_printf (grist_gstr, "%s:", uri[i].scheme);
|
||||||
"|"
|
|
||||||
"(" NOPARENS ")"
|
if (uri[i].flags & URI_AUTHORITY)
|
||||||
")*" /* Zero or more occurrences of either of these */
|
g_string_append (grist_gstr, "//");
|
||||||
"(?<![.,?!\\]])" /* Not allowed to end with these */
|
|
||||||
")?" /* Zero or one of this /path?query_string#fragment_id thing */
|
if (uri[i].flags & URI_USERINFO)
|
||||||
")|("
|
g_string_append (grist_gstr, USERINFO);
|
||||||
HOST OPT_PORT "/"
|
else if (uri[i].flags & URI_OPT_USERINFO)
|
||||||
"(" /* Optional "path?query_string#fragment_id" */
|
g_string_append (grist_gstr, USERINFO "?");
|
||||||
"("
|
|
||||||
"(" LPAR NOPARENS RPAR ")"
|
if (uri[i].flags & URI_AUTHORITY)
|
||||||
"|"
|
g_string_append (grist_gstr, HOST_URL OPT_PORT);
|
||||||
"(" NOPARENS ")"
|
|
||||||
")*" /* Zero or more occurrences of either of these */
|
if (uri[i].flags & URI_PATH)
|
||||||
"(?<![.,?!\\]])" /* Not allowed to end with these */
|
{
|
||||||
")?" /* Zero or one of this /path?query_string#fragment_id thing */
|
char *sep_escaped;
|
||||||
")"
|
|
||||||
")"
|
sep_escaped = g_regex_escape_string (uri[i].path_sep,
|
||||||
, scheme
|
strlen(uri[i].path_sep));
|
||||||
);
|
|
||||||
url_ret = make_re (grist, "re_url");
|
g_string_append_printf(grist_gstr, "(" "%s" PATH ")?",
|
||||||
g_free (scheme);
|
sep_escaped);
|
||||||
|
|
||||||
|
g_free(sep_escaped);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_string_append(grist_gstr, ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
grist = g_string_free (grist_gstr, FALSE);
|
||||||
|
|
||||||
|
url_ret = make_re (grist);
|
||||||
|
|
||||||
return url_ret;
|
return url_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EMAIL description --- */
|
/* EMAIL description --- */
|
||||||
#define EMAIL "[a-z][-_a-z0-9]+@" "(" HOST ")"
|
#define EMAIL "[a-z][-_a-z0-9]+@" "(" HOST_URL ")"
|
||||||
|
|
||||||
static GRegex *
|
static GRegex *
|
||||||
re_email (void)
|
re_email (void)
|
||||||
|
@ -457,11 +551,11 @@ re_email (void)
|
||||||
if (email_ret) return email_ret;
|
if (email_ret) return email_ret;
|
||||||
|
|
||||||
grist = g_strdup_printf (
|
grist = g_strdup_printf (
|
||||||
"(" /* EMAIL */
|
"("
|
||||||
EMAIL
|
EMAIL
|
||||||
")"
|
")"
|
||||||
);
|
);
|
||||||
email_ret = make_re (grist, "re_email");
|
email_ret = make_re (grist);
|
||||||
return email_ret;
|
return email_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,11 +587,11 @@ re_nick (void)
|
||||||
if (nick_ret) return nick_ret;
|
if (nick_ret) return nick_ret;
|
||||||
|
|
||||||
grist = g_strdup_printf (
|
grist = g_strdup_printf (
|
||||||
"(" /* NICK */
|
"("
|
||||||
NICK
|
NICK
|
||||||
")"
|
")"
|
||||||
);
|
);
|
||||||
nick_ret = make_re (grist, "re_nick");
|
nick_ret = make_re (grist);
|
||||||
return nick_ret;
|
return nick_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,21 +607,21 @@ re_channel (void)
|
||||||
if (channel_ret) return channel_ret;
|
if (channel_ret) return channel_ret;
|
||||||
|
|
||||||
grist = g_strdup_printf (
|
grist = g_strdup_printf (
|
||||||
"(" /* CHANNEL */
|
"("
|
||||||
CHANNEL
|
CHANNEL
|
||||||
")"
|
")"
|
||||||
);
|
);
|
||||||
channel_ret = make_re (grist, "re_channel");
|
channel_ret = make_re (grist);
|
||||||
return channel_ret;
|
return channel_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PATH description --- */
|
/* PATH description --- */
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
/* Windows path can be .\ ..\ or C: D: etc */
|
/* Windows path can be .\ ..\ or C: D: etc */
|
||||||
#define PATH "^(\\.{1,2}\\\\|[a-z]:).*"
|
#define FS_PATH "^(\\.{1,2}\\\\|[a-z]:).*"
|
||||||
#else
|
#else
|
||||||
/* Linux path can be / or ./ or ../ etc */
|
/* Linux path can be / or ./ or ../ etc */
|
||||||
#define PATH "^(/|\\./|\\.\\./).*"
|
#define FS_PATH "^(/|\\./|\\.\\./).*"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static GRegex *
|
static GRegex *
|
||||||
|
@ -539,10 +633,10 @@ re_path (void)
|
||||||
if (path_ret) return path_ret;
|
if (path_ret) return path_ret;
|
||||||
|
|
||||||
grist = g_strdup_printf (
|
grist = g_strdup_printf (
|
||||||
"(" /* PATH */
|
"("
|
||||||
PATH
|
FS_PATH
|
||||||
")"
|
")"
|
||||||
);
|
);
|
||||||
path_ret = make_re (grist, "re_path");
|
path_ret = make_re (grist);
|
||||||
return path_ret;
|
return path_ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,8 @@ extern void *url_tree;
|
||||||
#define WORD_NICK 2
|
#define WORD_NICK 2
|
||||||
#define WORD_CHANNEL 3
|
#define WORD_CHANNEL 3
|
||||||
#define WORD_HOST 4
|
#define WORD_HOST 4
|
||||||
#define WORD_EMAIL 5
|
#define WORD_HOST6 5
|
||||||
|
#define WORD_EMAIL 6
|
||||||
/* anything >0 will be displayed as a link by gtk_xtext_motion_notify() */
|
/* anything >0 will be displayed as a link by gtk_xtext_motion_notify() */
|
||||||
#define WORD_DIALOG -1
|
#define WORD_DIALOG -1
|
||||||
#define WORD_PATH -2
|
#define WORD_PATH -2
|
||||||
|
|
|
@ -1008,11 +1008,13 @@ fe_open_url_inner (const char *url)
|
||||||
static void
|
static void
|
||||||
fe_open_url_locale (const char *url)
|
fe_open_url_locale (const char *url)
|
||||||
{
|
{
|
||||||
if (url_check_word (url) == WORD_PATH)
|
int url_type = url_check_word (url);
|
||||||
{
|
|
||||||
#ifndef WIN32
|
|
||||||
char *uri;
|
char *uri;
|
||||||
|
|
||||||
|
/* gvfs likes file:// */
|
||||||
|
if (url_type == WORD_PATH)
|
||||||
|
{
|
||||||
|
#ifndef WIN32
|
||||||
uri = g_strconcat ("file://", url, NULL);
|
uri = g_strconcat ("file://", url, NULL);
|
||||||
fe_open_url_inner (uri);
|
fe_open_url_inner (uri);
|
||||||
g_free (uri);
|
g_free (uri);
|
||||||
|
@ -1020,6 +1022,18 @@ fe_open_url_locale (const char *url)
|
||||||
fe_open_url_inner (url);
|
fe_open_url_inner (url);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
/* IPv6 addr. Add http:// */
|
||||||
|
else if (url_type == WORD_HOST6)
|
||||||
|
{
|
||||||
|
/* IPv6 addrs in urls should be enclosed in [ ] */
|
||||||
|
if (*url != '[')
|
||||||
|
uri = g_strdup_printf ("http://[%s]", url);
|
||||||
|
else
|
||||||
|
uri = g_strdup_printf ("http://%s", url);
|
||||||
|
|
||||||
|
fe_open_url_inner (uri);
|
||||||
|
g_free (uri);
|
||||||
|
}
|
||||||
/* the http:// part's missing, prepend it, otherwise it won't always work */
|
/* the http:// part's missing, prepend it, otherwise it won't always work */
|
||||||
else if (strchr (url, ':') == NULL)
|
else if (strchr (url, ':') == NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2267,6 +2267,7 @@ mg_word_clicked (GtkWidget *xtext, char *word, GdkEventButton *even)
|
||||||
switch (word_type)
|
switch (word_type)
|
||||||
{
|
{
|
||||||
case WORD_URL:
|
case WORD_URL:
|
||||||
|
case WORD_HOST6:
|
||||||
case WORD_HOST:
|
case WORD_HOST:
|
||||||
word[end] = 0;
|
word[end] = 0;
|
||||||
fe_open_url (word + start);
|
fe_open_url (word + start);
|
||||||
|
@ -2293,6 +2294,7 @@ mg_word_clicked (GtkWidget *xtext, char *word, GdkEventButton *even)
|
||||||
menu_middlemenu (sess, even);
|
menu_middlemenu (sess, even);
|
||||||
break;
|
break;
|
||||||
case WORD_URL:
|
case WORD_URL:
|
||||||
|
case WORD_HOST6:
|
||||||
case WORD_HOST:
|
case WORD_HOST:
|
||||||
word[end] = 0;
|
word[end] = 0;
|
||||||
word += start;
|
word += start;
|
||||||
|
|
Loading…
Reference in New Issue