texinfo-commits
[Top][All Lists]
Advanced

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

[5997] better support of Info files with CR-LF line endings


From: Gavin D. Smith
Subject: [5997] better support of Info files with CR-LF line endings
Date: Sat, 27 Dec 2014 21:53:23 +0000

Revision: 5997
          http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=5997
Author:   gavin
Date:     2014-12-27 21:53:22 +0000 (Sat, 27 Dec 2014)
Log Message:
-----------
better support of Info files with CR-LF line endings

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

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog     2014-12-27 08:13:42 UTC (rev 5996)
+++ trunk/ChangeLog     2014-12-27 21:53:22 UTC (rev 5997)
@@ -1,3 +1,23 @@
+2014-12-27  Gavin Smith  <address@hidden>
+
+       * info/nodes.h (TAGS_TABLE_BEG_LABEL): Define without trailing 
+       '\n'.
+       (INDIRECT_TAGS_TABLE_LABEL, INDIRECT_TABLE_LABEL): Rename and 
+       remove trailing '\n'.
+       (TAGS_TABLE_END_LABEL): Define without leading '\n'.
+
+       * info/search.c (find_node_separator): Search backwards if 
+       beginning of search is after end of search.
+       (find_tags_table, find_file_section): Function renamed.  Take 
+       extra argument giving first line of section to look for.  Search 
+       backwards if beginning of search is after the end of search.
+       * info/search.c (looking_at_line): New function.
+
+       * info/nodes.c (build_tags_and_nodes): Call find_file_section to 
+       find end and start of tags table.
+       (get_nodes_of_tags_table): Assume we are passed the exact offset 
+       of the separator preceding the tag table.
+
 2014-12-26  Eli Zaretskii  <address@hidden>
 
        * info/info-utils.c (nl_langinfo) [__MINGW32__]: Redirect to

Modified: trunk/info/nodes.c
===================================================================
--- trunk/info/nodes.c  2014-12-27 08:13:42 UTC (rev 5996)
+++ trunk/info/nodes.c  2014-12-27 21:53:22 UTC (rev 5997)
@@ -72,40 +72,21 @@
     binding.end = 0;
   binding.flags = S_FoldCase;
 
