commit be41c3a70db77b11789389580e41b9605477a7a9 Author: Gavin Smith Date: Sun Mar 9 16:51:04 2014 +0000 * nodes.c (get_nodes_of_info_file): Set nodelen to -1 for all nodes. Initialize fields of NODE structure. (get_nodes_of_tag_table): Initialize fields of NODE structure. (info_node_of_file_buffer_tags): Call scan_node_contents on node contents. Tag expansion temporarily disabled. (info_get_node): Use xstrdup to allow calling info_parse_node in subsequent functions. (free_info_tag): Free tag.references if set. * nodes.h (NODE.content_cache): Field deleted. diff --git a/info-utils.h b/info-utils.h index 3b5db60..bd3b1ed 100644 --- a/info-utils.h +++ b/info-utils.h @@ -70,6 +70,10 @@ extern REFERENCE **info_xrefs_of_node (NODE *node); cross reference in this range. */ extern REFERENCE **info_xrefs (SEARCH_BINDING *binding); +/* If preprocess_nodes_p=On, remove syntax from NODE->contents. + Set NODE->references and other fields. */ +void scan_node_contents (NODE *node); + /* Get the entry associated with LABEL in REFERENCES. Return a pointer to the reference if found, or NULL. */ extern REFERENCE *info_get_labeled_reference (char *label, diff --git a/nodes.c b/nodes.c index 4c3344a..f0ee414 100644 --- a/nodes.c +++ b/nodes.c @@ -82,24 +82,38 @@ extern void maybe_build_dir_node (char *dirname); If the node cannot be found, return NULL. */ NODE * -info_get_node (char *filename, char *nodename, int flag) +info_get_node (char *filename_in, char *nodename_in, int flag) { NODE *node; FILE_BUFFER *file_buffer = NULL; + char *filename = 0, *nodename = 0; + info_recent_file_error = NULL; - info_parse_node (nodename, flag); + info_parse_node (nodename_in, flag); nodename = NULL; + /* We need to duplicate info_parsed_filename because it can be rewritten + when info_get_node_of_file_buffer is called below (which eventually + calls scan_node_contents). */ + /* FIXME: Change info_parse_node to make all this easier */ + if (info_parsed_filename) - filename = info_parsed_filename; + filename = xstrdup(info_parsed_filename); + else if (filename_in) + filename = xstrdup(filename_in); if (info_parsed_nodename) - nodename = info_parsed_nodename; + nodename = xstrdup(info_parsed_nodename); + else if (nodename_in) + nodename = xstrdup(nodename_in); + /* See comment above for use of xstrdup() */ /* If FILENAME is not specified, it defaults to "dir". */ if (!filename) - filename = "dir"; + filename = xstrdup("dir"); + + /* Both filename and nodename are set by now. */ /* If the file to be looked up is "dir", build the contents from all of the "dir"s and "localdir"s found in INFOPATH. */ @@ -116,6 +130,7 @@ info_get_node (char *filename, char *nodename, int flag) if (filesys_error_number) info_recent_file_error = filesys_error_string (filename, filesys_error_number); + free(filename); free(nodename); return NULL; } } @@ -136,6 +151,7 @@ info_get_node (char *filename, char *nodename, int flag) node = info_get_node_of_file_buffer ("TOP", file_buffer); } + free(filename); free(nodename); return node; } @@ -564,25 +580,27 @@ get_nodes_of_info_file (FILE_BUFFER *file_buffer) /* Okay, we have isolated the node name, and we know where the node starts. Remember this information. */ entry = xmalloc (sizeof (NODE)); - entry->content_cache = NULL; entry->nodename = xmalloc (1 + (end - start)); strncpy (entry->nodename, nodeline + start, end - start); entry->nodename[end - start] = 0; entry->nodestart = nodestart; + + /* Initialize fields. */ + entry->references = 0; + entry->display_pos = 0; + entry->contents = 0; + entry->parent = 0; + entry->flags = 0; + if (anchor) entry->nodelen = 0; else { - SEARCH_BINDING node_body; - - node_body.buffer = binding.buffer + binding.start; - node_body.start = 0; - node_body.end = binding.end - binding.start; - node_body.flags = S_FoldCase; - entry->nodelen = get_node_length (&node_body); + /* Record that the text of the node hasn't been scanned yet. */ + entry->nodelen = -1; } - entry->filename = file_buffer->fullpath; + entry->filename = xstrdup(file_buffer->fullpath); /* Add this tag to the array of tag structures in this FILE_BUFFER. */ add_pointer_to_array (entry, tags_index, file_buffer->tags, @@ -669,7 +687,13 @@ get_nodes_of_tags_table (FILE_BUFFER *file_buffer, break; entry = xmalloc (sizeof (NODE)); - entry->content_cache = NULL; + + /* Initialize sundry fields. */ + entry->references = 0; + entry->display_pos = 0; + entry->contents = 0; + entry->parent = 0; + entry->flags = 0; /* Find the beginning of the node definition. */ tmp_search->start += name_offset; @@ -694,7 +718,7 @@ get_nodes_of_tags_table (FILE_BUFFER *file_buffer, /* The filename of this node is currently known as the same as the name of this file. */ - entry->filename = file_buffer->fullpath; + entry->filename = xstrdup (file_buffer->fullpath); /* Add this node structure to the array of node structures in this FILE_BUFFER. */ @@ -961,6 +985,7 @@ info_node_of_file_buffer_tags (FILE_BUFFER *file_buffer, char *nodename) 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) @@ -973,54 +998,30 @@ info_node_of_file_buffer_tags (FILE_BUFFER *file_buffer, char *nodename) return NULL; } + if (!tag->contents) + tag->contents = subfile->contents + tag->nodestart; + /* 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->nodestart >= 0 && tag->nodestart < subfile->filesize)) + return NULL; - /* FIXME: why not just copy the NODE structure instead of - assigning the fields individually? */ node = xmalloc (sizeof (NODE)); - node->filename = subfile->fullpath; - node->parent = NULL; - node->nodename = tag->nodename; - - if (tag->content_cache) - node->contents = tag->content_cache; - else - node->contents = subfile->contents + tag->nodestart; - node->display_pos = 0; - node->flags = 0; - node_set_body_start (node); - - if (file_buffer->flags & N_HasTagsTable) + /* If TAG->nodelen hasn't been calculated yet: */ + if (tag->nodelen == -1) { - node->flags |= N_HasTagsTable; - - if (file_buffer->flags & N_TagsIndirect) - { - node->flags |= N_TagsIndirect; - node->parent = file_buffer->fullpath; - } - } - - if (subfile->flags & N_IsCompressed) - node->flags |= N_IsCompressed; - - /* 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, and NODE->contents - gets the address of the line defining this node. If we cannot - do that, the node isn't really here. */ - if (tag->nodelen == -1) - { - int min, max; + int min, max; char *node_sep; SEARCH_BINDING node_body; char *buff_end; + /* TAG->nodestart may be incorrect by a few bytes due to an + incorrect file tag table. Adjust TAG->nodestart to be the + exact address of the start of the node separator which starts + this node, and TAG->contents to be the address of the line + defining this node. */ + min = max = DEFAULT_INFO_FUDGE; if (strict_node_location_p) @@ -1040,10 +1041,9 @@ info_node_of_file_buffer_tags (FILE_BUFFER *file_buffer, char *nodename) this node, or NULL if the node wasn't found. NODE->contents is side-effected to point to right after the separator. */ - node_sep = adjust_nodestart (node, min, max); + node_sep = adjust_nodestart (tag, min, max); if (node_sep == NULL) { - free (node); return NULL; } /* Readjust tag->nodestart. */ @@ -1052,33 +1052,60 @@ info_node_of_file_buffer_tags (FILE_BUFFER *file_buffer, char *nodename) /* Calculate the length of the current node. */ buff_end = subfile->contents + subfile->filesize; - node_body.buffer = node->contents; + node_body.buffer = tag->contents; node_body.start = 0; node_body.end = buff_end - node_body.buffer; node_body.flags = 0; tag->nodelen = get_node_length (&node_body); - /* Expand eventual \b[...\b] constructs in the contents. - If found, update node->contents to point to the resulting - buffer. */ - if (tags_expand (node->contents, tag->nodelen, - &tag->content_cache, &tag->nodelen)) - node->contents = tag->content_cache; - node->nodelen = tag->nodelen; + + /* Read locations of references in node and similar. Rewrite + node from tag->contents if preprocess_nodes=On. */ + + scan_node_contents (tag); + + /* Disabled - we will expand tags in scan_node_contents. */ +#if 0 + char *old_contents = tag->contents; + + /* Expand eventual \b[...\b] constructs in the contents. */ + + int new_nodelen; + if (tags_expand (tag->contents, tag->nodelen, + &tag->contents, &new_nodelen)) + { + tag->nodelen = new_nodelen; + + /* Free output of parse_node. */ + if (old_contents) + free (old_contents); + } +#endif + *node = *tag; } else if (tag->nodelen == 0) /* anchor, return containing node */ { - free (node); + free(node); node = find_node_of_anchor (file_buffer, tag); } else + *node = *tag; + + node_set_body_start (node); + + if (file_buffer->flags & N_HasTagsTable) { - /* Since we know the length of this node, we have already - adjusted tag->nodestart to point to the exact start of - it. Simply skip the node separator. */ - node->contents += skip_node_separator (node->contents); - node->nodelen = tag->nodelen; + node->flags |= N_HasTagsTable; + + if (file_buffer->flags & N_TagsIndirect) + { + node->flags |= N_TagsIndirect; + node->parent = file_buffer->fullpath; + } } - + + if (subfile->flags & N_IsCompressed) + node->flags |= N_IsCompressed; + return node; } @@ -1186,8 +1213,8 @@ free_file_buffer_tags (FILE_BUFFER *file_buffer) static void free_info_tag (NODE *tag) { + if (tag->references) info_free_references (tag->references); free (tag->nodename); - free (tag->content_cache); /* We don't free tag->filename, because that filename is part of the subfiles list for the containing FILE_BUFFER. free_info_tags () diff --git a/nodes.h b/nodes.h index 1bf85b2..c4885d7 100644 --- a/nodes.h +++ b/nodes.h @@ -55,7 +55,10 @@ typedef struct { char *parent; /* Non-null is the logical file name. */ char *nodename; /* The name of this node. */ char *contents; /* Characters appearing in this node. */ - size_t nodelen; /* The length of the CONTENTS member. */ + size_t nodelen; /* The length of the CONTENTS member. + nodelen == -1 if length is unknown + because node hasn't been read yet. + nodelen == 0 if it is an anchor. */ unsigned long display_pos; /* Where to display at, if nonzero. */ long body_start; /* Offset of the actual node body */ int flags; /* See immediately below. */ @@ -63,9 +66,6 @@ typedef struct { references == 0 implies uninitialized, not empty */ long nodestart; /* The offset of the start of this node. */ - char *content_cache; /* Cache of the node contents; used if the - node contents must be preprocessed before - displaying it. */ char *up, *prev, *next; /* Names of nearby nodes. */ } NODE;