[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"));
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [5657] recover better when not looking at a reference; footnote redisplay for history,
Gavin D. Smith <=