-  if (search_backward (TAGS_TABLE_END_LABEL, &binding, &position)
-      == search_success)
+  position = find_file_section (&binding, TAGS_TABLE_END_LABEL);
+  if (position != -1)
     /* If there is a tag table, find the start of it, and grovel over it
        extracting tag information. */
     while (1)
       {
         long tags_table_begin, tags_table_end;
 
-        binding.end = position;
-        binding.start = binding.end - 5 - strlen (TAGS_TABLE_END_LABEL);
-        if (binding.start < 0)
-          binding.start = 0;
-
-        position = find_node_separator (&binding);
-
-        /* For this test, (and all others here) failure indicates a bogus
-           tags table.  Grovel the file. */
-        if (position == -1)
-          break;
-
         /* Remember the end of the tags table. */
-        binding.start = position;
-        tags_table_end = binding.start;
-        binding.end = 0;
+        tags_table_end = position - 1;
 
         /* Locate the start of the tags table. */
-        if (search_backward (TAGS_TABLE_BEG_LABEL, &binding, &position)
-           != search_success)
-          break;
-
-        binding.end = position;
-        binding.start = binding.end - 5 - strlen (TAGS_TABLE_BEG_LABEL);
-        position = find_node_separator (&binding);
-
+        binding.start = tags_table_end;
+        binding.end = 0;
+        position = find_file_section (&binding, TAGS_TABLE_BEG_LABEL);
         if (position == -1)
           break;
 
@@ -114,14 +95,14 @@
         file_buffer->flags |= N_HasTagsTable;
         tags_table_begin = position;
 
-        /* If this isn't an indirect tags table, just remember the nodes
-           described locally in this tags table.  Note that binding.end
-           is pointing to just after the beginning label. */
-        binding.start = binding.end;
-        binding.end = file_buffer->filesize;
-
-        if (!looking_at (TAGS_TABLE_IS_INDIRECT_LABEL, &binding))
+        position += skip_node_separator (file_buffer->contents + position);
+        position += strlen (TAGS_TABLE_BEG_LABEL);
+        position += strspn (file_buffer->contents + position, "\r\n");
+        if (!looking_at_line (TAGS_TABLE_IS_INDIRECT_LABEL,
+                              file_buffer->contents + position))
           {
+            /* If this isn't an indirect tags table, just remember the nodes
+               described locally in this tags table. */
             binding.start = tags_table_begin;
             binding.end = tags_table_end;
             get_nodes_of_tags_table (file_buffer, &binding);
@@ -129,23 +110,27 @@
           }
         else
           {
-            /* This is an indirect tags table.  Build TAGS member. */
+            /* This is an indirect tags table.  Find the indirect table
+               preceding the tags table. */
             SEARCH_BINDING indirect;
 
             indirect.start = tags_table_begin;
             indirect.end = 0;
-            indirect.buffer = binding.buffer;
+            indirect.buffer = file_buffer->contents;
             indirect.flags = S_FoldCase;
 
-            if (search_backward (INDIRECT_TAGS_TABLE_LABEL, &indirect,
-                                &position) != search_success)
-              {
-                /* This file is malformed.  Give up. */
-                return;
-              }
+            position = find_file_section (&indirect, INDIRECT_TABLE_LABEL);
+            if (position == -1)
+              /* This file is malformed.  Give up. */
+              return;
 
+            /* Skip "Indirect:" line. */
+            position += strlen (INDIRECT_TABLE_LABEL);
+            position += strspn (file_buffer->contents + position, "\r\n");
+
             indirect.start = position;
             indirect.end = tags_table_begin;
+
             binding.start = tags_table_begin;
             binding.end = tags_table_end;
             get_tags_of_indirect_tags_table (file_buffer, &indirect, &binding);
@@ -254,7 +239,7 @@
   tmp_search = copy_binding (buffer_binding);
 
   /* Find the start of the tags table. */
-  position = find_tags_table (tmp_search);
+  position = buffer_binding->start;
 
   /* If none, we're all done. */
   if (position == -1)
@@ -265,7 +250,6 @@
   tmp_search->start += skip_node_separator
     (tmp_search->buffer + tmp_search->start);
   tmp_search->start += strlen (TAGS_TABLE_BEG_LABEL);
-  tmp_search->start--;
 
   /* The tag table consists of lines containing node names and positions.
      Do each line until we find one that doesn't contain a node name. */
@@ -340,8 +324,8 @@
 }
 
 /* Remember in FILE_BUFFER the nodenames, subfilenames, and offsets within the
-   subfiles of every node which appears in TAGS_BINDING.  The 2nd argument is
-   a binding surrounding the indirect files list. */
+   subfiles of every node which appears in the tags table at TAGS_BINDING.  
The 
+   indirect files list is at INDIRECT_BINDING. */
 static void
 get_tags_of_indirect_tags_table (FILE_BUFFER *file_buffer,
     SEARCH_BINDING *indirect_binding, SEARCH_BINDING *tags_binding)

Modified: trunk/info/nodes.h
===================================================================
--- trunk/info/nodes.h  2014-12-27 08:13:42 UTC (rev 5996)
+++ trunk/info/nodes.h  2014-12-27 21:53:22 UTC (rev 5997)
@@ -82,9 +82,9 @@
 #define INFO_MENU_LABEL                 "\n* Menu:"
 #define INFO_MENU_ENTRY_LABEL           "\n* "
 #define INFO_XREF_LABEL                 "*Note"
-#define TAGS_TABLE_END_LABEL            "\nEnd Tag Table"
-#define TAGS_TABLE_BEG_LABEL            "Tag Table:\n"
-#define INDIRECT_TAGS_TABLE_LABEL       "Indirect:\n"
+#define TAGS_TABLE_END_LABEL            "End Tag Table"
+#define TAGS_TABLE_BEG_LABEL            "Tag Table:"
+#define INDIRECT_TABLE_LABEL            "Indirect:"
 #define TAGS_TABLE_IS_INDIRECT_LABEL    "(Indirect)"
 #define LOCAL_VARIABLES_LABEL           "Local Variables"
 #define CHARACTER_ENCODING_LABEL        "coding:"

Modified: trunk/info/search.c
===================================================================
--- trunk/info/search.c 2014-12-27 08:13:42 UTC (rev 5996)
+++ trunk/info/search.c 2014-12-27 21:53:22 UTC (rev 5997)
@@ -378,6 +378,24 @@
      string was found at binding->start. */
   return search_end == binding->start;
 }
