summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun McCance <shaunm@src.gnome.org>2004-09-28 21:06:28 +0000
committerShaun McCance <shaunm@src.gnome.org>2004-09-28 21:06:28 +0000
commite3bb4e22b3481da04d9a56f8ebfe4ae500dbbdb9 (patch)
treef576e829c0a7ddde4b64670e393716a330ed436f
parent1ecf041bc228ac8731c0ed8916acb0cffcdb0925 (diff)
downloadyelp-e3bb4e22b3481da04d9a56f8ebfe4ae500dbbdb9.tar.gz
- Added yelp-utils.[ch], which will simplify things eventually
* src/Makefile.am: * src/test-uri.c: * src/yelp-utils.c: * src/yelp-utils.h: - Added yelp-utils.[ch], which will simplify things eventually
-rw-r--r--ChangeLog8
-rw-r--r--src/Makefile.am9
-rw-r--r--src/test-uri.c89
-rw-r--r--src/yelp-utils.c423
-rw-r--r--src/yelp-utils.h67
5 files changed, 546 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index e770cb65..a086559d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2004-09-28 Shaun McCance <shaunm@gnome.org>
+
+ * src/Makefile.am:
+ * src/test-uri.c:
+ * src/yelp-utils.c:
+ * src/yelp-utils.h:
+ - Added yelp-utils.[ch], which will simplify things eventually
+
2004-09-24 Shaun McCance <shaunm@gnome.org>
* configure.in:
diff --git a/src/Makefile.am b/src/Makefile.am
index 50903e10..03943ac5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,7 +20,7 @@ INCLUDES = \
-DBINDIR=\""$(bindir)"\"
bin_PROGRAMS = yelp
-noinst_PROGRAMS = test-man-parser test-pager
+check_PROGRAMS = test-man-parser test-pager test-uri
yelp_LDFLAGS = -R$(MOZILLA_HOME)
@@ -64,6 +64,13 @@ test_pager_SOURCES = \
test_pager_LDADD = @YELP_LIBS@ $(POPT_LIBS) $(Z_LIBS) $(BZ_LIBS)
+test_uri_SOURCES = \
+ yelp-uri.c yelp-uri.h \
+ yelp-utils.c yelp-utils.h \
+ test-uri.c
+
+test_uri_LDADD = @YELP_LIBS@
+
yelp_SOURCES = \
$(gnome_yelp_idl_sources) \
yelp-base.c yelp-base.h \
diff --git a/src/test-uri.c b/src/test-uri.c
index e1ed8dfb..ea9aa3bf 100644
--- a/src/test-uri.c
+++ b/src/test-uri.c
@@ -26,67 +26,55 @@
#include <libgnome/gnome-program.h>
#include <libgnomevfs/gnome-vfs.h>
+#include "yelp-utils.h"
#include "yelp-uri.h"
-static void
-print_uri (YelpURI *uri)
+static void
+print_document_info (YelpDocumentInfo *doc)
{
gchar *type;
- gchar *str_uri;
-
- switch (yelp_uri_get_resource_type (uri)) {
- 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_ERROR:
- type = "YELP_URI_TYPE_ERROR";
- break;
- case YELP_URI_TYPE_GHELP:
- type = "YELP_URI_TYPE_GHELP";
+
+ switch (doc->type) {
+ case YELP_TYPE_ERROR:
+ type = "YELP_TYPE_ERROR";
break;
- case YELP_URI_TYPE_HTML:
- type = "YELP_URI_TYPE_HTML";
+ case YELP_TYPE_DOCBOOK_XML:
+ type = "YELP_TYPE_DOCBOOK_XML";
break;
- case YELP_URI_TYPE_MAN:
- type = "YELP_URI_TYPE_MAN";
+ case YELP_TYPE_DOCBOOK_SGML:
+ type = "YELP_TYPE_DOCBOOK_SGML";
break;
- case YELP_URI_TYPE_INFO:
- type = "YELP_URI_TYPE_INFO";
+ case YELP_TYPE_HTML:
+ type = "YELP_TYPE_HTML";
break;
- case YELP_URI_TYPE_TOC:
- type = "YELP_URI_TYPE_TOC";
+ case YELP_TYPE_MAN:
+ type = "YELP_TYPE_MAN";
break;
- case YELP_URI_TYPE_PATH:
- type = "YELP_URI_TYPE_PATH";
+ case YELP_TYPE_INFO:
+ type = "YELP_TYPE_INFO";
break;
- case YELP_URI_TYPE_FILE:
- type = "YELP_URI_TYPE_FILE";
+ case YELP_TYPE_TOC:
+ type = "YELP_TYPE_DOC";
break;
- default:
- type = NULL;
+ case YELP_TYPE_EXTERNAL:
+ type = "YELP_TYPE_EXTERNAL";
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);
- */
+ printf ("Address: %i\n"
+ "URI: %s\n"
+ "Type: %s\n",
+ (gint) doc,
+ doc->uri,
+ type);
}
int
main (int argc, char **argv)
{
GnomeProgram *program;
- GnomeVFSURI *uri;
+ YelpDocumentInfo *doc;
+ gint i;
if (argc < 2) {
g_print ("Usage: test-uri uri\n");
@@ -94,20 +82,23 @@ main (int argc, char **argv)
}
program = gnome_program_init (PACKAGE, VERSION,
- LIBGNOME_MODULE,
- argc, argv,
+ LIBGNOME_MODULE, argc, argv,
GNOME_PROGRAM_STANDARD_PROPERTIES,
NULL);
gnome_vfs_init ();
- uri = yelp_uri_new (argv[1]);
-
- g_print ("STRING : %s\n", argv[1]);
+ yelp_utils_init ();
- print_uri (uri);
-
- gnome_vfs_uri_unref (uri);
+ for (i = 1; i < argc; i++) {
+ if (i != 1)
+ printf ("\n");
+ doc = yelp_document_info_get (argv[i]);
+ if (doc)
+ print_document_info (doc);
+ else
+ printf ("Failed to load URI: %s\n", argv[i]);
+ }
gnome_vfs_shutdown ();
diff --git a/src/yelp-utils.c b/src/yelp-utils.c
new file mode 100644
index 00000000..a4f6b712
--- /dev/null
+++ b/src/yelp-utils.c
@@ -0,0 +1,423 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2003 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 <glib.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <libgnomevfs/gnome-vfs-mime-utils.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-program.h>
+
+#include "yelp-utils.h"
+#include "yelp-uri.h"
+
+#include <string.h>
+
+#define d(x)
+
+GHashTable *document_info_table;
+GMutex *document_info_mutex;
+
+static gchar * convert_ghelp_uri (gchar *uri);
+static gchar * convert_man_uri (gchar *uri);
+static gchar * convert_info_uri (gchar *uri);
+static YelpDocumentType get_document_type (gchar *uri);
+
+void
+yelp_utils_init (void)
+{
+ document_info_mutex = g_mutex_new ();
+ document_info_table =
+ g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ (GDestroyNotify) yelp_document_info_free);
+}
+
+YelpDocumentInfo *
+yelp_document_info_new (gchar *uri)
+{
+ YelpDocumentInfo *doc;
+ gchar *doc_uri;
+ YelpDocumentType doc_type;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ if (!strncmp (uri, "file:", 5)) {
+ doc_uri = g_strdup (uri);
+ doc_type = get_document_type (doc_uri);
+ }
+ if (!strncmp (uri, "ghelp:", 6)) {
+ doc_uri = convert_ghelp_uri (uri);
+ if (doc_uri)
+ doc_type = get_document_type (doc_uri);
+ }
+ else if (!strncmp (uri, "man:", 4)) {
+ doc_uri = convert_man_uri (uri);
+ doc_type = YELP_TYPE_MAN;
+ }
+ else if (!strncmp (uri, "info:", 5)) {
+ doc_uri = convert_info_uri (uri);
+ doc_type = YELP_TYPE_DOCBOOK_XML;
+ }
+ else if (!strncmp (uri, "x-yelp-toc:", 11)) {
+ }
+
+ if (doc_uri) {
+ doc = g_new0 (YelpDocumentInfo, 1);
+ doc->uri = doc_uri;
+ doc->type = doc_type;
+ return doc;
+ } else {
+ return NULL;
+ }
+}
+
+YelpDocumentInfo *
+yelp_document_info_get (gchar *uri)
+{
+ YelpDocumentInfo *doc;
+
+ g_mutex_lock (document_info_mutex);
+
+ doc = (YelpDocumentInfo *) g_hash_table_lookup (document_info_table, uri);
+
+ if (!doc) {
+ doc = yelp_document_info_new (uri);
+ if (doc && doc->type != YELP_TYPE_EXTERNAL) {
+ YelpDocumentInfo *old_doc;
+
+ if ((old_doc = g_hash_table_lookup (document_info_table, doc->uri))) {
+ yelp_document_info_free (doc);
+ doc = old_doc;
+ g_hash_table_insert (document_info_table,
+ g_strdup (uri),
+ doc);
+ } else {
+ g_hash_table_insert (document_info_table,
+ g_strdup (uri),
+ doc);
+ if (!g_str_equal (uri, doc->uri))
+ g_hash_table_insert (document_info_table,
+ g_strdup (doc->uri),
+ doc);
+ }
+ }
+ }
+
+ g_mutex_unlock (document_info_mutex);
+ return doc;
+}
+
+void
+yelp_document_info_free (YelpDocumentInfo *doc)
+{
+ if (!doc)
+ return;
+
+ g_free (doc->uri);
+ g_free (doc);
+}
+
+void
+yelp_document_page_free (YelpDocumentPage *page)
+{
+ if (!page)
+ return;
+
+ g_free (page->page_id);
+ g_free (page->title);
+ g_free (page->contents);
+
+ g_free (page->prev_id);
+ g_free (page->next_id);
+ g_free (page->toc_id);
+
+ g_free (page);
+}
+
+static YelpDocumentType
+get_document_type (gchar *uri)
+{
+ gchar *mime_type;
+ YelpDocumentType type;
+
+ g_return_val_if_fail (uri != NULL, YELP_TYPE_ERROR);
+
+ if (strncmp (uri, "file:", 5))
+ return YELP_TYPE_EXTERNAL;
+
+ mime_type = gnome_vfs_get_mime_type (uri);
+ g_return_val_if_fail (mime_type != NULL, YELP_TYPE_ERROR);
+
+ if (g_str_equal (mime_type, "text/xml"))
+ type = YELP_URI_TYPE_DOCBOOK_XML;
+ else if (g_str_equal (mime_type, "text/sgml"))
+ type = YELP_URI_TYPE_DOCBOOK_SGML;
+ else if (g_str_equal (mime_type, "text/html"))
+ type = YELP_URI_TYPE_HTML;
+ else
+ type = YELP_URI_TYPE_EXTERNAL;
+
+ g_free (mime_type);
+ return type;
+}
+
+/******************************************************************************/
+/** Convert fancy URIs to file URIs *******************************************/
+
+static gchar *
+locate_file_lang (gchar *path, gchar *file, gchar *lang)
+{
+ gchar *exts[] = {".xml", ".docbook", ".sgml", ".html", "", NULL};
+ gint i;
+ gchar *full, *uri = NULL;
+
+ for (i = 0; exts[i] != NULL; i++) {
+ full = g_strconcat (path, "/", lang, "/", file, exts[i], NULL);
+ if (g_file_test (full, G_FILE_TEST_EXISTS))
+ uri = g_strconcat ("file://", full, NULL);
+ g_free (full);
+ if (uri)
+ return uri;
+ }
+ return NULL;
+}
+
+static gchar *
+convert_ghelp_uri (gchar *uri)
+{
+ GSList *locations = NULL;
+ GSList *node;
+ gchar *path, *cur;
+ gchar *doc_id = NULL;
+ gchar *doc_name = NULL;
+ gchar *doc_uri = NULL;
+
+ GnomeProgram *program = gnome_program_get ();
+
+ if ((path = strchr(uri, ':')))
+ path++;
+ else
+ goto done;
+
+ if (path && path[0] == '/') {
+ if ((cur = strchr (path, '?')) || (cur = strchr (path, '#')))
+ *cur = '\0';
+ doc_uri = g_strconcat ("file://", path, NULL);
+ if (cur)
+ *cur = '#';
+
+ goto done;
+ }
+
+ if ((cur = strchr (path, '/'))) {
+ doc_id = g_strndup (path, cur - path);
+ path = cur + 1;
+ }
+
+ if ((cur = strchr (path, '?')) || (cur = strchr (path, '#')))
+ doc_name = g_strndup (path, cur - path);
+ else
+ doc_name = g_strdup (path);
+
+ if (doc_id)
+ gnome_program_locate_file (program,
+ GNOME_FILE_DOMAIN_HELP,
+ doc_id,
+ FALSE,
+ &locations);
+ else
+ gnome_program_locate_file (program,
+ GNOME_FILE_DOMAIN_HELP,
+ doc_name,
+ FALSE,
+ &locations);
+
+ if (!locations)
+ goto done;
+
+ for (node = locations; node; node = node->next) {
+ const GList *langs;
+ gchar *location = (gchar *) node->data;
+
+ 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;
+
+ doc_uri = locate_file_lang (location, doc_name, lang);
+
+ if (!doc_uri)
+ doc_uri = locate_file_lang (location, "index", lang);
+
+ if (doc_uri)
+ goto done;
+ }
+
+ /* Look in C locale since that exists for almost all documents */
+ doc_uri = locate_file_lang (location, doc_name, "C");
+ if (doc_uri)
+ goto done;
+
+ /* Last chance, look for index-file with C lang */
+ doc_uri = locate_file_lang (location, "index", "C");
+ }
+
+ done:
+ if (locations) {
+ g_slist_foreach (locations, (GFunc) g_free, NULL);
+ g_slist_free (locations);
+ }
+ g_free (doc_id);
+ g_free (doc_name);
+
+ if (!doc_uri)
+ g_warning ("Could not resolve ghelp URI: %s", uri);
+
+ return doc_uri;
+}
+
+static gchar *
+convert_man_uri (gchar *uri)
+{
+ gchar *path, *cur;
+ gchar *doc_uri = NULL;
+ gchar *man_name = NULL;
+ gchar *man_num = NULL;
+ gchar *man_dir = NULL;
+
+ static gchar **manpath = NULL;
+ static gchar *mandirs[] =
+ {"man1", "man2", "man3", "man4", "man5", "man6",
+ "man7", "man8", "man9", "mann", NULL};
+ gint i, j;
+
+ GDir *dir;
+ gchar *dirname;
+ const gchar *filename;
+ gchar *pattern;
+ GPatternSpec *pspec = NULL;
+
+ if ((path = strchr(uri, ':')))
+ path++;
+ else
+ goto done;
+
+ /* An absolute file path after man: */
+ if (path[0] == '/') {
+ doc_uri = g_strconcat ("file://", path, NULL);
+ goto done;
+ }
+
+ /* Get the manpath, either from the 'manpath' command, for from the
+ MANPATH envar. manpath is static, so this should only run once
+ for each program invocation.
+ */
+ if (!manpath) {
+ gchar *man;
+
+ if (!g_spawn_command_line_sync ("manpath", &man, NULL, NULL, NULL))
+ man = g_strdup (g_getenv ("MANPATH"));
+
+ g_strstrip (man);
+ manpath = g_strsplit (man, ":", -1);
+
+ g_free (man);
+ }
+
+ /* The URI is either man:frobnicate or man:frobnicate(1). If the former,
+ set man_name to everything after man:. If the latter, set man_name to
+ everything leading to (1), and man_num to the section number.
+ */
+ if ((cur = strchr (path, '('))) {
+ man_name = g_strndup (path, cur - path);
+ path = cur + 1;
+ if ((cur = strchr (path, ')')))
+ man_num = g_strndup (path, cur - path);
+ if (man_num[0]) {
+ man_dir = g_new (gchar, 5);
+ g_snprintf (man_dir, 5, "man%c", man_num[0]);
+ }
+ } else {
+ man_name = g_strdup (path);
+ }
+
+ /* Create the glob pattern. If we have man_num, then look for
+ man_name.man_num*. Otherwise, looks for man_name.*
+ */
+ if (man_num && man_num[0])
+ pattern = g_strdup_printf ("%s.%s*", man_name, man_num);
+ else
+ pattern = g_strdup_printf ("%s.*", man_name);
+ pspec = g_pattern_spec_new (pattern);
+ g_free (pattern);
+
+ for (i = 0; manpath[i]; i++) {
+ /* The man_dir/mandirs thing is probably cleverer than it should be. */
+ for (j = 0; man_dir ? j < 1 : mandirs[j]; j++) {
+ dirname = g_build_filename (manpath[i],
+ man_dir ? man_dir : mandirs[j],
+ NULL);
+ dir = g_dir_open (dirname, 0, NULL);
+ if (dir) {
+ while ((filename = g_dir_read_name (dir))) {
+ if (g_pattern_match_string (pspec, filename)) {
+ doc_uri = g_strconcat ("file://",
+ dirname, "/",
+ filename,
+ NULL);
+ g_dir_close (dir);
+ g_free (dirname);
+ goto done;
+ }
+ }
+ g_dir_close (dir);
+ }
+ g_free (dirname);
+ }
+ }
+
+ done:
+ g_pattern_spec_free (pspec);
+ g_free (man_dir);
+ g_free (man_num);
+ g_free (man_name);
+
+ return doc_uri;
+}
+
+static gchar *
+convert_info_uri (gchar *uri)
+{
+ // FIXME;
+ return NULL;
+}
diff --git a/src/yelp-utils.h b/src/yelp-utils.h
new file mode 100644
index 00000000..4c1e2978
--- /dev/null
+++ b/src/yelp-utils.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2003 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_UTILS_H__
+#define __YELP_UTILS_H__
+
+#include "yelp-uri.h"
+
+typedef struct _YelpDocumentInfo YelpDocumentInfo;
+typedef struct _YelpDocumentPage YelpDocumentPage;
+
+typedef enum {
+ YELP_TYPE_ERROR = 0,
+ YELP_TYPE_DOCBOOK_XML,
+ YELP_TYPE_DOCBOOK_SGML,
+ YELP_TYPE_HTML,
+ YELP_TYPE_MAN,
+ YELP_TYPE_INFO,
+ YELP_TYPE_TOC,
+ YELP_TYPE_EXTERNAL
+} YelpDocumentType;
+
+struct _YelpDocumentInfo {
+ gchar *uri;
+
+ YelpDocumentType type;
+};
+
+struct _YelpDocumentPage {
+ YelpDocumentInfo *document;
+ gchar *page_id;
+ gchar *title;
+ gchar *contents;
+
+ gchar *prev_id;
+ gchar *next_id;
+ gchar *toc_id;
+};
+
+void yelp_utils_init (void);
+
+YelpDocumentInfo * yelp_document_info_new (gchar *uri);
+YelpDocumentInfo * yelp_document_info_get (gchar *uri);
+void yelp_document_info_free (YelpDocumentInfo *doc);
+
+void yelp_document_page_free (YelpDocumentPage *page);
+
+#endif /* __YELP_PAGER_H__ */