texinfo-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[6428] save common node data in tag table


From: Gavin D. Smith
Subject: [6428] save common node data in tag table
Date: Mon, 13 Jul 2015 21:36:53 +0000

Revision: 6428
          http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=6428
Author:   gavin
Date:     2015-07-13 21:36:52 +0000 (Mon, 13 Jul 2015)
Log Message:
-----------
save common node data in tag table

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/info/dir.c
    trunk/info/indices.c
    trunk/info/info-utils.c
    trunk/info/man.c
    trunk/info/nodes.c
    trunk/info/nodes.h
    trunk/info/session.c
    trunk/info/window.c
    trunk/info/window.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog     2015-07-12 23:20:14 UTC (rev 6427)
+++ trunk/ChangeLog     2015-07-13 21:36:52 UTC (rev 6428)
@@ -1,3 +1,37 @@
+2015-07-13  Gavin Smith  <address@hidden>
+
+       * info/nodes.h (TAG): New field "cache".  Remove nodelen field.  
+       All uses of TAG.nodelen changed to use TAG.cache.nodelen.
+       * info/nodes.c (info_node_of_tag): Save information about node,
+       like contents and reference list, in cache field.
+       (find_node_from_tag): If reseting tag table entry, free and 
+       clear contents and reference lists.  Use N_IsInternal flag 
+       instead of N_WasRewritten to decide if a node has independent 
+       data.
+       (get_nodes_of_info_file, build_tag_table): Function renamed.
+
+       * info/window.c (text_buffer_to_node): Set N_IsInternal flag on node.
+       * info/dir.c (build_dir_node): Don't set N_IsInternal flag on 
+       node.
+       (get_dir_node): Don't do a deep copy of dir node.
+       * info/indices.c (info_indices_of_file_buffer): Don't free 
+       reference list of node returned from info_node_of_tag.
+       (info_index_apropos): Free contents of apropos node if scanning 
+       it changes it.  Don't set N_WasRewritten flag.
+       * info/man.c (get_manpage_node): Don't set N_IsInternal flag for 
+       man page node.  Don't return a new reference list each time the 
+       same man page is requested.
+       * info/window.c (test_buffer_to_node): Set N_IsInternal on 
+       returned node.
+
+       * info/session.c (info_split_window): Don't duplicate fields in 
+       copied node, as they are recorded in the tag table.
+       (free_history_node): Only free data in node if node is internal.
+       (info_select_reference): Copy fields of argument.
+
+       * info/window.c (calculate_line_starts): Have one line start at 
+       end of node.
+
 2015-07-12  Gavin Smith  <address@hidden>
 
        * info/display.c (display_update_window_1): Sometimes highlight 

Modified: trunk/info/dir.c
===================================================================
--- trunk/info/dir.c    2015-07-12 23:20:14 UTC (rev 6427)
+++ trunk/info/dir.c    2015-07-13 21:36:52 UTC (rev 6428)
@@ -53,11 +53,6 @@
   node = xmalloc (sizeof (NODE));
   *node = *dir_node;
 
-  /* Allow the node to be passed to free_history_node. */
-  if (node->flags & N_WasRewritten)
-    node->flags &= ~N_WasRewritten;
-  node->references = info_copy_references (node->references);
-  node->nodename = xstrdup (node->nodename);
   return node;
 }
 
@@ -143,10 +138,8 @@
         }
     }
 
-  {
-    node->flags |= (N_IsDir | N_IsInternal);
-    scan_node_contents (node, 0, 0);
-  }
+  node->flags |= N_IsDir;
+  scan_node_contents (node, 0, 0);
   return node;
 }
 
@@ -312,4 +305,3 @@
   return 0;
 }
 
-

