texinfo-commits
[Top][All Lists]
Advanced

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

[5657] recover better when not looking at a reference; footnote redispla


From: Gavin D. Smith
Subject: [5657] recover better when not looking at a reference; footnote redisplay for history
Date: Wed, 11 Jun 2014 11:16:27 +0000

Revision: 5657
          http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=5657
Author:   gavin
Date:     2014-06-11 11:16:25 +0000 (Wed, 11 Jun 2014)
Log Message:
-----------
recover better when not looking at a reference; footnote redisplay for history

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

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog     2014-06-10 17:11:10 UTC (rev 5656)
+++ trunk/ChangeLog     2014-06-11 11:16:25 UTC (rev 5657)
@@ -1,3 +1,24 @@
+2014-06-11  Gavin Smith  <address@hidden>
+
+       * info/info-utils.c (save_conversion_state, reset_conversion): New
+       functions.
+       (scan_node_contents): Call them.
+       (read_quoted_string): New parameter added.  All callers updated.
+       (scan_reference_label): Comment changed.
+       (scan_reference_target): Return value says whether syntax was
+       understood.  Call read_quoted_string directly instead of via
+       info_parse_node.
+       * info/session.c (info_move_to_xref): Check if list of references
+       in node is empty.  Don't handle cursor-movement-scrolls variable.
+       Unused function parameters removed.
+       (info_follow_menus): Use PARSE_NODE_VERBATIM instead of
+       PARSE_NODE_DFLT.
+       (info_move_to_prev_xref, info_move_to_next_xref): Go to reference in
+       next node if cursor-movement-scrolls is On.  Call the other function if
+       the count was negative.
+
+       * info/session.c (forget_node): Call info_get_or_remove_footnotes.
+
 2014-06-10  Gavin Smith  <address@hidden>
 
        * info/session.c (read_nodename_to_kill, kill_node, info_kill_node):

Modified: trunk/info/info-utils.c
===================================================================
--- trunk/info/info-utils.c     2014-06-10 17:11:10 UTC (rev 5656)
+++ trunk/info/info-utils.c     2014-06-11 11:16:25 UTC (rev 5657)
@@ -143,7 +143,7 @@
     }
 
   /* Parse out nodename. */
-  nodename_len = read_quoted_string (string, terminator,
+  nodename_len = read_quoted_string (string, terminator, 0,
                                      &info_parsed_nodename);
 
   string += nodename_len;
@@ -198,40 +198,77 @@
 
 /* Set *OUTPUT to a copy of the string starting at START and finishing at
    a character in TERMINATOR, unless START[0] == INFO_QUOTE, in which case
-   copy string from START+1 until the next occurence of INFO_QUOTE.  Return
-   length of string including any quoting characters.
+   copy string from START+1 until the next occurence of INFO_QUOTE.  If
+   TERMINATOR is an empty string, finish at a null character.   LINES is
+   the number of lines that the string can span.  If LINES is zero, there is no
+   limit.  Return length of string including any quoting characters.  Return
+   0 if input was invalid.
 
    TODO: Decide on best method of quoting. */
 long
-read_quoted_string (char *start, char *terminator, char **output)
+read_quoted_string (char *start, char *terminator, int lines, char **output)
 {
   long len;
+  char *nl = 0, saved_char;
 
+  if (lines)
+    {
+      int i;
+      nl = start;
+      for (i = 0; i < lines; i++)
+        {
+          nl = strchr (nl, '\n');
+          if (!nl)
+            break; /* End of input string reached. */
+          nl++;
+        }
+      if (nl)
+        {
+          saved_char = *nl;
+          *nl = '\0';
+        }
+    }
+
   if (start[0] != '\177')
     {
       len = strcspn (start, terminator);
 
-      *output = xmalloc (len + 1);
-      strncpy (*output, start, len);
-      (*output)[len] = '\0';
-
-      return len;
+      if (*terminator && !start[len])
+        len = 0;
+      else
+        {
+          *output = xmalloc (len + 1);
+          strncpy (*output, start, len);
+          (*output)[len] = '\0';
+        }
     }
 #ifdef QUOTE_NODENAMES
   else
     {
       len = strcspn (start + 1, "\177");
 
-      *output = xmalloc (len + 1);
-      strncpy (*output, start + 1, len);
-      (*output)[len] = '\0';
+      if (*terminator && !(start + 1)[len])
+        len = 0;
+      else
+        {
+          *output = xmalloc (len + 1);
+          strncpy (*output, start + 1, len);
+          (*output)[len] = '\0';
+        }
 
-      return len + 2;
+      len += 2;
     }
 #else /* ! QUOTE_NODENAMES */
-  *output = xstrdup ("");
-  return 0;
+  else
+    {
+      *output = xstrdup ("");
+      len = 0;
+    }
 #endif
+
+  if (nl)
+    *nl = saved_char;
+  return len;
 }
 
 
@@ -732,6 +769,27 @@
     text_buffer_init (&output_buf);
 }
 
