[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[no subject]
From: |
Patrice Dumas |
Date: |
Sun, 29 Sep 2024 04:36:37 -0400 (EDT) |
branch: master
commit bafb772b7122cc819d3369cbf99dac223f46819e
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Sun Jun 9 14:32:39 2024 +0200
* tp/Texinfo/XS/main/manipulate_tree.c (copy_associated_info)
(associate_info_references): move string, integer and misc_arg copying
to copy_associated_info.
* tp/Texinfo/XS/main/manipulate_tree.c (copy_tree_internal)
(copy_associated_info, get_copy_ref): directly copy an element that has
not been copied before and is seen in the tree. Remove
copy_tree_internal. No need for counter anymore as all the elements
are copied when needed. Remove increase_ref_counter.
* tp/Texinfo/XS/main/manipulate_tree.c (remove_associated_copy_info)
(remove_element_copy_info): since there are no reference to resolve
anymore in the second step, it is now only used to remove the
reference to the copy element in each element in the copied tree.
Rename associate_info_references as remove_associated_copy_info and
copy_extra_info as remove_element_copy_info.
---
ChangeLog | 19 +++
tp/Texinfo/XS/main/manipulate_tree.c | 282 +++++++++++------------------------
2 files changed, 109 insertions(+), 192 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index ebd6a2f8f3..7e3e9a3769 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2024-06-09 Patrice Dumas <pertusus@free.fr>
+
+ * tp/Texinfo/XS/main/manipulate_tree.c (copy_associated_info)
+ (associate_info_references): move string, integer and misc_arg copying
+ to copy_associated_info.
+
+ * tp/Texinfo/XS/main/manipulate_tree.c (copy_tree_internal)
+ (copy_associated_info, get_copy_ref): directly copy an element that has
+ not been copied before and is seen in the tree. Remove
+ copy_tree_internal. No need for counter anymore as all the elements
+ are copied when needed. Remove increase_ref_counter.
+
+ * tp/Texinfo/XS/main/manipulate_tree.c (remove_associated_copy_info)
+ (remove_element_copy_info): since there are no reference to resolve
+ anymore in the second step, it is now only used to remove the
+ reference to the copy element in each element in the copied tree.
+ Rename associate_info_references as remove_associated_copy_info and
+ copy_extra_info as remove_element_copy_info.
+
2024-06-09 Patrice Dumas <pertusus@free.fr>
* tp/Texinfo/XS/main/manipulate_tree.c (copy_extra_info): remove 'new'
diff --git a/tp/Texinfo/XS/main/manipulate_tree.c
b/tp/Texinfo/XS/main/manipulate_tree.c
index 1b20abfa3f..6a4eec8d0d 100644
--- a/tp/Texinfo/XS/main/manipulate_tree.c
+++ b/tp/Texinfo/XS/main/manipulate_tree.c
@@ -36,30 +36,15 @@
#include "manipulate_tree.h"
#include "unicode.h"
-ELEMENT *
-copy_tree_internal (ELEMENT* current, ELEMENT *parent);
-
-void
-increase_ref_counter (ELEMENT *element)
-{
- element->counter++;
-}
+/* To do the copy, we do two pass. First with copy_tree_internal, the tree is
+ copied and a flag and reference to the copy is put in all the elements,
+ taking care that each element is processed once only.
+ Then, remove_element_copy_info goes through the tree again and remove
+ the references to the copies.
+ */
ELEMENT *
-copy_element (ELEMENT *f)
-{
- ELEMENT *e = 0;
- if (f->flags & EF_copy)
- {
- e = f->elt_info[type_data[f->type].elt_info_number];
- }
- else
- {
- increase_ref_counter (f);
- }
- copy_tree_internal (f, 0);
- return e;
-}
+copy_tree_internal (ELEMENT* current);
void
copy_associated_info (ASSOCIATED_INFO *info, ASSOCIATED_INFO* new_info)
@@ -81,13 +66,10 @@ copy_associated_info (ASSOCIATED_INFO *info,
ASSOCIATED_INFO* new_info)
case extra_element_oot:
{
ELEMENT *f = k_ref->k.element;
- ELEMENT *copy = copy_element (f);
- if (copy)
- {
- KEY_PAIR *k
- = get_associated_info_key (new_info, key, k_ref->type);
- k->k.element = copy;
- }
+ ELEMENT *copy = copy_tree_internal (f);
+ KEY_PAIR *k
+ = get_associated_info_key (new_info, key, k_ref->type);
+ k->k.element = copy;
}
break;
case extra_contents:
@@ -105,15 +87,8 @@ copy_associated_info (ASSOCIATED_INFO *info,
ASSOCIATED_INFO* new_info)
}
else
{
- if (e->flags & EF_copy)
- add_to_element_list (new_extra_contents,
- e->elt_info[type_data[e->type].elt_info_number]);
- else
- {
- increase_ref_counter (e);
- add_to_element_list (new_extra_contents, 0);
- }
- copy_tree_internal (e, 0);
+ ELEMENT *copy = copy_tree_internal (e);
+ add_to_element_list (new_extra_contents, copy);
}
}
break;
@@ -127,29 +102,63 @@ copy_associated_info (ASSOCIATED_INFO *info,
ASSOCIATED_INFO* new_info)
for (j = 0; j < f->e.c->contents.number; j++)
{
ELEMENT *e = f->e.c->contents.list[j];
-
- if (e->flags & EF_copy)
+ ELEMENT *copy = copy_tree_internal (e);
+ add_to_contents_as_array (new_extra_element, copy);
+ }
+ break;
+ }
+ case extra_string:
+ { /* A simple string. */
+ char *value = k_ref->k.string;
+ KEY_PAIR *k = get_associated_info_key (new_info, key, k_ref->type);
+ k->k.string = strdup (value);
+ break;
+ }
+ case extra_integer:
+ { /* A simple integer. */
+ KEY_PAIR *k = get_associated_info_key (new_info, key, k_ref->type);
+ k->k.integer = k_ref->k.integer;
+ break;
+ }
+ case extra_misc_args:
+ {
+ int j;
+ KEY_PAIR *k = get_associated_info_key (new_info, key, k_ref->type);
+ ELEMENT_LIST *new_extra_misc_args = new_list();
+ k->k.list = new_extra_misc_args;
+ for (j = 0; j < k_ref->k.list->number; j++)
+ {
+ const ELEMENT *e = k_ref->k.list->list[j];
+ ELEMENT *new_e;
+ if (e->type == ET_other_text)
{
- add_to_contents_as_array (new_extra_element,
- e->elt_info[type_data[e->type].elt_info_number]);
+ new_e = new_text_element (ET_other_text);
+ if (e->e.text->end > 0)
+ text_append_n (new_e->e.text, e->e.text->text,
+ e->e.text->end);
}
else
{
- increase_ref_counter (e);
- add_to_contents_as_array (new_extra_element, 0);
+ new_e = new_element (ET_NONE);
+ KEY_PAIR *k_integer = lookup_extra (e, "integer");
+ if (k_integer)
+ {
+ add_extra_integer (new_e, "integer",
k_integer->k.integer);
+ }
}
- copy_tree_internal (e, 0);
+ add_to_element_list (new_extra_misc_args, new_e);
}
- break;
+ break;
}
default:
+ fatal ("copy_associated_info: unknown extra type");
break;
}
}
}
ELEMENT *
-copy_tree_internal (ELEMENT* current, ELEMENT *parent)
+copy_tree_internal (ELEMENT* current)
{
ELEMENT *new;
int i;
@@ -157,19 +166,7 @@ copy_tree_internal (ELEMENT* current, ELEMENT *parent)
if (current->flags & EF_copy)
{
- /* NOTE normally the parent is set when add_to_element_* is called below
- FIXME why a special need? */
- new = current->elt_info[elt_info_nr];
- if (parent && !new->parent)
- {
- /*
- fprintf (stderr, "PARENT curr %p parent %p %s new %p %s\n", current,
parent,
- print_element_debug (parent,
0),
- new, print_element_debug
(new, 1));
- */
- new->parent = parent;
- }
- return new;
+ return current->elt_info[elt_info_nr];
}
if (type_data[current->type].flags & TF_text)
@@ -181,7 +178,6 @@ copy_tree_internal (ELEMENT* current, ELEMENT *parent)
new->flags = current->flags;
- increase_ref_counter (current);
/* set that flag to mark that a copy of the element exists */
current->flags |= EF_copy;
@@ -204,14 +200,15 @@ copy_tree_internal (ELEMENT* current, ELEMENT *parent)
return new;
}
+ /* the parent of new is set in add_to_element* */
for (i = 0; i < current->e.c->args.number; i++)
{
- ELEMENT *added = copy_tree_internal (current->e.c->args.list[i], new);
+ ELEMENT *added = copy_tree_internal (current->e.c->args.list[i]);
add_to_element_args (new, added);
}
for (i = 0; i < current->e.c->contents.number; i++)
{
- ELEMENT *added = copy_tree_internal (current->e.c->contents.list[i],
new);
+ ELEMENT *added = copy_tree_internal (current->e.c->contents.list[i]);
add_to_element_contents (new, added);
}
@@ -220,9 +217,8 @@ copy_tree_internal (ELEMENT* current, ELEMENT *parent)
for (i = 0; i < elt_info_nr; i++)
if (current->elt_info[i])
{
- ELEMENT *copy = copy_element (current->elt_info[i]);
- if (copy)
- new->elt_info[i] = copy;
+ ELEMENT *copy = copy_tree_internal (current->elt_info[i]);
+ new->elt_info[i] = copy;
}
}
@@ -242,50 +238,17 @@ copy_tree_internal (ELEMENT* current, ELEMENT *parent)
return new;
}
-ELEMENT *
-get_copy_ref (ELEMENT *element)
-{
- ELEMENT *result;
- int elt_info_nr = type_data[element->type].elt_info_number;
-
- result = element->elt_info[elt_info_nr];
-
- element->counter--;
-
- if (element->counter == 0)
- /* all the reference to that element have been resolved, mark
- as copied by unsetting the flag and deallocate pointer to the copy */
- {
- element->flags &= ~EF_copy;
- if (elt_info_nr > 0)
- {
- element->elt_info = (ELEMENT **) realloc (element->elt_info,
- sizeof (ELEMENT *) * elt_info_nr);
- if (!element->elt_info)
- fatal ("realloc failed");
- }
- else
- {
- free (element->elt_info);
- element->elt_info = 0;
- }
- }
-
- return result;
-}
-
void
-copy_extra_info (ELEMENT *current);
+remove_element_copy_info (ELEMENT *current);
void
-associate_info_references (ASSOCIATED_INFO *info, ASSOCIATED_INFO *new_info)
+remove_associated_copy_info (ASSOCIATED_INFO *info)
{
int i;
for (i = 0; i < info->info_number; i++)
{
const KEY_PAIR *k_ref = &info->info[i];
- const char *key = k_ref->key;
int j;
if (k_ref->type == extra_deleted)
@@ -297,40 +260,21 @@ associate_info_references (ASSOCIATED_INFO *info,
ASSOCIATED_INFO *new_info)
case extra_element_oot:
{
ELEMENT *f = k_ref->k.element;
- KEY_PAIR *k;
- k = lookup_associated_info (new_info, key);
- if (!k)
- {
- ELEMENT *e = get_copy_ref (f);
- k = get_associated_info_key (new_info, key,
- k_ref->type);
- k->k.element = e;
- }
- if (f->flags & EF_copy)
- copy_extra_info (f);
+ remove_element_copy_info (f);
break;
}
case extra_contents:
case extra_directions:
{
- KEY_PAIR *k = lookup_associated_info (new_info, key);
- ELEMENT_LIST *new_extra_contents = k->k.list;
for (j = 0; j < k_ref->k.list->number; j++)
{
ELEMENT *e = k_ref->k.list->list[j];
- ELEMENT *new_e = new_extra_contents->list[j];
if (!e && info->info[i].type == extra_directions)
{
}
else
{
- if (!new_e)
- {
- ELEMENT *new_ref = get_copy_ref (e);
- new_extra_contents->list[j] = new_ref;
- }
- if (e->flags & EF_copy)
- copy_extra_info (e);
+ remove_element_copy_info (e);
}
}
break;
@@ -338,90 +282,51 @@ associate_info_references (ASSOCIATED_INFO *info,
ASSOCIATED_INFO *new_info)
case extra_container:
{
const ELEMENT *f = k_ref->k.element;
- KEY_PAIR *k = lookup_associated_info (new_info, key);
- ELEMENT *new_extra_element = k->k.element;
for (j = 0; j < f->e.c->contents.number; j++)
{
ELEMENT *e = f->e.c->contents.list[j];
- ELEMENT *new_e = new_extra_element->e.c->contents.list[j];
- if (!new_e)
- {
- ELEMENT *new_ref = get_copy_ref (e);
- new_extra_element->e.c->contents.list[j] = new_ref;
- }
-
- if (e->flags & EF_copy)
- copy_extra_info (e);
+ remove_element_copy_info (e);
}
break;
}
- case extra_string:
- { /* A simple string. */
- char *value = k_ref->k.string;
- KEY_PAIR *k = get_associated_info_key (new_info, key, k_ref->type);
- k->k.string = strdup (value);
- break;
- }
- case extra_integer:
- { /* A simple integer. */
- KEY_PAIR *k = get_associated_info_key (new_info, key, k_ref->type);
- k->k.integer = k_ref->k.integer;
- break;
- }
- case extra_misc_args:
- {
- int j;
- KEY_PAIR *k = get_associated_info_key (new_info, key, k_ref->type);
- ELEMENT_LIST *new_extra_misc_args = new_list();
- k->k.list = new_extra_misc_args;
- for (j = 0; j < k_ref->k.list->number; j++)
- {
- const ELEMENT *e = k_ref->k.list->list[j];
- ELEMENT *new_e;
- if (e->type == ET_other_text)
- {
- new_e = new_text_element (ET_other_text);
- if (e->e.text->end > 0)
- text_append_n (new_e->e.text, e->e.text->text,
- e->e.text->end);
- }
- else
- {
- new_e = new_element (ET_NONE);
- KEY_PAIR *k_integer = lookup_extra (e, "integer");
- if (k_integer)
- {
- add_extra_integer (new_e, "integer",
k_integer->k.integer);
- }
- }
- add_to_element_list (new_extra_misc_args, new_e);
- }
- break;
- }
default:
- fatal ("associate_info_references: unknown extra type");
break;
}
}
}
void
-copy_extra_info (ELEMENT *current)
+remove_element_copy_info (ELEMENT *current)
{
int i;
+ int elt_info_nr;
if (! (current->flags & EF_copy))
/* already done */
return;
- ELEMENT *new = get_copy_ref (current);
+ elt_info_nr = type_data[current->type].elt_info_number;
+ /* mark as copied by unsetting the flag and deallocate pointer to the copy */
+ current->flags &= ~EF_copy;
+ if (elt_info_nr > 0)
+ {
+ current->elt_info = (ELEMENT **) realloc (current->elt_info,
+ sizeof (ELEMENT *) * elt_info_nr);
+ if (!current->elt_info)
+ fatal ("realloc failed");
+ }
+ else
+ {
+ free (current->elt_info);
+ current->elt_info = 0;
+ }
if (! (type_data[current->type].flags & TF_text))
{
for (i = 0; i < current->e.c->args.number; i++)
- copy_extra_info (current->e.c->args.list[i]);
+ remove_element_copy_info (current->e.c->args.list[i]);
for (i = 0; i < current->e.c->contents.number; i++)
- copy_extra_info (current->e.c->contents.list[i]);
+ remove_element_copy_info (current->e.c->contents.list[i]);
if (type_data[current->type].elt_info_number > 0)
{
@@ -431,26 +336,19 @@ copy_extra_info (ELEMENT *current)
if (current->elt_info[j])
{
ELEMENT *f = current->elt_info[j];
-
- if (!new->elt_info[j])
- {
- ELEMENT *e = get_copy_ref (f);
- new->elt_info[j] = e;
- }
- if (f->flags & EF_copy)
- copy_extra_info (f);
+ remove_element_copy_info (f);
}
}
}
- associate_info_references (¤t->extra_info, &new->extra_info);
+ remove_associated_copy_info (¤t->extra_info);
}
}
ELEMENT *
copy_tree (ELEMENT *current)
{
- ELEMENT *copy = copy_tree_internal (current, 0);
- copy_extra_info (current);
+ ELEMENT *copy = copy_tree_internal (current);
+ remove_element_copy_info (current);
return copy;
}