summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun McCance <shaunm@gnome.org>2009-06-26 13:42:48 -0500
committerShaun McCance <shaunm@gnome.org>2009-06-26 13:43:33 -0500
commitec875fad52c99c6cebd19fb7a784e97dce716001 (patch)
tree632272257020423fa623c45bc325cea757613242
parent69c0a57db9526ea5f5316ccbde6ec0c6399b40f3 (diff)
downloadyelp-ec875fad52c99c6cebd19fb7a784e97dce716001.tar.gz
Initial work on new old new YelpUri API
-rw-r--r--src/Makefile.am11
-rw-r--r--src/test-uri.c165
-rw-r--r--src/yelp-uri.c580
-rw-r--r--src/yelp-uri.h78
4 files changed, 760 insertions, 74 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index b8b8dccf..5a47fbfc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -108,6 +108,10 @@ endif
# test-transform \
# test-resolver
+check_PROGRAMS = \
+ test-document \
+ test-uri
+
test_document_SOURCES = \
yelp-debug.c yelp-debug.h \
yelp-docbook.c yelp-docbook.h \
@@ -164,6 +168,13 @@ test_resolver_CFLAGS = $(YELP_CFLAGS) $(AM_CFLAGS) $(YELP_DEFINES)
test_resolver_LDADD = $(YELP_LIBS)
test_resolver_LDFLAGS = $(AM_LDFLAGS)
+test_uri_SOURCES = \
+ yelp-uri.c yelp-uri.h \
+ test-uri.c
+test_uri_CFLAGS = $(YELP_CFLAGS) $(AM_CFLAGS) $(YELP_DEFINES)
+test_uri_LDADD = $(YELP_LIBS)
+test_uri_LDFLAGS = $(AM_LDFLAGS)
+
@INTLTOOL_SERVER_RULE@
BUILT_SOURCES = yelp-marshal.h stamp-yelp-marshal.h yelp-marshal.c server-bindings.h \
diff --git a/src/test-uri.c b/src/test-uri.c
index 6d0caeb3..4eef76df 100644
--- a/src/test-uri.c
+++ b/src/test-uri.c
@@ -1,4 +1,4 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* Copyright (C) 2002 Mikael Hallendal <micke@imendio.com>
*
@@ -21,99 +21,116 @@
*/
#include <config.h>
+#include <stdio.h>
-#include <libgnome/gnome-init.h>
-#include <libgnome/gnome-program.h>
-
-#include "yelp-utils.h"
+#include "yelp-uri.h"
static void
-print_doc_info (YelpDocInfo *doc)
+print_uri (YelpUri *uri)
{
- gchar *type, *uri, *file;
- gboolean hasfile = FALSE;
- gint i, max, tmp;
+ gchar *type, *tmp, **tmpv;
- switch (yelp_doc_info_get_type(doc)) {
- case YELP_DOC_TYPE_ERROR:
- type = "YELP_DOC_TYPE_ERROR";
- break;
- case YELP_DOC_TYPE_DOCBOOK_XML:
- type = "YELP_DOC_TYPE_DOCBOOK_XML";
- break;
- case YELP_DOC_TYPE_DOCBOOK_SGML:
- type = "YELP_DOC_TYPE_DOCBOOK_SGML";
- break;
- case YELP_DOC_TYPE_HTML:
- type = "YELP_DOC_TYPE_HTML";
- break;
- case YELP_DOC_TYPE_XHTML:
- type = "YELP_DOC_TYPE_XHTML";
- break;
- case YELP_DOC_TYPE_MAN:
- type = "YELP_DOC_TYPE_MAN";
- break;
- case YELP_DOC_TYPE_INFO:
- type = "YELP_DOC_TYPE_INFO";
- break;
- case YELP_DOC_TYPE_TOC:
- type = "YELP_DOC_TYPE_DOC";
- break;
- case YELP_DOC_TYPE_EXTERNAL:
- type = "YELP_DOC_TYPE_EXTERNAL";
- break;
+ switch (yelp_uri_get_document_type (uri)) {
+ case YELP_URI_DOCUMENT_TYPE_DOCBOOK:
+ type = "DOCBOOK";
+ break;
+ case YELP_URI_DOCUMENT_TYPE_MALLARD:
+ type = "MALLARD";
+ break;
+ case YELP_URI_DOCUMENT_TYPE_MAN:
+ type = "MAN";
+ break;
+ case YELP_URI_DOCUMENT_TYPE_INFO:
+ type = "INFO";
+ break;
+ case YELP_URI_DOCUMENT_TYPE_TEXT:
+ type = "TEXT";
+ break;
+ case YELP_URI_DOCUMENT_TYPE_HTML:
+ type = "HTML";
+ break;
+ case YELP_URI_DOCUMENT_TYPE_XHTML:
+ type = "XHTML";
+ break;
+ case YELP_URI_DOCUMENT_TYPE_TOC:
+ type = "TOC";
+ break;
+ case YELP_URI_DOCUMENT_TYPE_SEARCH:
+ type = "SEARCH";
+ break;
+ case YELP_URI_DOCUMENT_TYPE_NOT_FOUND:
+ type = "NOT FOUND";
+ break;
+ case YELP_URI_DOCUMENT_TYPE_EXTERNAL:
+ type = "EXTERNAL";
+ break;
+ case YELP_URI_DOCUMENT_TYPE_ERROR:
+ type = "ERROR";
+ break;
+ case YELP_URI_DOCUMENT_TYPE_UNKNOWN:
+ type = "UNKNOWN";
+ break;
}
- printf ("Address: %i\n", (guint) doc);
- printf ("Type: %s\n", type);
+ printf ("TYPE: %s\n", type);
+
+ tmp = yelp_uri_get_base_uri (uri);
+ if (tmp) {
+ printf ("URI: %s\n", tmp);
+ g_free (tmp);
+ }
- max = 0;
- tmp = YELP_URI_TYPE_ANY;
- while ((tmp = tmp >> 1))
- max++;
+ tmpv = yelp_uri_get_search_path (uri);
+ if (tmpv) {
+ int i;
+ for (i = 0; tmpv[i]; i++) {
+ if (i == 0)
+ printf ("PATH: %s\n", tmpv[i]);
+ else
+ printf (" %s\n", tmpv[i]);
+ }
+ g_strfreev (tmpv);
+ }
- for (i = 0; i <= max; i++) {
- uri = yelp_doc_info_get_uri (doc, NULL, 1 << i);
- if (uri) {
- printf ("URI: %s\n", uri);
- if ((1 << i) == YELP_URI_TYPE_FILE)
- hasfile = TRUE;
- g_free (uri);
- }
+ tmp = yelp_uri_get_page_id (uri);
+ if (tmp) {
+ printf ("PAGE: %s\n", tmp);
+ g_free (tmp);
}
- if (hasfile) {
- file = yelp_doc_info_get_filename (doc);
- printf ("Filename: %s\n", file);
- g_free (file);
+ tmp = yelp_uri_get_frag_id (uri);
+ if (tmp) {
+ printf ("FRAG: %s\n", tmp);
+ g_free (tmp);
}
}
int
main (int argc, char **argv)
{
- GnomeProgram *program;
- YelpDocInfo *doc;
- gint i;
-
+ YelpUri *parent = NULL;
+ YelpUri *uri = NULL;
+
+ g_type_init ();
+ g_log_set_always_fatal (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
+
if (argc < 2) {
- g_print ("Usage: test-uri uri\n");
- return 1;
+ g_print ("Usage: test-uri uri\n");
+ return 1;
}
- program = gnome_program_init (PACKAGE, VERSION,
- LIBGNOME_MODULE, argc, argv,
- GNOME_PROGRAM_STANDARD_PROPERTIES,
- NULL);
-
- for (i = 1; i < argc; i++) {
- if (i != 1)
- printf ("\n");
- doc = yelp_doc_info_get (argv[i], FALSE);
- if (doc)
- print_doc_info (doc);
- else
- printf ("Failed to load URI: %s\n", argv[i]);
+ if (argc > 2) {
+ parent = yelp_uri_resolve (argv[1]);
+ uri = yelp_uri_resolve_relative (parent, argv[2]);
+ } else {
+ uri = yelp_uri_resolve (argv[1]);
+ }
+ if (uri) {
+ print_uri (uri);
+ g_object_unref (uri);
+ }
+ if (parent) {
+ g_object_unref (parent);
}
return 0;
diff --git a/src/yelp-uri.c b/src/yelp-uri.c
new file mode 100644
index 00000000..1c402f77
--- /dev/null
+++ b/src/yelp-uri.c
@@ -0,0 +1,580 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2009 Shaun McCance <shaunm@gnome.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm@gnome.org>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "yelp-uri.h"
+#include "yelp-debug.h"
+
+#define YELP_URI_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_URI, YelpUriPriv))
+
+struct _YelpUriPriv {
+ YelpUriDocumentType doctype;
+ GFile *gfile;
+ gchar **search_path;
+ gchar *page_id;
+ gchar *frag_id;
+};
+
+static void uri_class_init (YelpUriClass *klass);
+static void uri_init (YelpUri *uri);
+static void uri_dispose (GObject *object);
+
+static void resolve_file_uri (YelpUri *ret,
+ gchar *arg);
+static void resolve_file_path (YelpUri *ret,
+ YelpUri *base,
+ gchar *arg);
+static void resolve_ghelp_uri (YelpUri *ret,
+ gchar *arg);
+static void resolve_man_uri (YelpUri *ret,
+ gchar *arg);
+static void resolve_info_uri (YelpUri *ret,
+ gchar *arg);
+static void resolve_page_and_frag (YelpUri *ret,
+ gchar *arg);
+static void resolve_common (YelpUri *ret);
+static gboolean is_man_path (gchar *uri,
+ gchar *encoding);
+
+static GObjectClass *parent_class;
+
+
+/******************************************************************************/
+
+static const gchar *mancats[] = {
+ "0p",
+ "1", "1p", "1g", "1t", "1x", "1ssl", "1m",
+ "2",
+ "3", "3o", "3t", "3p", "3blt", "3nas", "3form", "3menu", "3tiff", "3ssl", "3readline",
+ "3ncurses", "3curses", "3f", "3pm", "3perl", "3qt", "3x", "3X11",
+ "4", "4x",
+ "5", "5snmp", "5x", "5ssl",
+ "6", "6x",
+ "7", "7gcc", "7x", "7ssl",
+ "8", "8l", "9", "0p",
+ NULL
+};
+
+/******************************************************************************/
+
+GType
+yelp_uri_get_type (void)
+{
+ static GType type = 0;
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (YelpUriClass),
+ NULL, NULL,
+ (GClassInitFunc) uri_class_init,
+ NULL, NULL,
+ sizeof (YelpUri),
+ 0,
+ (GInstanceInitFunc) uri_init,
+ };
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "YelpUri",
+ &info, 0);
+ }
+ return type;
+}
+
+static void
+uri_class_init (YelpUriClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ parent_class = g_type_class_peek_parent (klass);
+ object_class->dispose = uri_dispose;
+ g_type_class_add_private (klass, sizeof (YelpUriPriv));
+}
+
+static void
+uri_init (YelpUri *uri)
+{
+ uri->priv = YELP_URI_GET_PRIVATE (uri);
+}
+
+static void
+uri_dispose (GObject *object)
+{
+ YelpUri *uri = YELP_URI (object);
+
+ if (uri->priv->gfile)
+ g_object_unref (uri->priv->gfile);
+ g_strfreev (uri->priv->search_path);
+ g_free (uri->priv->page_id);
+ g_free (uri->priv->frag_id);
+
+ parent_class->dispose (object);
+}
+
+/******************************************************************************/
+
+YelpUri *
+yelp_uri_resolve (gchar *arg)
+{
+ return yelp_uri_resolve_relative (NULL, arg);
+}
+
+YelpUri *
+yelp_uri_resolve_relative (YelpUri *base, gchar *arg)
+{
+ YelpUri *ret;
+
+ ret = (YelpUri *) g_object_new (YELP_TYPE_URI, NULL);
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_UNKNOWN;
+
+ if (g_str_has_prefix (arg, "ghelp:") || g_str_has_prefix (arg, "gnome-help:")) {
+ resolve_ghelp_uri (ret, arg);
+ }
+ else if (g_str_has_prefix (arg, "file:")) {
+ resolve_file_uri (ret, arg);
+ }
+ else if (g_str_has_prefix (arg, "man:")) {
+ resolve_man_uri (ret, arg);
+ }
+ else if (g_str_has_prefix (arg, "info:")) {
+ resolve_info_uri (ret, arg);
+ }
+ else if (strchr (arg, ':')) {
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_EXTERNAL;
+ ret->priv->gfile = g_file_new_for_uri (arg);
+ TRUE;
+ }
+ else {
+ resolve_file_path (ret, base, arg);
+ }
+
+ return ret;
+}
+
+YelpUriDocumentType
+yelp_uri_get_document_type (YelpUri *uri)
+{
+ return uri->priv->doctype;
+}
+
+gchar *
+yelp_uri_get_base_uri (YelpUri *uri)
+{
+ return uri->priv->gfile ? g_file_get_uri (uri->priv->gfile) : NULL;
+}
+
+gchar **
+yelp_uri_get_search_path (YelpUri *uri)
+{
+ return g_strdupv (uri->priv->search_path);
+}
+
+gchar *
+yelp_uri_get_page_id (YelpUri *uri)
+{
+ return g_strdup (uri->priv->page_id);
+}
+
+gchar *
+yelp_uri_get_frag_id (YelpUri *uri)
+{
+ return g_strdup (uri->priv->frag_id);
+}
+
+/******************************************************************************/
+
+static void
+resolve_file_uri (YelpUri *ret, gchar *arg)
+{
+ gchar *uri;
+ gchar *hash;
+
+ hash = strchr (arg, '#');
+ if (hash)
+ uri = g_strndup (arg, hash - arg);
+ else
+ uri = arg;
+
+ ret->priv->gfile = g_file_new_for_uri (uri);
+
+ if (hash) {
+ resolve_page_and_frag (ret, hash + 1);
+ g_free (uri);
+ }
+
+ resolve_common (ret);
+}
+
+static void
+resolve_file_path (YelpUri *ret, YelpUri *base, gchar *arg)
+{
+ gchar *path;
+ gchar *hash;
+
+ hash = strchr (arg, '#');
+ if (hash)
+ path = g_strndup (arg, hash - arg);
+ else
+ path = arg;
+
+ if (arg[0] == '/') {
+ ret->priv->gfile = g_file_new_for_path (path);
+ }
+ else if (base && base->priv->gfile) {
+ ret->priv->gfile = g_file_resolve_relative_path (base->priv->gfile, path);
+ }
+ else {
+ gchar *cur;
+ GFile *curfile;
+ cur = g_get_current_dir ();
+ curfile = g_file_new_for_path (cur);
+ ret->priv->gfile = g_file_resolve_relative_path (curfile, path);
+ g_object_unref (curfile);
+ g_free (cur);
+ }
+
+ if (hash) {
+ resolve_page_and_frag (ret, hash + 1);
+ g_free (path);
+ }
+
+ resolve_common (ret);
+}
+
+static void
+resolve_ghelp_uri (YelpUri *ret, gchar *arg)
+{
+ /* ghelp:/path/to/file
+ * ghelp:document
+ */
+ gchar *colon;
+
+ colon = strchr (arg, ':');
+ if (!colon) {
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_ERROR;
+ return;
+ }
+
+ colon++;
+ if (*colon == '/') {
+ gchar *newuri;
+ newuri = g_strdup_printf ("file:%s", colon);
+ resolve_file_uri (ret, newuri);
+ g_free (newuri);
+ return;
+ }
+
+}
+
+static void
+resolve_man_uri (YelpUri *ret, gchar *arg)
+{
+ /* man:/path/to/file
+ * man:name(section)
+ * man:name.section
+ * man:name
+ */
+ static gchar **manpath = NULL;
+ const gchar * const * langs = g_get_language_names ();
+ gchar *newarg = NULL;
+ gchar *section = NULL;
+ gchar *name = NULL;
+ gchar *fullpath = NULL;
+ /* not to be freed */
+ gchar *colon, *hash;
+ gchar *lbrace = NULL;
+ gchar *rbrace = NULL;
+ gint i, j, k;
+
+ if (g_str_has_prefix (arg, "man:/")) {
+ gchar *newuri;
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_MAN;
+ newuri = g_strdup_printf ("file:%s", arg + 4);
+ resolve_file_uri (ret, newuri);
+ g_free (newuri);
+ return;
+ }
+
+ if (!manpath) {
+ /* Initialize manpath only once */
+ const gchar *env = g_getenv ("MANPATH");
+ if (!env || env[0] == '\0')
+ env = "/usr/share/man:/usr/man:/usr/local/share/man:/usr/local/man";
+ manpath = g_strsplit (env, ":", 0);
+ }
+
+ colon = strchr (arg, ':');
+ if (colon)
+ colon++;
+ else
+ colon = arg;
+
+ hash = strchr (colon, '#');
+ if (hash)
+ newarg = g_strndup (colon, hash - colon);
+ else
+ newarg = g_strdup (colon);
+
+ lbrace = strrchr (newarg, '(');
+ if (lbrace) {
+ rbrace = strrchr (lbrace, ')');
+ if (rbrace) {
+ section = g_strndup (lbrace + 1, rbrace - lbrace - 1);
+ name = g_strndup (newarg, lbrace - newarg);
+ } else {
+ section = NULL;
+ name = strdup (newarg);
+ }
+ } else {
+ lbrace = strrchr (newarg, '.');
+ if (lbrace) {
+ section = strdup (lbrace + 1);
+ name = g_strndup (newarg, lbrace - newarg);
+ } else {
+ section = NULL;
+ name = strdup (newarg);
+ }
+ }
+
+ for (i = 0; langs[i]; i++) {
+ for (j = 0; manpath[j]; j++) {
+ gchar *langdir;
+ if (g_str_equal (langs[i], "C"))
+ langdir = g_strdup (manpath[j]);
+ else
+ langdir = g_strconcat (manpath[j], "/", langs[i], NULL);
+ if (!g_file_test (langdir, G_FILE_TEST_IS_DIR)) {
+ g_free (langdir);
+ continue;
+ }
+
+ for (k = 0; section ? k == 0 : mancats[k] != NULL; k++) {
+ gchar *sectiondir;
+ if (section)
+ sectiondir = g_strconcat ("man", section, NULL);
+ else
+ sectiondir = g_strconcat ("man", mancats[k], NULL);
+
+ fullpath = g_strconcat (langdir, "/", sectiondir,
+ "/", name, ".", sectiondir + 3,
+ NULL);
+ if (g_file_test (fullpath, G_FILE_TEST_IS_REGULAR))
+ goto gotit;
+ g_free (fullpath);
+
+ fullpath = g_strconcat (langdir, "/", sectiondir,
+ "/", name, ".", sectiondir + 3, ".gz",
+ NULL);
+ if (g_file_test (fullpath, G_FILE_TEST_IS_REGULAR))
+ goto gotit;
+ g_free (fullpath);
+
+ fullpath = g_strconcat (langdir, "/", sectiondir,
+ "/", name, ".", sectiondir + 3, ".bz2",
+ NULL);
+ if (g_file_test (fullpath, G_FILE_TEST_IS_REGULAR))
+ goto gotit;
+ g_free (fullpath);
+
+ fullpath = g_strconcat (langdir, "/", sectiondir,
+ "/", name, ".", sectiondir + 3, ".lzma",
+ NULL);
+ if (g_file_test (fullpath, G_FILE_TEST_IS_REGULAR))
+ goto gotit;
+ g_free (fullpath);
+
+ fullpath = NULL;
+ gotit:
+ g_free (sectiondir);
+ if (fullpath)
+ break;
+ }
+ g_free (langdir);
+ if (fullpath)
+ break;
+ }
+ if (fullpath)
+ break;
+ }
+
+ if (fullpath) {
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_MAN;
+ ret->priv->gfile = g_file_new_for_path (fullpath);
+ resolve_common (ret);
+ g_free (fullpath);
+ } else {
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_NOT_FOUND;
+ }
+
+ if (hash)
+ resolve_page_and_frag (ret, hash + 1);
+
+ g_free (newarg);
+}
+
+static void
+resolve_info_uri (YelpUri *ret, gchar *arg)
+{
+ /* FIXME */
+}
+
+static void
+resolve_page_and_frag (YelpUri *ret, gchar *arg)
+{
+ gchar *hash;
+
+ if (!arg || arg[0] == '\0')
+ return;
+
+ hash = strchr (arg, '#');
+ if (hash) {
+ ret->priv->page_id = g_strndup (arg, hash - arg);
+ ret->priv->frag_id = g_strdup (hash + 1);
+ } else {
+ ret->priv->page_id = g_strdup (arg);
+ ret->priv->frag_id = g_strdup (arg);
+ }
+ return;
+}
+
+static void
+resolve_common (YelpUri *ret)
+{
+ GFileInfo *info;
+ GError *error = NULL;
+
+ info = g_file_query_info (ret->priv->gfile,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE ","
+ G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE,
+ G_FILE_QUERY_INFO_NONE,
+ NULL, &error);
+ if (error) {
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_NOT_FOUND;
+ else
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_ERROR;
+ g_error_free (error);
+ return;
+ }
+
+ if (ret->priv->search_path == NULL) {
+ if (g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE) ==
+ G_FILE_TYPE_DIRECTORY) {
+ ret->priv->search_path = g_new0 (gchar *, 2);
+ ret->priv->search_path[0] = g_file_get_path (ret->priv->gfile);
+ } else {
+ GFile *parent = g_file_get_parent (ret->priv->gfile);
+ ret->priv->search_path = g_new0 (gchar *, 2);
+ ret->priv->search_path[0] = g_file_get_path (parent);
+ g_object_unref (parent);
+ }
+ }
+
+ if (ret->priv->doctype == YELP_URI_DOCUMENT_TYPE_UNKNOWN) {
+ if (g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE) ==
+ G_FILE_TYPE_DIRECTORY) {
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_MALLARD;
+ }
+ else {
+ gchar *basename;
+ const gchar *mime_type = g_file_info_get_attribute_string (info,
+ G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE);
+ basename = g_file_get_basename (ret->priv->gfile);
+ if (g_str_equal (mime_type, "text/xml") ||
+ g_str_equal (mime_type, "application/docbook+xml") ||
+ g_str_equal (mime_type, "application/xml")) {
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_DOCBOOK;
+ }
+ else if (g_str_equal (mime_type, "text/html")) {
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_HTML;
+ }
+ else if (g_str_equal (mime_type, "application/xhtml+xml")) {
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_XHTML;
+ }
+ else if (g_str_equal (mime_type, "application/x-gzip")) {
+ if (g_str_has_suffix (basename, ".info.gz"))
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_INFO;
+ else if (is_man_path (basename, "gz"))
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_MAN;
+ }
+ else if (g_str_equal (mime_type, "application/x-bzip")) {
+ if (g_str_has_suffix (basename, ".info.bz2"))
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_INFO;
+ else if (is_man_path (basename, "bz2"))
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_MAN;
+ }
+ else if (g_str_equal (mime_type, "application/x-lzma")) {
+ if (g_str_has_suffix (basename, ".info.lzma"))
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_INFO;
+ else if (is_man_path (basename, "lzma"))
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_MAN;
+ }
+ else if (g_str_equal (mime_type, "application/octet-stream")) {
+ if (g_str_has_suffix (basename, ".info"))
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_INFO;
+ else if (is_man_path (basename, NULL))
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_MAN;
+ }
+ else if (g_str_equal (mime_type, "text/plain")) {
+ if (g_str_has_suffix (basename, ".info"))
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_INFO;
+ else if (is_man_path (basename, NULL))
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_MAN;
+ else
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_TEXT;
+ }
+ else {
+ ret->priv->doctype = YELP_URI_DOCUMENT_TYPE_EXTERNAL;
+ }
+ }
+ }
+}
+
+static gboolean
+is_man_path (gchar *path, gchar *encoding)
+{
+ gchar **iter = (gchar **) mancats;
+
+ if (encoding && *encoding) {
+ while (iter && *iter) {
+ gchar *ending = g_strdup_printf ("%s.%s", *iter, encoding);
+ if (g_str_has_suffix (path, ending)) {
+ g_free (ending);
+ return TRUE;
+ }
+ g_free (ending);
+ iter++;
+ }
+ } else {
+ while (iter && *iter) {
+ if (g_str_has_suffix (path, *iter)) {
+ return TRUE;
+ }
+ iter++;
+ }
+ }
+ return FALSE;
+}
diff --git a/src/yelp-uri.h b/src/yelp-uri.h
new file mode 100644
index 00000000..9562f509
--- /dev/null
+++ b/src/yelp-uri.h
@@ -0,0 +1,78 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2009 Shaun McCance <shaunm@gnome.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm@gnome.org>
+ */
+
+#ifndef __YELP_URI_H__
+#define __YELP_URI_H__
+
+#include <glib-object.h>
+
+#define YELP_TYPE_URI (yelp_uri_get_type ())
+#define YELP_URI(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_URI, YelpUri))
+#define YELP_URI_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_URI, YelpUriClass))
+#define YELP_IS_URI(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_URI))
+#define YELP_IS_URI_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_URI))
+#define YELP_URI_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_URI, YelpUriClass))
+
+typedef struct _YelpUri YelpUri;
+typedef struct _YelpUriClass YelpUriClass;
+typedef struct _YelpUriPriv YelpUriPriv;
+
+typedef enum {
+ YELP_URI_DOCUMENT_TYPE_UNKNOWN = 0,
+ YELP_URI_DOCUMENT_TYPE_DOCBOOK,
+ YELP_URI_DOCUMENT_TYPE_MALLARD,
+ YELP_URI_DOCUMENT_TYPE_MAN,
+ YELP_URI_DOCUMENT_TYPE_INFO,
+ YELP_URI_DOCUMENT_TYPE_TEXT,
+ YELP_URI_DOCUMENT_TYPE_HTML,
+ YELP_URI_DOCUMENT_TYPE_XHTML,
+ YELP_URI_DOCUMENT_TYPE_TOC,
+ YELP_URI_DOCUMENT_TYPE_SEARCH,
+ YELP_URI_DOCUMENT_TYPE_NOT_FOUND,
+ YELP_URI_DOCUMENT_TYPE_EXTERNAL,
+ YELP_URI_DOCUMENT_TYPE_ERROR
+} YelpUriDocumentType;
+
+struct _YelpUri {
+ GObject parent;
+ YelpUriPriv *priv;
+};
+
+struct _YelpUriClass {
+ GObjectClass parent_class;
+};
+
+
+GType yelp_uri_get_type (void);
+
+YelpUri * yelp_uri_resolve (gchar *arg);
+YelpUri * yelp_uri_resolve_relative (YelpUri *base,
+ gchar *arg);
+
+YelpUriDocumentType yelp_uri_get_document_type (YelpUri *uri);
+gchar * yelp_uri_get_base_uri (YelpUri *uri);
+gchar ** yelp_uri_get_search_path (YelpUri *uri);
+gchar * yelp_uri_get_page_id (YelpUri *uri);
+gchar * yelp_uri_get_frag_id (YelpUri *uri);
+
+
+#endif /* __YELP_URI_H__ */