+static size_t saved_offset;
+static char *saved_inptr;
+static long saved_difference;
+
+void
+save_conversion_state (void)
+{
+  saved_offset = text_buffer_off (&output_buf);
+  saved_inptr = inptr;
+  saved_difference = output_bytes_difference;
+}
+
+/* Go back to the saved state of the output stream. */
+void
+reset_conversion (void)
+{
+  text_buffer_off (&output_buf) = saved_offset;
+  inptr = saved_inptr;
+  output_bytes_difference = saved_difference;
+}
+
 /* Copy bytes from input to output with no encoding conversion. */
 static void
 copy_direct (long n)
@@ -1124,7 +1182,7 @@
       /* Separate at commas or newlines, so it will work for
          filenames including full stops. */
       /* TODO: Account for "(dir)" and "(DIR)". */
-      value_length = read_quoted_string (inptr, "\n\t,", store_in);
+      value_length = read_quoted_string (inptr, "\n\t,", 1, store_in);
 
       /* Skip past value and any quoting or separating characters. */
       skip_input (value_length);
@@ -1234,10 +1292,10 @@
   copy_input_to_output (skip_whitespace_and_newlines (inptr));
 }
 
-/* Output reference label and update ENTRY.  inptr should be on the first
+/* Output reference label and update ENTRY.  INPTR should be on the first
    non-whitespace byte of label when this function is called.  It is left
-   at the first non-whitespace character after the colon terminating the
-   label.  Return 0 if invalid syntax is encountered. */
+   at the first character after the colon terminating the label.  Return 0 if
+   invalid syntax is encountered. */
 static int
 scan_reference_label (REFERENCE *entry)
 {
@@ -1246,15 +1304,14 @@
   char *label = 0;
   long label_len;
 
-  /* Search forward to ":" to get label name. */
-  /* Cross-references may have a newline in the middle. */
+  /* Search forward to ":" to get label name.  Cross-references may have
+     a newline in the middle. */
   if (entry->type == REFERENCE_MENU_ITEM)
-    label_len = read_quoted_string (inptr, ":", &label);
+    label_len = read_quoted_string (inptr, ":", 1, &label);
   else
-    /* TODO: Limit lines label can cross. */
-    label_len = read_quoted_string (inptr, "\n:", &label);
+    label_len = read_quoted_string (inptr, ":", 2, &label);
     
-  if (inptr[label_len] != ':')
+  if (label_len == 0)
     return 0;
 
   entry->label = label;
@@ -1321,169 +1378,175 @@
   return 1;
 }
 
