[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[5466] free contents during apropos search
From: |
Gavin D. Smith |
Subject: |
[5466] free contents during apropos search |
Date: |
Mon, 21 Apr 2014 17:32:27 +0000 |
Revision: 5466
http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=5466
Author: gavin
Date: 2014-04-21 17:32:26 +0000 (Mon, 21 Apr 2014)
Log Message:
-----------
free contents during apropos search
Modified Paths:
--------------
trunk/ChangeLog
trunk/info/indices.c
trunk/info/nodes.c
trunk/info/nodes.h
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2014-04-21 15:22:24 UTC (rev 5465)
+++ trunk/ChangeLog 2014-04-21 17:32:26 UTC (rev 5466)
@@ -1,5 +1,16 @@
-2014-04-17 Gavin Smith <address@hidden>
+2014-04-21 Gavin Smith <address@hidden>
+ * info/nodes.c: (info_node_of_file_buffer_tags, info_node_of_tag):
+ Function split out.
+ (find_node_of_anchor): Function merged into info_node_of_tag. Don't
+ assume anything about length of node separator.
+
+ * info/indices.c (info_indices_of_file_buffer): Call info_node_of_tag
+ instead of info_get_node. Free contents after each file searched
+ to conserve memory.
+
+2014-04-21 Gavin Smith <address@hidden>
+
* info/nodes.c: Minor formatting.
(SUBFILE, get_tags_of_indirect_tags_table): Move typedef
into body of function.
Modified: trunk/info/indices.c
===================================================================
--- trunk/info/indices.c 2014-04-21 15:22:24 UTC (rev 5465)
+++ trunk/info/indices.c 2014-04-21 17:32:26 UTC (rev 5466)
@@ -55,7 +55,8 @@
static size_t index_nodenames_slots = 0;
/* Add the name of NODE, and the range of the associated index elements
- (passed in ARRAY) to index_nodenames. */
+ (passed in ARRAY) to index_nodenames. ARRAY must have at least one
+ element. */
static void
add_index_to_index_nodenames (REFERENCE **array, NODE *node)
{
@@ -137,9 +138,8 @@
NODE *node;
REFERENCE **menu;
- /* Found one. Get its menu. */
- node = info_get_node (tag->filename, tag->nodename,
- PARSE_NODE_VERBATIM);
+ node = info_node_of_tag (file_buffer, &file_buffer->tags[i]);
+
if (!node)
continue;
@@ -628,6 +628,9 @@
/* Concatenate with the other indices. */
all_indices = info_concatenate_references (all_indices, this_index);
}
+ /* Try to avoid running out of memory */
+ free (this_fb->contents);
+ this_fb->contents = NULL;
}
info_free_references (dir_menu);
Modified: trunk/info/nodes.c
===================================================================
--- trunk/info/nodes.c 2014-04-21 15:22:24 UTC (rev 5465)
+++ trunk/info/nodes.c 2014-04-21 17:32:26 UTC (rev 5466)
@@ -883,7 +883,6 @@
char **filename, char **nodename,
char *filename_in, char *nodename_in);
static void node_set_body_start (NODE *node);
-static NODE *find_node_of_anchor (FILE_BUFFER *file_buffer, NODE *tag);
static int adjust_nodestart (FILE_BUFFER *file_buffer, NODE *tag);
static NODE *info_node_of_file_buffer_tags (FILE_BUFFER *file_buffer,
char *nodename);
@@ -1073,74 +1072,6 @@
return node;
}
-/* Return the node that contains TAG in FILE_BUFFER, else
- (pathologically) NULL. Called from info_node_of_file_buffer_tags. */
-static NODE *
-find_node_of_anchor (FILE_BUFFER *file_buffer, NODE *tag)
-{
- int anchor_pos, node_pos;
- NODE *node_tag;
- NODE *node;
-
- /* Look through the tag list for the anchor. */
- for (anchor_pos = 0; file_buffer->tags[anchor_pos]; anchor_pos++)
- {
- NODE *t = file_buffer->tags[anchor_pos];
- if (t->nodestart == tag->nodestart)
- break;
- }
-
- /* Should not happen, because we should always find the anchor. */
- if (!file_buffer->tags[anchor_pos])
- return NULL;
-
- /* We've found the anchor. Look backwards in the tag table for the
- preceding node (we're assuming the tags are given in order),
- skipping over any preceding anchors. */
- for (node_pos = anchor_pos - 1;
- node_pos >= 0 && file_buffer->tags[node_pos]->nodelen == 0;
- node_pos--)
- ;
-
- /* An info file with an anchor before any nodes is pathological, but
- it's possible, so don't crash. */
- if (node_pos < 0)
- return NULL;
-
- /* We have the tag for the node that contained the anchor tag. */
- node_tag = file_buffer->tags[node_pos];
-
- /* Look up the node name in the tag table to get the actual node.
- This is a recursive call, but it can't recurse again, because we
- call it with a real node. */
- node = info_node_of_file_buffer_tags (file_buffer, node_tag->nodename);
-
- /* Start displaying the node at the anchor position. */
- if (node)
- { /* The nodestart for real nodes is three characters before the `F'
- in the `File:' line (a newline, the CTRL-_, and another
- newline). The nodestart for anchors is the actual position.
- But we offset by only 2, rather than 3, because if an anchor is
- at the beginning of a paragraph, it's nicer for it to end up on
- the beginning of the first line of the paragraph rather than
- the blank line before it. (makeinfo has no way of knowing that
- a paragraph is going to start, so we can't fix it there.) */
- node->display_pos = file_buffer->tags[anchor_pos]->nodestart
- - (node_tag->nodestart + 2);
-
- /* Otherwise an anchor at the end of a node ends up displaying at
- the end of the last line of the node (way over on the right of
- the screen), which looks wrong. */
- if (node->display_pos >= (unsigned long) node->nodelen)
- node->display_pos = node->nodelen - 1;
-
- /* Don't search in the node for the xref text, it's not there. */
- node->flags |= N_FromAnchor;
- }
-
- return node;
-}
-
/* Magic number that RMS used to decide how much a tags table pointer could
be off by. I feel that it should be much smaller, like 4. */
#define DEFAULT_INFO_FUDGE 1000
@@ -1219,102 +1150,152 @@
tag->nodelen = get_node_length (&node_body);
}
-/* Return the node from FILE_BUFFER which matches NODENAME by searching
- the tags table in FILE_BUFFER, or NULL. */
-static NODE *
-info_node_of_file_buffer_tags (FILE_BUFFER *file_buffer, char *nodename)
+/* Return the node described by *TAG_PTR, retrieving contents from subfile
+ if the file is split. Return 0 on failure. */
+NODE *
+info_node_of_tag (FILE_BUFFER *fb, NODE **tag_ptr)
{
- NODE *tag;
- int i;
+ NODE *tag = *tag_ptr;
+ NODE *node;
+ /* If not a split file, subfile == fb */
+ FILE_BUFFER *subfile;
+
+ if (!strcmp (fb->filename, tag->filename))
+ subfile = fb;
+ else
+ subfile = info_find_file_internal (tag->filename, INFO_NO_TAGS);
+ if (!subfile)
+ return NULL;
- /* If no tags at all (possibly a misformatted info file), quit. */
- if (!file_buffer->tags)
+ if (!subfile->contents)
+ {
+ info_reload_file_buffer_contents (subfile);
+ if (!subfile->contents)
+ return NULL;
+ }
+
+ /* If we were able to find this file and load it, then return
+ the node within it. */
+ if (!(tag->nodestart >= 0 && tag->nodestart < subfile->filesize))
return NULL;
- for (i = 0; (tag = file_buffer->tags[i]); i++)
- if (strcmp (nodename, tag->nodename) == 0)
- {
- NODE *node;
- /* If not a split file, subfile == file_buffer */
- FILE_BUFFER *subfile = info_find_file_internal (tag->filename,
- INFO_NO_TAGS);
- if (!subfile)
- return NULL;
+ node = 0;
- if (!subfile->contents)
- {
- info_reload_file_buffer_contents (subfile);
- if (!subfile->contents)
- return NULL;
- }
+ /* If not an anchor and contents of node are not available: */
+ if (tag->nodelen != 0 && !tag->contents)
+ {
+ char *new_contents;
+ long new_nodelen;
- /* If we were able to find this file and load it, then return
- the node within it. */
- if (!(tag->nodestart >= 0 && tag->nodestart < subfile->filesize))
- return NULL;
+ /* If TAG->nodelen hasn't been calculated yet, then we aren't
+ in a position to trust the entry pointer. Adjust things so
+ that ENTRY->nodestart gets the exact address of the start of
+ the node separator which starts this node. If we cannot
+ do that, the node isn't really here. */
+ if (tag->nodelen == -1)
+ {
+ char *node_sep;
- node = 0;
+ if (!adjust_nodestart (subfile, tag))
+ return NULL; /* Node not found. */
+ }
- /* If not an anchor and contents of node are not available: */
- if (tag->nodelen != 0 && !tag->contents)
- {
- char *new_contents;
- long new_nodelen;
+ /* Right after the separator. */
+ tag->contents = subfile->contents + tag->nodestart;
+ tag->contents += skip_node_separator (tag->contents);
- /* If TAG->nodelen hasn't been calculated yet, then we aren't
- in a position to trust the entry pointer. Adjust things so
- that ENTRY->nodestart gets the exact address of the start of
- the node separator which starts this node. If we cannot
- do that, the node isn't really here. */
- if (tag->nodelen == -1)
- {
- char *node_sep;
+ /* This may be already calculated, but be out of date
+ due to previous calls to tags_expand. */
+ set_tag_nodelen (subfile, tag);
- if (!adjust_nodestart (subfile, tag))
- return NULL; /* Node not found. */
- }
+ /* Expand eventual \b[...\b] constructs in the contents.
+ If found, update tag->contents to point to the resulting
+ buffer. */
+ if (tags_expand (tag->contents, tag->nodelen,
+ &new_contents, &new_nodelen))
+ {
+ tag->contents = new_contents;
+ tag->nodelen = new_nodelen;
+ tag->flags |= N_WasRewritten;
+ }
- /* Right after the separator. */
- tag->contents = subfile->contents + tag->nodestart;
- tag->contents += skip_node_separator (tag->contents);
+ node_set_body_start (tag);
+ }
+ else if (tag->nodelen == 0) /* anchor, return containing node */
+ {
+ int anchor_pos, node_pos;
- /* This may be already calculated, but be out of date
- due to previous calls to tags_expand. */
- set_tag_nodelen (subfile, tag);
+ anchor_pos = tag_ptr - fb->tags;
- /* Expand eventual \b[...\b] constructs in the contents.
- If found, update tag->contents to point to the resulting
- buffer. */
- if (tags_expand (tag->contents, tag->nodelen,
- &new_contents, &new_nodelen))
- {
- tag->contents = new_contents;
- tag->nodelen = new_nodelen;
- tag->flags |= N_WasRewritten;
- }
-
- node_set_body_start (tag);
- }
- else if (tag->nodelen == 0) /* anchor, return containing node */
- {
- node = find_node_of_anchor (file_buffer, tag);
- }
+ /* Look backwards in the tag table for the node preceding
+ the anchor (we're assuming the tags are given in order),
+ skipping over any preceding anchors. */
+ for (node_pos = anchor_pos - 1;
+ node_pos >= 0 && fb->tags[node_pos]->nodelen == 0;
+ node_pos--)
+ ;
- if (!node)
- {
- node = xmalloc (sizeof (NODE));
- *node = *tag;
- }
+ /* An info file with an anchor before any nodes is pathological, but
+ it's possible, so don't crash. */
+ if (node_pos < 0)
+ return NULL;
- /* We can't set this when tag table is built, because
- if file is split, we don't know which of the sub-files
- are compressed. */
- if (subfile->flags & N_IsCompressed)
- node->flags |= N_IsCompressed;
-
- return node;
+ /* Get the actual node from the tag. This is a recursive call, but
+ it can't recurse again, because we call it with a real node. */
+ node = info_node_of_tag (fb, &fb->tags[node_pos]);
+
+ if (node)
+ {
+ /* Start displaying the node at the anchor position. */
+ node->display_pos = tag->nodestart
+ - (node->nodestart
+ + skip_node_separator (subfile->contents
+ + fb->tags[node_pos]->nodestart));
+
+ /* Otherwise an anchor at the end of a node ends up displaying at
+ the end of the last line of the node (way over on the right of
+ the screen), which looks wrong. */
+ if (node->display_pos >= (unsigned long) node->nodelen)
+ node->display_pos = node->nodelen - 1;
+
+ /* Don't search in the node for the xref text, it's not there. */
+ node->flags |= N_FromAnchor;
}
+ }
+ if (!node)
+ {
+ node = xmalloc (sizeof (NODE));
+ *node = *tag;
+ }
+
+ /* We can't set this when tag table is built, because
+ if file is split, we don't know which of the sub-files
+ are compressed. */
+ if (subfile->flags & N_IsCompressed)
+ node->flags |= N_IsCompressed;
+
+ return node;
+}
+
+/* Return the node from FILE_BUFFER which matches NODENAME by searching
+ the tags table in FILE_BUFFER, or NULL. */
+static NODE *
+info_node_of_file_buffer_tags (FILE_BUFFER *file_buffer, char *nodename)
+{
+ NODE *tag;
+ int i;
+
+ /* If no tags at all (possibly a misformatted info file), quit. */
+ if (!file_buffer->tags)
+ return NULL;
+
+ for (i = 0; (tag = file_buffer->tags[i]); i++)
+ if (strcmp (nodename, tag->nodename) == 0)
+ {
+ return info_node_of_tag (file_buffer, &file_buffer->tags[i]);
+ }
+
/* There was a tag table for this file, and the node wasn't found.
Return NULL, since this file doesn't contain the desired node. */
return NULL;
Modified: trunk/info/nodes.h
===================================================================
--- trunk/info/nodes.h 2014-04-21 15:22:24 UTC (rev 5465)
+++ trunk/info/nodes.h 2014-04-21 17:32:26 UTC (rev 5466)
@@ -149,6 +149,8 @@
extern NODE *info_get_node_with_defaults (char *filename, char *nodename,
int flag, WINDOW *window);
+extern NODE *info_node_of_tag (FILE_BUFFER *fb, NODE **tag_ptr);
+
/* Return a pointer to a NODE structure for the Info node NODENAME in
FILE_BUFFER. NODENAME can be passed as NULL, in which case the
nodename of "Top" is used. If the node cannot be found, return a
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [5466] free contents during apropos search,
Gavin D. Smith <=