Modified: trunk/info/indices.c
===================================================================
--- trunk/info/indices.c        2015-07-12 23:20:14 UTC (rev 6427)
+++ trunk/info/indices.c        2015-07-13 21:36:52 UTC (rev 6428)
@@ -148,7 +148,7 @@
       for (i = 0; (tag = file_buffer->tags[i]); i++)
         {
           if (strcasestr (tag->nodename, "Index")
-              && tag->nodelen != 0) /* Not an anchor. */
+              && tag->cache.nodelen != 0) /* Not an anchor. */
             {
               NODE *node;
               REFERENCE **menu;
@@ -180,9 +180,6 @@
                   free (old_result);
                   }
                 }
-              free (menu);
-              node->references = 0; /* Don't free the elements in the
-                                       reference list. */
               free_history_node (node);
             }
         }
@@ -678,7 +675,9 @@
         {
           /* Create the node.  FIXME: Labels and node names taken from the
              indices of Info files may be in a different character encoding to 
-             the one currently being used. */
+             the one currently being used.
+             This problem is reduced by makeinfo not putting quotation marks 
+             from @samp, etc., into node names and index entries. */
           register int i;
 
           text_buffer_init (&message);
@@ -715,10 +714,14 @@
         }
 
       apropos_node = text_buffer_to_node (&message);
-      scan_node_contents (apropos_node, 0, 0);
+      {
+        char *old_contents = apropos_node->contents;
+        scan_node_contents (apropos_node, 0, 0);
+        if (old_contents != apropos_node->contents)
+          free (old_contents);
+      }
 
       name_internal_node (apropos_node, xstrdup (apropos_list_nodename));
-      apropos_node->flags |= N_WasRewritten;
 
       /* Find/Create a window to contain this node. */
       {

Modified: trunk/info/info-utils.c
===================================================================
--- trunk/info/info-utils.c     2015-07-12 23:20:14 UTC (rev 6427)
+++ trunk/info/info-utils.c     2015-07-13 21:36:52 UTC (rev 6428)
@@ -1023,7 +1023,8 @@
                    = (*anchor_to_adjust)->nodestart - output_bytes_difference;
 
                 anchor_to_adjust++;
-                if (!*anchor_to_adjust || (*anchor_to_adjust)->nodelen != 0)
+                if (!*anchor_to_adjust
+                    || (*anchor_to_adjust)->cache.nodelen != 0)
                   {
                     anchor_to_adjust = 0;
                     break;
@@ -1636,7 +1637,8 @@
       anchor_to_adjust = tag_ptr + 1;
       if (!*anchor_to_adjust)
         anchor_to_adjust = 0;
-      else if (*anchor_to_adjust && (*anchor_to_adjust)->nodelen != 0)
+      else if (*anchor_to_adjust
+               && (*anchor_to_adjust)->cache.nodelen != 0)
         anchor_to_adjust = 0;
 
       if (!node->subfile)

Modified: trunk/info/man.c
===================================================================
--- trunk/info/man.c    2015-07-12 23:20:14 UTC (rev 6427)
+++ trunk/info/man.c    2015-07-13 21:36:52 UTC (rev 6428)
@@ -79,7 +79,7 @@
       node = info_create_node ();
       node->fullpath = MANPAGE_FILE_BUFFER_NAME;
       node->nodename = xstrdup (pagename);
-      node->flags |= (N_HasTagsTable | N_IsManPage | N_IsInternal);
+      node->flags |= N_HasTagsTable | N_IsManPage;
 
       /* Save this node. */
       add_pointer_to_array (node, manpage_node_index,
@@ -123,13 +123,12 @@
         }
 
       node->body_start = strcspn (node->contents, "\n");
+      node->references = xrefs_of_manpage (node);
+      node->up = "(dir)";
     }
 
   node2 = xmalloc (sizeof (NODE));
   *node2 = *node;
-  node2->references = xrefs_of_manpage (node2);
-  node2->nodename = xstrdup (pagename);
-  node2->up = xstrdup ("(dir)");
   return node2;
 }
 

