[yelp] [libyelp] Adding info documents; still a few problems, but it mostly works
- From: Shaun McCance <shaunm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [yelp] [libyelp] Adding info documents; still a few problems, but it mostly works
- Date: Mon, 26 Apr 2010 23:03:00 +0000 (UTC)
commit 04c47abd3669dd5522091e9cfed4466183c4c5ef
Author: Shaun McCance <shaunm gnome org>
Date: Mon Apr 26 18:02:32 2010 -0500
[libyelp] Adding info documents; still a few problems, but it mostly works
libyelp/Makefile.am | 4 +
libyelp/yelp-docbook-document.c | 13 +-
libyelp/yelp-document.c | 3 +-
libyelp/yelp-info-document.c | 482 +++++++++++++++++++++++++++++++++++
libyelp/yelp-info-document.h | 52 ++++
{src => libyelp}/yelp-info-parser.c | 113 ++++----
{src => libyelp}/yelp-info-parser.h | 10 +-
libyelp/yelp-magic-decompressor.c | 5 +-
libyelp/yelp-uri.c | 7 +-
src/yelp-info.c | 436 -------------------------------
src/yelp-info.h | 53 ----
11 files changed, 621 insertions(+), 557 deletions(-)
---
diff --git a/libyelp/Makefile.am b/libyelp/Makefile.am
index 770ce02..880b94b 100644
--- a/libyelp/Makefile.am
+++ b/libyelp/Makefile.am
@@ -6,6 +6,8 @@ libyelp_la_SOURCES = \
yelp-error.c \
yelp-docbook-document.c \
yelp-document.c \
+ yelp-info-document.c \
+ yelp-info-parser.c \
yelp-io-channel.c \
yelp-location-entry.c \
yelp-lzma-decompressor.c \
@@ -30,6 +32,7 @@ libyelp_la_LIBADD = \
libyelp_headers = \
yelp-docbook-document.h \
yelp-document.h \
+ yelp-info-document.h \
yelp-location-entry.h \
yelp-mallard-document.h \
yelp-settings.h \
@@ -55,6 +58,7 @@ EXTRA_DIST = \
yelp-bz2-decompressor.h \
yelp-debug.h \
yelp-error.h \
+ yelp-info-parser.h \
yelp-io-channel.h \
yelp-lzma-decompressor.h \
yelp-magic-decompressor.h \
diff --git a/libyelp/yelp-docbook-document.c b/libyelp/yelp-docbook-document.c
index 3849f53..a9c097c 100644
--- a/libyelp/yelp-docbook-document.c
+++ b/libyelp/yelp-docbook-document.c
@@ -152,9 +152,15 @@ yelp_docbook_document_dispose (GObject *object)
{
YelpDocbookDocumentPrivate *priv = GET_PRIV (object);
- g_object_unref (priv->uri);
+ if (priv->uri) {
+ g_object_unref (priv->uri);
+ priv->uri = NULL;
+ }
- g_object_unref (priv->sections);
+ if (priv->sections) {
+ g_object_unref (priv->sections);
+ priv->sections = NULL;
+ }
G_OBJECT_CLASS (yelp_docbook_document_parent_class)->dispose (object);
}
@@ -807,10 +813,9 @@ transform_finalized (YelpDocbookDocument *docbook,
{
YelpDocbookDocumentPrivate *priv = GET_PRIV (docbook);
- debug_print (DB_FUNCTION, "entering\n");
+ debug_print (DB_FUNCTION, "entering\n");
if (priv->xmldoc)
xmlFreeDoc (priv->xmldoc);
priv->xmldoc = NULL;
-
}
diff --git a/libyelp/yelp-document.c b/libyelp/yelp-document.c
index d30e402..af93cc6 100644
--- a/libyelp/yelp-document.c
+++ b/libyelp/yelp-document.c
@@ -30,6 +30,7 @@
#include "yelp-debug.h"
#include "yelp-document.h"
#include "yelp-error.h"
+#include "yelp-info-document.h"
#include "yelp-docbook-document.h"
#include "yelp-mallard-document.h"
#include "yelp-simple-document.h"
@@ -170,7 +171,7 @@ yelp_document_get_for_uri (YelpUri *uri)
/* FIXME */
break;
case YELP_URI_DOCUMENT_TYPE_INFO:
- /* FIXME */
+ document = yelp_info_document_new (uri);
break;
case YELP_URI_DOCUMENT_TYPE_TOC:
/* FIXME */
diff --git a/libyelp/yelp-info-document.c b/libyelp/yelp-info-document.c
new file mode 100644
index 0000000..13358a3
--- /dev/null
+++ b/libyelp/yelp-info-document.c
@@ -0,0 +1,482 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2007 Don Scorgie <dscorgie svn gnome org>
+ * Copyright (C) 2010 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: Don Scorgie <dscorgie svn gnome org>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <libxml/tree.h>
+
+#include "yelp-error.h"
+#include "yelp-info-document.h"
+#include "yelp-info-parser.h"
+#include "yelp-transform.h"
+#include "yelp-debug.h"
+#include "yelp-settings.h"
+
+#define STYLESHEET DATADIR"/yelp/xslt/info2html.xsl"
+
+typedef enum {
+ INFO_STATE_BLANK, /* Brand new, run transform as needed */
+ INFO_STATE_PARSING, /* Parsing/transforming document, please wait */
+ INFO_STATE_PARSED, /* All done, if we ain't got it, it ain't here */
+ INFO_STATE_STOP /* Stop everything now, object to be disposed */
+} InfoState;
+
+typedef struct _YelpInfoDocumentPrivate YelpInfoDocumentPrivate;
+struct _YelpInfoDocumentPrivate {
+ YelpUri *uri;
+ InfoState state;
+
+ GMutex *mutex;
+ GThread *thread;
+
+ xmlDocPtr xmldoc;
+ GtkTreeModel *sections;
+
+ gboolean process_running;
+ gboolean transform_running;
+
+ YelpTransform *transform;
+ guint chunk_ready;
+ guint finished;
+ guint error;
+
+ gchar *root_id;
+ gchar *visit_prev_id;
+};
+
+
+static void yelp_info_document_class_init (YelpInfoDocumentClass *klass);
+static void yelp_info_document_init (YelpInfoDocument *info);
+static void yelp_info_document_dispose (GObject *object);
+static void yelp_info_document_finalize (GObject *object);
+
+/* YelpDocument */
+static gboolean info_request_page (YelpDocument *document,
+ const gchar *page_id,
+ GCancellable *cancellable,
+ YelpDocumentCallback callback,
+ gpointer user_data);
+
+/* YelpTransform */
+static void transform_chunk_ready (YelpTransform *transform,
+ gchar *chunk_id,
+ YelpInfoDocument *info);
+static void transform_finished (YelpTransform *transform,
+ YelpInfoDocument *info);
+static void transform_error (YelpTransform *transform,
+ YelpInfoDocument *info);
+static void transform_finalized (YelpInfoDocument *info,
+ gpointer transform);
+
+static void info_document_process (YelpInfoDocument *info);
+static gboolean info_sections_visit (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ YelpInfoDocument *info);
+static void info_document_disconnect (YelpInfoDocument *info);
+
+
+G_DEFINE_TYPE (YelpInfoDocument, yelp_info_document, YELP_TYPE_DOCUMENT);
+#define GET_PRIV(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_INFO_DOCUMENT, YelpInfoDocumentPrivate))
+
+static void
+yelp_info_document_class_init (YelpInfoDocumentClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ YelpDocumentClass *document_class = YELP_DOCUMENT_CLASS (klass);
+
+ object_class->dispose = yelp_info_document_dispose;
+ object_class->finalize = yelp_info_document_finalize;
+
+ document_class->request_page = info_request_page;
+
+ g_type_class_add_private (klass, sizeof (YelpInfoDocumentPrivate));
+}
+
+static void
+yelp_info_document_init (YelpInfoDocument *info)
+{
+ YelpInfoDocumentPrivate *priv = GET_PRIV (info);
+
+ priv->state = INFO_STATE_BLANK;
+ priv->xmldoc = NULL;
+ priv->mutex = g_mutex_new ();
+}
+
+static void
+yelp_info_document_dispose (GObject *object)
+{
+ YelpInfoDocumentPrivate *priv = GET_PRIV (object);
+
+ if (priv->uri) {
+ g_object_unref (priv->uri);
+ priv->uri = NULL;
+ }
+
+ if (priv->sections) {
+ g_object_unref (priv->sections);
+ priv->sections = NULL;
+ }
+
+ if (priv->transform) {
+ g_object_unref (priv->transform);
+ priv->transform = NULL;
+ }
+
+ G_OBJECT_CLASS (yelp_info_document_parent_class)->dispose (object);
+}
+
+static void
+yelp_info_document_finalize (GObject *object)
+{
+ YelpInfoDocumentPrivate *priv = GET_PRIV (object);
+
+ if (priv->xmldoc)
+ xmlFreeDoc (priv->xmldoc);
+
+ g_free (priv->root_id);
+ g_free (priv->visit_prev_id);
+
+ g_mutex_free (priv->mutex);
+
+ G_OBJECT_CLASS (yelp_info_document_parent_class)->finalize (object);
+}
+
+/******************************************************************************/
+
+YelpDocument *
+yelp_info_document_new (YelpUri *uri)
+{
+ YelpInfoDocument *info;
+ YelpInfoDocumentPrivate *priv;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ info = (YelpInfoDocument *) g_object_new (YELP_TYPE_INFO_DOCUMENT, NULL);
+ priv = GET_PRIV (info);
+
+ priv->uri = g_object_ref (uri);
+
+ return (YelpDocument *) info;
+}
+
+
+/******************************************************************************/
+/** YelpDocument **************************************************************/
+
+static gboolean
+info_request_page (YelpDocument *document,
+ const gchar *page_id,
+ GCancellable *cancellable,
+ YelpDocumentCallback callback,
+ gpointer user_data)
+{
+ YelpInfoDocumentPrivate *priv = GET_PRIV (document);
+ gchar *docuri;
+ GError *error;
+ gboolean handled;
+
+ if (page_id == NULL)
+ page_id = priv->root_id;
+
+ handled =
+ YELP_DOCUMENT_CLASS (yelp_info_document_parent_class)->request_page (document,
+ page_id,
+ cancellable,
+ callback,
+ user_data);
+ if (handled) {
+ return;
+ }
+
+ g_mutex_lock (priv->mutex);
+
+ switch (priv->state) {
+ case INFO_STATE_BLANK:
+ priv->state = INFO_STATE_PARSING;
+ priv->process_running = TRUE;
+ g_object_ref (document);
+ priv->thread = g_thread_create ((GThreadFunc) info_document_process,
+ document, FALSE, NULL);
+ break;
+ case INFO_STATE_PARSING:
+ break;
+ case INFO_STATE_PARSED:
+ case INFO_STATE_STOP:
+ docuri = yelp_uri_get_document_uri (priv->uri);
+ error = g_error_new (YELP_ERROR, YELP_ERROR_NOT_FOUND,
+ _("The page â??%sâ?? was not found in the document â??%sâ??."),
+ page_id, docuri);
+ g_free (docuri);
+ yelp_document_signal (document, page_id,
+ YELP_DOCUMENT_SIGNAL_ERROR,
+ error);
+ g_error_free (error);
+ break;
+ }
+
+ g_mutex_unlock (priv->mutex);
+}
+
+
+/******************************************************************************/
+/** YelpTransform *************************************************************/
+
+static void
+transform_chunk_ready (YelpTransform *transform,
+ gchar *chunk_id,
+ YelpInfoDocument *info)
+{
+ YelpInfoDocumentPrivate *priv = GET_PRIV (info);
+ gchar *content;
+
+ g_assert (transform == priv->transform);
+
+ if (priv->state == INFO_STATE_STOP) {
+ info_document_disconnect (info);
+ return;
+ }
+
+ content = yelp_transform_take_chunk (transform, chunk_id);
+ yelp_document_give_contents (YELP_DOCUMENT (info),
+ chunk_id,
+ content,
+ "application/xhtml+xml");
+
+ yelp_document_signal (YELP_DOCUMENT (info),
+ chunk_id,
+ YELP_DOCUMENT_SIGNAL_CONTENTS,
+ NULL);
+}
+
+static void
+transform_finished (YelpTransform *transform,
+ YelpInfoDocument *info)
+{
+ YelpInfoDocumentPrivate *priv = GET_PRIV (info);
+ gchar *docuri;
+ GError *error;
+
+ g_assert (transform == priv->transform);
+
+ if (priv->state == INFO_STATE_STOP) {
+ info_document_disconnect (info);
+ return;
+ }
+
+ info_document_disconnect (info);
+ priv->state = INFO_STATE_PARSED;
+
+ /* We want to free priv->xmldoc, but we can't free it before transform
+ is finalized. Otherwise, we could crash when YelpTransform frees
+ its libxslt resources.
+ */
+ g_object_weak_ref ((GObject *) transform,
+ (GWeakNotify) transform_finalized,
+ info);
+
+ docuri = yelp_uri_get_document_uri (priv->uri);
+ error = g_error_new (YELP_ERROR, YELP_ERROR_NOT_FOUND,
+ _("The requested page was not found in the document â??%sâ??."),
+ docuri);
+ g_free (docuri);
+ yelp_document_error_pending ((YelpDocument *) info, error);
+ g_error_free (error);
+}
+
+static void
+transform_error (YelpTransform *transform,
+ YelpInfoDocument *info)
+{
+ YelpInfoDocumentPrivate *priv = GET_PRIV (info);
+ GError *error;
+
+ g_assert (transform == priv->transform);
+
+ if (priv->state == INFO_STATE_STOP) {
+ info_document_disconnect (info);
+ return;
+ }
+
+ error = yelp_transform_get_error (transform);
+ yelp_document_error_pending ((YelpDocument *) info, error);
+ g_error_free (error);
+
+ info_document_disconnect (info);
+}
+
+static void
+transform_finalized (YelpInfoDocument *info,
+ gpointer transform)
+{
+ YelpInfoDocumentPrivate *priv = GET_PRIV (info);
+
+ if (priv->xmldoc)
+ xmlFreeDoc (priv->xmldoc);
+ priv->xmldoc = NULL;
+}
+
+
+
+/******************************************************************************/
+/** Threaded ******************************************************************/
+
+static void
+info_document_process (YelpInfoDocument *info)
+{
+ YelpInfoDocumentPrivate *priv = GET_PRIV (info);
+ GFile *file = NULL;
+ gchar *filepath = NULL;
+ GError *error;
+ gint params_i = 0;
+ gchar **params = NULL;
+
+ file = yelp_uri_get_file (priv->uri);
+ if (file == NULL) {
+ error = g_error_new (YELP_ERROR, YELP_ERROR_NOT_FOUND,
+ _("The file does not exist."));
+ yelp_document_error_pending ((YelpDocument *) info, error);
+ g_error_free (error);
+ goto done;
+ }
+
+ filepath = g_file_get_path (file);
+ g_object_unref (file);
+ if (!g_file_test (filepath, G_FILE_TEST_IS_REGULAR)) {
+ error = g_error_new (YELP_ERROR, YELP_ERROR_NOT_FOUND,
+ _("The file â??%sâ?? does not exist."),
+ filepath);
+ yelp_document_error_pending ((YelpDocument *) info, error);
+ g_error_free (error);
+ goto done;
+ }
+
+ priv->sections = (GtkTreeModel *) yelp_info_parser_parse_file (filepath);
+ gtk_tree_model_foreach (priv->sections,
+ (GtkTreeModelForeachFunc) info_sections_visit,
+ info);
+ priv->xmldoc = yelp_info_parser_parse_tree ((GtkTreeStore *) priv->sections);
+
+ if (priv->xmldoc == NULL) {
+ error = g_error_new (YELP_ERROR, YELP_ERROR_PROCESSING,
+ _("The file â??%sâ?? could not be parsed because it is"
+ " not a well-formed info page."),
+ filepath);
+ yelp_document_error_pending ((YelpDocument *) info, error);
+ goto done;
+ }
+
+ g_mutex_lock (priv->mutex);
+ if (priv->state == INFO_STATE_STOP) {
+ g_mutex_unlock (priv->mutex);
+ goto done;
+ }
+
+ priv->transform = yelp_transform_new (STYLESHEET);
+ priv->chunk_ready =
+ g_signal_connect (priv->transform, "chunk-ready",
+ (GCallback) transform_chunk_ready,
+ info);
+ priv->finished =
+ g_signal_connect (priv->transform, "finished",
+ (GCallback) transform_finished,
+ info);
+ priv->error =
+ g_signal_connect (priv->transform, "error",
+ (GCallback) transform_error,
+ info);
+
+ params = yelp_settings_get_all_params (yelp_settings_get_default (), 0, ¶ms_i);
+
+ priv->transform_running = TRUE;
+ yelp_transform_start (priv->transform,
+ priv->xmldoc,
+ NULL,
+ (const gchar * const *) params);
+ g_strfreev (params);
+ g_mutex_unlock (priv->mutex);
+
+ done:
+ g_free (filepath);
+ priv->process_running = FALSE;
+ g_object_unref (info);
+}
+
+static gboolean
+info_sections_visit (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ YelpInfoDocument *info)
+{
+ YelpInfoDocumentPrivate *priv = GET_PRIV (info);
+ gchar *page_id, *title;
+
+ gtk_tree_model_get (model, iter,
+ INFO_PARSER_COLUMN_PAGE_NO, &page_id,
+ INFO_PARSER_COLUMN_PAGE_NAME, &title,
+ -1);
+ yelp_document_set_page_id ((YelpDocument *) info, page_id, page_id);
+ yelp_document_set_page_title ((YelpDocument *) info, page_id, title);
+
+ if (priv->root_id == NULL) {
+ priv->root_id = g_strdup (page_id);
+ yelp_document_set_page_id ((YelpDocument *) info, NULL, page_id);
+ }
+ yelp_document_set_root_id ((YelpDocument *) info, page_id, priv->root_id);
+
+ if (priv->visit_prev_id != NULL) {
+ yelp_document_set_prev_id ((YelpDocument *) info, page_id, priv->visit_prev_id);
+ yelp_document_set_next_id ((YelpDocument *) info, priv->visit_prev_id, page_id);
+ g_free (priv->visit_prev_id);
+ }
+ priv->visit_prev_id = page_id;
+ g_free (title);
+ return FALSE;
+}
+
+static void
+info_document_disconnect (YelpInfoDocument *info)
+{
+ YelpInfoDocumentPrivate *priv = GET_PRIV (info);
+ if (priv->chunk_ready) {
+ g_signal_handler_disconnect (priv->transform, priv->chunk_ready);
+ priv->chunk_ready = 0;
+ }
+ if (priv->finished) {
+ g_signal_handler_disconnect (priv->transform, priv->finished);
+ priv->finished = 0;
+ }
+ if (priv->error) {
+ g_signal_handler_disconnect (priv->transform, priv->error);
+ priv->error = 0;
+ }
+ yelp_transform_cancel (priv->transform);
+ g_object_unref (priv->transform);
+ priv->transform = NULL;
+ priv->transform_running = FALSE;
+}
diff --git a/libyelp/yelp-info-document.h b/libyelp/yelp-info-document.h
new file mode 100644
index 0000000..4013944
--- /dev/null
+++ b/libyelp/yelp-info-document.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2007 Don Scorgie <dscorgie svn 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: Don Scorgie <dscorgie svn gnome org>
+ */
+
+#ifndef __YELP_INFO_DOCUMENT_H__
+#define __YELP_INFO_DOCUMENT_H__
+
+#include <glib-object.h>
+
+#include "yelp-document.h"
+
+#define YELP_TYPE_INFO_DOCUMENT (yelp_info_document_get_type ())
+#define YELP_INFO_DOCUMENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_INFO_DOCUMENT, YelpInfoDocument))
+#define YELP_INFO_DOCUMENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_INFO_DOCUMENT, YelpInfoDocumentClass))
+#define YELP_IS_INFO_DOCUMENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_INFO_DOCUMENT))
+#define YELP_IS_INFO_DOCUMENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_INFO_DOCUMENT))
+#define YELP_INFO_DOCUMENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_INFO_DOCUMENT, YelpInfoDocumentClass))
+
+typedef struct _YelpInfoDocument YelpInfoDocument;
+typedef struct _YelpInfoDocumentClass YelpInfoDocumentClass;
+typedef struct _YelpInfoPriv YelpInfoPriv;
+
+struct _YelpInfoDocument {
+ YelpDocument parent;
+};
+
+struct _YelpInfoDocumentClass {
+ YelpDocumentClass parent_class;
+};
+
+GType yelp_info_document_get_type (void);
+YelpDocument * yelp_info_document_new (YelpUri *uri);
+
+#endif /* __YELP_INFO_DOCUMENT_H__ */
diff --git a/src/yelp-info-parser.c b/libyelp/yelp-info-parser.c
similarity index 94%
rename from src/yelp-info-parser.c
rename to libyelp/yelp-info-parser.c
index 276d878..e6f58df 100644
--- a/src/yelp-info-parser.c
+++ b/libyelp/yelp-info-parser.c
@@ -1,5 +1,6 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
- * Copyright (C) 2005 Davyd Madeley <davyd madeley id au>
+ * Copyright (C) 2005 Davyd Madeley <davyd madeley id au>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -27,9 +28,8 @@
#include <gtk/gtk.h>
#include <string.h>
-#include "yelp-io-channel.h"
#include "yelp-info-parser.h"
-#include "yelp-utils.h"
+#include "yelp-magic-decompressor.h"
#include "yelp-debug.h"
@@ -186,15 +186,6 @@ enum
PAGE_OTHER
};
-enum
-{
- COLUMN_PAGE_NO,
- COLUMN_PAGE_NAME,
- COLUMN_PAGE_CONTENT,
-
- N_COLUMNS
-};
-
static int
page_type (char *page)
{
@@ -213,32 +204,42 @@ page_type (char *page)
static char
*open_info_file (char *file)
{
- GIOChannel *channel = NULL;
- int i;
- gsize len;
- char *str;
- GError *error = NULL;
- GIOStatus result = G_IO_STATUS_NORMAL;
-
- debug_print (DB_DEBUG, "!! Opening %s...\n", file);
-
- channel = yelp_io_channel_new_file (file, &error);
- if (!channel) {
- return NULL;
- }
- result = g_io_channel_read_to_end (channel, &str, &len, &error);
- if (result != G_IO_STATUS_NORMAL) {
- return NULL;
- }
- g_io_channel_shutdown (channel, FALSE, NULL);
- g_io_channel_unref (channel);
-
- /* C/glib * cannot really handle \0 in strings, convert. */
- for (i = 0; i < (len - 1); i++)
- if (str[i] == INFO_TAG_OPEN[0] && str[i+1] == INFO_TAG_OPEN[1])
- str[i] = INFO_C_TAG_OPEN[0];
-
- return str;
+ GFile *gfile;
+ GConverter *converter;
+ GFileInputStream *file_stream;
+ GInputStream *stream;
+ gchar buf[1024];
+ gssize bytes;
+ GString *string;
+ gchar *str;
+ int i;
+
+ gfile = g_file_new_for_path (file);
+ file_stream = g_file_read (gfile, NULL, NULL);
+ converter = (GConverter *) yelp_magic_decompressor_new ();
+ stream = g_converter_input_stream_new ((GInputStream *) file_stream, converter);
+ string = g_string_new (NULL);
+
+ while ((bytes = g_input_stream_read (stream, buf, 1024, NULL, NULL)) > 0)
+ g_string_append_len (string, buf, bytes);
+
+ g_object_unref (stream);
+ /*
+ g_object_unref (converter);
+ g_object_unref (file_stream);
+ g_object_unref (file);
+ */
+
+ str = string->str;
+
+ /* C/glib * cannot really handle \0 in strings, convert. */
+ for (i = 0; i < (string->len - 1); i++)
+ if (str[i] == INFO_TAG_OPEN[0] && str[i+1] == INFO_TAG_OPEN[1])
+ str[i] = INFO_C_TAG_OPEN[0];
+
+ g_string_free (string, FALSE);
+
+ return str;
}
static gchar *
@@ -628,9 +629,9 @@ process_page (GtkTreeStore *tree, GHashTable *nodes2offsets,
tmp = g_strdup (node);
tmp = g_strdelimit (tmp, " ", '_');
gtk_tree_store_set (tree, iter,
- COLUMN_PAGE_NO, tmp,
- COLUMN_PAGE_NAME, node,
- COLUMN_PAGE_CONTENT, parts[2],
+ INFO_PARSER_COLUMN_PAGE_NO, tmp,
+ INFO_PARSER_COLUMN_PAGE_NAME, node,
+ INFO_PARSER_COLUMN_PAGE_CONTENT, parts[2],
-1);
g_free (tmp);
@@ -788,7 +789,7 @@ GtkTreeStore
* rather then consolidating these into one dictionary, we'll just
* chain our lookups */
processed_table = g_malloc0 (pages * sizeof (int));
- tree = gtk_tree_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING,
+ tree = gtk_tree_store_new (INFO_PARSER_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING);
nodes2iters = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) gtk_tree_iter_free);
@@ -828,9 +829,9 @@ parse_tree_level (GtkTreeStore *tree, xmlNodePtr *node, GtkTreeIter iter)
do
{
gtk_tree_model_get (GTK_TREE_MODEL (tree), &iter,
- COLUMN_PAGE_NO, &page_no,
- COLUMN_PAGE_NAME, &page_name,
- COLUMN_PAGE_CONTENT, &page_content,
+ INFO_PARSER_COLUMN_PAGE_NO, &page_no,
+ INFO_PARSER_COLUMN_PAGE_NAME, &page_name,
+ INFO_PARSER_COLUMN_PAGE_CONTENT, &page_content,
-1);
debug_print (DB_DEBUG, "Got Section: %s\n", page_name);
if (strstr (page_content, "*Note") ||
@@ -914,8 +915,8 @@ resolve_frag_id (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
gchar **xref = data;
gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
- COLUMN_PAGE_NO, &page_no,
- COLUMN_PAGE_NAME, &page_name,
+ INFO_PARSER_COLUMN_PAGE_NO, &page_no,
+ INFO_PARSER_COLUMN_PAGE_NAME, &page_name,
-1);
if (g_str_equal (page_name, *xref)) {
g_free (*xref);
@@ -1029,9 +1030,9 @@ yelp_info_parse_menu (GtkTreeStore *tree, xmlNodePtr *node,
ref1 = xmlNewTextChild (mholder, NULL, BAD_CAST "a",
BAD_CAST tmp);
g_free (tmp);
- tmp = g_strconcat ("?", xref, NULL);
+ tmp = g_strconcat ("xref:", xref, NULL);
xmlNewProp (ref1, BAD_CAST "href", BAD_CAST tmp);
- g_free (tmp);
+ g_free (tmp);
} else { /* Indexy type menu - we gotta do a little work to fix the
* spacing
*/
@@ -1047,19 +1048,19 @@ yelp_info_parse_menu (GtkTreeStore *tree, xmlNodePtr *node,
ref1 = xmlNewTextChild (mholder, NULL, BAD_CAST "a",
BAD_CAST title);
- tmp = g_strconcat ("?", xref, NULL);
+ tmp = g_strconcat ("xref:", xref, NULL);
xmlNewProp (ref1, BAD_CAST "href", BAD_CAST tmp);
- g_free (tmp);
+ g_free (tmp);
xmlNewTextChild (mholder, NULL, BAD_CAST "spacing",
BAD_CAST sp);
tmp = g_strconcat (g_strstrip(ref), ".", NULL);
ref1 = xmlNewTextChild (mholder, NULL, BAD_CAST "a",
BAD_CAST tmp);
g_free (tmp);
- tmp = g_strconcat ("?", xref, NULL);
+ tmp = g_strconcat ("xref:", xref, NULL);
xmlNewProp (ref1, BAD_CAST "href", BAD_CAST tmp);
- g_free (tmp);
+ g_free (tmp);
g_free (sp);
}
xmlNewTextChild (mholder, NULL, BAD_CAST "para",
@@ -1214,7 +1215,7 @@ info_process_text_notes (xmlNodePtr *node, gchar *content, GtkTreeStore *tree)
link = g_strstrip (link);
length = strlen (link) - 1;
link[length] = '\0';
- href = g_strconcat ("?", link, NULL);
+ href = g_strconcat ("xref:", link, NULL);
link[length] = 'a';
g_free (link);
@@ -1249,8 +1250,8 @@ info_process_text_notes (xmlNodePtr *node, gchar *content, GtkTreeStore *tree)
frag = g_strndup (url, tmp1 - url);
g_strstrip (frag);
gtk_tree_model_foreach (GTK_TREE_MODEL (tree), resolve_frag_id, &frag);
- href = g_strconcat ("?", frag, NULL);
- g_free (frag);
+ href = g_strconcat ("xref:", frag, NULL);
+ g_free (frag);
}
for (ulink = urls; *ulink != NULL; ulink++) {
if (ulink == urls)
diff --git a/src/yelp-info-parser.h b/libyelp/yelp-info-parser.h
similarity index 83%
rename from src/yelp-info-parser.h
rename to libyelp/yelp-info-parser.h
index 23eb71a..d338a59 100644
--- a/src/yelp-info-parser.h
+++ b/libyelp/yelp-info-parser.h
@@ -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) 2004, Davyd Madeley
*
@@ -27,7 +27,13 @@
#include <gtk/gtk.h>
#include <libxml/tree.h>
-#include "yelp-utils.h"
+enum {
+ INFO_PARSER_COLUMN_PAGE_NO,
+ INFO_PARSER_COLUMN_PAGE_NAME,
+ INFO_PARSER_COLUMN_PAGE_CONTENT,
+ INFO_PARSER_N_COLUMNS
+};
+
GtkTreeStore *yelp_info_parser_parse_file (char *file);
xmlDocPtr yelp_info_parser_parse_tree (GtkTreeStore *tree);
diff --git a/libyelp/yelp-magic-decompressor.c b/libyelp/yelp-magic-decompressor.c
index cf1b09b..f1bf5a0 100644
--- a/libyelp/yelp-magic-decompressor.c
+++ b/libyelp/yelp-magic-decompressor.c
@@ -49,7 +49,10 @@ yelp_magic_decompressor_dispose (GObject *object)
{
YelpMagicDecompressor *decompressor;
- g_object_unref (decompressor->magic_decoder_ring);
+ if (decompressor->magic_decoder_ring) {
+ g_object_unref (decompressor->magic_decoder_ring);
+ decompressor->magic_decoder_ring = NULL;
+ }
G_OBJECT_CLASS (yelp_magic_decompressor_parent_class)->dispose (object);
}
diff --git a/libyelp/yelp-uri.c b/libyelp/yelp-uri.c
index 4ea70d5..fa2497e 100644
--- a/libyelp/yelp-uri.c
+++ b/libyelp/yelp-uri.c
@@ -279,14 +279,12 @@ resolve_async (YelpUri *uri)
break;
case YELP_URI_DOCUMENT_TYPE_DOCBOOK:
case YELP_URI_DOCUMENT_TYPE_MALLARD:
+ case YELP_URI_DOCUMENT_TYPE_INFO:
resolve_xref_uri (uri);
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:
@@ -968,7 +966,8 @@ resolve_xref_uri (YelpUri *uri)
priv->frag_id ? "#" : "",
priv->frag_id ? priv->frag_id : "",
NULL);
- else if (g_str_has_prefix (priv->docuri, "file:"))
+ else if (g_str_has_prefix (priv->docuri, "file:") ||
+ g_str_has_prefix (priv->docuri, "info:") )
priv->fulluri = g_strconcat (priv->docuri,
(priv->page_id || priv->frag_id) ? "#" : "",
priv->page_id ? priv->page_id : "",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]