[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[8320] parsetexi parse_node_manual split elements in main tree
From: |
gavinsmith0123 |
Subject: |
[8320] parsetexi parse_node_manual split elements in main tree |
Date: |
Wed, 17 Oct 2018 17:48:14 -0400 (EDT) |
Revision: 8320
http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=8320
Author: gavin
Date: 2018-10-17 17:48:14 -0400 (Wed, 17 Oct 2018)
Log Message:
-----------
parsetexi parse_node_manual split elements in main tree
Modified Paths:
--------------
trunk/tp/Texinfo/XS/parsetexi/end_line.c
trunk/tp/Texinfo/XS/parsetexi/tree.c
trunk/tp/Texinfo/XS/parsetexi/tree.h
Modified: trunk/tp/Texinfo/XS/parsetexi/end_line.c
===================================================================
--- trunk/tp/Texinfo/XS/parsetexi/end_line.c 2018-10-17 19:53:19 UTC (rev
8319)
+++ trunk/tp/Texinfo/XS/parsetexi/end_line.c 2018-10-17 21:48:14 UTC (rev
8320)
@@ -855,57 +855,42 @@
parse_node_manual (ELEMENT *node)
{
NODE_SPEC_EXTRA *result;
- ELEMENT *trimmed;
- ELEMENT *manual;
+ ELEMENT *new;
+ int idx = 0; /* index into node->contents */
result = malloc (sizeof (NODE_SPEC_EXTRA));
- result->manual_content = 0;
- trimmed = trim_spaces_comment_from_content (node);
+ result->manual_content = result->node_content = 0;
+
/* If the content starts with a '(', try to get a manual name. */
- if (trimmed->contents.number > 0 && trimmed->contents.list[0]->text.end > 0
- && trimmed->contents.list[0]->text.text[0] == '(')
+ if (node->contents.number > 0 && node->contents.list[0]->text.end > 0
+ && node->contents.list[0]->text.text[0] == '(')
{
+ ELEMENT *manual, *first;
+ char *opening_bracket, *closing_bracket;
+
/* Handle nested parentheses in the manual name, for whatever reason. */
+ int bracket_count = 1; /* Number of ( seen minus number of ) seen. */
- ELEMENT *e;
- char *opening_bracket, *closing_bracket;
- int bracket_count = 0;
-
manual = new_element (ET_NONE);
- /* If the first contents element is "(" alone, discard it, otherwise
- remove the leading "(". */
- if (trimmed->contents.list[0]->text.end > 1)
+ /* If the first contents element is "(" followed by more text, split
+ the leading "(" into its own element. */
+ first = node->contents.list[0];
+ if (first->text.end > 1)
{
- /* Replace the first element with another element with the leading
- "(" removed. */
- /* TODO: Would it be simpler to split the text element
- in node->contents as well, to avoid having out-of-tree
- elements? */
- ELEMENT *first;
- first = malloc (sizeof (ELEMENT));
- memcpy (first, trimmed->contents.list[0], sizeof (ELEMENT));
- first->parent_type = route_not_in_tree;
- first->text.text = malloc (first->text.space);
- memcpy (first->text.text,
- trimmed->contents.list[0]->text.text + 1,
- trimmed->contents.list[0]->text.end);
+ memmove (first->text.text, first->text.text + 1, first->text.end);
first->text.end--;
- trimmed->contents.list[0] = first;
+ new = new_element (0);
+ text_append_n (&new->text, "(", 1);
+ insert_into_contents (node, new, 0);
}
- else
- {
- (void) remove_from_contents (trimmed, 0);
- /* Note the removed element still is present in the original
- node->contents in the main tree. */
- }
- bracket_count++;
+ idx++;
- while (trimmed->contents.number > 0)
+ for (; idx < node->contents.number; idx++)
{
- ELEMENT *e = remove_from_contents (trimmed, 0);
- char *p;
+ ELEMENT *e = node->contents.list[idx];
+ char *p, *q;
if (e->text.end == 0)
{
@@ -952,62 +937,68 @@
/* Split the element in two, putting the part before the ")"
in the manual name, leaving the part afterwards for the
node name. */
- /* TODO: Same as above re route_not_in_tree. */
- ELEMENT *before, *after;
+ remove_from_contents (node, idx); /* Remove 'e'. */
p--; /* point at ) */
if (p > e->text.text)
{
- before = new_element (ET_NONE);
- before->parent_type = route_not_in_tree;
- before->parent = node; // FIXME - try not to set this
- text_append_n (&before->text, e->text.text,
+ /* text before ), part of the manual name */
+ new = new_element (ET_NONE);
+ text_append_n (&new->text, e->text.text,
p - e->text.text);
- add_to_contents_as_array (manual, before);
+ insert_into_contents (node, new, idx++);
+
+ add_to_contents_as_array (manual, new);
}
+ new = new_element (0);
+ text_append_n (&new->text, ")", 1);
+ insert_into_contents (node, new, idx++);
+
/* Skip ')' and any following whitespace.
Note that we don't manage to skip any multibyte
UTF-8 space characters here. */
p++;
- p += strspn (p, whitespace_chars);
+ q = p + strspn (p, whitespace_chars);
+ if (q > p)
+ {
+ new = new_element (0);
+ text_append_n (&new->text, p, q - p);
+ insert_into_contents (node, new, idx++);
+ }
+
+ p = q;
if (*p)
{
- after = new_element (ET_NONE);
- text_append_n (&after->text, p,
+ /* text after ), part of the node name. */
+ new = new_element (ET_NONE);
+ text_append_n (&new->text, p,
e->text.text + e->text.end - p);
-
- insert_into_contents (trimmed, after, 0);
- after->parent_type = route_not_in_tree;
- after->parent = node;
+ insert_into_contents (node, new, idx);
}
- if (e->parent_type == route_not_in_tree)
- destroy_element (e);
+ destroy_element (e);
break;
}
- }
+ } /* for */
if (bracket_count == 0)
result->manual_content = manual;
else /* unbalanced */
{
- destroy_element (trimmed);
- trimmed = manual;
+ destroy_element (manual);
+ idx = 0; /* Back to the start, and consider the whole thing
+ as a node name. */
}
}
/* If anything left, it is the node name. */
- if (trimmed->contents.number > 0)
+ if (idx < node->contents.number)
{
- trimmed->parent_type = route_not_in_tree;
- trimmed->parent = node;
- result->node_content = trimmed;
+ new = new_element (0);
+ insert_slice_into_contents (new, 0, node, idx, node->contents.number);
+ result->node_content = new;
}
- else
- {
- result->node_content = 0;
- destroy_element (trimmed);
- }
+
return result;
}
Modified: trunk/tp/Texinfo/XS/parsetexi/tree.c
===================================================================
--- trunk/tp/Texinfo/XS/parsetexi/tree.c 2018-10-17 19:53:19 UTC (rev
8319)
+++ trunk/tp/Texinfo/XS/parsetexi/tree.c 2018-10-17 21:48:14 UTC (rev
8320)
@@ -167,6 +167,19 @@
}
}
+/* Make sure there is space for at least N more elements. */
+static void
+reallocate_list_for (int n, ELEMENT_LIST *list)
+{
+ if (list->number + n >= list->space)
+ {
+ list->space += n + 1;
+ list->list = realloc (list->list, list->space * sizeof (ELEMENT *));
+ if (!list->list)
+ abort (); /* Out of memory. */
+ }
+}
+
void
add_to_element_contents (ELEMENT *parent, ELEMENT *e)
{
@@ -238,6 +251,25 @@
list->number++;
}
+/* Insert elements to the contents of TO at position WHERE from FROM
+ from START inclusive to END exclusive. Do not set the parent fields. */
+void
+insert_slice_into_contents (ELEMENT *to, int where, ELEMENT *from,
+ int start, int end)
+{
+ int num = end - start;
+ reallocate_list_for (num, &to->contents);
+
+ memmove (&to->contents.list[where + num],
+ &to->contents.list[where],
+ (to->contents.number - where) * sizeof (ELEMENT *));
+ memmove (&to->contents.list[where],
+ &from->contents.list[start],
+ num * sizeof (ELEMENT *));
+
+ to->contents.number += num;
+}
+
ELEMENT *
remove_from_contents (ELEMENT *parent, int where)
{
Modified: trunk/tp/Texinfo/XS/parsetexi/tree.h
===================================================================
--- trunk/tp/Texinfo/XS/parsetexi/tree.h 2018-10-17 19:53:19 UTC (rev
8319)
+++ trunk/tp/Texinfo/XS/parsetexi/tree.h 2018-10-17 21:48:14 UTC (rev
8320)
@@ -1,19 +1,3 @@
-/* Copyright 2010, 2011, 2012, 2013, 2014, 2015
- Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
ELEMENT *new_element (enum element_type type);
void add_to_element_contents (ELEMENT *parent, ELEMENT *e);
void add_to_contents_as_array (ELEMENT *parent, ELEMENT *e);
@@ -20,6 +4,8 @@
void add_to_element_args (ELEMENT *parent, ELEMENT *e);
void insert_into_contents (ELEMENT *parent, ELEMENT *e, int where);
void insert_into_args (ELEMENT *parent, ELEMENT *e, int where);
+void insert_slice_into_contents (ELEMENT *to, int idx, ELEMENT *from,
+ int start, int end);
ELEMENT *remove_from_contents (ELEMENT *parent, int where);
ELEMENT *last_args_child (ELEMENT *current);
ELEMENT *last_contents_child (ELEMENT *current);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [8320] parsetexi parse_node_manual split elements in main tree,
gavinsmith0123 <=