From 3e436f20450845cd7b7a6516ce2e1fdcb8047182 Mon Sep 17 00:00:00 2001 From: Shaun McCance Date: Thu, 6 Nov 2003 17:41:37 +0000 Subject: - New GObjectified URI code * src/test-uri: * src/yelp-uri.c: * src/yelp-uri.h: - New GObjectified URI code * src/test-pager.c: * src/yelp-db-pager.c: * src/yelp-db-pager.h: * src/yelp-pager.c: * src/yelp-pager.h: - New transformation code --- ChangeLog | 14 + src/test-pager.c | 78 +++++ src/test-uri.c | 129 +++++--- src/yelp-db-pager.c | 580 ++++++++++++++++++++++++++++++++++ src/yelp-db-pager.h | 54 ++++ src/yelp-pager.c | 535 ++++++++++++++++++++++++++++++++ src/yelp-pager.h | 94 ++++++ src/yelp-uri.c | 876 ++++++++++++++++++++++++++-------------------------- src/yelp-uri.h | 85 +++-- 9 files changed, 1937 insertions(+), 508 deletions(-) create mode 100644 src/test-pager.c create mode 100644 src/yelp-db-pager.c create mode 100644 src/yelp-db-pager.h create mode 100644 src/yelp-pager.c create mode 100644 src/yelp-pager.h diff --git a/ChangeLog b/ChangeLog index fc0a5977..7b6967a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2003-11-06 Shaun McCance + + * src/test-uri: + * src/yelp-uri.c: + * src/yelp-uri.h: + - New GObjectified URI code + + * src/test-pager.c: + * src/yelp-db-pager.c: + * src/yelp-db-pager.h: + * src/yelp-pager.c: + * src/yelp-pager.h: + - New transformation code + 2003-10-12 Shaun McCance * src/yelp-cache.c: diff --git a/src/test-pager.c b/src/test-pager.c new file mode 100644 index 00000000..2fb00335 --- /dev/null +++ b/src/test-pager.c @@ -0,0 +1,78 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2002 Shaun McCance + * + * 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, Cambridge, MA 02139, USA. + * + * Author: Shaun McCance + */ + +#include +#include + +#include "yelp-pager.h" +#include "yelp-db-pager.h" + +void list_sections (YelpPager *pager); +void save_chunk (YelpPager *pager, + gchar *chunk_id); + +gint +main (gint argc, gchar **argv) +{ + YelpURI *uri; + YelpPager *pager; + + if (argc < 2) { + return 1; + } + + g_type_init (); + g_thread_init (NULL); + + uri = yelp_uri_new (argv[1]); + pager = yelp_db_pager_new (uri); + + g_signal_connect (pager, + "sections", + G_CALLBACK (list_sections), + NULL); + + g_signal_connect (pager, + "chunk", + G_CALLBACK (save_chunk), + NULL); + + yelp_pager_start (pager); + + gtk_main (); + + return 0; +} + +void save_chunk (YelpPager *pager, gchar *chunk_id) +{ + printf("save_chunk: %s\n", chunk_id); +} + +void +list_sections (YelpPager *pager) +{ + const GtkTreeModel *sections; + + sections = yelp_pager_get_sections (pager); + + printf ("%i\n", gtk_tree_model_get_n_columns (sections)); +} diff --git a/src/test-uri.c b/src/test-uri.c index 544db2d2..7f2d16d0 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: 8 -*- */ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* * Copyright (C) 2002 Mikael Hallendal * @@ -26,68 +26,115 @@ #include #include - #include "yelp-uri.h" static void print_uri (YelpURI *uri) { - gchar *str_uri; + gchar *type; + gchar *str_uri; - g_print ("URI_TYPE : %d\n", yelp_uri_get_type (uri)); - g_print ("URI_PATH : %s\n", yelp_uri_get_path (uri)); - g_print ("URI_SECTION: %s\n", yelp_uri_get_section (uri)); - - str_uri = yelp_uri_to_string (uri); - g_print ("URI_TO_STRING: %s\n", str_uri); - g_free (str_uri); + switch (yelp_uri_get_resource_type (uri)) { + case YELP_URI_TYPE_UNKNOWN: + type = "YELP_URI_TYPE_UNKNOWN"; + break; + case YELP_URI_TYPE_RELATIVE: + type = "YELP_URI_TYPE_RELATIVE"; + break; + case YELP_URI_TYPE_DOCBOOK_XML: + type = "YELP_URI_TYPE_DOCBOOK_XML"; + break; + case YELP_URI_TYPE_DOCBOOK_SGML: + type = "YELP_URI_TYPE_DOCBOOK_SGML"; + break; + case YELP_URI_TYPE_GHELP: + type = "YELP_URI_TYPE_GHELP"; + break; + case YELP_URI_TYPE_HTML: + type = "YELP_URI_TYPE_HTML"; + break; + case YELP_URI_TYPE_MAN: + type = "YELP_URI_TYPE_MAN"; + break; + case YELP_URI_TYPE_INFO: + type = "YELP_URI_TYPE_INFO"; + break; + case YELP_URI_TYPE_TOC: + type = "YELP_URI_TYPE_TOC"; + break; + case YELP_URI_TYPE_PATH: + type = "YELP_URI_TYPE_PATH"; + break; + case YELP_URI_TYPE_FILE: + type = "YELP_URI_TYPE_FILE"; + break; + default: + type = NULL; + break; + } + g_print ("TYPE : %s\n", type); + g_print ("PATH : %s\n", yelp_uri_get_path (uri)); + if (yelp_uri_get_fragment (uri)) + g_print ("FRAGMENT : %s\n", yelp_uri_get_fragment (uri)); + g_print ("\n"); + + /* + str_uri = yelp_uri_to_string (uri); + g_print ("URI_TO_STRING: %s\n", str_uri); + g_free (str_uri); + */ } int main (int argc, char **argv) { - GnomeProgram *program; - YelpURI *uri; - YelpURI *rel_uri; + GnomeProgram *program; + YelpURI *uri; + YelpURI *rel_uri; - if (argc < 2) { - g_print ("Usage: test-uri uri\n"); - return 1; - } + if (argc < 2) { + g_print ("Usage: test-uri uri\n"); + return 1; + } + + program = gnome_program_init (PACKAGE, VERSION, + LIBGNOME_MODULE, + argc, argv, + GNOME_PROGRAM_STANDARD_PROPERTIES, + NULL); - program = gnome_program_init (PACKAGE, VERSION, - LIBGNOME_MODULE, - argc, argv, - GNOME_PROGRAM_STANDARD_PROPERTIES, - NULL); + gnome_vfs_init (); - gnome_vfs_init (); + uri = yelp_uri_new (argv[1]); - uri = yelp_uri_new (argv[1]); - - if (!yelp_uri_exists (uri)) { - g_print ("URI (%s) does not exist\n", argv[1]); + /* + if (!yelp_uri_exists (uri)) { + g_print ("URI (%s) does not exist\n", argv[1]); - return 1; - } + return 1; + } + */ - print_uri (uri); + g_print ("STRING : %s\n", argv[1]); + print_uri (uri); - g_print ("---------------\n"); + /* + g_print ("---------------\n"); - rel_uri = yelp_uri_get_relative (uri, "?link"); - print_uri (rel_uri); - yelp_uri_unref (rel_uri); + rel_uri = yelp_uri_get_relative (uri, "?link"); + print_uri (rel_uri); + g_object_unref (rel_uri); - g_print ("---------------\n"); + g_print ("---------------\n"); - rel_uri = yelp_uri_get_relative (uri, "link"); - print_uri (rel_uri); - yelp_uri_unref (rel_uri); + rel_uri = yelp_uri_get_relative (uri, "link"); + print_uri (rel_uri); + g_object_unref (rel_uri); + */ - yelp_uri_unref (uri); + g_object_unref (uri); - gnome_vfs_shutdown (); + gnome_vfs_shutdown (); - return 0; + return 0; } diff --git a/src/yelp-db-pager.c b/src/yelp-db-pager.c new file mode 100644 index 00000000..da8a2642 --- /dev/null +++ b/src/yelp-db-pager.c @@ -0,0 +1,580 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2003 Shaun McCance + * + * 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 + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "yelp-db-pager.h" + +#define YELP_NAMESPACE "http://www.gnome.org/yelp/ns" + +#define DB_STYLESHEET_PATH DATADIR"/sgml/docbook/yelp/" +#define DB_STYLESHEET DB_STYLESHEET_PATH"db2html.xsl" + +#define MAX_CHUNK_DEPTH 2 + +#define d(x) + +struct _YelpDBPagerPriv { + GMutex *sects_mutex; + GtkTreeModel *sects; + + GMutex *frags_mutex; + GHashTable *frags_hash; +}; + +typedef struct _DBWalker DBWalker; +struct _DBWalker { + YelpDBPager *pager; + gchar *chunk_id; + + xmlDocPtr doc; + xmlNodePtr cur; + + GtkTreeIter *iter; + + gint depth; +}; + +static void db_pager_class_init (YelpDBPagerClass *klass); +static void db_pager_init (YelpDBPager *pager); +static void db_pager_dispose (GObject *gobject); + +void db_pager_process (YelpPager *pager); +void db_pager_cancel (YelpPager *pager); +const gchar * db_pager_resolve_uri (YelpPager *pager, + YelpURI *uri); +const GtkTreeModel * db_pager_get_sections (YelpPager *pager); + +static void walker_walk_xml (DBWalker *walker); +gboolean walker_is_chunk (DBWalker *walker); + +gboolean xml_is_division (xmlNodePtr node); +gboolean xml_is_info (xmlNodePtr node); +gchar * xml_get_title (xmlNodePtr node); + +void xslt_yelp_document (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltStylePreCompPtr comp); +void xslt_yelp_cache (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltStylePreCompPtr comp); + +static YelpPagerClass *parent_class; + +GType +yelp_db_pager_get_type (void) +{ + static GType type = 0; + + if (!type) { + static const GTypeInfo info = { + sizeof (YelpDBPagerClass), + NULL, + NULL, + (GClassInitFunc) db_pager_class_init, + NULL, + NULL, + sizeof (YelpDBPager), + 0, + (GInstanceInitFunc) db_pager_init, + }; + type = g_type_register_static (YELP_TYPE_PAGER, + "YelpDBPager", + &info, 0); + } + return type; +} + +static void +db_pager_class_init (YelpDBPagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + YelpPagerClass *pager_class = YELP_PAGER_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->dispose = db_pager_dispose; + + pager_class->process = db_pager_process; + pager_class->cancel = db_pager_cancel; + pager_class->resolve_uri = db_pager_resolve_uri; + pager_class->get_sections = db_pager_get_sections; +} + +static void +db_pager_init (YelpDBPager *pager) +{ + YelpDBPagerPriv *priv; + + priv = g_new0 (YelpDBPagerPriv, 1); + pager->priv = priv; + + pager->priv->sects_mutex = g_mutex_new (); + pager->priv->sects = NULL; + + pager->priv->frags_mutex = g_mutex_new (); + pager->priv->frags_hash = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); +} + +static void +db_pager_dispose (GObject *object) +{ + YelpDBPager *pager = YELP_DB_PAGER (object); + + g_mutex_free (pager->priv->sects_mutex); + g_object_unref (pager->priv->sects); + + g_mutex_free (pager->priv->frags_mutex); + g_hash_table_destroy (pager->priv->frags_hash); + + g_free (pager->priv); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +/******************************************************************************/ + +/** + * yelp_db_pager_new: + * @uri: the URI of the DocBook document to process. + * + * Creates a new YelpDBPager. + **/ +YelpPager * +yelp_db_pager_new (YelpURI *uri) +{ + YelpDBPager *pager; + + g_return_val_if_fail (YELP_IS_URI (uri), NULL); + + pager = (YelpDBPager *) g_object_new (YELP_TYPE_DB_PAGER, + "uri", uri, + NULL); + + g_mutex_lock (pager->priv->sects_mutex); + pager->priv->sects = + GTK_TREE_MODEL (gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_STRING)); + g_mutex_unlock (pager->priv->sects_mutex); + + return (YelpPager *) pager; +} + +void +db_pager_process (YelpPager *pager) +{ + const YelpURI *uri = yelp_pager_get_uri (pager); + gchar *uri_str = yelp_uri_get_path ((YelpURI *) uri); + DBWalker *walker; + GError *error; + + xmlParserCtxtPtr ctxt; + xsltStylesheetPtr stylesheet; + xsltTransformContextPtr tctxt; + + gchar *uri_slash; + gchar *doc_name; + gchar *doc_path; + const gchar *params[9]; + + g_return_if_fail (pager != NULL); + g_return_if_fail (YELP_IS_DB_PAGER (pager)); + + g_object_ref (pager); + + ctxt = xmlCreateFileParserCtxt (uri_str); + ctxt->replaceEntities = TRUE; + ctxt->validate = FALSE; + ctxt->loadsubset = TRUE; + xmlParseDocument (ctxt); + + if (ctxt->myDoc == NULL) { + error = NULL; + yelp_pager_error (pager, error); + + return; + } + + walker = g_new0 (DBWalker, 1); + walker->pager = YELP_DB_PAGER (pager); + walker->doc = ctxt->myDoc; + walker->cur = xmlDocGetRootElement (walker->doc); + + walker_walk_xml (walker); + + yelp_pager_lock_state (pager); + g_signal_emit_by_name (pager, "sections"); + yelp_pager_unlock_state (pager); + + uri_slash = g_strrstr (uri_str, "/"); + doc_name = g_strndup (uri_str, uri_slash - uri_str + 1); + doc_path = g_strdup (uri_slash + 1); + + params[0] = "doc_name"; + params[1] = g_strconcat("\"", doc_name, "\"", NULL) ; + params[2] = "doc_path"; + params[3] = g_strconcat("\"file://", doc_path, "/\"", NULL) ; + params[4] = "stylesheet_path"; + params[5] = g_strconcat("\"file://", DB_STYLESHEET_PATH, "/\"", NULL) ; + params[6] = "chunk_depth"; + params[7] = "2"; + params[8] = NULL; + + stylesheet = xsltParseStylesheetFile (DB_STYLESHEET); + tctxt = xsltNewTransformContext (stylesheet, + ctxt->myDoc); + tctxt->_private = pager; + xsltRegisterExtElement (tctxt, + "document", + YELP_NAMESPACE, + (xsltTransformFunction) xslt_yelp_document); + xsltRegisterExtElement (tctxt, + "cache", + YELP_NAMESPACE, + (xsltTransformFunction) xslt_yelp_cache); + xsltApplyStylesheetUser (stylesheet, + ctxt->myDoc, + params, + NULL, NULL, + tctxt); + + xsltFreeStylesheet (stylesheet); + xmlFreeParserCtxt (ctxt); + + g_free (doc_name); + g_free (doc_path); + + yelp_pager_lock_state (pager); + yelp_pager_set_state (pager, YELP_PAGER_STATE_FINISH); + g_signal_emit_by_name (pager, "finish"); + yelp_pager_unlock_state (pager); + + g_object_unref (pager); +} + +void +db_pager_cancel (YelpPager *pager) +{ +} + +const gchar * +db_pager_resolve_uri (YelpPager *pager, YelpURI *uri) +{ + YelpDBPager *db_pager; + gchar *frag_id; + const gchar *chunk_id; + + g_return_val_if_fail (pager != NULL, NULL); + g_return_val_if_fail (YELP_IS_DB_PAGER (pager), NULL); + + db_pager = YELP_DB_PAGER (pager); + + frag_id = yelp_uri_get_fragment (uri); + + g_mutex_lock (db_pager->priv->frags_mutex); + chunk_id = + (const gchar *) g_hash_table_lookup (db_pager->priv->frags_hash, + frag_id); + g_mutex_unlock (db_pager->priv->frags_mutex); + + g_free (frag_id); + return chunk_id; +} + +const GtkTreeModel * +db_pager_get_sections (YelpPager *pager) +{ + g_return_val_if_fail (pager != NULL, NULL); + g_return_val_if_fail (YELP_IS_DB_PAGER (pager), NULL); + + return YELP_DB_PAGER (pager)->priv->sects; +} + +void +xslt_yelp_document (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltStylePreCompPtr comp) +{ + GError *error; + xmlChar *chunk_id = NULL; + xmlChar *chunk_buf; + gint buf_size; + YelpPager *pager; + xsltStylesheetPtr style = NULL; + const char *old_outfile; + xmlDocPtr new_doc, old_doc; + xmlNodePtr old_insert; + + if (!ctxt || !node || !inst || !comp) + return; + + pager = (YelpPager *) ctxt->_private; + + chunk_id = xsltEvalAttrValueTemplate (ctxt, inst, + (const xmlChar *) "href", + NULL); + if (chunk_id == NULL) { + xsltTransformError (ctxt, NULL, inst, + _("No href attribute found on yelp:document")); + error = NULL; + yelp_pager_error (pager, error); + + return; + } + + old_outfile = ctxt->outputFile; + old_doc = ctxt->output; + old_insert = ctxt->insert; + ctxt->outputFile = (const char *) chunk_id; + + style = xsltNewStylesheet (); + if (style == NULL) { + xsltTransformError (ctxt, NULL, inst, + _("Out of memory")); + error = NULL; + yelp_pager_error (pager, error); + + return; + } + + style->omitXmlDeclaration = TRUE; + + new_doc = xmlNewDoc ("1.0"); + new_doc->charset = XML_CHAR_ENCODING_UTF8; + ctxt->output = new_doc; + ctxt->insert = (xmlNodePtr) new_doc; + + xsltApplyOneTemplate (ctxt, node, inst->children, NULL, NULL); + + xmlDocDumpFormatMemory (new_doc, &chunk_buf, &buf_size, 0); + + ctxt->outputFile = old_outfile; + ctxt->output = old_doc; + ctxt->insert = old_insert; + + yelp_pager_lock_state (pager); + + yelp_pager_add_chunk (pager, chunk_id, chunk_buf); + g_signal_emit_by_name (pager, "chunk", chunk_id); + + yelp_pager_unlock_state (pager); + + xmlFreeDoc (new_doc); +} + +void +xslt_yelp_cache (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltStylePreCompPtr comp) +{ +} + +static void +walker_walk_xml (DBWalker *walker) +{ + xmlChar *id = NULL; + xmlChar *title = NULL; + gchar *old_id; + xmlNodePtr cur; + xmlNodePtr old_cur; + GtkTreeIter iter; + GtkTreeIter *old_iter; + YelpDBPagerPriv *priv = walker->pager->priv; + + id = xmlGetProp (walker->cur, "id"); + + if (walker_is_chunk (walker)) { + if (xml_is_info (walker->cur)) { + xmlFree (id); + id = g_strdup ("titlepage"); + } + + title = xml_get_title (walker->cur); + + if (id) { + gtk_tree_store_append (GTK_TREE_STORE (priv->sects), + &iter, walker->iter); + + gtk_tree_store_set (GTK_TREE_STORE (priv->sects), + &iter, + 0, g_strdup (id), + 1, g_strdup (title), + -1); + + old_id = walker->chunk_id; + walker->chunk_id = id; + + old_iter = walker->iter; + walker->iter = &iter; + } + } + + old_cur = walker->cur; + walker->depth++; + + if (id) { + g_mutex_lock (priv->frags_mutex); + g_hash_table_insert (priv->frags_hash, + g_strdup (id), + g_strdup (walker->chunk_id)); + g_mutex_unlock (priv->frags_mutex); + } + + cur = walker->cur->children; + while (cur != NULL) { + if (cur->type == XML_ELEMENT_NODE) { + walker->cur = cur; + walker_walk_xml (walker); + } + cur = cur->next; + } + + walker->depth--; + walker->cur = old_cur; + + if (walker_is_chunk (walker) && id) { + walker->iter = old_iter; + walker->chunk_id = old_id; + } + + xmlFree (id); + xmlFree (title); +} + +gchar * +xml_get_title (xmlNodePtr node) +{ + gchar *title = NULL; + xmlNodePtr cur; + + if (xml_is_info (node)) + title = _("Titlepage"); + else if (node->parent->type == XML_DOCUMENT_NODE) + title = _("Contents"); + else { + cur = node->children; + while (cur != NULL) { + if (cur->name == (xmlChar *) "title") { + if (title) + g_free (title); + title = xmlNodeGetContent (cur); + } + else if (cur->name == (xmlChar *) "titleabbrev") { + if (title) + g_free (title); + title = xmlNodeGetContent (cur); + break; + } + + cur = cur->next; + } + } + + return title; +} + +gboolean +walker_is_chunk (DBWalker *walker) +{ + if (walker->depth <= MAX_CHUNK_DEPTH) { + if (xml_is_division (walker->cur)) + return TRUE; + else if (walker->depth == 1 && xml_is_info (walker->cur)) + return TRUE; + } + return FALSE; +} + +gboolean +xml_is_division (xmlNodePtr node) +{ + return (!xmlStrcmp (node->name, (const xmlChar *) "appendix") || + !xmlStrcmp (node->name, (const xmlChar *) "article") || + !xmlStrcmp (node->name, (const xmlChar *) "book") || + !xmlStrcmp (node->name, (const xmlChar *) "bibliography") || + !xmlStrcmp (node->name, (const xmlChar *) "chapter") || + !xmlStrcmp (node->name, (const xmlChar *) "colophon") || + !xmlStrcmp (node->name, (const xmlChar *) "glossary") || + !xmlStrcmp (node->name, (const xmlChar *) "index") || + !xmlStrcmp (node->name, (const xmlChar *) "part") || + !xmlStrcmp (node->name, (const xmlChar *) "preface") || + !xmlStrcmp (node->name, (const xmlChar *) "reference") || + !xmlStrcmp (node->name, (const xmlChar *) "refentry") || + !xmlStrcmp (node->name, (const xmlChar *) "refsect1") || + !xmlStrcmp (node->name, (const xmlChar *) "refsect2") || + !xmlStrcmp (node->name, (const xmlChar *) "refsect3") || + !xmlStrcmp (node->name, (const xmlChar *) "refsection") || + !xmlStrcmp (node->name, (const xmlChar *) "sect1") || + !xmlStrcmp (node->name, (const xmlChar *) "sect2") || + !xmlStrcmp (node->name, (const xmlChar *) "sect3") || + !xmlStrcmp (node->name, (const xmlChar *) "sect4") || + !xmlStrcmp (node->name, (const xmlChar *) "sect5") || + !xmlStrcmp (node->name, (const xmlChar *) "section") || + !xmlStrcmp (node->name, (const xmlChar *) "set") || + !xmlStrcmp (node->name, (const xmlChar *) "setindex") || + !xmlStrcmp (node->name, (const xmlChar *) "simplesect") ); +} + +gboolean +xml_is_info (xmlNodePtr node) +{ + return (!xmlStrcmp (node->name, (const xmlChar *) "appendixinfo") || + !xmlStrcmp (node->name, (const xmlChar *) "articleinfo") || + !xmlStrcmp (node->name, (const xmlChar *) "bookinfo") || + !xmlStrcmp (node->name, (const xmlChar *) "bibliographyinfo") || + !xmlStrcmp (node->name, (const xmlChar *) "chapterinfo") || + !xmlStrcmp (node->name, (const xmlChar *) "glossaryinfo") || + !xmlStrcmp (node->name, (const xmlChar *) "indexinfo") || + !xmlStrcmp (node->name, (const xmlChar *) "partinfo") || + !xmlStrcmp (node->name, (const xmlChar *) "prefaceinfo") || + !xmlStrcmp (node->name, (const xmlChar *) "referenceinfo") || + !xmlStrcmp (node->name, (const xmlChar *) "refentryinfo") || + !xmlStrcmp (node->name, (const xmlChar *) "refsect1info") || + !xmlStrcmp (node->name, (const xmlChar *) "refsect2info") || + !xmlStrcmp (node->name, (const xmlChar *) "refsect3info") || + !xmlStrcmp (node->name, (const xmlChar *) "refsectioninfo") || + !xmlStrcmp (node->name, (const xmlChar *) "sect1info") || + !xmlStrcmp (node->name, (const xmlChar *) "sect2info") || + !xmlStrcmp (node->name, (const xmlChar *) "sect3info") || + !xmlStrcmp (node->name, (const xmlChar *) "sect4info") || + !xmlStrcmp (node->name, (const xmlChar *) "sect5info") || + !xmlStrcmp (node->name, (const xmlChar *) "sectioninfo") || + !xmlStrcmp (node->name, (const xmlChar *) "setinfo") || + !xmlStrcmp (node->name, (const xmlChar *) "setindexinfo") ); +} diff --git a/src/yelp-db-pager.h b/src/yelp-db-pager.h new file mode 100644 index 00000000..2cbb2f78 --- /dev/null +++ b/src/yelp-db-pager.h @@ -0,0 +1,54 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2003 Shaun McCance + * + * 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 + */ + +#ifndef __YELP_DB_PAGER_H__ +#define __YELP_DB_PAGER_H__ + +#include + +#include "yelp-pager.h" + +#define YELP_TYPE_DB_PAGER (yelp_db_pager_get_type ()) +#define YELP_DB_PAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_DB_PAGER, YelpDBPager)) +#define YELP_DB_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_DB_PAGER, YelpDBPagerClass)) +#define YELP_IS_DB_PAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_DB_PAGER)) +#define YELP_IS_DB_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_DB_PAGER)) +#define YELP_DB_PAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_DB_PAGER, YelpDBPagerClass)) + +typedef struct _YelpDBPager YelpDBPager; +typedef struct _YelpDBPagerClass YelpDBPagerClass; +typedef struct _YelpDBPagerPriv YelpDBPagerPriv; + +struct _YelpDBPager { + YelpPager parent; + + YelpDBPagerPriv *priv; +}; + +struct _YelpDBPagerClass { + YelpPagerClass parent_class; +}; + +GType yelp_db_pager_get_type (void); +YelpPager * yelp_db_pager_new (YelpURI *uri); + +#endif /* __YELP_DB_PAGER_H__ */ diff --git a/src/yelp-pager.c b/src/yelp-pager.c new file mode 100644 index 00000000..c07fa689 --- /dev/null +++ b/src/yelp-pager.c @@ -0,0 +1,535 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2003 Shaun McCance + * + * 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 + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "yelp-pager.h" +#include "yelp-marshal.h" +#include "yelp-uri.h" + +#define d(x) + +struct _YelpPagerPriv { + YelpURI *uri; + + GMutex *state_mutex; + YelpPagerState state; + + GMutex *error_mutex; + GError *error; + + GMutex *chunk_mutex; + GHashTable *chunk_hash; +}; + +enum { + PROP_0, + PROP_URI +}; + +enum { + START, + SECTIONS, + CHUNK, + FINISH, + CANCEL, + ERROR, + LAST_SIGNAL +}; + +static void pager_class_init (YelpPagerClass *klass); +static void pager_init (YelpPager *pager); +static void pager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void pager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void pager_dispose (GObject *object); + + +static GObjectClass *parent_class; +static gint signals[LAST_SIGNAL] = { 0 }; + +GType +yelp_pager_get_type (void) +{ + static GType type = 0; + + if (!type) { + static const GTypeInfo info = { + sizeof (YelpPagerClass), + NULL, + NULL, + (GClassInitFunc) pager_class_init, + NULL, + NULL, + sizeof (YelpPager), + 0, + (GInstanceInitFunc) pager_init, + }; + type = g_type_register_static (G_TYPE_OBJECT, + "YelpPager", + &info, 0); + } + return type; +} + +static void +pager_class_init (YelpPagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->set_property = pager_set_property; + object_class->get_property = pager_get_property; + object_class->dispose = pager_dispose; + + g_object_class_install_property + (object_class, + PROP_URI, + g_param_spec_object ("uri", + _("Document URI"), + _("The URI of the document to be processed"), + YELP_TYPE_URI, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + + signals[START] = g_signal_new + ("start", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, 0, + NULL, NULL, + yelp_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[SECTIONS] = g_signal_new + ("sections", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, 0, + NULL, NULL, + yelp_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[CHUNK] = g_signal_new + ("chunk", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, 0, + NULL, NULL, + yelp_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); + + signals[FINISH] = g_signal_new + ("finish", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, 0, + NULL, NULL, + yelp_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[CANCEL] = g_signal_new + ("cancel", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, 0, + NULL, NULL, + yelp_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[ERROR] = g_signal_new + ("error", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, 0, + NULL, NULL, + yelp_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +pager_init (YelpPager *pager) +{ + YelpPagerPriv *priv; + + priv = g_new0 (YelpPagerPriv, 1); + pager->priv = priv; + + pager->priv->uri = NULL; + pager->priv->state = YELP_PAGER_STATE_NEW; + + pager->priv->state_mutex = g_mutex_new (); + pager->priv->error_mutex = g_mutex_new (); + pager->priv->chunk_mutex = g_mutex_new (); + + pager->priv->error = NULL; + pager->priv->chunk_hash = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); +} + +static void +pager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + YelpPager *pager = YELP_PAGER (object); + + switch (prop_id) { + case PROP_URI: + if (pager->priv->uri) + g_object_unref (pager->priv->uri); + pager->priv->uri = (YelpURI *) g_value_get_object (value); + g_object_ref (pager->priv->uri); + break; + default: + break; + } +} + +static void +pager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + YelpPager *pager = YELP_PAGER (object); + + switch (prop_id) { + case PROP_URI: + g_value_set_object (value, pager->priv->uri); + break; + default: + break; + } +} + +static void +pager_dispose (GObject *object) +{ + YelpPager *pager = YELP_PAGER (object); + + g_object_unref (pager->priv->uri); + + g_mutex_free (pager->priv->state_mutex); + g_mutex_free (pager->priv->error_mutex); + g_mutex_free (pager->priv->chunk_mutex); + + if (pager->priv->error) + g_error_free (pager->priv->error); + + g_hash_table_destroy (pager->priv->chunk_hash); + + g_free (pager->priv); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +/******************************************************************************/ + +/** + * yelp_pager_start: + * @pager: a #YelpPager. + * + * Spawns a thread to process the document. If the document has already + * been processed, no thread will be spawned, and %FALSE will be returned. + **/ +gboolean +yelp_pager_start (YelpPager *pager) +{ + GError *error = NULL; + + g_return_val_if_fail (pager != NULL, FALSE); + g_return_val_if_fail (YELP_IS_PAGER (pager), FALSE); + + yelp_pager_lock_state (pager); + + switch (yelp_pager_get_state (pager)) { + case YELP_PAGER_STATE_NEW: + case YELP_PAGER_STATE_CANCEL: + yelp_pager_set_state (pager, YELP_PAGER_STATE_START); + + g_object_ref (pager); + g_signal_emit (pager, signals[START], 0); + + g_thread_create ((GThreadFunc) (YELP_PAGER_GET_CLASS (pager)->process), + pager, FALSE, &error); + + if (error) { + yelp_pager_unlock_state (pager); + yelp_pager_error (pager, error); + g_object_unref (pager); + + return FALSE; + } + + yelp_pager_unlock_state (pager); + g_object_unref (pager); + return TRUE; + + default: + yelp_pager_unlock_state (pager); + g_object_unref (pager); + return FALSE; + } +} + +/** + * yelp_pager_cancel: + * @pager: a #YelpPager. + * + * Cancels the document processing. The processing thread may continue + * for a short while after this function returns before it recognizes + * that it has been cancelled. + **/ +void +yelp_pager_cancel (YelpPager *pager) +{ + g_return_if_fail (pager != NULL); + g_return_if_fail (YELP_IS_PAGER (pager)); + + YELP_PAGER_GET_CLASS (pager)->cancel (pager); +} + +/** + * yelp_pager_get_uri: + * @pager: a #YelpPager. + * + * Returns the URI of the documnt @pager is transforming. + **/ +const YelpURI * +yelp_pager_get_uri (YelpPager *pager) +{ + g_return_val_if_fail (pager != NULL, FALSE); + g_return_val_if_fail (YELP_IS_PAGER (pager), FALSE); + + return (const YelpURI *) (pager->priv->uri); +} + +/** + * yelp_pager_get_state: + * @pager: a #YelpPager + * + * Returns the state of @pager. This does not handle locking itself. You + * must call yelp_pager_lock_state before and yelp_pager_unlock_state after. + **/ +YelpPagerState +yelp_pager_get_state (YelpPager *pager) +{ + g_return_val_if_fail (pager != NULL, 0); + g_return_val_if_fail (YELP_IS_PAGER (pager), 0); + + return pager->priv->state; +} + +/** + * yelp_pager_set_state: + * @pager: a #YelpPager + * @state: a #YelpPagerState + * + * Sets the state of @pager to @state. This does not handle locking itself. You + * must call yelp_pager_lock_state before and yelp_pager_unlock_state after. + **/ +void +yelp_pager_set_state (YelpPager *pager, YelpPagerState state) +{ + g_return_if_fail (pager != NULL); + g_return_if_fail (YELP_IS_PAGER (pager)); + + pager->priv->state = state; +} + +/** + * yelp_pager_lock_state: + * @pager: a #YelpPager. + * + * Locks the state @pager. You should generally maintain a lock on the state + * across most operations on @pager. + **/ +void +yelp_pager_lock_state (YelpPager *pager) +{ + g_return_if_fail (pager != NULL); + g_return_if_fail (YELP_IS_PAGER (pager)); + + g_mutex_lock (pager->priv->state_mutex); +} + +/** + * yelp_pager_unlock_state: + * @pager: a #YelpPager. + * + * Releases a lock on the state of @pager. + **/ +void +yelp_pager_unlock_state (YelpPager *pager) +{ + g_return_if_fail (pager != NULL); + g_return_if_fail (YELP_IS_PAGER (pager)); + + g_mutex_unlock (pager->priv->state_mutex); +} + +/** + * yelp_pager_get_error: + * @pager: a #YelpPager. + * + * Returns a #GError for the processing error. + * The caller is responsible for freeing the #GError. + **/ +GError * +yelp_pager_get_error (YelpPager *pager) +{ + GError *error; + + g_return_val_if_fail (pager != NULL, NULL); + g_return_val_if_fail (YELP_IS_PAGER (pager), NULL); + + g_mutex_lock (pager->priv->error_mutex); + + if (pager->priv->error) + error = g_error_copy (pager->priv->error); + else + error = NULL; + + g_mutex_unlock (pager->priv->error_mutex); + + return error; +} + +/** + * yelp_pager_error: + * @pager: a #YelpPager + * @error: a #GError + * + * Sets the error of @pager and emits the "error" signal. You must + * release locks on the state before calling this. + **/ +void +yelp_pager_error (YelpPager *pager, GError *error) +{ + yelp_pager_lock_state (pager); + g_mutex_lock (pager->priv->error_mutex); + + if (pager->priv->error) + g_error_free (pager->priv->error); + pager->priv->error = error; + + g_mutex_unlock (pager->priv->error_mutex); + + yelp_pager_set_state (pager, YELP_PAGER_STATE_ERROR); + + g_signal_emit_by_name (pager, "error"); + yelp_pager_unlock_state (pager); +} + +/** + * yelp_pager_get_sections: + * @pager: a #YelpPager + * + * Returns a reference to the #GtkTreeModel where the section outline is stored. + **/ +const GtkTreeModel * +yelp_pager_get_sections (YelpPager *pager) +{ + g_return_val_if_fail (pager != NULL, NULL); + g_return_val_if_fail (YELP_IS_PAGER (pager), NULL); + + return YELP_PAGER_GET_CLASS (pager)->get_sections (pager); +} + +/** + * yelp_pager_lookup_chunk: + * @pager: a #YelpPager + * @uri: a #YelpURI + * + * Look up and return the appropriate chunk for @uri, automatically resolving + * which chunk to use based on the fragment identifier. + **/ +const gchar * +yelp_pager_lookup_chunk (YelpPager *pager, YelpURI *uri) +{ + gchar *chunk_id = NULL; + gchar *chunk; + + g_return_val_if_fail (pager != NULL, NULL); + g_return_val_if_fail (YELP_IS_PAGER (pager), NULL); + + chunk_id = (gchar *) (YELP_PAGER_GET_CLASS (pager)->resolve_uri (pager, uri)); + + if (chunk_id) + chunk_id = g_strdup (chunk_id); + else + chunk_id = yelp_uri_get_fragment (uri); + + chunk = (gchar *) yelp_pager_get_chunk (pager, chunk_id); + + g_free (chunk_id); + + return (const gchar *) chunk; +} + +/** + * yelp_pager_get_chunk: + * @pager: a #YelpPager + * @id: the chunk id + * + * Return the chunk with id @id. + **/ +const gchar * +yelp_pager_get_chunk (YelpPager *pager, gchar *id) +{ + gchar *chunk; + + g_return_val_if_fail (pager != NULL, NULL); + g_return_val_if_fail (YELP_IS_PAGER (pager), NULL); + + g_mutex_lock (pager->priv->chunk_mutex); + chunk = (gchar *) g_hash_table_lookup (pager->priv->chunk_hash, id); + g_mutex_unlock (pager->priv->chunk_mutex); + + return (const gchar *) chunk; +} + +/** + * yelp_pager_add_chunk: + * @pager: a #YelpPager + * @id: the id of the new chunk + * @chunk: the contents of the new chunk + * + * Add the chunk @chunk with id @id. + **/ +void +yelp_pager_add_chunk (YelpPager *pager, gchar *id, gchar *chunk) +{ + g_return_if_fail (pager != NULL); + g_return_if_fail (YELP_IS_PAGER (pager)); + + g_mutex_lock (pager->priv->chunk_mutex); + g_hash_table_insert (pager->priv->chunk_hash, id, chunk); + g_mutex_unlock (pager->priv->chunk_mutex); +} diff --git a/src/yelp-pager.h b/src/yelp-pager.h new file mode 100644 index 00000000..ef8f5f98 --- /dev/null +++ b/src/yelp-pager.h @@ -0,0 +1,94 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2003 Shaun McCance + * + * 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 + */ + +#ifndef __YELP_PAGER_H__ +#define __YELP_PAGER_H__ + +#include +#include +#include "yelp-uri.h" + +#define YELP_TYPE_PAGER (yelp_pager_get_type ()) +#define YELP_PAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_PAGER, YelpPager)) +#define YELP_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_PAGER, YelpPagerClass)) +#define YELP_IS_PAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_PAGER)) +#define YELP_IS_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_PAGER)) +#define YELP_PAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_PAGER, YelpPagerClass)) + +typedef struct _YelpPager YelpPager; +typedef struct _YelpPagerClass YelpPagerClass; +typedef struct _YelpPagerPriv YelpPagerPriv; + +typedef enum { + YELP_PAGER_STATE_NEW, + YELP_PAGER_STATE_START, + YELP_PAGER_STATE_ERROR, + YELP_PAGER_STATE_CANCEL, + YELP_PAGER_STATE_FINISH +} YelpPagerState; + +struct _YelpPager { + GObject parent; + + YelpPagerPriv *priv; +}; + +struct _YelpPagerClass { + GObjectClass parent_class; + + /* Virtual Functions */ + void (*process) (YelpPager *pager); + void (*cancel) (YelpPager *pager); + const gchar * (*resolve_uri) (YelpPager *pager, + YelpURI *uri); + const GtkTreeModel * (*get_sections) (YelpPager *pager); + +}; + +GType yelp_pager_get_type (void); + +gboolean yelp_pager_start (YelpPager *pager); +void yelp_pager_cancel (YelpPager *pager); + +const YelpURI * yelp_pager_get_uri (YelpPager *pager); + +YelpPagerState yelp_pager_get_state (YelpPager *pager); +void yelp_pager_set_state (YelpPager *pager, + YelpPagerState state); +void yelp_pager_lock_state (YelpPager *pager); +void yelp_pager_unlock_state (YelpPager *pager); + +GError * yelp_pager_get_error (YelpPager *pager); +void yelp_pager_error (YelpPager *pager, + GError *error); + +const GtkTreeModel * yelp_pager_get_sections (YelpPager *pager); + +const gchar * yelp_pager_lookup_chunk (YelpPager *pager, + YelpURI *uri); +const gchar * yelp_pager_get_chunk (YelpPager *pager, + gchar *id); +void yelp_pager_add_chunk (YelpPager *pager, + gchar *id, + gchar *chunk); + +#endif /* __YELP_PAGER_H__ */ diff --git a/src/yelp-uri.c b/src/yelp-uri.c index 33463c47..2994a9e3 100644 --- a/src/yelp-uri.c +++ b/src/yelp-uri.c @@ -1,6 +1,6 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Copyright (C) 2002 Mikael Hallendal + * Copyright (C) 2003 Shaun McCance * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -17,7 +17,8 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * - * Author: Mikael Hallendal + * Author: Shaun McCance + * Based on implementation by Mikael Hallendal */ #include @@ -32,14 +33,14 @@ #define d(x) -struct _YelpURI { - YelpURIType type; - gchar *path; - gchar *section; - gint ref_count; - gboolean exists; +struct _YelpURIPriv { + YelpURIType type; + gchar *path; + gchar *frag; + gboolean exists; }; +/* static gchar * uri_get_doc_path (const gchar *str_uri); static YelpURIType uri_get_doc_type (const gchar *str_uri, const gchar *doc_path); @@ -51,167 +52,463 @@ static gchar * uri_locate_help_file (const gchar *path, static gchar * uri_locate_help_file_with_lang (const gchar *path, const gchar *file_name, const gchar *locate); +*/ -static gchar * -uri_get_doc_path (const gchar *str_uri) + +static void uri_class_init (YelpURIClass *klass); +static void uri_init (YelpURI *uri); +static void uri_dispose (GObject *gobject); + +static void uri_parse_uri (YelpURI *uri, + const gchar *uri_str); +static void uri_parse_ghelp_uri (YelpURI *uri, + const gchar *uri_str); +static void uri_resource_type (YelpURI *uri); +static gchar * uri_locate_file (gchar *path, + gchar *file); +static gchar * uri_locate_file_lang (gchar *path, + gchar *file, + gchar *lang); + +static GObjectClass *parent_class; + +GType +yelp_uri_get_type (void) { - gchar *no_anchor_uri; - gchar *ret_val = NULL; - const gchar *ch = NULL; - - /* remove the anchor from the doc path */ - if ((ch = strchr (str_uri, '?')) || (ch = strchr (str_uri, '#'))) { - no_anchor_uri = g_strndup (str_uri, ch - str_uri); - } else { - no_anchor_uri = g_strdup (str_uri); - } + 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; +} - if (no_anchor_uri[0] == '/') { - ret_val = g_strdup (no_anchor_uri); - } - else if (!g_ascii_strncasecmp (no_anchor_uri, "man:", 4)) { - ret_val = g_strdup (no_anchor_uri + 4); - } - else if (!g_ascii_strncasecmp (no_anchor_uri, "info:", 5)) { - if (!g_ascii_strncasecmp (no_anchor_uri + 5, "dir", 3)) { - ret_val = g_strdup ("info"); - } else { - ret_val = g_strdup (no_anchor_uri + 5); - } - } - else if (!g_ascii_strncasecmp (no_anchor_uri, "toc:", 4)) { - ret_val = g_strdup (no_anchor_uri + 4); - } - else if (!g_ascii_strncasecmp (no_anchor_uri, "index:", 6)) { - ret_val = g_strdup (no_anchor_uri + 6); - } - else if (!g_ascii_strncasecmp (no_anchor_uri, "path:", 5)) { - ret_val = g_strdup (no_anchor_uri + 5); - } - else if (!g_ascii_strncasecmp (no_anchor_uri, "ghelp:", 6)) { - ret_val = uri_get_path_from_ghelp_uri (no_anchor_uri + 6); - } - else if (!g_ascii_strncasecmp (no_anchor_uri, "file:", 5)) { - ret_val = g_strdup (no_anchor_uri + 5); - } else { - ret_val = g_strdup (no_anchor_uri); - } - - g_free (no_anchor_uri); +static void +uri_class_init (YelpURIClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); - return ret_val; + parent_class = g_type_class_peek_parent (klass); + + object_class->dispose = uri_dispose; } -static YelpURIType -uri_get_doc_type (const gchar *str_uri, const gchar *doc_path) +static void +uri_init (YelpURI *uri) { - YelpURIType ret_val = YELP_URI_TYPE_UNKNOWN; + YelpURIPriv *priv; - if (!g_ascii_strncasecmp (str_uri, "man:", 4)) { - ret_val = YELP_URI_TYPE_MAN; - } - else if (!g_ascii_strncasecmp (str_uri, "info:", 5)) { - if (!g_ascii_strncasecmp (str_uri + 5, "dir", 3)) { - ret_val = YELP_URI_TYPE_TOC; - } else { - ret_val = YELP_URI_TYPE_INFO; - } - } - else if (!g_ascii_strncasecmp (str_uri, "toc:", 4)) { - ret_val = YELP_URI_TYPE_TOC; - } - else if (!g_ascii_strncasecmp (str_uri, "index:", 6)) { - ret_val = YELP_URI_TYPE_INDEX; - } - else if (!g_ascii_strncasecmp (str_uri, "path:", 5)) { - ret_val = YELP_URI_TYPE_PATH; - } - else if (!g_ascii_strncasecmp (str_uri, "file:", 5) || - str_uri[0] == '/') { - ret_val = YELP_URI_TYPE_FILE; - } - else if (!g_ascii_strncasecmp (str_uri, "ghelp:", 6)) { - gchar *mime_type = NULL; - gchar *docpath; + priv = g_new0 (YelpURIPriv, 1); + uri->priv = priv; - if (doc_path) { - docpath = (gchar *) doc_path; - } else { - docpath = uri_get_doc_path (str_uri); - } + uri->priv->type = YELP_URI_TYPE_UNKNOWN; + uri->priv->path = NULL; + uri->priv->frag = NULL; +} - mime_type = gnome_vfs_get_mime_type (docpath); - - if (mime_type) { - if (!g_strcasecmp (mime_type, "text/xml")) { - ret_val = YELP_URI_TYPE_DOCBOOK_XML; - } - else if (!g_strcasecmp (mime_type, "text/sgml")) { - ret_val = YELP_URI_TYPE_DOCBOOK_SGML; - } - else if (!g_strcasecmp (mime_type, "text/html")) { - ret_val = YELP_URI_TYPE_HTML; - } - - g_free (mime_type); - } - - if (docpath != doc_path) { - g_free (docpath); - } - - if (ret_val == YELP_URI_TYPE_UNKNOWN) { - ret_val = YELP_URI_TYPE_GHELP_OTHER; - } - } +static void +uri_dispose (GObject *object) +{ + YelpURI *uri = YELP_URI (object); + + g_free (uri->priv->path); + g_free (uri->priv->frag); + + g_free (uri->priv); - return ret_val; + G_OBJECT_CLASS (parent_class)->dispose (object); } -static gchar * -uri_get_doc_section (const gchar *str_uri) +/******************************************************************************/ + +YelpURI * +yelp_uri_new (const gchar *uri_str) { - const gchar *ch = NULL; + YelpURI *uri; + + uri = g_object_new (YELP_TYPE_URI, NULL); + + uri_parse_uri (uri, uri_str); + + return uri; +} + +gboolean +yelp_uri_exists (YelpURI *uri) +{ + gboolean exists; - if ((ch = strchr (str_uri, '?')) || (ch = strchr (str_uri, '#'))) { - return g_strdup (ch + 1); - } + g_return_val_if_fail (uri != NULL, FALSE); - return NULL; + if (!uri->priv->path) + return FALSE; + + switch (uri->priv->type) { + case YELP_URI_TYPE_TOC: + case YELP_URI_TYPE_MAN: + case YELP_URI_TYPE_INFO: + case YELP_URI_TYPE_PATH: + case YELP_URI_TYPE_UNKNOWN: + exists = TRUE; + break; + case YELP_URI_TYPE_DOCBOOK_XML: + case YELP_URI_TYPE_DOCBOOK_SGML: + case YELP_URI_TYPE_HTML: + case YELP_URI_TYPE_FILE: + exists = g_file_test (uri->priv->path, G_FILE_TEST_EXISTS); + break; + default: + exists = FALSE; + } + + return exists; } -static gchar * -uri_get_path_from_ghelp_uri (const gchar *path) +YelpURIType +yelp_uri_get_resource_type (YelpURI *uri) { + g_return_val_if_fail (uri != NULL, YELP_URI_TYPE_UNKNOWN); + g_return_val_if_fail (YELP_IS_URI (uri), YELP_URI_TYPE_UNKNOWN); + + return uri->priv->type; +} + +gchar * +yelp_uri_get_path (YelpURI *uri) { - gchar *ret_val = NULL; - gchar *work_path; - - work_path = g_strdup (path); + g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (YELP_IS_URI (uri), NULL); + + return g_strdup (uri->priv->path); +} + +gchar * yelp_uri_get_fragment (YelpURI *uri) +{ + g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (YELP_IS_URI (uri), NULL); + + return g_strdup (uri->priv->frag); +} + +gchar * +yelp_uri_to_string (YelpURI *uri) +{ + gchar *type; + gchar *uri_str = NULL; - g_strstrip (work_path); + g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (YELP_IS_URI (uri), NULL); - if (path[0] == '/') { - /* Absolute URL */ - gint i = 1; - gint len = strlen (work_path); - - while (i < len && work_path[i] == '/') { - ++i; - } + if (uri->priv->type == YELP_URI_TYPE_UNKNOWN) { + if (uri->priv->path) + return g_strdup (uri->priv->path); - /* Should we always try to use xml here even if full * - * path to a sgml or html document is given? */ + return NULL; + } + + switch (uri->priv->type) { + case YELP_URI_TYPE_MAN: + type = g_strdup ("man:"); + break; + case YELP_URI_TYPE_INFO: + type = g_strdup ("info:"); + break; + case YELP_URI_TYPE_DOCBOOK_XML: + case YELP_URI_TYPE_DOCBOOK_SGML: + case YELP_URI_TYPE_FILE: + case YELP_URI_TYPE_HTML: + type = g_strdup ("file:"); + case YELP_URI_TYPE_GHELP: + type = g_strdup ("ghelp:"); + break; + case YELP_URI_TYPE_TOC: + type = g_strdup ("toc:"); + break; + case YELP_URI_TYPE_PATH: + type = g_strdup ("path:"); + break; + default: + g_assert_not_reached (); + break; + } + + if (uri->priv->frag) + uri_str = g_strconcat (type, uri->priv->path, + "#", uri->priv->frag, + NULL); + else + uri_str = g_strconcat (type, uri->priv->path, NULL); + + g_free (type); + + return uri_str; +} + +/******************************************************************************/ - ret_val = g_strdup (work_path + (i - 1)); +static void +uri_parse_uri (YelpURI *uri, const gchar *uri_str) +{ + gchar *c; + gchar *scheme = NULL; + gchar *path = NULL; + + YelpURIPriv *priv = uri->priv; + + if ((c = strchr (uri_str, '?')) || (c = strchr (uri_str, '#'))) { + path = g_strndup (uri_str, c - uri_str); + priv->frag = g_strdup (c + 1); + } else { + path = g_strdup (uri_str); + priv->frag = NULL; + } + + if ((c = strchr (path, ':'))) { + priv->path = g_strdup (c + 1); + scheme = g_strndup (path, c - path); + } else { + priv->type = YELP_URI_TYPE_RELATIVE; + priv->path = path; + return; + } + + g_free (path); + + if (!g_ascii_strcasecmp (scheme, "ghelp") && priv->path[0] != '/') { + path = priv->path; + priv->path = NULL; + + uri_parse_ghelp_uri (uri, path); + + g_free (path); + return; + } + + if (!g_ascii_strcasecmp (scheme, "ghelp") || + !g_ascii_strcasecmp (scheme, "file")) { + + uri_resource_type (uri); + } + else if (!g_ascii_strcasecmp (scheme, "man")) { + priv->type = YELP_URI_TYPE_MAN; + } + else if (!g_ascii_strcasecmp (scheme, "info")) { + // FIXME: This just throws away info sections. + if (!g_ascii_strncasecmp (priv->path, "dir", 3)) { + g_free (priv->path); + priv->path = g_strdup ("info"); + priv->type = YELP_URI_TYPE_TOC; } else { - ret_val = uri_get_path_from_relative (path); + priv->type = YELP_URI_TYPE_INFO; + } + } + else if (!g_ascii_strcasecmp (scheme, "path")) { + priv->type = YELP_URI_TYPE_PATH; + } + else if (!g_ascii_strcasecmp (scheme, "toc")) { + priv->type = YELP_URI_TYPE_TOC; + } +} + +static void +uri_parse_ghelp_uri (YelpURI *uri, const gchar *uri_str) +{ + GSList *locations = NULL; + GSList *node; + gchar *c; + gchar *doc; + gchar *file; + + YelpURIPriv *priv = uri->priv; + GnomeProgram *program = gnome_program_get (); + + if ((c = strchr (uri_str, '/'))) { + /* 2: ghelp:AisleRiot2/Klondike */ + doc = g_strndup (uri_str, c - uri_str); + file = g_strdup (c + 1); + } else { + /* 1: ghelp:nautilus */ + doc = g_strdup (uri_str); + file = g_strdup (uri_str); + } + + gnome_program_locate_file (program, + GNOME_FILE_DOMAIN_HELP, + doc, + FALSE, + &locations); + + if (!locations) { + priv->type = YELP_URI_TYPE_GHELP; + priv->path = g_strdup (uri_str); + return; + } + + for (node = locations; node; node = node->next) { + gchar *path; + + path = uri_locate_file ((gchar *) node->data, file); + + if (path) { + priv->path = path; + uri_resource_type (uri); + break; + } + } + + g_free (doc); + g_free (file); +} + +static void +uri_resource_type (YelpURI *uri) +{ + gchar *mime_type = gnome_vfs_get_mime_type (uri->priv->path); + + if (mime_type) { + if (!g_strcasecmp (mime_type, "text/xml")) + uri->priv->type = YELP_URI_TYPE_DOCBOOK_XML; + else if (!g_strcasecmp (mime_type, "text/sgml")) + uri->priv->type = YELP_URI_TYPE_DOCBOOK_SGML; + else if (!g_strcasecmp (mime_type, "text/html")) + uri->priv->type = YELP_URI_TYPE_HTML; + } + + g_free (mime_type); +} + +static gchar * +uri_locate_file (gchar *path, gchar *file) +{ + gchar *ret; + const GList *langs; + + langs = gnome_i18n_get_language_list ("LC_MESSAGES"); + + for (; langs != NULL; langs = langs->next) { + gchar *lang = langs->data; + + /* This has to be a valid language AND a language with + * no encoding postfix. The language will come up without + * encoding next */ + if (lang == NULL || strchr (lang, '.') != NULL) + continue; + + ret = uri_locate_file_lang (path, file, lang); + + if (!ret) { + /* Check for index file in wanted locale */ + ret = uri_locate_file_lang (path, "index", lang); } + + if (ret) + return ret; + } + + /* Look in C locale since that exists for almost all documents */ + ret = uri_locate_file_lang (path, file, "C"); + if (ret) + return ret; + + /* Last chance, look for index-file with C lang */ + return uri_locate_file_lang (path, "index", "C"); +} + +static gchar * +uri_locate_file_lang (gchar *path, gchar *file, gchar *lang) +{ + gchar *exts[] = {".xml", ".docbook", ".sgml", ".html", "", NULL}; + gint i; + + for (i = 0; exts[i] != NULL; i++) { + gchar *full; + + full = g_strconcat (path, "/", lang, "/", file, exts[i], NULL); + + if (g_file_test (full, G_FILE_TEST_EXISTS)) + return full; + + g_free (full); + } + + return NULL; +} + +gboolean +yelp_uri_equal (YelpURI *uri1, YelpURI *uri2) +{ + g_return_val_if_fail (uri1 != NULL, FALSE); + g_return_val_if_fail (uri2 != NULL, FALSE); + + if (uri1->priv->type == uri2->priv->type && + yelp_uri_equal_path (uri1, uri2) && + yelp_uri_equal_fragment (uri1, uri2)) + + return TRUE; + else + return FALSE; +} + +gboolean +yelp_uri_equal_path (YelpURI *uri1, YelpURI *uri2) +{ + g_return_val_if_fail (uri1 != NULL, FALSE); + g_return_val_if_fail (uri2 != NULL, FALSE); + + if (uri1->priv->path == NULL) { + if (uri2->priv->path == NULL) + return TRUE; + else + return FALSE; + } - g_free (work_path); + if (uri2->priv->path == NULL) + return FALSE; - return ret_val; + if (!strcmp (uri1->priv->path, uri2->priv->path)) + return TRUE; + + return FALSE; +} + +gboolean +yelp_uri_equal_fragment (YelpURI *uri1, YelpURI *uri2) +{ + g_return_val_if_fail (uri1 != NULL, FALSE); + g_return_val_if_fail (uri2 != NULL, FALSE); + + if (uri1->priv->frag == NULL) { + if (uri2->priv->frag == NULL) + return TRUE; + else + return FALSE; + } + + if (uri2->priv->frag == NULL) + return FALSE; + + if (!strcmp (uri1->priv->frag, uri2->priv->frag)) + return TRUE; + + return FALSE; } + + + +/****************************************************************************** static gchar * uri_get_path_from_relative (const gchar *path) { @@ -226,11 +523,9 @@ uri_get_path_from_relative (const gchar *path) program = gnome_program_get (); if ((ch = strchr (path, '/'))) { - /* 2: ghelp:AisleRiot2/Klondike */ doc_id = g_strndup (path, ch - path); file_name = g_strdup (ch + 1); } else { - /* 1: ghelp:nautilus */ doc_id = (gchar *)path; file_name = (gchar *)path; } @@ -277,185 +572,11 @@ uri_get_path_from_relative (const gchar *path) return ret_val; } -static gchar * -uri_locate_help_file (const gchar *path, const gchar *file_name) -{ - gchar *ret_val; - const GList *lang_list; - - lang_list = gnome_i18n_get_language_list ("LC_MESSAGES"); - - for (;lang_list != NULL; lang_list = lang_list->next) { - const gchar *lang = lang_list->data; - - d(g_print ("lang: %s\n", lang)); - - /* This has to be a valid language AND a language with - * no encoding postfix. The language will come up without - * encoding next */ - if (lang == NULL || strchr (lang, '.') != NULL) { - continue; - } - - ret_val = uri_locate_help_file_with_lang (path, file_name, - lang); - - if (!ret_val) { - /* Check for index file in wanted locale */ - ret_val = uri_locate_help_file_with_lang (path, - "index", - lang); - } - - if (ret_val) { - return ret_val; - } - } - - /* Look in C locale since that exists for almost all documents */ - ret_val = uri_locate_help_file_with_lang (path, file_name, "C"); - - if (ret_val) { - return ret_val; - } - - /* Last chance, look for index-file with C lang */ - return uri_locate_help_file_with_lang (path, "index", "C"); -} - -static gchar * -uri_locate_help_file_with_lang (const gchar *path, - const gchar *file_name, - const gchar *lang) -{ - gchar *exts[] = {".xml", ".docbook", ".sgml", ".html", "", NULL}; - gint i; - - for (i = 0; exts[i] != NULL; i++) { - gchar *full; - - full = g_strconcat (path, "/", lang, "/", - file_name, exts[i], NULL); - - if (g_file_test (full, G_FILE_TEST_EXISTS)) { - return full; - } - - g_free (full); - } - - return NULL; -} - - -YelpURI * -yelp_uri_new (const gchar *str_uri) -{ - YelpURI *uri; - - uri = g_new0 (YelpURI, 1); - - d(g_print ("New YelpURI: %s\n", str_uri)); - - uri->path = uri_get_doc_path (str_uri); - uri->type = uri_get_doc_type (str_uri, uri->path); - uri->section = uri_get_doc_section (str_uri); - uri->ref_count = 1; - - d(g_print ("Resulting path: %s section: %s\n", - uri->path, - uri->section)); - - return uri; -} - gboolean yelp_uri_exists (YelpURI *uri) { - gboolean ret_val; - YelpURI *no_index; - - g_return_val_if_fail (uri != NULL, FALSE); - - if (!uri->path) { - return FALSE; - } - - switch (uri->type) { - case YELP_URI_TYPE_TOC: - case YELP_URI_TYPE_MAN: - case YELP_URI_TYPE_INFO: - case YELP_URI_TYPE_PATH: - case YELP_URI_TYPE_UNKNOWN: - ret_val = TRUE; - break; - case YELP_URI_TYPE_DOCBOOK_XML: - case YELP_URI_TYPE_DOCBOOK_SGML: - case YELP_URI_TYPE_HTML: - case YELP_URI_TYPE_FILE: - ret_val = g_file_test (uri->path, G_FILE_TEST_EXISTS); - break; - case YELP_URI_TYPE_INDEX: - no_index = yelp_uri_from_index (uri); - ret_val = yelp_uri_exists (no_index); - yelp_uri_unref (no_index); - break; - default: - ret_val = FALSE; - } - - return ret_val; } -YelpURIType -yelp_uri_get_type (YelpURI *uri) -{ - g_return_val_if_fail (uri != NULL, YELP_URI_TYPE_UNKNOWN); - - return uri->type; -} - -const gchar * -yelp_uri_get_path (YelpURI *uri) -{ - g_return_val_if_fail (uri != NULL, NULL); - - return uri->path; -} - -const gchar * -yelp_uri_get_section (YelpURI *uri) -{ - g_return_val_if_fail (uri != NULL, NULL); - - return uri->section; -} - -YelpURI * -yelp_uri_ref (YelpURI *uri) -{ - g_return_val_if_fail (uri != NULL, NULL); - - uri->ref_count++; - - return uri; -} - -void -yelp_uri_unref (YelpURI *uri) -{ - g_return_if_fail (uri != NULL); - - uri->ref_count--; - - if (uri->ref_count == 0) { - d(g_print ("Freeing up URI\n")); - - g_free (uri->path); - g_free (uri->section); - g_free (uri); - } -} YelpURI * yelp_uri_copy (YelpURI *uri) @@ -507,127 +628,7 @@ yelp_uri_get_relative (YelpURI *uri, const gchar *link) return new_uri; } -gboolean -yelp_uri_equal (YelpURI *uri1, YelpURI *uri2) -{ - if (uri1->type == uri2->type && - yelp_uri_equal_path (uri1, uri2) && - yelp_uri_equal_section (uri1, uri2)) { - return TRUE; - } - - return FALSE; -} -gboolean -yelp_uri_equal_path (YelpURI *uri1, YelpURI *uri2) -{ - g_return_val_if_fail (uri1 != NULL, FALSE); - g_return_val_if_fail (uri2 != NULL, FALSE); - - if (uri1->path == NULL) { - if (uri2->path == NULL) { - return TRUE; - } else { - return FALSE; - } - } - - if (uri2->path == NULL) { - return FALSE; - } - - if (!strcmp (uri1->path, uri2->path)) { - return TRUE; - } - - return FALSE; -} - -gboolean -yelp_uri_equal_section (YelpURI *uri1, YelpURI *uri2) -{ - g_return_val_if_fail (uri1 != NULL, FALSE); - g_return_val_if_fail (uri2 != NULL, FALSE); - - if (uri1->section == NULL) { - if (uri2->section == NULL) { - return TRUE; - } else { - return FALSE; - } - } - - if (uri2->section == NULL) { - return FALSE; - } - - if (!strcmp (uri1->section, uri2->section)) { - return TRUE; - } - - return FALSE; -} - -gchar * -yelp_uri_to_string (YelpURI *uri) -{ - gchar *type; - gchar *ret_val = NULL; - - g_return_val_if_fail (uri != NULL, NULL); - - if (uri->type == YELP_URI_TYPE_UNKNOWN) { - if (uri->path) { - return g_strdup (uri->path); - } - - return NULL; - } - - switch (uri->type) { - case YELP_URI_TYPE_MAN: - type = g_strdup ("man:"); - break; - case YELP_URI_TYPE_INFO: - type = g_strdup ("info:"); - break; - case YELP_URI_TYPE_DOCBOOK_XML: - case YELP_URI_TYPE_DOCBOOK_SGML: - case YELP_URI_TYPE_HTML: - case YELP_URI_TYPE_GHELP_OTHER: - type = g_strdup ("ghelp:"); - break; - case YELP_URI_TYPE_TOC: - type = g_strdup ("toc:"); - break; - case YELP_URI_TYPE_PATH: - type = g_strdup ("path:"); - break; - case YELP_URI_TYPE_FILE: - type = g_strdup ("file:"); - break; - case YELP_URI_TYPE_INDEX: - type = g_strdup ("index:"); - break; - default: - g_assert_not_reached (); - break; - } - - if (uri->section) { - ret_val = g_strconcat (type, uri->path, "?", uri->section, - NULL); - } else { - ret_val = g_strconcat (type, uri->path, NULL); - } - - g_free (type); - - d(g_print ("URI_TO_STRING: %s\n", ret_val)); - - return ret_val; -} YelpURI * yelp_uri_to_index (YelpURI *uri) @@ -667,3 +668,4 @@ yelp_uri_no_path (YelpURI *uri) return FALSE; } +*/ diff --git a/src/yelp-uri.h b/src/yelp-uri.h index 824365f6..2c46d455 100644 --- a/src/yelp-uri.h +++ b/src/yelp-uri.h @@ -1,6 +1,6 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Copyright (C) 2002 Mikael Hallendal + * Copyright (C) 2003 Shaun McCance * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -17,7 +17,8 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * - * Author: Mikael Hallendal + * Author: Shaun McCance + * Based on implementation by Mikael Hallendal */ #ifndef __YELP_URI_H__ @@ -25,47 +26,71 @@ #include -#define YELP_URI(x) ((YelpURI *) x) +#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_TYPE_UNKNOWN, - YELP_URI_TYPE_DOCBOOK_XML, - YELP_URI_TYPE_DOCBOOK_SGML, - YELP_URI_TYPE_GHELP_OTHER, - YELP_URI_TYPE_HTML, - YELP_URI_TYPE_MAN, - YELP_URI_TYPE_INFO, - YELP_URI_TYPE_TOC, - YELP_URI_TYPE_INDEX, - YELP_URI_TYPE_PATH, - YELP_URI_TYPE_FILE + YELP_URI_TYPE_UNKNOWN, + YELP_URI_TYPE_RELATIVE, + YELP_URI_TYPE_DOCBOOK_XML, + YELP_URI_TYPE_DOCBOOK_SGML, + YELP_URI_TYPE_HTML, + YELP_URI_TYPE_MAN, + YELP_URI_TYPE_INFO, + + YELP_URI_TYPE_GHELP, + YELP_URI_TYPE_GHELP_OTHER, + YELP_URI_TYPE_TOC, + YELP_URI_TYPE_INDEX, + YELP_URI_TYPE_PATH, + YELP_URI_TYPE_FILE } YelpURIType; -typedef struct _YelpURI YelpURI; +struct _YelpURI { + GObject parent; + + YelpURIPriv *priv; +}; + +struct _YelpURIClass { + GObjectClass parent_class; +}; -YelpURI * yelp_uri_new (const gchar *str_uri); -gboolean yelp_uri_exists (YelpURI *uri); -YelpURIType yelp_uri_get_type (YelpURI *uri); -const gchar * yelp_uri_get_path (YelpURI *uri); -const gchar * yelp_uri_get_section (YelpURI *uri); +GType yelp_uri_get_type (void); -YelpURI * yelp_uri_ref (YelpURI *uri); -void yelp_uri_unref (YelpURI *uri); +YelpURI * yelp_uri_new (const gchar *uri_str); +gboolean yelp_uri_exists (YelpURI *uri); +YelpURIType yelp_uri_get_resource_type (YelpURI *uri); +gchar * yelp_uri_get_path (YelpURI *uri); +gchar * yelp_uri_get_fragment (YelpURI *uri); + +gchar * yelp_uri_to_string (YelpURI *uri); + +gboolean yelp_uri_equal (YelpURI *uri1, + YelpURI *uri2); +gboolean yelp_uri_equal_path (YelpURI *uri1, + YelpURI *uri2); +gboolean yelp_uri_equal_fragment (YelpURI *uri1, + YelpURI *uri2); + +/* YelpURI * yelp_uri_copy (YelpURI *uri); YelpURI * yelp_uri_get_relative (YelpURI *uri, const gchar *link); -gboolean yelp_uri_equal (YelpURI *uri1, - YelpURI *uri2); -gboolean yelp_uri_equal_path (YelpURI *uri1, - YelpURI *uri2); -gboolean yelp_uri_equal_section (YelpURI *uri1, - YelpURI *uri2); -gchar * yelp_uri_to_string (YelpURI *uri); YelpURI * yelp_uri_to_index (YelpURI *uri); YelpURI * yelp_uri_from_index (YelpURI *uri); gboolean yelp_uri_no_path (YelpURI *uri); +*/ #endif /* __YELP_URI_H__ */ -- cgit v1.2.1