Modified: trunk/info/nodes.c
===================================================================
--- trunk/info/nodes.c  2015-07-12 23:20:14 UTC (rev 6427)
+++ trunk/info/nodes.c  2015-07-13 21:36:52 UTC (rev 6428)
@@ -46,7 +46,7 @@
 
 /* Functions for tag table creation and destruction. */
 
-static void get_nodes_of_info_file (FILE_BUFFER *file_buffer);
+static void build_tag_table (FILE_BUFFER *file_buffer);
 static void get_nodes_of_tags_table (FILE_BUFFER *file_buffer,
     SEARCH_BINDING *buffer_binding);
 static void get_tags_of_indirect_tags_table (FILE_BUFFER *file_buffer,
@@ -139,9 +139,8 @@
           }
       }
 
-  /* This file doesn't contain any kind of tags table.  Grovel the
-     file and build node entries for it. */
-  get_nodes_of_info_file (file_buffer);
+  /* This file doesn't have a tag table. */
+  build_tag_table (file_buffer);
 }
 
 /* Set fields on new tag table entry. */
@@ -163,7 +162,7 @@
    FILE_BUFFER->tags, and the number of allocated slots in
    FILE_BUFFER->tags_slots. */
 static void
-get_nodes_of_info_file (FILE_BUFFER *file_buffer)
+build_tag_table (FILE_BUFFER *file_buffer)
 {
   long nodestart;
   size_t tags_index = 0;
@@ -213,10 +212,10 @@
       init_file_buffer_tag (file_buffer, entry);
 
       if (anchor)
-        entry->nodelen = 0;
+        entry->cache.nodelen = 0;
       else
         /* Record that the length is unknown. */
-        entry->nodelen = -1;
+        entry->cache.nodelen = -1;
 
       entry->filename = file_buffer->fullpath;
 
@@ -310,7 +309,7 @@
 
       /* If a node, we don't know the length yet, but if it's an
          anchor, the length is 0. */
-      entry->nodelen = anchor ? 0 : -1;
+      entry->cache.nodelen = anchor ? 0 : -1;
 
       /* The filename of this node is currently known as the same as the
          name of this file. */
@@ -846,12 +845,12 @@
 {
   TAG *t = xmalloc (sizeof (TAG));
 
+  memset (t, 0, sizeof (TAG));
   t->filename = 0;
   t->nodename = 0;
   t->nodestart = -1;
   t->nodestart_adjusted = -1;
-  t->nodelen = -1;
-  t->flags = 0;
+  t->cache.nodelen = -1;
 
   return t;
 }
@@ -1203,8 +1202,14 @@
          the subfile. */
       if (!strcmp ((*t)->filename, fb->fullpath))
         {
+          NODE *n = &(*t)->cache;
           (*t)->nodestart_adjusted = -1;
-          (*t)->nodelen = -1;
+          if (n->flags & N_WasRewritten)
+            free (n->contents);
+          info_free_references (n->references);
+          free (n->next); free (n->prev); free (n->up);
+          memset (n, 0, sizeof (NODE));
+          n->nodelen = -1;
         }
     }
 