-static void
+/* INPTR should be at the first character after the colon
+   terminating the label.  Return 0 on syntax error. */
+static int
 scan_reference_target (REFERENCE *entry, NODE *node, int in_parentheses)
 {
+  char *target;
+
+  int length; /* Length of specification */
+  int i;
+
   /* If this reference entry continues with another ':' then the reference is
      within the same file, and the nodename is the same as the label. */
   if (*inptr == ':')
     {
       skip_input (1);
-
       if (entry->type == REFERENCE_MENU_ITEM)
         write_extra_bytes_to_output (" ", 1);
 
       entry->filename = 0;
       entry->nodename = xstrdup (entry->label);
+      return 1;
     }
-  else
-    {
-      /* This entry continues with a specific nodename.  Parse the
-         nodename from the specification. */
 
-      int length; /* Length of specification */
-      int i;
+  /* This entry continues with a specific nodename.  Parse the
+     nodename from the specification. */
 
-      if (entry->type != REFERENCE_MENU_ITEM)
-        {
-          char saved_char;
-          char *nl_off;
-          int space_at_start_of_line = 0;
+  /* Skip any following spaces after the ":". */
+  if (entry->type == REFERENCE_MENU_ITEM)
+    copy_input_to_output (skip_whitespace (inptr));
+  else
+    skip_input (skip_whitespace (inptr));
 
-          /* Skip any following spaces after the ":". */
-          skip_input (skip_whitespace (inptr));
+  if (!read_quoted_string (inptr, ",.", 2, &target))
+    return 0;
 
-          length = info_parse_node (inptr, PARSE_NODE_SKIP_NEWLINES);
+  if (entry->type == REFERENCE_XREF)
+    {
+      char *nl_off;
+      int space_at_start_of_line = 0;
 
-          /* Check if there is a newline in the target. */
-          saved_char = inptr[length];
-          inptr[length] = '\0';
-          nl_off = strchr (inptr, '\n');
-          inptr[length] = saved_char;
+      length = info_parse_node (target, PARSE_NODE_VERBATIM);
 
-          if (nl_off)
-            space_at_start_of_line = skip_whitespace (nl_off + 1);
-          
-          if (info_parsed_filename)
+      /* Check if there is a newline in the target. */
+      nl_off = strchr (target, '\n');
+      if (nl_off)
+        space_at_start_of_line = skip_whitespace (nl_off + 1);
+      
+      if (info_parsed_filename)
+        {
+          /* Rough heuristic of whether it's worth outputing a newline
+             now or later. */
+          if (nl_off
+              && nl_off < inptr + (length - space_at_start_of_line) / 2)
             {
-              /* Rough heuristic of whether it's worth outputing a newline
-                 now or later. */
-              if (nl_off
-                  && nl_off < inptr + (length - space_at_start_of_line) / 2)
-                {
-                  int i;
-                  write_extra_bytes_to_output ("\n", 1);
+              int i;
+              write_extra_bytes_to_output ("\n", 1);
 
-                  for (i = 0; i < space_at_start_of_line; i++)
-                    write_extra_bytes_to_output (" ", 1);
-                  skip_input (strspn (inptr, " "));
-                  nl_off = 0;
-                }
-              else if (inptr[-1] != '\n')
+              for (i = 0; i < space_at_start_of_line; i++)
                 write_extra_bytes_to_output (" ", 1);
-              write_extra_bytes_to_output ("(", 1);
-              write_extra_bytes_to_output (info_parsed_filename,
-                strlen (info_parsed_filename));
-              write_extra_bytes_to_output (" manual)",
-                                           strlen (" manual)"));
+              skip_input (strspn (inptr, " "));
+              nl_off = 0;
             }
+          else if (inptr[-1] != '\n')
+            write_extra_bytes_to_output (" ", 1);
+          write_extra_bytes_to_output ("(", 1);
+          write_extra_bytes_to_output (info_parsed_filename,
+            strlen (info_parsed_filename));
+          write_extra_bytes_to_output (" manual)",
+                                       strlen (" manual)"));
+        }
 
-          /* Output terminating punctuation, unless we are in a reference
-             like "(*note Label:(file)node.)". */
-          if (!in_parentheses)
-            skip_input (length);
-          else
-            skip_input (length + 1);
+      /* Output terminating punctuation, unless we are in a reference
+         like "(*note Label:(file)node.)". */
+      if (!in_parentheses)
+        skip_input (length);
+      else
+        skip_input (length + 1);
 
-          /* Copy any terminating punctuation before the optional newline. */
-          copy_input_to_output (strspn (inptr, ".),"));
+      /* Copy any terminating punctuation before the optional newline. */
+      copy_input_to_output (strspn (inptr, ".),"));
 
-          /* Output a newline if one is needed.  Don't do it at the end
-             a paragraph. */
-          if (nl_off && *inptr != '\n')
-            { 
-              int i;
+      /* Output a newline if one is needed.  Don't do it at the end
+         a paragraph. */
+      if (nl_off && *inptr != '\n')
+        { 
+          int i;
 
-              write_extra_bytes_to_output ("\n", 1);
-              for (i = 0; i < space_at_start_of_line; i++)
-                write_extra_bytes_to_output (" ", 1);
-              skip_input (strspn (inptr, " "));
-            }
+          write_extra_bytes_to_output ("\n", 1);
+          for (i = 0; i < space_at_start_of_line; i++)
+            write_extra_bytes_to_output (" ", 1);
+          skip_input (strspn (inptr, " "));
         }
-      else /* entry->type == REFERENCE_MENU_ITEM */
+    }
+  else /* entry->type == REFERENCE_MENU_ITEM */
+    {
+      int line_len;
+
+      if (node->flags & N_IsDir)
         {
-          int line_len;
+          /* Set line_len to length of line so far. */
 
-          if (node->flags & N_IsDir)
-            {
-              /* Set line_len to length of line so far. */
+          char *linestart;
+          linestart = memrchr (input_start, '\n', inptr - input_start);
+          if (!linestart)
+            linestart = input_start;
+          else
+            linestart++; /* Point to first character after newline. */
+          line_len = inptr - linestart;
+        }
 
-              char *linestart;
-              linestart = memrchr (input_start, '\n', inptr - input_start);
-              if (!linestart)
-                linestart = input_start;
-              else
-                linestart++; /* Point to first character after newline. */
-              line_len = inptr - linestart;
-            }
+      length = info_parse_node (inptr, PARSE_NODE_DFLT);
+      if (inptr[length] == '.') /* Include a '.' terminating the entry. */
+        length++;
 
-          length = info_parse_node (inptr, PARSE_NODE_DFLT);
-          if (inptr[length] == '.') /* Include a '.' terminating the entry. */
-            length++;
-
-          if (node->flags & N_IsIndex)
-            /* For index nodes, output the destination as well,
-               which will be the name of the node the index entry
-               refers to. */
-            copy_input_to_output (length);
-          else 
+      if (node->flags & N_IsIndex)
+        /* For index nodes, output the destination as well,
+           which will be the name of the node the index entry
+           refers to. */
+        copy_input_to_output (length);
+      else 
+        {
+          skip_input (length);
+          if (!(node->flags & N_IsDir)) 
             {
-              skip_input (length);
-              if (!(node->flags & N_IsDir)) 
-                {
-                  /* Output spaces the length of the node specifier to avoid
-                     messing up left edge of second column of menu. */
-                  for (i = 0; i < length; i++)
-                    write_extra_bytes_to_output (" ", 1);
-                }
+              /* Output spaces the length of the node specifier to avoid
+                 messing up left edge of second column of menu. */
+              for (i = 0; i < length; i++)
+                write_extra_bytes_to_output (" ", 1);
             }
+        }
 
-          if (node->flags & N_IsDir) 
+      if (node->flags & N_IsDir) 
+        {
+          if (inptr[strspn (inptr, " ")] != '\n')
             {
-              if (inptr[strspn (inptr, " ")] != '\n')
-                {
-                  for (i = 0; i < length; i++)
-                    write_extra_bytes_to_output (" ", 1);
-                }
-              else
-                {
-                  /* For a dir node, if there is no more text in this line,
-                     check if there is a menu entry description in the next
-                     line to the right of the end of the label, and display it
-                     in this line. */
-                  skip_input (strspn (inptr, " "));
-                  if (line_len <= strspn (inptr + 1, " "))
-                    skip_input (1 + line_len);
-                }
+              for (i = 0; i < length; i++)
+                write_extra_bytes_to_output (" ", 1);
             }
+          else
+            {
+              /* For a dir node, if there is no more text in this line,
+                 check if there is a menu entry description in the next
+                 line to the right of the end of the label, and display it
+                 in this line. */
+              skip_input (strspn (inptr, " "));
+              if (line_len <= strspn (inptr + 1, " "))
+                skip_input (1 + line_len);
+            }
         }
+    }
+  free (target);
 
-      if (info_parsed_filename)
-        entry->filename = xstrdup (info_parsed_filename);
+  if (info_parsed_filename)
+    entry->filename = xstrdup (info_parsed_filename);
 
-      if (info_parsed_nodename)
-        entry->nodename = xstrdup (info_parsed_nodename);
+  if (info_parsed_nodename)
+    entry->nodename = xstrdup (info_parsed_nodename);
 
-      if (!preprocess_nodes_p)
-        entry->line_number = info_parsed_line_number;
-      else
-        /* Adjust line offset in file to one in displayed text.  This
-           does not work perfectly because we can't know exactly what
-           text will be inserted/removed: for example, due to expansion
-           of an image tag.  This subtracts 1 for a removed node information
-           line. */
-        entry->line_number = info_parsed_line_number - 1;
-    }
+  if (!preprocess_nodes_p)
+    entry->line_number = info_parsed_line_number;
+  else
+    /* Adjust line offset in file to one in displayed text.  This
+       does not work perfectly because we can't know exactly what
+       text will be inserted/removed: for example, due to expansion
+       of an image tag.  This subtracts 1 for a removed node information
+       line. */
+    entry->line_number = info_parsed_line_number - 1;
+
+  return 1;
 }
 
 /* BASE is earlier in a block of allocated memory than PTR, and the block
@@ -1596,19 +1659,22 @@
       if (safe_string_index (inptr, -1, s.buffer, s.end) == '(')
         in_parentheses = 1;
 
+      save_conversion_state ();
       scan_reference_marker (entry);
 
-      /* Read and output reference label (up until colon). */
-      if (!scan_reference_label (entry))
+      if (!scan_reference_label (entry)
+         || !scan_reference_target (entry, node, in_parentheses))
         {
-          /* This is not a menu entry or reference. */
+          /* This is not a menu entry or reference.  Do not add to our list. */
+          char *cur_inptr = inptr;
+          reset_conversion ();
+          copy_input_to_output (cur_inptr - inptr);
+
+          info_reference_free (entry);
           s.start = inptr - s.buffer;
           continue;
         }
 
-      /* Get target of reference and update entry. */
-      scan_reference_target (entry, node, in_parentheses);
-
       add_pointer_to_array (entry, refs_index, refs, refs_slots, 50);
 
       s.start = inptr - s.buffer;

Modified: trunk/info/info-utils.h
===================================================================
--- trunk/info/info-utils.h     2014-06-10 17:11:10 UTC (rev 5656)
+++ trunk/info/info-utils.h     2014-06-11 11:16:25 UTC (rev 5657)
@@ -60,7 +60,8 @@
 */ 
 int info_parse_node (char *string, int flag);
 
-long read_quoted_string (char *start, char *terminator, char **output);
+long read_quoted_string (char *start, char *terminator, int lines,
+                         char **output);
 
 void scan_node_contents (FILE_BUFFER *fb, NODE **node_ptr);
 

Modified: trunk/info/nodes.c
===================================================================
--- trunk/info/nodes.c  2014-06-10 17:11:10 UTC (rev 5656)
+++ trunk/info/nodes.c  2014-06-11 11:16:25 UTC (rev 5657)
@@ -223,7 +223,7 @@
 
       /* Record nodename and nodestart. */
       entry = info_create_node ();
-      read_quoted_string (nodeline + start, ",\n\t", &entry->nodename);
+      read_quoted_string (nodeline + start, ",\n\t", 0, &entry->nodename);
       entry->nodestart = nodestart;
 
       init_file_buffer_tag (file_buffer, entry);

Modified: trunk/info/search.c
===================================================================
--- trunk/info/search.c 2014-06-10 17:11:10 UTC (rev 5656)
+++ trunk/info/search.c 2014-06-11 11:16:25 UTC (rev 5657)
@@ -619,7 +619,7 @@
       s.start += offset;
       s.start += skip_whitespace (s.buffer + s.start); 
       nodename_start = s.buffer + s.start;
-      read_quoted_string (nodename_start, "\n\t,", &read_nodename);
+      read_quoted_string (nodename_start, "\n\t,", 0, &read_nodename);
       if (!read_nodename)
         return -1;
 

Modified: trunk/info/session.c
===================================================================
--- trunk/info/session.c        2014-06-10 17:11:10 UTC (rev 5656)
+++ trunk/info/session.c        2014-06-11 11:16:25 UTC (rev 5657)
@@ -319,6 +319,8 @@
   i = --win->hist_index;
 
   window_set_node_of_window (win, win->hist[i - 1]->node);
+  if (auto_footnotes_p)
+    info_get_or_remove_footnotes (win);
   set_window_pagetop (win, win->hist[i - 1]->pagetop);
   win->point = win->hist[i - 1]->point;
   window_compute_line_map (win);
@@ -2161,21 +2163,18 @@
     }
 }
 
