[yelp/yelp-3-0] [yelp-uri] Reworked ghelp URI resolver
- From: Shaun McCance <shaunm src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [yelp/yelp-3-0] [yelp-uri] Reworked ghelp URI resolver
- Date: Mon, 12 Oct 2009 21:48:01 +0000 (UTC)
commit c6f42db8238cb0056677f1e3c76488f8ad7377e0
Author: Shaun McCance <shaunm gnome org>
Date: Fri Oct 9 11:42:52 2009 -0500
[yelp-uri] Reworked ghelp URI resolver
libyelp/yelp-uri.c | 153 +++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 115 insertions(+), 38 deletions(-)
---
diff --git a/libyelp/yelp-uri.c b/libyelp/yelp-uri.c
index b8d157a..88bf1e8 100644
--- a/libyelp/yelp-uri.c
+++ b/libyelp/yelp-uri.c
@@ -37,6 +37,7 @@ static void yelp_uri_init (YelpUri *uri);
static void yelp_uri_dispose (GObject *object);
static void yelp_uri_finalize (GObject *object);
+static void resolve_start (YelpUri *uri);
static void resolve_async (YelpUri *uri);
static gboolean resolve_final (YelpUri *uri);
@@ -187,9 +188,16 @@ void
yelp_uri_resolve (YelpUri *uri)
{
YelpUriPrivate *priv = GET_PRIV (uri);
- if (priv->resolver == NULL)
- priv->resolver = g_thread_create ((GThreadFunc) resolve_async,
- uri, FALSE, NULL);
+
+ if (priv->res_base && !yelp_uri_is_resolved (priv->res_base)) {
+ g_signal_connect_swapped (priv->res_base, "resolved",
+ G_CALLBACK (resolve_start),
+ uri);
+ yelp_uri_resolve (priv->res_base);
+ }
+ else {
+ resolve_start (uri);
+ }
}
/* We want code to be able to do something like this:
@@ -216,6 +224,16 @@ yelp_uri_resolve (YelpUri *uri)
* 4) Once a URI is resolved, it is immutable.
*/
static void
+resolve_start (YelpUri *uri)
+{
+ YelpUriPrivate *priv = GET_PRIV (uri);
+
+ if (priv->resolver == NULL)
+ priv->resolver = g_thread_create ((GThreadFunc) resolve_async,
+ uri, FALSE, NULL);
+}
+
+static void
resolve_async (YelpUri *uri)
{
YelpUriPrivate *priv = GET_PRIV (uri);
@@ -233,6 +251,40 @@ resolve_async (YelpUri *uri)
else if (g_str_has_prefix (priv->res_arg, "info:")) {
resolve_info_uri (uri);
}
+ else if (priv->res_base != NULL) {
+ YelpUriPrivate *base_priv = GET_PRIV (priv->res_base);
+ switch (base_priv->doctype) {
+ case YELP_URI_DOCUMENT_TYPE_UNRESOLVED:
+ break;
+ case YELP_URI_DOCUMENT_TYPE_DOCBOOK:
+ /* FIXME: set page_id and frag_id */
+ break;
+ case YELP_URI_DOCUMENT_TYPE_MALLARD:
+ /* FIXME: set page_id and frag_id */
+ break;
+ case YELP_URI_DOCUMENT_TYPE_MAN:
+ /* FIXME: what do we do? */
+ break;
+ case YELP_URI_DOCUMENT_TYPE_INFO:
+ /* FIXME: what do we do? */
+ break;
+ case YELP_URI_DOCUMENT_TYPE_TEXT:
+ case YELP_URI_DOCUMENT_TYPE_HTML:
+ case YELP_URI_DOCUMENT_TYPE_XHTML:
+ /* FIXME: look up a relative file */
+ break;
+ case YELP_URI_DOCUMENT_TYPE_TOC:
+ /* FIXME: what do we do? */
+ break;
+ case YELP_URI_DOCUMENT_TYPE_SEARCH:
+ /* FIXME: what do we do? */
+ break;
+ case YELP_URI_DOCUMENT_TYPE_NOT_FOUND:
+ case YELP_URI_DOCUMENT_TYPE_EXTERNAL:
+ case YELP_URI_DOCUMENT_TYPE_ERROR:
+ break;
+ }
+ }
else {
resolve_file_path (uri);
}
@@ -252,6 +304,16 @@ resolve_final (YelpUri *uri)
else
priv->doctype = YELP_URI_DOCUMENT_TYPE_ERROR;
+ if (priv->res_base) {
+ g_object_unref (priv->res_base);
+ priv->res_base = NULL;
+ }
+
+ if (priv->res_arg) {
+ g_free (priv->res_arg);
+ priv->res_arg = NULL;
+ }
+
g_signal_emit (uri, uri_signals[RESOLVED], 0);
return FALSE;
}
@@ -475,12 +537,12 @@ static void
resolve_ghelp_uri (YelpUri *uri)
{
/* ghelp:/path/to/file
- * ghelp:document
+ * ghelp:document[/file][?page][#frag]
*/
YelpUriPrivate *priv = GET_PRIV (uri);
const gchar const *helpdirs[3] = {"help", "gnome/help", NULL};
- gchar *docid = NULL;
- gchar *colon, *hash, *slash, *pageid; /* do not free */
+ gchar *document, *slash, *query, *hash;
+ gchar *colon, *c; /* do not free */
colon = strchr (priv->res_arg, ':');
if (!colon) {
@@ -488,50 +550,65 @@ resolve_ghelp_uri (YelpUri *uri)
return;
}
- colon++;
- if (*colon == '/') {
+ slash = query = hash = NULL;
+ for (c = colon; *c != '\0'; c++) {
+ if (*c == '#' && hash == NULL)
+ hash = c;
+ else if (*c == '?' && query == NULL && hash == NULL)
+ query = c;
+ else if (*c == '/' && slash == NULL && query == NULL && hash == NULL)
+ slash = c;
+ }
+
+ if (slash || query || hash)
+ document = g_strndup (colon + 1,
+ (slash ? slash : (query ? query : hash)) - colon - 1);
+ else
+ document = g_strdup (colon + 1);
+
+ if (slash && (query || hash))
+ slash = g_strndup (slash + 1,
+ (query ? query : hash) - slash - 1);
+ else if (slash)
+ slash = g_strdup (slash + 1);
+
+ if (query && hash)
+ query = g_strndup (query + 1,
+ hash - query - 1);
+ else if (query)
+ query = g_strdup (query + 1);
+
+ if (hash)
+ hash = g_strdup (hash + 1);
+
+ if (*(colon + 1) == '/') {
gchar *newuri;
- newuri = g_strdup_printf ("file:%s", colon);
+ newuri = g_strdup_printf ("file:/%s", slash);
g_free (priv->res_arg);
priv->res_arg = newuri;
resolve_file_uri (uri);
- return;
- }
-
- hash = strchr (colon, '?');
- if (!hash)
- hash = strchr (colon, '#');
- if (hash) {
- resolve_page_and_frag (uri, hash + 1);
- docid = g_strndup (colon, hash - colon);
}
else {
- docid = g_strdup (colon);
+ resolve_data_dirs (uri, helpdirs, document, slash ? slash : document);
}
- slash = strchr (docid, '/');
- if (slash) {
- *slash = '\0';
- pageid = slash + 1;
+ if (query && hash) {
+ priv->page_id = query;
+ priv->frag_id = hash;
}
- else {
- pageid = docid;
+ else if (query) {
+ priv->page_id = query;
+ if (priv->tmptype != YELP_URI_DOCUMENT_TYPE_MALLARD)
+ priv->frag_id = g_strdup (query);
}
-
- resolve_data_dirs (uri, helpdirs, docid, pageid);
-
- /* Specifying pages and anchors for Mallard documents with ghelp URIs is sort
- of hacked on. This is a touch inconsistent, but it maintains compatibility
- with the way things worked in 2.28, and ghelp URIs should be entering
- compatibility-only mode.
- */
- if (priv->tmptype == YELP_URI_DOCUMENT_TYPE_MALLARD && pageid != docid) {
- if (priv->page_id)
- g_free (priv->page_id);
- priv->page_id = g_strdup (pageid);
+ else if (hash) {
+ priv->page_id = hash;
+ priv->frag_id = g_strdup (hash);
}
- g_free (docid);
+ g_free (document);
+ g_free (slash);
+ return;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]