@@ -1230,9 +1235,9 @@
       for (h = w->hist; *h; h++)
         {
           NODE *n = (*h)->node;;
-          if (!(n->flags & N_WasRewritten)
-              && (n->subfile ? (n->subfile == fb->fullpath)
-                             : (n->fullpath == fb->fullpath)))
+          if (!(n->flags & N_IsInternal)
+              && (n->subfile ? (!strcmp (n->subfile, fb->fullpath))
+                             : (!strcmp (n->fullpath, fb->fullpath))))
             {
               /* The call to info_get_node is indirectly recursive, but it 
                  should not recurse twice because of the N_EOLs_Converted 
@@ -1270,7 +1275,7 @@
   node_body.end = subfile->filesize;
   node_body.flags = 0;
   node_body.start += skip_node_separator (node_body.buffer + node_body.start);
-  tag->nodelen = get_node_length (&node_body);
+  tag->cache.nodelen = get_node_length (&node_body);
 }
 
 /* Return the node described by *TAG_PTR, retrieving contents from subfile
@@ -1313,7 +1318,7 @@
 
   node = 0;
 
-  is_anchor = tag->nodelen == 0;
+  is_anchor = tag->cache.nodelen == 0;
  
   if (is_anchor)
     {
@@ -1323,7 +1328,7 @@
          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 >= 0 && fb->tags[node_pos]->cache.nodelen == 0;
            node_pos--)
         ;
 
@@ -1339,12 +1344,9 @@
 
   /* Get the node. */
 
-  /* If TAG->nodelen hasn't been calculated yet, then we aren't
-     in a position to trust the entry pointer.  Adjust things so
-     that TAG->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)
+  /* We haven't checked the entry pointer yet.  Look for the node
+     around about it and adjust it if necessary. */
+  if (tag->cache.nodelen == -1)
     {
       if (!find_node_from_tag (parent, subfile, tag))
         return NULL; /* Node not found. */
@@ -1352,26 +1354,30 @@
       set_tag_nodelen (subfile, tag);
     }
 
-  /* Initialize the node from the tag. */
-  node = info_create_node ();
+  if (!tag->cache.contents)
+    {
+      NODE *cache = &tag->cache;
+      cache->contents = subfile->contents + tag->nodestart_adjusted;
+      cache->contents += skip_node_separator (cache->contents);
+      cache->nodename = tag->nodename;
+      cache->flags = tag->flags;
 
-  node->nodename = xstrdup (tag->nodename);
-  node->nodelen = tag->nodelen;
-  node->flags = tag->flags;
-  node->fullpath = parent->fullpath;
-  if (parent != subfile)
-    node->subfile = tag->filename;
+      cache->fullpath = parent->fullpath;
+      if (parent != subfile)
+        cache->subfile = tag->filename;
 
-  node->contents = subfile->contents + tag->nodestart_adjusted;
-  node->contents += skip_node_separator (node->contents);
+      /* Read locations of references in node and similar.  Strip Info file
+         syntax from node if preprocess_nodes=On.  Adjust the offsets of
+         anchors that occur within the node.*/
+      scan_node_contents (cache, parent, tag_ptr);
 
-  /* Read locations of references in node and similar.  Strip Info file
-     syntax from node if preprocess_nodes=On.  Adjust the offsets of
-     anchors that occur within the node.*/
-  scan_node_contents (node, parent, tag_ptr);
+      if (!preprocess_nodes_p)
+        node_set_body_start (cache);
+    }
 
-  if (!preprocess_nodes_p)
-    node_set_body_start (node);
+  /* Initialize the node from the tag. */
+  node = xmalloc (sizeof (NODE));
+  memcpy (node, &tag->cache, sizeof (NODE));
 
   /* We can't set this when tag table is built, because
      if file is split, we don't know which of the sub-files

Modified: trunk/info/nodes.h
===================================================================
--- trunk/info/nodes.h  2015-07-12 23:20:14 UTC (rev 6427)
+++ trunk/info/nodes.h  2015-07-13 21:36:52 UTC (rev 6428)
@@ -104,11 +104,8 @@
   char *nodename;               /* The node pointed to by this tag. */
   long nodestart;               /* The value read from the tag table. */
   long nodestart_adjusted;
-  size_t nodelen;               /* The length of this node.
-                                   nodelen == -1 if length is unknown
-                                   because node hasn't been read yet.
-                                   nodelen == 0 if it is an anchor. */
   int flags;                    /* Same as NODE.flags. */
+  NODE cache;
 } TAG;
 
 /* The following structure is used to remember information about the contents

Modified: trunk/info/session.c
===================================================================
--- trunk/info/session.c        2015-07-12 23:20:14 UTC (rev 6427)
+++ trunk/info/session.c        2015-07-13 21:36:52 UTC (rev 6428)
@@ -871,13 +871,13 @@
 void
 free_history_node (NODE *n)
 {
-  if (!n)
-    return;
-  if (n->flags & N_WasRewritten)
-    free (n->contents);
-  info_free_references (n->references);
-  free (n->next); free (n->prev); free (n->up);
-  free (n->nodename);
+  if (n && (n->flags & N_IsInternal))
+    {
+      free (n->contents);
+      info_free_references (n->references);
+      free (n->next); free (n->prev); free (n->up);
+      free (n->nodename);
+    }
   free (n);
 }
 
@@ -1840,19 +1840,22 @@
       NODE *copy = xmalloc (sizeof (NODE));
       *copy = *window->node; /* Field-by-field copy of structure. */
 
-      /* This allows us to free nodes without checking if these fields
-         are shared by NODE objects in other windows. */
-      copy->references = info_copy_references (copy->references);
-      copy->nodename = xstrdup (copy->nodename);
+      if (copy->flags & N_IsInternal)
+        {
+          /* This allows us to free nodes without checking if these fields
+             are shared by NODE objects in other windows.  For non-internal
+             nodes, this data is stored in the tag table. */
+          copy->references = info_copy_references (copy->references);
+          copy->nodename = xstrdup (copy->nodename);
 
-      if (copy->up)
-        copy->up = xstrdup (copy->up);
-      if (copy->next)
-        copy->next = xstrdup (copy->next);
-      if (copy->prev)
-        copy->prev = xstrdup (copy->prev);
-      if (copy->flags & N_WasRewritten)
-        copy->contents = xstrdup (copy->contents);
+          if (copy->up)
+            copy->up = xstrdup (copy->up);
+          if (copy->next)
+            copy->next = xstrdup (copy->next);
+          if (copy->prev)
+            copy->prev = xstrdup (copy->prev);
+          copy->contents = xstrdup (copy->contents);
+        }
 
       info_set_node_of_window (split, copy);
       /* Make sure point still appears in the active window. */
@@ -1992,9 +1995,17 @@
   NODE *node;
   char *file_system_error = NULL;
 
-  node = info_get_node_with_defaults (entry->filename, entry->nodename,
-                                      window->node);
+  /* We need to copy everything from entry because the call to 
+     info_get_node_with_defaults can free it if it came from
+     the tag table of a file. */
+  char *filename = entry->filename;
+  char *nodename = entry->nodename;
+  char *label = entry->label;
+  int line_number = entry->line_number;
 
+  /* problem here: this call can free 'entry' if the tag table is rewritten. */
+  node = info_get_node_with_defaults (filename, nodename, window->node);
+
   /* Try something a little weird.  If the node couldn't be found, and the
      reference was of the form "foo::", see if the entry->label can be found
      as a file, with a node of "Top". */
@@ -2003,13 +2014,12 @@
       if (info_recent_file_error)
         file_system_error = xstrdup (info_recent_file_error);
 
-      if (entry->nodename
-          && entry->label && (strcmp (entry->nodename, entry->label) == 0))
+      if (nodename && label && !strcmp (nodename, label))
         {
           free (file_system_error);
           file_system_error = NULL;
 
-          node = info_get_node (entry->label, "Top");
+          node = info_get_node (label, "Top");
           if (!node && info_recent_file_error)
             file_system_error = xstrdup (info_recent_file_error);
         }
@@ -2023,8 +2033,7 @@
           free (file_system_error);
         }
       else