-/* Move to the next or previous cross reference in this node. */
+/* Move to the next or previous cross reference in this node.  Return 0 if
+   there aren't any. */
 static int
-info_move_to_xref (WINDOW *window, int count, unsigned char key, int dir)
+info_move_to_xref (WINDOW *window, int dir)
 {
   long placement = -1;
   NODE *node = window->node;
   REFERENCE **ref;
 
   /* Fail if there are no references in node */
-  if (!node->references)
-    {
-      if (!cursor_movement_scrolls_p)
-              info_error ("%s", msg_no_xref_node);
-      return cursor_movement_scrolls_p;
-    }
+  if (!node->references || !node->references[0])
+    return 0;
 
   if (dir == 1) /* Search forwards */
     for (ref = node->references; *ref != 0; ref++)
@@ -2193,34 +2192,42 @@
         placement = (*ref)->start;
       }
 
-  /* If there was neither a menu or xref entry appearing in this node after
-     point, choose the first menu or xref entry appearing in this node. */
   if (placement == -1)
     {
+      /* There was neither a menu or xref entry appearing in this node
+         after point. */
       if (cursor_movement_scrolls_p)
-        return 1;
+        return 0;
       else
+        /* Choose the first menu or xref entry appearing in this node. */
         placement = node->references[0]->start;
     }
 
   window->point = placement;
   window_adjust_pagetop (window);
