summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavyd Madeley <davyd@madeley.id.au>2005-01-02 08:11:37 +0000
committerDavyd Madeley <davyd@src.gnome.org>2005-01-02 08:11:37 +0000
commita41b04e4335343dea793cba7a5c3069507cac748 (patch)
treed3cc2dc2d3371be7dc932f4668464172deeb9196
parent66a1f51d59e4785eb356678feeea32216ec1337b (diff)
downloadyelp-a41b04e4335343dea793cba7a5c3069507cac748.tar.gz
Chained info support, parser fixes, and free some memory we'll never need
2005-01-02 Davyd Madeley <davyd@madeley.id.au> * src/yelp-info-parser.c: Chained info support, parser fixes, and free some memory we'll never need again a little earlier to save space.
-rw-r--r--ChangeLog5
-rw-r--r--src/yelp-info-parser.c156
2 files changed, 154 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 3c9ee87a..b5c8ee1c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2005-01-02 Davyd Madeley <davyd@madeley.id.au>
+
+ * src/yelp-info-parser.c: Chained info support, parser fixes, and free
+ some memory we'll never need again a little earlier to save space.
+
2005-01-01 Shaun McCance <shaunm@gnome.org>
* src/yelp-db-pager.c:
diff --git a/src/yelp-info-parser.c b/src/yelp-info-parser.c
index bd5b2599..49fb9356 100644
--- a/src/yelp-info-parser.c
+++ b/src/yelp-info-parser.c
@@ -16,6 +16,7 @@ enum
{
PAGE_TAG_TABLE,
PAGE_NODE,
+ PAGE_INDIRECT,
PAGE_OTHER
};
@@ -33,12 +34,104 @@ page_type (char *page)
{
if (strncmp (page, "Tag Table:\n", 11) == 0)
return PAGE_TAG_TABLE;
+ else if (strncmp (page, "Indirect:\n", 10) == 0)
+ return PAGE_INDIRECT;
else if (strncmp (page, "File: ", 6) == 0)
return PAGE_NODE;
else
return PAGE_OTHER;
}
+static char
+*open_info_file (char *file)
+{
+ GIOChannel *channel;
+ int i;
+ int len;
+ char *str;
+
+ g_print ("!! Opening %s...\n", file);
+
+ channel = yelp_io_channel_new_file (file, NULL);
+ g_io_channel_read_to_end (channel, &str, &len, NULL);
+ g_io_channel_shutdown (channel, FALSE, NULL);
+
+ for (i = 0; i < len - 1; i++)
+ {
+ if (str[i] == '\0' && str[i+1] == '\b')
+ {
+ g_print ("=> got a NULL, replacing\n");
+ str[i] = ' '; str[i+1] = ' ';
+ }
+ }
+
+ return str;
+}
+
+static char
+*process_indirect_map (char *page)
+{
+ char **lines;
+ char **ptr;
+ char *composite;
+
+ lines = g_strsplit (page, "\n", 0);
+ composite = NULL;
+
+ for (ptr = lines + 1; *ptr != NULL; ptr++);
+ for (ptr--; ptr != lines; ptr--)
+ {
+ char **items;
+ char *filename;
+ char *str;
+ char **pages;
+ int offset;
+ int plength;
+
+ g_print ("Line: %s\n", *ptr);
+ items = g_strsplit (*ptr, ": ", 2);
+
+ if (items[0])
+ {
+ filename = g_strdup_printf (
+ "/usr/share/info/%s.gz", items[0]);
+ str = open_info_file (filename);
+
+ pages = g_strsplit (str, "", 2);
+ g_free (str);
+
+ offset = atoi(items[1]);
+ plength = strlen(pages[1]);
+
+ g_print ("Need to make string %s+%i bytes = %i\n",
+ items[1], plength,
+ offset + plength);
+
+ if (!composite) /* not yet created, malloc it */
+ {
+ int length;
+
+ length = offset + plength;
+ composite = g_malloc (sizeof (char) *
+ length + 1);
+ memset (composite, '-', length);
+ composite[length + 1] = '\0';
+ }
+ composite[offset] = '';
+ memcpy (composite + offset + 1, pages[1], plength);
+
+ g_free (filename);
+ g_strfreev (pages);
+ }
+
+ g_strfreev (items);
+ }
+
+ g_strfreev (lines);
+
+ return composite;
+}
+
static GHashTable
*process_tag_table (char *page)
{
@@ -191,9 +284,16 @@ process_page (GtkTreeStore *tree, GHashTable *nodes2offsets,
node2iter (nodes2iters, up));
}
else if (up && prev)
+ {
+ g_print ("+++ Parent: %s Previous: %s\n", up, prev);
+ if (node2iter (nodes2iters, up))
+ g_print ("++++ Have parent node!\n");
+ if (node2iter (nodes2iters, prev))
+ g_print ("++++ Have previous node!\n");
gtk_tree_store_insert_after (tree, iter,
node2iter (nodes2iters, up),
node2iter (nodes2iters, prev));
+ }
else
{
g_print ("# node %s was not put in tree\n", node);
@@ -232,26 +332,25 @@ GtkTreeStore
GHashTable *nodes2iters;
int *processed_table;
GtkTreeStore *tree;
+ int pt;
char *str;
- int len;
- GIOChannel *channel;
-
- channel = yelp_io_channel_new_file (file, NULL);
- g_io_channel_read_to_end (channel, &str, &len, NULL);
- g_io_channel_shutdown (channel, FALSE, NULL);
+ gboolean chained_info;
+ str = open_info_file (file);
page_list = g_strsplit (str, "\n", 0);
g_free (str);
pages = 0;
offset = 0;
+ chained_info = FALSE;
offsets2pages = g_hash_table_new (g_str_hash, g_str_equal);
for (ptr = page_list; *ptr != NULL; ptr++)
{
g_print ("page %i at offset %i\n", pages, offset);
+/* g_print ("page starts:\n%s...\n", *ptr); */
g_hash_table_insert (offsets2pages,
g_strdup_printf ("%i", offset),
@@ -261,13 +360,47 @@ GtkTreeStore
offset += strlen (*ptr);
if (pages) offset += 2;
pages++;
- if (page_type (*ptr) == PAGE_TAG_TABLE)
+ pt = page_type (*ptr);
+ if (pt == PAGE_TAG_TABLE)
{
g_print ("Have the Tag Table\n");
/* this needs to be freed later too */
nodes2offsets = process_tag_table (*ptr);
break;
}
+ else if (pt == PAGE_INDIRECT)
+ {
+ g_print ("Have the indirect mapping table\n");
+ chained_info = TRUE;
+ str = process_indirect_map (*ptr);
+ }
+ }
+
+ if (chained_info)
+ {
+ /* this is a chained info file, and therefore will require
+ * more processing */
+ g_strfreev (page_list);
+ g_hash_table_destroy (offsets2pages);
+
+ pages = 0;
+ offset = 0;
+
+ page_list = g_strsplit (str, "\n", 0);
+ offsets2pages = g_hash_table_new (g_str_hash, g_str_equal);
+
+ g_free (str);
+
+ for (ptr = page_list; *ptr != NULL; ptr++)
+ {
+ g_print ("page %i at offset %i\n", pages, offset);
+ g_hash_table_insert (offsets2pages,
+ g_strdup_printf ("%i", offset),
+ GINT_TO_POINTER (pages));
+ offset += strlen (*ptr);
+ if (pages) offset += 2;
+ pages++;
+ }
}
/* at this point we have two dictionaries,
@@ -322,6 +455,11 @@ parse_tree_level (GtkTreeStore *tree, xmlNodePtr *node, GtkTreeIter iter)
newnode = xmlNewTextChild (*node, NULL,
BAD_CAST "Section",
page_content);
+ /* if we free the page content, now it's in the XML, we can
+ * save some memory */
+ g_free (page_content);
+ page_content = NULL;
+
xmlNewProp (newnode, "id", g_strdup (page_no));
xmlNewProp (newnode, "name", g_strdup (page_name));
if (gtk_tree_model_iter_children (GTK_TREE_MODEL (tree),
@@ -340,8 +478,10 @@ yelp_info_parser_parse_tree (GtkTreeStore *tree)
xmlNodePtr node;
GtkTreeIter iter;
+ /*
xmlChar *xmlbuf;
int bufsiz;
+ */
doc = xmlNewDoc ("1.0");
node = xmlNewNode (NULL, BAD_CAST "Info");
@@ -358,8 +498,10 @@ yelp_info_parser_parse_tree (GtkTreeStore *tree)
else
g_print ("Empty tree?\n");
+ /*
xmlDocDumpFormatMemory (doc, &xmlbuf, &bufsiz, 1);
g_print ("XML follows:\n%s\n", xmlbuf);
+ */
return doc;
}