texinfo-commits
[Top][All Lists]
Advanced

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

[6012] better support for Info files with CR-LF line endings


From: Gavin D. Smith
Subject: [6012] better support for Info files with CR-LF line endings
Date: Thu, 01 Jan 2015 18:30:25 +0000

Revision: 6012
          http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=6012
Author:   gavin
Date:     2015-01-01 18:30:23 +0000 (Thu, 01 Jan 2015)
Log Message:
-----------
better support for Info files with CR-LF line endings

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/info/info-utils.c
    trunk/info/nodes.c
    trunk/info/nodes.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog     2014-12-30 21:54:02 UTC (rev 6011)
+++ trunk/ChangeLog     2015-01-01 18:30:23 UTC (rev 6012)
@@ -1,3 +1,28 @@
+2015-01-01  Gavin Smith  <address@hidden>
+
+       * info/nodes.h (TAG): Add 'nodestart_adjusted' field and remove 
+       'orig_nodestart'.
+       (NODE): Remove 'nodestart' field.
+       * info/nodes.c (info_create_tag): Update.
+
+       * info/nodes.c (adjust_nodestart): Set offset of found node in 
+       'nodestart_adjusted' field of NODE.
+       (set_tag_nodelen, info_node_of_tag): Use 'nodestart_adjusted'
+       for actual start of a node.
+
+       * info/info-utils.c (copy_input_to_output): Set adjusted anchors 
+       in 'nodestart_adjusted'.
+       (scan_node_contents): Get 'nodestart' for node from TAG object 
+       instead of from NODE.
+
+       * info/nodes.c (find_node_of_tag): Arguments changed.  If node 
+       not found, call convert_eols to convert file buffer in place, 
+       reset the tag table, look for the node again, and reload any 
+       nodes in the history of a window.
+
+       * info/nodes.c (convert_eols): Set 'filesize' on destination 
+       FILE_BUFFER.
+
 2014-12-30  Gavin Smith  <address@hidden>
 
        * info/nodes.h (TAG): Struct type reintroduced (removed on

Modified: trunk/info/info-utils.c
===================================================================
--- trunk/info/info-utils.c     2014-12-30 21:54:02 UTC (rev 6011)
+++ trunk/info/info-utils.c     2015-01-01 18:30:23 UTC (rev 6012)
@@ -1007,7 +1007,9 @@
             while ((*anchor_to_adjust)->nodestart - node_offset
                    <= inptr - input_start)
               {
-                (*anchor_to_adjust)->nodestart -= output_bytes_difference;
+                (*anchor_to_adjust)->nodestart_adjusted
+                   = (*anchor_to_adjust)->nodestart - output_bytes_difference;
+
                 anchor_to_adjust++;
                 if (!*anchor_to_adjust || (*anchor_to_adjust)->nodelen != 0)
                   {
@@ -1675,7 +1677,7 @@
           file_contents = f->contents;
         }
       node_offset = (*tag_ptr)->nodestart
-        + skip_node_separator (file_contents + node->nodestart);
+        + skip_node_separator (file_contents + (*tag_ptr)->nodestart);
     }
   else
     anchor_to_adjust = 0;

Modified: trunk/info/nodes.c
===================================================================
--- trunk/info/nodes.c  2014-12-30 21:54:02 UTC (rev 6011)
+++ trunk/info/nodes.c  2015-01-01 18:30:23 UTC (rev 6012)
@@ -874,7 +874,7 @@
   t->filename = 0;
   t->nodename = 0;
   t->nodestart = -1;
-  t->orig_nodestart = -1;
+  t->nodestart_adjusted = -1;
   t->nodelen = -1;
   t->flags = 0;
 
@@ -1121,6 +1121,7 @@
      want to waste storage.  */
   destination->contents = xrealloc (destination->contents,
                                     d - destination->contents + 1);
+  destination->filesize = d - destination->contents;
 }
 
 /* Magic number that RMS used to decide how much a tags table pointer could
@@ -1131,8 +1132,8 @@
    way that tags are implemented, the physical nodestart may
    not actually be where the tag says it is.  If that is the case,
    set N_UpdateTags in NODE->flags.  If the node is found, return non-zero.
-   Set NODE->nodestart directly on the separator that precedes this node.
-   If the node could not be found, return 0. */
+   Set NODE->nodestart_adjusted directly on the separator that precedes this 
+   node.  If the node could not be found, return 0. */
 static int
 adjust_nodestart (FILE_BUFFER *fb, TAG *node, int slack)
 {
@@ -1180,36 +1181,36 @@
         node->flags |= N_UpdateTags;
     }
 