-  return 0;
+  return 1;
 }
 
 DECLARE_INFO_COMMAND (info_move_to_prev_xref,
                       _("Move to the previous cross reference"))
 {
   if (count < 0)
-    info_move_to_prev_xref (window, -count, key);
+    info_move_to_next_xref (window, -count, key);
   else
     {
-      while (info_move_to_xref (window, count, key, -1))
+      if (!info_move_to_xref (window, -1))
         {
-          info_error_was_printed = 0;
-          if (backward_move_node_structure (window, info_scroll_behaviour))
-            break;
-          window->point = window->node->nodelen - 1;
+          if (!cursor_movement_scrolls_p)
+            info_error ("%s", msg_no_xref_node);
+          else
+            {
+              if (backward_move_node_structure (window, info_scroll_behaviour)
+                  == 0)
+                {
+                  window->point = window->node->nodelen - 1;
+                  info_move_to_xref (window, -1);
+                }
+            }
         }
     }
 }
@@ -2229,19 +2236,18 @@
                       _("Move to the next cross reference"))
 {
   if (count < 0)
-    info_move_to_next_xref (window, -count, key);
+    info_move_to_prev_xref (window, -count, key);
   else
     {
-      /* Note: This can cause some blinking when the next cross reference is
-         located several nodes further. This effect can be easily suppressed
-         by setting display_inhibited to 1, however this will also make
-         error messages to be dumped on stderr, instead on the echo area. */ 
-      while (info_move_to_xref (window, count, key, 1))
+      if (!info_move_to_xref (window, 1))
         {
-          info_error_was_printed = 0;
-          if (forward_move_node_structure (window, info_scroll_behaviour))
-            break;
-          window->point = 0;
+          if (!cursor_movement_scrolls_p)
+            info_error ("%s", msg_no_xref_node);
+          else
+            {
+              forward_move_node_structure (window, info_scroll_behaviour);
+              info_move_to_xref (window, 1);
+            }
         }
     }
 }
@@ -2310,10 +2316,10 @@
       /* Try to find this node.  */
       if (initial_node->parent)
         node = info_get_node (initial_node->parent, entry->nodename,
-                              PARSE_NODE_DFLT);
+                              PARSE_NODE_VERBATIM);
       else
         node = info_get_node (initial_node->filename, entry->nodename,
-                              PARSE_NODE_DFLT);
+                              PARSE_NODE_VERBATIM);
       if (!node)
         {
          debug (3, ("no matching node found"));




reply via email to

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