[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[5665] make references to file names containing full stops work again
From: |
Gavin D. Smith |
Subject: |
[5665] make references to file names containing full stops work again |
Date: |
Sun, 15 Jun 2014 15:12:22 +0000 |
Revision: 5665
http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=5665
Author: gavin
Date: 2014-06-15 15:12:21 +0000 (Sun, 15 Jun 2014)
Log Message:
-----------
make references to file names containing full stops work again
Modified Paths:
--------------
trunk/ChangeLog
trunk/info/info-utils.c
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2014-06-13 12:52:35 UTC (rev 5664)
+++ trunk/ChangeLog 2014-06-15 15:12:21 UTC (rev 5665)
@@ -1,3 +1,14 @@
+2014-06-15 Gavin Smith <address@hidden>
+
+ * info/info-utils.c (read_bracketed_filename): Split out from
+ info_parse_node and rewritten for clarity.
+ (read_quoted_string): Set output parameter to null on error.
+ (avoid_see_see): Include '(' character when searching backward.
+ (scan_reference_target): Call read_bracketed_filename instead of
+ info_parse_node to get filename.
+ (scan_node_contents): Check if cross-reference within parentheses was a
+ "*note".
+
2014-06-13 Gavin Smith <address@hidden>
* info/session.c (forget_node): Don't forget the last node in the
Modified: trunk/info/info-utils.c
===================================================================
--- trunk/info/info-utils.c 2014-06-13 12:52:35 UTC (rev 5664)
+++ trunk/info/info-utils.c 2014-06-15 15:12:21 UTC (rev 5665)
@@ -46,6 +46,53 @@
calling info_parse_xxx (). */
char *info_parsed_nodename = NULL;
+/* Read a filename surrounded by "(" and ")", accounting for matching
+ characters. Return length of read filename. On error, set *FILENAME
+ to null and return 0. */
+int
+read_bracketed_filename (char *string, char **filename)
+{
+ register int i = 0;
+ int count = 0; /* Level of nesting. */
+ int first_close = -1; /* First ")" encountered. */
+
+ *filename = 0;
+ if (*string != '(')
+ return 0;
+
+ string++;
+ count = 1;
+ for (i = 0; string[i]; i++)
+ {
+ if (string[i] == '(')
+ count++;
+ else if (string[i] == ')')
+ {
+ if (first_close == -1)
+ first_close = i;
+
+ count--;
+ if (count == 0)
+ break;
+ }
+ }
+
+ /* If string ended before brackets were balanced, take the first ")" as
+ terminating the filename. */
+ if (count > 0)
+ {
+ if (first_close == -1)
+ return 0;
+ i = first_close;
+ }
+
+ /* Remember parsed filename. */
+ *filename = xcalloc (1, i + 1);
+ memcpy (*filename, string, i);
+
+ return i + 2; /* Length of filename plus "(" and ")". */
+}
+
/* Parse the filename and nodename out of STRING, saving in
INFO_PARSED_FILENAME and INFO_PARSED_NODENAME. These variables should not
be freed by calling code. If either is missing, the relevant variable is
@@ -53,9 +100,7 @@
void
info_parse_node (char *string)
{
- register int i = 0;
int nodename_len;
- char *terminator;
free (info_parsed_filename);
free (info_parsed_nodename);
@@ -68,48 +113,8 @@
string += skip_whitespace_and_newlines (string);
- /* Check for (FILENAME)NODENAME. */
- if (*string == '(')
- {
- int bcnt;
- int bfirst;
-
- i = 0;
- /* Advance past the opening paren. */
- string++;
+ string += read_bracketed_filename (string, &info_parsed_filename);
- /* Find the closing paren. Handle nested parens correctly. */
- for (bcnt = 0, bfirst = -1; string[i]; i++)
- {
- if (string[i] == ')')
- {
- if (bcnt == 0)
- {
- bfirst = -1;
- break;
- }
- else if (!bfirst)
- bfirst = i;
- bcnt--;
- }
- else if (string[i] == '(')
- bcnt++;
- }
-
- if (bfirst >= 0)
- i = bfirst;
-
- /* Remember parsed filename. */
- info_parsed_filename = xcalloc (1, i+1);
- memcpy (info_parsed_filename, string, i);
-
- /* Point directly at the nodename. */
- string += i;
-
- if (*string)
- string++;
- }
-
/* Parse out nodename. */
string += skip_whitespace_and_newlines (string);
nodename_len = strlen (string);
@@ -159,7 +164,10 @@
len = strcspn (start, terminator);
if (*terminator && !start[len])
- len = 0;
+ {
+ len = 0;
+ *output = 0;
+ }
else
{
*output = xmalloc (len + 1);
@@ -173,7 +181,10 @@
len = strcspn (start + 1, "\177");
if (*terminator && !(start + 1)[len])
- len = 0;
+ {
+ len = 0;
+ *output = 0;
+ }
else
{
*output = xmalloc (len + 1);
@@ -1123,7 +1134,7 @@
}
}
-/* Check if preceding word is a word like "see". BASE points before PTR in
+/* Check if preceding word is a word like "see". BASE points before PTR in
a block of allocated memory. */
static int
avoid_see_see (char *ptr, char *base)
@@ -1140,10 +1151,12 @@
/* Skip past whitespace, and then go to beginning of preceding word. */
ptr--;
- while (ptr > base && (*ptr == ' ' || *ptr == '\n' || *ptr == '\t'))
+ while (ptr > base && (*ptr == ' ' || *ptr == '\n' || *ptr == '\t'
+ || *ptr == '('))
ptr--;
- while (ptr > base && !(*ptr == ' ' || *ptr == '\n' || *ptr == '\t'))
+ while (ptr > base && !(*ptr == ' ' || *ptr == '\n' || *ptr == '\t'
+ || *ptr == '(' ))
{
ptr--;
word_len++;
@@ -1308,11 +1321,6 @@
static int
scan_reference_target (REFERENCE *entry, NODE *node, int in_parentheses)
{
- char *target;
-
- int info_parsed_line_number = 0;
-
- int length; /* Length of specification */
int i;
/* If this reference entry continues with another ':' then the reference is
@@ -1328,37 +1336,45 @@
return 1;
}
- /* This entry continues with a specific nodename. Parse the
- nodename from the specification. */
+ /* This entry continues with a specific target. Parse the
+ file name and node name from the specification. */
- /* 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));
-
- length = read_quoted_string (inptr, ",.", 2, &target);
- if (!length)
- return 0;
-
if (entry->type == REFERENCE_XREF)
{
- char *nl_off;
+ int length = 0; /* Length of specification */
+ char *target_start = inptr;
+ char *nl_off = 0;
int space_at_start_of_line = 0;
- info_parse_node (target);
+ length += skip_whitespace_and_newlines (inptr);
+ length += read_bracketed_filename (inptr + length, &entry->filename);
+
+ length += skip_whitespace_and_newlines (inptr + length);
+
+ /* Get the node name. */
+ length += read_quoted_string (inptr + length, ",.", 2, &entry->nodename);
+
+ skip_input (length);
+
/* Check if there is a newline in the target. */
- nl_off = strchr (target, '\n');
+ nl_off = strchr (target_start, '\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 < inptr)
+ space_at_start_of_line = skip_whitespace (nl_off + 1);
+ else
+ nl_off = 0;
+ }
+
+ if (entry->filename)
+ {
+ /* Heuristic of whether it's worth outputing a newline before the
+ filename. This checks whether the newline appears more
+ than half way through the text, and therefore which side is
+ longer. */
if (nl_off
- && nl_off < inptr + (length - space_at_start_of_line) / 2)
+ && nl_off < target_start + (length - space_at_start_of_line) / 2)
{
int i;
write_extra_bytes_to_output ("\n", 1);
@@ -1368,19 +1384,22 @@
skip_input (strspn (inptr, " "));
nl_off = 0;
}
- else if (inptr[-1] != '\n')
- write_extra_bytes_to_output (" ", 1);
+ else
+
+ if (*inptr != '\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 (entry->filename,
+ strlen (entry->filename));
write_extra_bytes_to_output (" manual)",
strlen (" manual)"));
}
-
- /* Output terminating punctuation, unless we are in a reference
+
+ /* Hide terminating punctuation if we are in a reference
like "(*note Label:(file)node.)". */
- skip_input (length);
- if (in_parentheses && (inptr[0] == '.' || inptr[0] == ','))
+ if (in_parentheses && inptr[0] == '.')
skip_input (1);
/* Copy any terminating punctuation before the optional newline. */
@@ -1401,7 +1420,17 @@
else /* entry->type == REFERENCE_MENU_ITEM */
{
int line_len;
+ int length = 0; /* Length of specification */
+ length = skip_whitespace (inptr);
+ length += read_bracketed_filename (inptr + length, &entry->filename);
+ length += skip_whitespace (inptr + length);
+
+ /* Get the node name. */
+ length += read_quoted_string (inptr + length, ",.", 2, &entry->nodename);
+ if (inptr[length] == '.') /* A '.' terminating the entry. */
+ length++;
+
if (node->flags & N_IsDir)
{
/* Set line_len to length of line so far. */
@@ -1415,48 +1444,12 @@
line_len = inptr - linestart;
}
- info_parse_node (target);
-
- 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. */
+ /* Show the name of the node the index entry refers to. */
copy_input_to_output (length);
- else
+ else 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);
- }
- }
-
- /* Parse "(line ...)" part of menus, if any. */
- {
- /* Skip any whitespace first, and then a newline in case the item
- was so long to contain the ``(line ...)'' string in the same
- physical line. */
- copy_input_to_output (skip_whitespace (inptr));
- if (*inptr == '\n')
- copy_input_to_output (skip_whitespace (inptr));
-
- if (!strncmp (inptr, "(line ", strlen ("(line ")))
- {
- copy_input_to_output (strlen ("(line "));
- info_parsed_line_number = strtol (inptr, 0, 0);
- }
- else
- info_parsed_line_number = 0;
- }
-
- if (node->flags & N_IsDir)
- {
if (inptr[strspn (inptr, " ")] != '\n')
{
for (i = 0; i < length; i++)
@@ -1473,24 +1466,36 @@
skip_input (1 + line_len);
}
}
- }
- free (target);
+ else
+ skip_input (length);
- if (info_parsed_filename)
- entry->filename = xstrdup (info_parsed_filename);
+ /* Parse "(line ...)" part of menus, if any. */
+ {
+ char *lineptr = inptr;
+ /* Skip any whitespace first, and then a newline in case the item
+ was so long to contain the ``(line ...)'' string in the same
+ physical line. */
+ lineptr += skip_whitespace (inptr);
+ if (*lineptr == '\n')
+ lineptr += 1 + skip_whitespace (lineptr + 1);
- if (info_parsed_nodename)
- entry->nodename = xstrdup (info_parsed_nodename);
+ if (!strncmp (lineptr, "(line ", strlen ("(line ")))
+ {
+ lineptr += strlen ("(line ");
+ entry->line_number = strtol (lineptr, 0, 0);
+ }
+ else
+ entry->line_number = 0;
+ }
- 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 > 1)
+ /* 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--;
+ }
return 1;
}
@@ -1602,7 +1607,8 @@
/* Create REFERENCE entity. */
entry = info_new_reference (0, 0);
- if (safe_string_index (inptr, -1, s.buffer, s.end) == '(')
+ if (safe_string_index (inptr, -1, s.buffer, s.end) == '('
+ && safe_string_index (inptr, 1, s.buffer, s.end) == 'n')
in_parentheses = 1;
save_conversion_state ();
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [5665] make references to file names containing full stops work again,
Gavin D. Smith <=