+
+/* Return non-zero if POINTER is looking at the text at STRING before an 
+   end-of-line. */
+int
+looking_at_line (char *string, char *pointer)
+{
+  int len;
+
+  len = strlen (string);
+  if (strncmp (pointer, string, len) != 0)
+    return 0;
+
+  pointer += len;
+  if (*pointer == '\n' || !strncmp (pointer, "\r\n", 2)
+      || *pointer == '\0')
+    return 1;
+  return 0;
+}
 
 /* **************************************************************** */
 /*                                                                  */
@@ -429,25 +447,28 @@
 /* **************************************************************** */
 
 /* Return the absolute position of the first occurence of a node separator
-   starting in BINDING->buffer.  The search starts at BINDING->start.
-   Return -1 if no node separator was found. */
+   starting in BINDING->buffer between BINDING->start and BINDING->end 
+   inclusive.  Return -1 if no node separator was found. */
 long
 find_node_separator (SEARCH_BINDING *binding)
 {
   register long i;
   char *body;
+  int dir;
 
   body = binding->buffer;
+  dir = binding->start < binding->end ? 1 : -1;
 
   /* A node is started by [^L]^_[^L][\r]\n.  That is to say, the C-l's are
      optional, but the US and NEWLINE are not.  This separator holds
      true for all separated elements in an Info file, including the tags
      table (if present) and the indirect tags table (if present). */
-  for (i = binding->start; i < binding->end; i++)
+  i = binding->start;
+  while (1)
+    {
       /* Note that bytes are read in order from the buffer, so if at any
          point a null byte is encountered signifying the end of the buffer,
          no more bytes will be read past that point. */
-
       if (body[i] == INFO_COOKIE)
         {
           int j = i + 1;
@@ -461,6 +482,11 @@
             return i;
         }
 
+      if (i == binding->end)
+        break;
+      i += dir;
+    }
+
   return -1;
 }
 
@@ -506,27 +532,40 @@
   return i;
 }
 
-/* Return the absolute position of the beginning of a tags table in this
-   binding starting the search at binding->start. */
+/* Return the absolute position of the beginning of a section in this file
+   whose first line is LABEL, starting the search at binding->start. */
 long
-find_tags_table (SEARCH_BINDING *binding)
+find_file_section (SEARCH_BINDING *binding, char *label)
 {
-  SEARCH_BINDING tmp_search;
+  SEARCH_BINDING s;
   long position;
+  int dir;
 
-  tmp_search.buffer = binding->buffer;
-  tmp_search.start = binding->start;
-  tmp_search.end = binding->end;
-  tmp_search.flags = S_FoldCase;
+  s.buffer = binding->buffer;
+  s.start = binding->start;
+  s.end = binding->end;
+  s.flags = S_FoldCase;
+  dir = binding->start < binding->end ? 1 : -1;
 
-  while ((position = find_node_separator (&tmp_search)) != -1 )
+  while ((position = find_node_separator (&s)) != -1 )
     {
-      tmp_search.start = position;
-      tmp_search.start += skip_node_separator (tmp_search.buffer
-          + tmp_search.start);
+      long offset = position;
+      offset += skip_node_separator (s.buffer + offset);
+      if (looking_at_line (label, s.buffer + offset))
+        return position;
 
-      if (looking_at (TAGS_TABLE_BEG_LABEL, &tmp_search))
-        return position;
+      if (dir > 0)
+        {
+          s.start = offset;
+          if (s.start >= s.end)
+            break;
+        }
+      else
+        {
+          s.start = position - 1;
+          if (s.start <= s.end)
+            break;
+        }
     }
   return -1;
 }

Modified: trunk/info/search.h
===================================================================
--- trunk/info/search.h 2014-12-27 08:13:42 UTC (rev 5996)
+++ trunk/info/search.h 2014-12-27 21:53:22 UTC (rev 5997)
@@ -64,6 +64,7 @@
                char *buffer, size_t buflen,
                regmatch_t **matches_out, size_t *match_count_out);
 extern int looking_at (char *string, SEARCH_BINDING *binding);
+int looking_at_line (char *string, char *pointer);
 
 /* Note that STRING_IN_LINE () always returns the offset of the 1st character
    after the string. */
@@ -81,7 +82,7 @@
 extern int skip_node_separator (char *body);
 
 extern long find_node_separator (SEARCH_BINDING *binding);
-extern long find_tags_table (SEARCH_BINDING *binding);
+long find_file_section (SEARCH_BINDING *binding, char *label);
 extern long find_node_in_binding (char *nodename, SEARCH_BINDING *binding);
 
 #endif /* not INFO_SEARCH_H */




reply via email to

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