-  /* Do we want this? */
-  /* TODO: Use TAG again to store the tags, and add an extra field to store
-     the original values. */
-  node->nodestart = s.buffer + position - fb->contents;
+  node->nodestart_adjusted = s.buffer + position - fb->contents;
   return 1;
 }
 
-/* Look in the contents of *FB_PTR for a node referred to with TAG.
-  
-   If we have to update the contents of the file, *PARENT and *FB_PTR can be 
-   changed to a different FILE_BUFFER. */
+/* Look in the contents of *FB_PTR for a node referred to with TAG.  Set
+   the location if found in TAG->nodestart_adjusted.
+
+   PARENT->tags contains the tags table for the whole file.  If file is
+   non-split, PARENT should be the same as FB. */
 static int
-find_node_from_tag (FILE_BUFFER **parent, FILE_BUFFER **fb_ptr, TAG *tag)
+find_node_from_tag (FILE_BUFFER *parent, FILE_BUFFER *fb, TAG *tag)
 {
   int success;
-
-  FILE_BUFFER *fb = *fb_ptr;
-  int file_already_used = 1;
-  FILE_BUFFER *dest_fb;
   int slack;
+  TAG **t;
+  WINDOW *w;
 
   /* Start off with a small fudge to reduce chance of finding a node and then
      later having to convert the EOL's, leaving us with the question of what to
      do with the existing buffer and the nodes that refer to it. */
   if (!(fb->flags & N_EOLs_Converted))
-    slack = DEFAULT_INFO_FUDGE;
+    slack = 4;
   else
     slack = DEFAULT_INFO_FUDGE;
 
-  success = adjust_nodestart (fb, tag, slack);
+  if (tag->nodestart_adjusted != -1)
+    success = 1;
+  else
+    success = adjust_nodestart (fb, tag, slack);
+
   if (success)
     return success;
 
@@ -1220,51 +1221,66 @@
      some versions of makeinfo, it's possible that it has CR-LF line endings 
      with the CR bytes not counted in the tag table. */
 
-  /* TODO: Check if there are already nodes in windows from this file.  If
-     not, we can convert the buffer in place. */  
+  convert_eols (fb, fb);
+  fb->flags |= N_EOLs_Converted;
 
-  if (file_already_used)
+  /* Restore tags table to what was read from the file. */
+  for (t = parent->tags; *t; t++)
     {
-      FILE_BUFFER *new_fb = xmalloc (sizeof (FILE_BUFFER));
+      /* For split files, only restore the part of the tag table for
+         the subfile. */
+      if (!strcmp ((*t)->filename, fb->fullpath))
+        {
+          (*t)->nodestart_adjusted = -1;
+          (*t)->nodelen = -1;
+        }
+    }
 
-      memcpy (new_fb, fb, sizeof (FILE_BUFFER));
-      new_fb->contents = xmalloc (fb->filesize + 1);
+  /* Look for the node again. */
+  success = adjust_nodestart (fb, tag, DEFAULT_INFO_FUDGE);
 
-      /* TODO: Copy and restore tags table. */
+  /* For each window, check for file buffer being used in window history, 
+     including currently displayed node, and amend it to refer properly to the 
+     converted file buffer.  (Window history was set in 
info_set_node_of_window 
+     in session.c. )
 
-      add_pointer_to_array (new_fb, info_loaded_files_index,
-              info_loaded_files, info_loaded_files_slots, 10);
+     There is a chance that there is a NODE in some local variable 
+     somewhere, which we can't update. */
 
-      dest_fb = new_fb;
-    }
+  for (w = windows; w; w = w->next)
+    {
+      WINDOW_STATE **h;
 
-  convert_eols (dest_fb, fb);
-  dest_fb->flags |= N_EOLs_Converted;
+      if (!w->hist)
+        continue;
 
-  success = adjust_nodestart (dest_fb, tag, DEFAULT_INFO_FUDGE);
-  if (success)
-    {
-      /* Stop the old record being used again. */
-      if (dest_fb != fb)
+      for (h = w->hist; *h; h++)
         {
-          fb->fullpath = "";
-          fb->filename = "";
-
-          /* TODO: Could we also try to convert nodes referring to the old 
-             buffer, to save space? */
+          NODE *n = (*h)->node;;
+          if (!(n->flags & N_WasRewritten)
+              && (n->subfile ? (n->subfile == fb->fullpath)
+                             : (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 
+                 conditional above. */
+              (*h)->node = info_get_node (n->fullpath, n->nodename);
+              if ((*h)->node)
+                free_history_node (n);
+              else
+                {
+                  /* We found the node before, but now we can't.  Just leave
+                     the node as it was (possibly with its contents pointer
+                     pointing to the wrong place). */
+                  (*h)->node = n;
+                }
+            }
         }
-
-      /* If file is split, leave PARENT as it is, otherwise update both FB_PTR 
-         and PARENT to the new file. */
-      if (*parent == *fb_ptr)
-        *parent = dest_fb;
-      *fb_ptr = dest_fb;
-      return success;
     }
-  else
-    /* Throw the converted buffer away?  Or keep it to stop us ever having
-       to do the conversion step again? */
 
+  if (success)
+    return success;
+
   return 0;
 }
 
@@ -1275,7 +1291,7 @@
   SEARCH_BINDING node_body;
 
   node_body.buffer = subfile->contents;
-  node_body.start = tag->nodestart;
+  node_body.start = tag->nodestart_adjusted;
   node_body.end = subfile->filesize;
   node_body.flags = 0;
   node_body.start += skip_node_separator (node_body.buffer + node_body.start);
@@ -1355,25 +1371,23 @@
      do that, the node isn't really here. */
   if (tag->nodelen == -1)
     {
-      if (!find_node_from_tag (&parent, &subfile, tag))
+      if (!find_node_from_tag (parent, subfile, tag))
         return NULL; /* Node not found. */
 
       set_tag_nodelen (subfile, tag);
     }
 
-
   /* Initialize the node from the tag. */
   node = info_create_node ();
 
   node->nodename = xstrdup (tag->nodename);
-  node->nodestart = tag->nodestart;
   node->nodelen = tag->nodelen;
   node->flags = tag->flags;
-  node->fullpath = fb->fullpath;
+  node->fullpath = parent->fullpath;
   if (parent != subfile)
     node->subfile = tag->filename;
 
-  node->contents = subfile->contents + tag->nodestart;
+  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
@@ -1394,9 +1408,10 @@
     {
       /* Start displaying the node at the anchor position.  */
 
-      node->display_pos = anchor_tag->nodestart
-        - (node->nodestart
-           + skip_node_separator (subfile->contents + tag->nodestart));
+      node->display_pos = anchor_tag->nodestart_adjusted
+        - (tag->nodestart_adjusted
+           + skip_node_separator (subfile->contents
+                                  + tag->nodestart_adjusted));
 
       /* 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

Modified: trunk/info/nodes.h
===================================================================
--- trunk/info/nodes.h  2014-12-30 21:54:02 UTC (rev 6011)
+++ trunk/info/nodes.h  2015-01-01 18:30:23 UTC (rev 6012)
@@ -51,7 +51,6 @@
   REFERENCE **references;       /* Cross-references or menu items in node.
                                    references == 0 implies uninitialized,
                                    not empty */
-  long nodestart;               /* The offset of the start of this node. */
   char *up, *prev, *next;       /* Names of nearby nodes. */
 } NODE;
 
@@ -102,8 +101,8 @@
 typedef struct {
   char *filename;               /* The file where this node can be found. */
   char *nodename;               /* The node pointed to by this tag. */
-  long nodestart;               /* The offset of the start of this node. */
-  long orig_nodestart;          /* The value read from the tag table. */
+  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.




reply via email to

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