-        info_error (msg_cant_find_node,
-                    entry->nodename ? entry->nodename : "Top");
+        info_error (msg_cant_find_node, nodename ? nodename : "Top");
       return 0;
     }
 
@@ -2048,10 +2057,10 @@
         }
   info_set_node_of_window (window, node);
 
-  if (entry->line_number > 0)
+  if (line_number > 0)
     {
       /* Go to the line given by entry->line_number. */
-      long line = window_log_to_phys_line (window, entry->line_number - 1);
+      long line = window_log_to_phys_line (window, line_number - 1);
 
       if (line >= 0 && line < window->line_count)
         {
@@ -2220,9 +2229,6 @@
   else /* !menu_item && !xref */
     return;
 
-  /* Default the selected reference to the one which is on the line that
-     point is in. */
-
   line_no = window_line_of_point (window);
   this_line = window->line_starts[line_no];
   if (window->line_starts[line_no + 1])
@@ -2230,6 +2236,8 @@
   else
     next_line = window->node->nodelen;
 
+  /* Look for a reference in the current line, preferring one that
+     the point is in, otherwise preferring after the point. */
   for (which = 0; refs[which]; which++)
     {
       /* If we got to the next line without finding an eligible reference. */
@@ -2257,7 +2265,6 @@
   if (closest != -1)
     defentry = refs[closest];
 
-  /* If we are going to ask the user a question, do it now. */
   if (ask_p)
     {
       char *prompt;
@@ -2918,7 +2925,7 @@
       if (count == 0 || (count == 1 && !info_explicit_arg))
         count = -1;
       for (i = 0; count && fb->tags[i]; i++)
-        if (fb->tags[i]->nodelen != 0) /* don't count anchor tags */
+        if (fb->tags[i]->cache.nodelen != 0) /* don't count anchor tags */
           {
             count--;
             last_node_tag_idx = i;
@@ -2951,7 +2958,7 @@
       int last_node_tag_idx = -1;
 
       for (i = 0; count && fb->tags[i]; i++)
-        if (fb->tags[i]->nodelen != 0) /* don't count anchor tags */
+        if (fb->tags[i]->cache.nodelen != 0) /* don't count anchor tags */
           {
             count--;
             last_node_tag_idx = i;
@@ -4073,7 +4080,7 @@
             }
           
           tag = file_buffer->tags[i];
-          if (tag->nodelen != 0)
+          if (tag->cache.nodelen != 0)
             break;
         }
 
@@ -4115,7 +4122,7 @@
         }
 
       if (dir < 0)
-        start = tag->nodelen;
+        start = tag->cache.nodelen;
       else
         start = 0;
 

Modified: trunk/info/window.c
===================================================================
--- trunk/info/window.c 2015-07-12 23:20:14 UTC (rev 6427)
+++ trunk/info/window.c 2015-07-13 21:36:52 UTC (rev 6428)
@@ -1146,6 +1146,7 @@
   text_buffer_add_char (tb, '\0');
 
   node->contents = text_buffer_base (tb);
+  node->flags |= N_IsInternal;
   return node;
 }
 
@@ -1246,8 +1247,12 @@
     }
 
   if (pl_chars)
-    collect_line_starts (win, ll_num, pl_start);
+    collect_line_starts (win, ll_num++, pl_start);
 
+  /* Have one line start at the end of the node. */
+  collect_line_starts (win, ll_num, mbi_cur_ptr (iter) - win->node->contents);
+  win->line_count--;
+
   /* Finally, initialize the line map for the current line. */
   window_line_map_init (win);
 }

Modified: trunk/info/window.h
===================================================================
--- trunk/info/window.h 2015-07-12 23:20:14 UTC (rev 6427)
+++ trunk/info/window.h 2015-07-13 21:36:52 UTC (rev 6428)
@@ -84,7 +84,7 @@
   long *line_starts;    /* Offsets of printed line starts in node->contents.*/
   long *log_line_no;    /* Number of logical line corresponding to each
                            physical one. */
-  long line_count;      /* Number of elements in LINE_STARTS and LOG_LINE_NO.*/
+  long line_count;      /* Number of printed lines in node. */
   size_t line_slots;    /* Allocated space in LINE_STARTS and LOG_LINE_NO. */
 
   int flags;            /* See below for details. */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]