texinfo-commits
[Top][All Lists]
Advanced

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

branch master updated: * tp/Texinfo/XS/parsetexi/labels.c (internal_xref


From: Patrice Dumas
Subject: branch master updated: * tp/Texinfo/XS/parsetexi/labels.c (internal_xref_list) (remember_internal_xref, reset_internal_xrefs, forget_internal_xrefs): use an ELEMENT_LIST for internal_xref_list.
Date: Tue, 24 Oct 2023 18:23:18 -0400

This is an automated email from the git hooks/post-receive script.

pertusus pushed a commit to branch master
in repository texinfo.

The following commit(s) were added to refs/heads/master by this push:
     new 8e20a52cec * tp/Texinfo/XS/parsetexi/labels.c (internal_xref_list) 
(remember_internal_xref, reset_internal_xrefs, forget_internal_xrefs): use an 
ELEMENT_LIST for internal_xref_list.
8e20a52cec is described below

commit 8e20a52cec545018376e9414bf0941139fde9d81
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Wed Oct 25 00:23:10 2023 +0200

    * tp/Texinfo/XS/parsetexi/labels.c (internal_xref_list)
    (remember_internal_xref, reset_internal_xrefs, forget_internal_xrefs):
    use an ELEMENT_LIST for internal_xref_list.
    
    * tp/Texinfo/Transformations.pm (regenerate_master_menu),
    tp/Texinfo/Common.pm (replace_element_in_contents),
    tp/Texinfo/XS/main/tree.ctp/Texinfo/XS/main/tree.c
    (remove_element_from_list, replace_element_in_contents),
    tp/Texinfo/XS/structuring_transfo/transformations.c
    (regenerate_master_menu): when removing an existing @detailmenu,
    remove it also from the global commands information and remove the
    associated menu entry nodes from internal references, add the new
    master menu to global commands information.
    
    * tp/Texinfo/Common.pm (import)
    (relate_index_entries_to_table_items_in_tree)
    (move_index_entries_after_items_in_tree, protect_colon_in_tree)
    (protect_comma_in_tree, protect_node_after_label_in_tree),
    tp/Texinfo/Structuring.pm (import, associate_internal_references)
    (sectioning_structure, nodes_tree, set_menus_node_directions)
    (complete_node_tree_with_menus, check_nodes_are_referenced)
    (number_floats), tp/Texinfo/Transformations.pm (import)
    (fill_gaps_in_sectioning, reference_to_arg_in_tree)
    (complete_tree_nodes_menus, complete_tree_nodes_missing_menu)
    (regenerate_master_menu, insert_nodes_for_sectioning_commands)
    (protect_hashchar_at_line_beginning)
    (protect_first_parenthesis_in_targets),
    tp/Texinfo/XS/structuring_transfo/StructuringTransfo.xs,
    tp/t/test_utils.pl, tp/texi2any.pl: override
    directly the perl functions with XS, remove associated _XS_*
    functions. Update conditions of XS use to correspond to the cases of
    functions overriding.
    
    * tp/Texinfo/Structuring.pm (import, rebuild_tree),
    tp/Texinfo/XS/structuring_transfo/StructuringTransfo.xs
    (rebuild_tree): add to be able to rebuild a tree after modification by
    XS code.
    
    * tp/t/automatic_nodes.t, : skip tests that test perl but not XS
    when XS is used.
    
    * tp/t/automatic_menus.t, tp/t/automatic_nodes.t,
    tp/t/do_master_menu.t, tp/t/index_before_item.t,
    tp/t/protect_character_in_texinfo.t, tp/t/reference_to_text_in_tree.t,
    tp/t/test_fill_gaps_in_sectioning.t, tp/t/test_protect_contents.t,
    tp/t/test_protect_hashchar_at_line_beginning.t: rebuild tree or
    document to pass tests when there is a parsing and
    transformations/structuring in XS, but perl is used for conversion of
    the tree back to texinfo code.
---
 ChangeLog                                          |  53 ++++++++
 tp/Texinfo/Common.pm                               |  83 +++++--------
 tp/Texinfo/Structuring.pm                          | 114 ++++-------------
 tp/Texinfo/Transformations.pm                      | 135 ++++++++-------------
 tp/Texinfo/XS/main/tree.c                          |  40 ++++++
 tp/Texinfo/XS/main/tree.h                          |   3 +
 tp/Texinfo/XS/parsetexi/labels.c                   |  20 +--
 tp/Texinfo/XS/parsetexi/labels.h                   |   3 +-
 tp/Texinfo/XS/parsetexi/parser.c                   |  10 +-
 .../XS/structuring_transfo/StructuringTransfo.xs   | 119 +++++++++---------
 .../XS/structuring_transfo/transformations.c       |  42 ++++++-
 tp/t/automatic_menus.t                             |   3 +
 tp/t/automatic_nodes.t                             |  30 ++++-
 tp/t/do_master_menu.t                              |  14 +--
 tp/t/index_before_item.t                           |   3 +
 tp/t/protect_character_in_texinfo.t                |  14 ++-
 tp/t/reference_to_text_in_tree.t                   |   3 +
 tp/t/test_fill_gaps_in_sectioning.t                |  13 +-
 tp/t/test_protect_contents.t                       |   4 +
 tp/t/test_protect_hashchar_at_line_beginning.t     |  24 ++--
 tp/t/test_utils.pl                                 |   9 +-
 tp/texi2any.pl                                     |   9 +-
 22 files changed, 402 insertions(+), 346 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a85ea87f5f..a197bdda06 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,56 @@
+2023-10-24  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/XS/parsetexi/labels.c (internal_xref_list)
+       (remember_internal_xref, reset_internal_xrefs, forget_internal_xrefs):
+       use an ELEMENT_LIST for internal_xref_list.
+
+       * tp/Texinfo/Transformations.pm (regenerate_master_menu),
+       tp/Texinfo/Common.pm (replace_element_in_contents),
+       tp/Texinfo/XS/main/tree.ctp/Texinfo/XS/main/tree.c
+       (remove_element_from_list, replace_element_in_contents),
+       tp/Texinfo/XS/structuring_transfo/transformations.c
+       (regenerate_master_menu): when removing an existing @detailmenu,
+       remove it also from the global commands information and remove the
+       associated menu entry nodes from internal references, add the new
+       master menu to global commands information.
+
+
+       * tp/Texinfo/Common.pm (import)
+       (relate_index_entries_to_table_items_in_tree)
+       (move_index_entries_after_items_in_tree, protect_colon_in_tree)
+       (protect_comma_in_tree, protect_node_after_label_in_tree),
+       tp/Texinfo/Structuring.pm (import, associate_internal_references)
+       (sectioning_structure, nodes_tree, set_menus_node_directions)
+       (complete_node_tree_with_menus, check_nodes_are_referenced)
+       (number_floats), tp/Texinfo/Transformations.pm (import)
+       (fill_gaps_in_sectioning, reference_to_arg_in_tree)
+       (complete_tree_nodes_menus, complete_tree_nodes_missing_menu)
+       (regenerate_master_menu, insert_nodes_for_sectioning_commands)
+       (protect_hashchar_at_line_beginning)
+       (protect_first_parenthesis_in_targets),
+       tp/Texinfo/XS/structuring_transfo/StructuringTransfo.xs,
+       tp/t/test_utils.pl, tp/texi2any.pl: override
+       directly the perl functions with XS, remove associated _XS_*
+       functions. Update conditions of XS use to correspond to the cases of
+       functions overriding.
+
+       * tp/Texinfo/Structuring.pm (import, rebuild_tree),
+       tp/Texinfo/XS/structuring_transfo/StructuringTransfo.xs
+       (rebuild_tree): add to be able to rebuild a tree after modification by
+       XS code.
+
+       * tp/t/automatic_nodes.t, : skip tests that test perl but not XS
+       when XS is used.
+
+       * tp/t/automatic_menus.t, tp/t/automatic_nodes.t,
+       tp/t/do_master_menu.t, tp/t/index_before_item.t,
+       tp/t/protect_character_in_texinfo.t, tp/t/reference_to_text_in_tree.t,
+       tp/t/test_fill_gaps_in_sectioning.t, tp/t/test_protect_contents.t,
+       tp/t/test_protect_hashchar_at_line_beginning.t: rebuild tree or
+       document to pass tests when there is a parsing and
+       transformations/structuring in XS, but perl is used for conversion of
+       the tree back to texinfo code.
+
 2023-10-24  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/XS/main/builtin_commands.c (element_builtin_cmd)
diff --git a/tp/Texinfo/Common.pm b/tp/Texinfo/Common.pm
index 1054f863a9..aa5b8b5ece 100644
--- a/tp/Texinfo/Common.pm
+++ b/tp/Texinfo/Common.pm
@@ -84,23 +84,23 @@ sub import {
     if (!defined $ENV{TEXINFO_XS_PARSER}
         or $ENV{TEXINFO_XS_PARSER} eq '1') {
       Texinfo::XSLoader::override(
-        "Texinfo::Common::_XS_relate_index_entries_to_table_items_in_tree",
+        "Texinfo::Common::relate_index_entries_to_table_items_in_tree",
         "Texinfo::StructTransf::relate_index_entries_to_table_items_in_tree"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Common::_XS_move_index_entries_after_items_in_tree",
+        "Texinfo::Common::move_index_entries_after_items_in_tree",
         "Texinfo::StructTransf::move_index_entries_after_items_in_tree"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Common::_XS_protect_colon_in_tree",
+        "Texinfo::Common::protect_colon_in_tree",
         "Texinfo::StructTransf::protect_colon_in_tree"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Common::_XS_protect_comma_in_tree",
+        "Texinfo::Common::protect_comma_in_tree",
         "Texinfo::StructTransf::protect_comma_in_tree"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Common::_XS_protect_node_after_label_in_tree",
+        "Texinfo::Common::protect_node_after_label_in_tree",
         "Texinfo::StructTransf::protect_node_after_label_in_tree"
       );
       Texinfo::XSLoader::override(
@@ -1665,6 +1665,28 @@ sub split_custom_heading_command_contents($)
   return $result;
 }
 
+# FIXME document?
+# currently untested/unused, but there is a similar function in XS that
+# is used.
+sub replace_element_in_contents($$$)
+{
+  my $parent = shift;
+  my $removed = shift;
+  my $added = shift;
+
+  return 0 if (!defined($parent) or !$parent->{'contents'});
+
+  my $nr_contents = scalar(@{$parent->{'contents'}});
+  for (my $i = 0; $i < $nr_contents; $i++) {
+    my $content = $parent->{'contents'}->[$i];
+    if ($content eq $removed) {
+      $parent->{'contents'}->[$i] = $added;
+      return 1;
+    }
+  }
+  return 0;
+}
+
 # not currently used
 sub find_parent_root_command($$);
 sub find_parent_root_command($$)
@@ -2111,20 +2133,10 @@ sub _protect_comma($$)
   return _protect_text($current, quotemeta(','));
 }
 
-sub _XS_protect_comma_in_tree($)
-{
-  return 1;
-}
-
 sub protect_comma_in_tree($)
 {
   my $tree = shift;
 
-  if (not _XS_protect_comma_in_tree($tree)
-      and $XS_only and $tree->{'tree_document_descriptor'}) {
-    return $tree;
-  }
-
   return modify_tree($tree, \&_protect_comma);
 }
 
@@ -2222,20 +2234,10 @@ sub _protect_colon($$)
   return _protect_text($current, quotemeta(':'));
 }
 
-sub _XS_protect_colon_in_tree($)
-{
-  return 1;
-}
-
 sub protect_colon_in_tree($)
 {
   my $tree = shift;
 
-  if (not _XS_protect_colon_in_tree($tree)
-      and $XS_only and $tree->{'tree_document_descriptor'}) {
-    return $tree;
-  }
-
   return modify_tree($tree, \&_protect_colon);
 }
 
@@ -2247,20 +2249,10 @@ sub _protect_node_after_label($$)
   return _protect_text($current, '['. quotemeta(".\t,") .']');
 }
 
-sub _XS_protect_node_after_label_in_tree($)
-{
-  return 1;
-}
-
 sub protect_node_after_label_in_tree($)
 {
   my $tree = shift;
 
-  if (not _XS_protect_node_after_label_in_tree($tree)
-      and $XS_only and $tree->{'tree_document_descriptor'}) {
-    return $tree;
-  }
-
   return modify_tree($tree, \&_protect_node_after_label);
 }
 
@@ -2400,21 +2392,11 @@ sub _move_index_entries_after_items($$)
   return undef;
 }
 
-sub _XS_move_index_entries_after_items_in_tree($)
-{
-  return 1;
-}
-
 # For @itemize/@enumerate
 sub move_index_entries_after_items_in_tree($)
 {
   my $tree = shift;
 
-  if (not _XS_move_index_entries_after_items_in_tree($tree)
-      and $XS_only) {
-    return undef;
-  }
-
   modify_tree($tree, \&_move_index_entries_after_items);
 }
 
@@ -2497,22 +2479,11 @@ sub _relate_index_entries_to_table_items($$$)
   return undef;
 }
 
-sub _XS_relate_index_entries_to_table_items_in_tree($)
-{
-  return 1;
-}
-
 sub relate_index_entries_to_table_items_in_tree($$)
 {
   my $tree = shift;
   my $indices_information = shift;
 
-  # The XS function retrieves the indices information associated with the tree.
-  if (not _XS_relate_index_entries_to_table_items_in_tree($tree)
-      and $XS_only) {
-    return undef;
-  }
-
   modify_tree($tree, \&_relate_index_entries_to_table_items,
               $indices_information);
 }
diff --git a/tp/Texinfo/Structuring.pm b/tp/Texinfo/Structuring.pm
index 8450307fdc..4126c5c132 100644
--- a/tp/Texinfo/Structuring.pm
+++ b/tp/Texinfo/Structuring.pm
@@ -89,8 +89,10 @@ sub import {
         or $ENV{TEXINFO_XS_PARSER} ne '0') {
       Texinfo::XSLoader::override(
         "Texinfo::Structuring::rebuild_document",
-        "Texinfo::StructTransf::rebuild_document",
-      );
+        "Texinfo::StructTransf::rebuild_document");
+      Texinfo::XSLoader::override(
+        "Texinfo::Structuring::rebuild_tree",
+        "Texinfo::StructTransf::rebuild_tree");
       Texinfo::XSLoader::override(
         "Texinfo::Structuring::clear_document_errors",
         "Texinfo::StructTransf::clear_document_errors",
@@ -100,35 +102,35 @@ sub import {
         "Texinfo::StructTransf::copy_tree"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Structuring::_XS_associate_internal_references",
+        "Texinfo::Structuring::associate_internal_references",
         "Texinfo::StructTransf::associate_internal_references"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Structuring::_XS_sectioning_structure",
+        "Texinfo::Structuring::sectioning_structure",
         "Texinfo::StructTransf::sectioning_structure"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Structuring::_XS_warn_non_empty_parts",
+        "Texinfo::Structuring::warn_non_empty_parts",
         "Texinfo::StructTransf::warn_non_empty_parts"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Structuring::_XS_nodes_tree",
+        "Texinfo::Structuring::nodes_tree",
         "Texinfo::StructTransf::nodes_tree"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Structuring::_XS_set_menus_node_directions",
+        "Texinfo::Structuring::set_menus_node_directions",
         "Texinfo::StructTransf::set_menus_node_directions"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Structuring::_XS_complete_node_tree_with_menus",
+        "Texinfo::Structuring::complete_node_tree_with_menus",
         "Texinfo::StructTransf::complete_node_tree_with_menus"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Structuring::_XS_check_nodes_are_referenced",
+        "Texinfo::Structuring::check_nodes_are_referenced",
         "Texinfo::StructTransf::check_nodes_are_referenced"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Structuring::_XS_number_floats",
+        "Texinfo::Structuring::number_floats",
         "Texinfo::StructTransf::number_floats"
       );
       Texinfo::XSLoader::override(
@@ -188,6 +190,16 @@ sub rebuild_document($;$)
   return $document;
 }
 
+# this method does nothing, but the XS override rebuilds the perl
+# tree based on XS data.
+sub rebuild_tree($;$)
+{
+  my $tree = shift;
+  my $no_store = shift;
+
+  return $tree;
+}
+
 # this method does nothing, but the XS override clears the document errors
 sub clear_document_errors($)
 {
@@ -210,11 +222,6 @@ sub copy_tree($;$)
   return $result;
 }
 
-sub _XS_sectioning_structure($)
-{
-  return 1;
-}
-
 # Go through the sectioning commands (e.g. @chapter, not @node), and
 # set:
 # 'section_level'
@@ -228,11 +235,6 @@ sub sectioning_structure($$$)
   my $customization_information = shift;
   my $root = shift;
 
-  if (not _XS_sectioning_structure($root)
-      and $XS_only) {
-    return undef;
-  }
-
   my $sec_root;
   my $previous_section;
   my $previous_toplevel;
@@ -459,22 +461,12 @@ sub _print_sectioning_tree($)
   return $result;
 }
 
-sub _XS_warn_non_empty_parts($)
-{
-  return 1;
-}
-
 sub warn_non_empty_parts($$$)
 {
   my $document = shift;
   my $registrar = shift;
   my $customization_information = shift;
 
-  if (not _XS_warn_non_empty_parts($document)
-      and $XS_only) {
-    return undef;
-  }
-
   my $global_commands = $document->global_commands_information();
 
   if ($global_commands->{'part'}) {
@@ -630,22 +622,12 @@ sub get_node_node_childs_from_sectioning
   return @node_childs;
 }
 
-sub _XS_check_nodes_are_referenced($)
-{
-  return 1;
-}
-
 # In general should be called only after complete_node_tree_with_menus
 # to try to generate menus automatically before checking.
-sub check_nodes_are_referenced
+sub check_nodes_are_referenced($$$)
 {
   my ($document, $registrar, $customization_information) = @_;
 
-  if (not _XS_check_nodes_are_referenced($document)
-      and $XS_only) {
-    return undef;
-  }
-
   my $nodes_list = $document->nodes_list();
   my $identifier_target = $document->labels_information();
   my $refs = $document->internal_references_information();
@@ -751,11 +733,6 @@ sub _first_menu_node($$)
   return undef;
 }
 
-sub _XS_set_menus_node_directions($)
-{
-  return 1;
-}
-
 # set menu_directions
 sub set_menus_node_directions($$$)
 {
@@ -763,11 +740,6 @@ sub set_menus_node_directions($$$)
   my $registrar = shift;
   my $customization_information = shift;
 
-  if (not _XS_set_menus_node_directions($document)
-      and $XS_only) {
-    return undef;
-  }
-
   my $global_commands = $document->global_commands_information();
   my $nodes_list = $document->nodes_list();
   my $identifier_target = $document->labels_information();
@@ -894,11 +866,6 @@ sub _section_direction_associated_node($$)
   return undef;
 }
 
-sub _XS_complete_node_tree_with_menus($)
-{
-  return 1;
-}
-
 # complete automatic directions with menus (and first node
 # for Top node).
 # Checks on structure related to menus.
@@ -908,11 +875,6 @@ sub complete_node_tree_with_menus($$$)
   my $registrar = shift;
   my $customization_information = shift;
 
-  if (not _XS_complete_node_tree_with_menus($document)
-      and $XS_only) {
-    return undef;
-  }
-
   my $nodes_list = $document->nodes_list();
   my $identifier_target = $document->labels_information();
 
@@ -1119,11 +1081,6 @@ sub complete_node_tree_with_menus($$$)
   }
 }
 
-sub _XS_nodes_tree($)
-{
-  return 1;
-}
-
 # set node directions based on sectioning and @node explicit directions
 sub nodes_tree($$$)
 {
@@ -1131,11 +1088,6 @@ sub nodes_tree($$$)
   my $registrar = shift;
   my $customization_information = shift;
 
-  if (not _XS_nodes_tree($document)
-      and $XS_only) {
-    return undef;
-  }
-
   my $root = $document->tree();
   my $identifier_target = $document->labels_information();
 
@@ -1272,11 +1224,6 @@ sub nodes_tree($$$)
   return \@nodes_list;
 }
 
-sub _XS_associate_internal_references($)
-{
-  return 1;
-}
-
 # For each internal reference command, set the 'normalized' key, in the
 # @*ref first argument or in 'menu_entry_node' extra.
 sub associate_internal_references($$$)
@@ -1285,11 +1232,6 @@ sub associate_internal_references($$$)
   my $registrar = shift;
   my $customization_information = shift;
 
-  if (not _XS_associate_internal_references($document)
-      and $XS_only) {
-    return undef;
-  }
-
   my $identifier_target = $document->labels_information();
   my $refs = $document->internal_references_information();
 
@@ -1344,20 +1286,10 @@ sub associate_internal_references($$$)
   }
 }
 
-sub _XS_number_floats($)
-{
-  return 1;
-}
-
 sub number_floats($)
 {
   my $document = shift;
 
-  if (not _XS_number_floats($document)
-      and $XS_only) {
-    return undef;
-  }
-
   my $floats = $document->floats_information();
 
   return if (!defined($floats));
diff --git a/tp/Texinfo/Transformations.pm b/tp/Texinfo/Transformations.pm
index 9f8abe1a9a..d7b9de4b93 100644
--- a/tp/Texinfo/Transformations.pm
+++ b/tp/Texinfo/Transformations.pm
@@ -57,35 +57,35 @@ sub import {
     if (!defined $ENV{TEXINFO_XS_PARSER}
         or $ENV{TEXINFO_XS_PARSER} eq '1') {
       Texinfo::XSLoader::override(
-        "Texinfo::Transformations::_XS_fill_gaps_in_sectioning",
+        "Texinfo::Transformations::fill_gaps_in_sectioning",
         "Texinfo::StructTransf::fill_gaps_in_sectioning"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Transformations::_XS_reference_to_arg_in_tree",
+        "Texinfo::Transformations::reference_to_arg_in_tree",
         "Texinfo::StructTransf::reference_to_arg_in_tree"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Transformations::_XS_complete_tree_nodes_menus",
+        "Texinfo::Transformations::complete_tree_nodes_menus",
         "Texinfo::StructTransf::complete_tree_nodes_menus"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Transformations::_XS_complete_tree_nodes_missing_menu",
+        "Texinfo::Transformations::complete_tree_nodes_missing_menu",
         "Texinfo::StructTransf::complete_tree_nodes_missing_menu"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Transformations::_XS_regenerate_master_menu",
+        "Texinfo::Transformations::regenerate_master_menu",
         "Texinfo::StructTransf::regenerate_master_menu"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Transformations::_XS_insert_nodes_for_sectioning_commands",
+        "Texinfo::Transformations::insert_nodes_for_sectioning_commands",
         "Texinfo::StructTransf::insert_nodes_for_sectioning_commands"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Transformations::_XS_protect_hashchar_at_line_beginning",
+        "Texinfo::Transformations::protect_hashchar_at_line_beginning",
         "Texinfo::StructTransf::protect_hashchar_at_line_beginning"
       );
       Texinfo::XSLoader::override(
-        "Texinfo::Transformations::_XS_protect_first_parenthesis_in_targets",
+        "Texinfo::Transformations::protect_first_parenthesis_in_targets",
         "Texinfo::StructTransf::protect_first_parenthesis_in_targets"
       );
     }
@@ -136,20 +136,10 @@ sub _correct_level($$;$)
   }
 }
 
-sub _XS_fill_gaps_in_sectioning($)
-{
-  return 1;
-}
-
 sub fill_gaps_in_sectioning($)
 {
   my $root = shift;
 
-  if (not _XS_fill_gaps_in_sectioning($root)
-      and $XS_only) {
-    return undef;
-  }
-
   my $contents_nr = scalar(@{$root->{'contents'}});
 
   my @added_sections;
@@ -282,17 +272,10 @@ sub _reference_to_arg($$$)
   }
 }
 
-sub _XS_reference_to_arg_in_tree($)
-{
-  return 1;
-}
-
 sub reference_to_arg_in_tree($)
 {
   my $tree = shift;
 
-  _XS_reference_to_arg_in_tree($tree);
-
   return Texinfo::Common::modify_tree($tree, \&_reference_to_arg);
 }
 
@@ -444,22 +427,12 @@ sub _reassociate_to_node($$$)
   return undef;
 }
 
-sub _XS_insert_nodes_for_sectioning_commands($)
-{
-  return 1;
-}
-
 sub insert_nodes_for_sectioning_commands($;$$)
 {
   my $document = shift;
   my $registrar = shift;
   my $customization_information = shift;
 
-  if (not _XS_insert_nodes_for_sectioning_commands($document)
-      and $XS_only) {
-    return undef;
-  }
-
   my $root = $document->tree();
 
   my @added_nodes;
@@ -614,22 +587,12 @@ sub _get_non_automatic_nodes_with_sections($)
   return [ @non_automatic_nodes ];
 }
 
-sub _XS_complete_tree_nodes_menus($$)
-{
-  return 1;
-}
-
 # This should be called after Texinfo::Structuring::sectioning_structure.
 sub complete_tree_nodes_menus($;$)
 {
   my $root = shift;
   my $use_sections = shift;
 
-  if (not _XS_complete_tree_nodes_menus($root, $use_sections)
-      and $XS_only) {
-    return undef;
-  }
-
   my $non_automatic_nodes = _get_non_automatic_nodes_with_sections($root);
   foreach my $node (@{$non_automatic_nodes}) {
     complete_node_menu($node, $use_sections);
@@ -637,22 +600,12 @@ sub complete_tree_nodes_menus($;$)
 
 }
 
-sub _XS_complete_tree_nodes_missing_menu($$)
-{
-  return 1;
-}
-
 # this only complete menus if there was no menu
 sub complete_tree_nodes_missing_menu($;$)
 {
   my $root = shift;
   my $use_sections = shift;
 
-  if (not _XS_complete_tree_nodes_missing_menu($root, $use_sections)
-      and $XS_only) {
-    return undef;
-  }
-
   my $non_automatic_nodes = _get_non_automatic_nodes_with_sections($root);
   foreach my $node (@{$non_automatic_nodes}) {
     if (not $node->{'extra'}->{'menus'}
@@ -667,11 +620,6 @@ sub complete_tree_nodes_missing_menu($;$)
   }
 }
 
-sub _XS_regenerate_master_menu($$)
-{
-  return 1;
-}
-
 # customization_information is used to pass down a translatable object with
 # customization information for the gdt() call.
 sub regenerate_master_menu($$;$)
@@ -680,11 +628,6 @@ sub regenerate_master_menu($$;$)
   my $customization_information = shift;
   my $use_sections = shift;
 
-  if (not _XS_regenerate_master_menu($document, $use_sections)
-      and $XS_only) {
-    return undef;
-  }
-
   my $identifier_target = $document->labels_information();
 
   my $top_node = $identifier_target->{'Top'};
@@ -700,6 +643,8 @@ sub regenerate_master_menu($$;$)
                       $use_sections);
   return undef if (!defined($new_master_menu));
 
+  my $global_detailmenu
+    = $document->global_commands_information()->{'detailmenu'};
   foreach my $menu (@{$top_node->{'extra'}->{'menus'}}) {
     my $detailmenu_index = 0;
     foreach my $entry (@{$menu->{'contents'}}) {
@@ -708,6 +653,44 @@ sub regenerate_master_menu($$;$)
         $new_master_menu->{'parent'} = $menu;
         splice (@{$menu->{'contents'}}, $detailmenu_index, 1,
                 $new_master_menu);
+        # also replace in global commands
+        my $index = 0;
+        my $global_detailmenu_index = -1;
+        foreach my $detailmenu_global (@$global_detailmenu) {
+          if ($detailmenu_global eq $entry) {
+            $global_detailmenu_index = $index;
+            last;
+          }
+          $index++;
+        }
+        if ($global_detailmenu_index >= 0) {
+          splice (@$global_detailmenu, $global_detailmenu_index, 1,
+                  $new_master_menu);
+        }
+        # FIXME use an API?
+        my $internal_references = $document->internal_references_information();
+        foreach my $detailmenu_entry (@{$entry->{'contents'}}) {
+          if ($detailmenu_entry->{'type'}
+              and $detailmenu_entry->{'type'} eq 'menu_entry') {
+            foreach my $entry_content (@{$detailmenu_entry->{'contents'}}) {
+              if ($entry_content->{'type'}
+                  and $entry_content->{'type'} eq 'menu_entry_node') {
+                my $index = 0;
+                my $internal_references_idx = -1;
+                foreach my $internal_ref (@$internal_references) {
+                  if ($internal_ref eq $entry_content) {
+                    $internal_references_idx = $index;
+                    last;
+                  }
+                  $index++;
+                }
+                if ($internal_references_idx >= 0) {
+                  splice (@$internal_references, $internal_references_idx, 1);
+                }
+              }
+            }
+          }
+        }
         return 1;
       }
       $detailmenu_index++;
@@ -753,6 +736,7 @@ sub regenerate_master_menu($$;$)
   }
   # insert master menu
   splice (@{$last_menu->{'contents'}}, $index, 0, $new_master_menu);
+  push @$global_detailmenu, $new_master_menu;
 
   return 1;
 }
@@ -913,23 +897,12 @@ sub _protect_hashchar_at_line_beginning($$$)
   return undef;
 }
 
-sub _XS_protect_hashchar_at_line_beginning($)
-{
-  return 1;
-}
-
 sub protect_hashchar_at_line_beginning($$$)
 {
   my $registrar = shift;
   my $customization_information = shift;
   my $tree = shift;
 
-  if (not _XS_protect_hashchar_at_line_beginning ($tree)
-      and $XS_only) {
-    # FIXME return a tree
-    return undef;
-  }
-
   return Texinfo::Common::modify_tree($tree, 
\&_protect_hashchar_at_line_beginning,
                       [$registrar, $customization_information]);
 }
@@ -947,20 +920,10 @@ sub _protect_first_parenthesis_in_targets($$$)
   return undef;
 }
 
-sub _XS_protect_first_parenthesis_in_targets($)
-{
-  return 1;
-}
-
 sub protect_first_parenthesis_in_targets($)
 {
   my $tree = shift;
 
-  if (not _XS_protect_first_parenthesis_in_targets($tree)
-      and $XS_only) {
-    return undef;
-  }
-
   Texinfo::Common::modify_tree($tree, \&_protect_first_parenthesis_in_targets);
 }
 
diff --git a/tp/Texinfo/XS/main/tree.c b/tp/Texinfo/XS/main/tree.c
index 2f82095409..42ca334051 100644
--- a/tp/Texinfo/XS/main/tree.c
+++ b/tp/Texinfo/XS/main/tree.c
@@ -395,6 +395,25 @@ remove_from_args (ELEMENT *parent, int where)
   return remove_from_element_list (list, where);
 }
 
+ELEMENT *
+remove_element_from_list (ELEMENT_LIST *list, ELEMENT *e)
+{
+  int i;
+  int index = -1;
+  for (i = 0; i < list->number; i++)
+    {
+      if (list->list[i] == e)
+        {
+          index = i;
+          break;
+        }
+    }
+  if (index >= 0)
+    return remove_from_element_list (list, index);
+
+  return 0;
+}
+
 /* Remove elements from START inclusive to END exclusive.  Do not
    free any of them. */
 void
@@ -469,6 +488,27 @@ args_child_by_index (ELEMENT *e, int index)
   return e->args.list[index];
 }
 
+/* do not set parent as it can be used to replace in a container element */
+int
+replace_element_in_contents (ELEMENT *parent, ELEMENT *removed, ELEMENT *added)
+{
+  int i;
+
+  if (!parent || !parent->contents.number)
+    return 0;
+
+  for (i = 0; i < parent->contents.number; i++)
+    {
+      ELEMENT *content = parent->contents.list[i];
+      if (content == removed)
+        {
+          parent->contents.list[i] = added;
+          return 1;
+        }
+    }
+  return 0;
+}
+
 /* should only be used if the nse->manual_content
    and nse->node_content are not already in the tree,
    in practice when the node spec was created by
diff --git a/tp/Texinfo/XS/main/tree.h b/tp/Texinfo/XS/main/tree.h
index 428b60b774..3851b14228 100644
--- a/tp/Texinfo/XS/main/tree.h
+++ b/tp/Texinfo/XS/main/tree.h
@@ -15,6 +15,7 @@ void add_to_element_args (ELEMENT *parent, ELEMENT *e);
 void insert_into_element_list (ELEMENT_LIST *list, ELEMENT *e, int where);
 void insert_into_contents (ELEMENT *parent, ELEMENT *e, int where);
 void insert_into_args (ELEMENT *parent, ELEMENT *e, int where);
+ELEMENT *remove_element_from_list (ELEMENT_LIST *list, ELEMENT *e);
 void insert_slice_into_contents (ELEMENT *to, int idx, ELEMENT *from,
                                  int start, int end);
 void insert_contents_slice_into_args (ELEMENT *to, int where, ELEMENT *from,
@@ -32,6 +33,8 @@ ELEMENT *contents_child_by_index (ELEMENT *e, int index);
 ELEMENT *args_child_by_index (ELEMENT *e, int index);
 void destroy_element (ELEMENT *e);
 void destroy_element_and_children (ELEMENT *e);
+int replace_element_in_contents (ELEMENT *parent, ELEMENT *removed,
+                                 ELEMENT *added);
 void destroy_node_spec (NODE_SPEC_EXTRA *nse);
 
 #define element_contents_number(e) ((e)->contents.number)
diff --git a/tp/Texinfo/XS/parsetexi/labels.c b/tp/Texinfo/XS/parsetexi/labels.c
index 1634dd1ba9..f68a945cb5 100644
--- a/tp/Texinfo/XS/parsetexi/labels.c
+++ b/tp/Texinfo/XS/parsetexi/labels.c
@@ -131,34 +131,26 @@ wipe_identifiers_target (void)
 
 
 
-ELEMENT **internal_xref_list = 0;
-size_t internal_xref_number = 0;
-size_t internal_xref_space = 0;
+ELEMENT_LIST internal_xref_list = {0, 0, 0};
 
 void
 remember_internal_xref (ELEMENT *element)
 {
-  if (internal_xref_number == internal_xref_space)
-    {
-      internal_xref_list = realloc (internal_xref_list,
-                             (internal_xref_space += 2)
-                             * sizeof (*internal_xref_list));
-    }
-  internal_xref_list[internal_xref_number++] = element;
+  add_to_element_list (&internal_xref_list, element);
 }
 
 /* not used */
 void
 reset_internal_xrefs (void)
 {
-  internal_xref_number = 0;
+  internal_xref_list.number = 0;
 }
 
 void
 forget_internal_xrefs (void)
 {
-  internal_xref_number = 0;
-  internal_xref_space = 0;
-  internal_xref_list = 0;
+  internal_xref_list.number = 0;
+  internal_xref_list.space = 0;
+  internal_xref_list.list = 0;
 }
 
diff --git a/tp/Texinfo/XS/parsetexi/labels.h b/tp/Texinfo/XS/parsetexi/labels.h
index f24dbd7b57..775bec7c5e 100644
--- a/tp/Texinfo/XS/parsetexi/labels.h
+++ b/tp/Texinfo/XS/parsetexi/labels.h
@@ -30,8 +30,7 @@ void check_register_target_element_label (ELEMENT 
*label_element,
 void wipe_identifiers_target (void);
 
 
-extern ELEMENT **internal_xref_list;
-extern size_t internal_xref_number;
+extern ELEMENT_LIST internal_xref_list;
 
 void remember_internal_xref (ELEMENT *element);
 void reset_internal_xrefs (void);
diff --git a/tp/Texinfo/XS/parsetexi/parser.c b/tp/Texinfo/XS/parsetexi/parser.c
index 34e13a0f97..46ceec0a9f 100644
--- a/tp/Texinfo/XS/parsetexi/parser.c
+++ b/tp/Texinfo/XS/parsetexi/parser.c
@@ -2507,12 +2507,12 @@ store_document (ELEMENT *root)
 
   internal_references = malloc (sizeof (ELEMENT_LIST));
 
-  internal_xref_list = realloc (internal_xref_list,
-                                internal_xref_number * sizeof (ELEMENT));
+  internal_xref_list.list = realloc (internal_xref_list.list,
+                             internal_xref_list.number * sizeof (ELEMENT));
 
-  internal_references->list = internal_xref_list;
-  internal_references->number = internal_xref_number;
-  internal_references->space = internal_xref_number;
+  internal_references->list = internal_xref_list.list;
+  internal_references->number = internal_xref_list.number;
+  internal_references->space = internal_xref_list.number;
 
   memcpy (doc_global_info, &global_info, sizeof (GLOBAL_INFO));
   if (global_info.input_encoding_name)
diff --git a/tp/Texinfo/XS/structuring_transfo/StructuringTransfo.xs 
b/tp/Texinfo/XS/structuring_transfo/StructuringTransfo.xs
index 92135c6243..3620cbbc19 100644
--- a/tp/Texinfo/XS/structuring_transfo/StructuringTransfo.xs
+++ b/tp/Texinfo/XS/structuring_transfo/StructuringTransfo.xs
@@ -118,6 +118,31 @@ rebuild_document (SV *document_in, ...)
     OUTPUT:
         RETVAL
 
+SV *
+rebuild_tree (SV *tree_in, ...)
+      PROTOTYPE: $;$
+      PREINIT:
+        int no_store = 0;
+        DOCUMENT *document = 0;
+      CODE:
+        if (items > 1)
+          if (SvOK(ST(1)))
+            no_store = SvIV (ST(1));
+
+        document = get_sv_tree_document (tree_in, "rebuild_tree");
+        if (document)
+          {
+            ELEMENT *tree;
+
+            build_document (document->descriptor, no_store);
+            tree = document->tree;
+            RETVAL = newRV_inc ((SV *) tree->hv);
+          }
+        else
+          RETVAL = newSV(0);
+    OUTPUT:
+        RETVAL
+
 void
 remove_document_descriptor (int document_descriptor)
 
@@ -137,9 +162,7 @@ void
 clear_document_errors (int document_descriptor)
 
 void
-set_document_options (sv_options_in, document_in)
-        SV *sv_options_in
-        SV *document_in
+set_document_options (SV *sv_options_in, SV *document_in)
     PREINIT:
         DOCUMENT *document = 0;
      CODE:
@@ -152,8 +175,7 @@ set_document_options (sv_options_in, document_in)
           }
 
 void
-fill_gaps_in_sectioning (tree_in)
-        SV *tree_in
+fill_gaps_in_sectioning (SV *tree_in)
     PREINIT:
         ELEMENT *added_sections;
         DOCUMENT *document;
@@ -170,9 +192,7 @@ fill_gaps_in_sectioning (tree_in)
 # FIXME what to do with the parent argument?
 # FIXME add another way to call that returns a fake tree?
 int
-copy_tree (tree_in, parent_in)
-        SV *tree_in
-        SV *parent_in
+copy_tree (SV *tree_in, SV *parent_in)
     PREINIT:
         ELEMENT *result;
         DOCUMENT *document;
@@ -203,9 +223,10 @@ copy_tree (tree_in, parent_in)
     OUTPUT:
         RETVAL
 
+# $indices_information argument is ignored, it is found with the document
 void
-relate_index_entries_to_table_items_in_tree (tree_in)
-        SV *tree_in
+relate_index_entries_to_table_items_in_tree (SV *tree_in, ...)
+    PROTOTYPE: $$
     PREINIT:
         DOCUMENT *document;
      CODE:
@@ -238,8 +259,7 @@ move_index_entries_after_items_in_tree (tree_in)
 # argument could be modified.  Here, tree_in is always a container
 # that is not modified, so there is no need to return a tree.
 void
-reference_to_arg_in_tree (tree_in)
-        SV *tree_in
+reference_to_arg_in_tree (SV *tree_in)
     PREINIT:
         DOCUMENT *document = 0;
      CODE:
@@ -250,8 +270,8 @@ reference_to_arg_in_tree (tree_in)
           reference_to_arg_in_tree (document->tree);
 
 void
-associate_internal_references (document_in)
-        SV *document_in
+associate_internal_references (SV *document_in, ...)
+    PROTOTYPE: $$$
     PREINIT:
         DOCUMENT *document = 0;
     CODE:
@@ -264,9 +284,9 @@ associate_internal_references (document_in)
 # The perl function returns a list of sections, but it is only used
 # to register in the document.  It is better to reserve the return
 # value for a return status, if it becomes needed.
+# TODO change call in perl code to put tree first
 void
-sectioning_structure (tree_in)
-        SV *tree_in
+sectioning_structure (SV *registrar, SV *customization_information, SV 
*tree_in)
     PREINIT:
         DOCUMENT *document = 0;
      CODE:
@@ -279,8 +299,8 @@ sectioning_structure (tree_in)
           }
 
 void
-warn_non_empty_parts (document_in)
-        SV *document_in
+warn_non_empty_parts (SV *document_in, ...)
+   PROTOTYPE: $$$
     PREINIT:
         DOCUMENT *document = 0;
     CODE:
@@ -290,8 +310,8 @@ warn_non_empty_parts (document_in)
           warn_non_empty_parts (document);
 
 void
-set_menus_node_directions (document_in)
-        SV *document_in
+set_menus_node_directions (SV *document_in, ...)
+  PROTOTYPE: $$$
     PREINIT:
         DOCUMENT *document = 0;
     CODE:
@@ -301,8 +321,8 @@ set_menus_node_directions (document_in)
           set_menus_node_directions (document);
 
 void
-complete_node_tree_with_menus (document_in)
-        SV *document_in
+complete_node_tree_with_menus (SV *document_in, ...)
+  PROTOTYPE: $$$
     PREINIT:
         DOCUMENT *document = 0;
     CODE:
@@ -312,8 +332,8 @@ complete_node_tree_with_menus (document_in)
           complete_node_tree_with_menus (document);
 
 void
-check_nodes_are_referenced (document_in)
-        SV *document_in
+check_nodes_are_referenced (SV *document_in, ...)
+  PROTOTYPE: $$$
     PREINIT:
         DOCUMENT *document = 0;
     CODE:
@@ -323,8 +343,7 @@ check_nodes_are_referenced (document_in)
           check_nodes_are_referenced (document);
 
 void
-number_floats (document_in)
-        SV *document_in
+number_floats (SV *document_in)
     PREINIT:
         DOCUMENT *document = 0;
     CODE:
@@ -334,15 +353,13 @@ number_floats (document_in)
           number_floats (document);
 
 void
-complete_tree_nodes_menus (tree_in, use_sections_in)
-        SV *tree_in
-        SV *use_sections_in;
+complete_tree_nodes_menus (SV *tree_in, SV *use_sections_in=0)
     PREINIT:
         DOCUMENT *document = 0;
         int use_sections = 0;
      CODE:
         document = get_sv_tree_document (tree_in, "complete_tree_nodes_menus");
-        if (SvOK (use_sections_in))
+        if (use_sections_in && SvOK (use_sections_in))
           {
             use_sections = SvIV (use_sections_in);
           }
@@ -350,16 +367,14 @@ complete_tree_nodes_menus (tree_in, use_sections_in)
           complete_tree_nodes_menus (document->tree, use_sections);
 
 void
-complete_tree_nodes_missing_menu (tree_in, use_sections_in)
-        SV *tree_in
-        SV *use_sections_in;
+complete_tree_nodes_missing_menu (SV *tree_in, SV *use_sections_in=0)
     PREINIT:
         DOCUMENT *document = 0;
         int use_sections = 0;
      CODE:
         document = get_sv_tree_document (tree_in,
                              "complete_tree_nodes_missing_menu");
-        if (SvOK (use_sections_in))
+        if (use_sections_in && SvOK (use_sections_in))
           {
             use_sections = SvIV (use_sections_in);
           }
@@ -367,16 +382,14 @@ complete_tree_nodes_missing_menu (tree_in, 
use_sections_in)
           complete_tree_nodes_missing_menu (document->tree, use_sections);
 
 void
-regenerate_master_menu (document_in, use_sections_in)
-        SV *document_in
-        SV *use_sections_in;
+regenerate_master_menu (SV *document_in, SV *customization_information, SV 
*use_sections_in=0)
     PREINIT:
         DOCUMENT *document = 0;
         int use_sections = 0;
     CODE:
         document = get_sv_document_document (document_in,
                                              "regenerate_master_menu");
-        if (SvOK (use_sections_in))
+        if (use_sections_in && SvOK (use_sections_in))
           {
             use_sections = SvIV (use_sections_in);
           }
@@ -387,8 +400,8 @@ regenerate_master_menu (document_in, use_sections_in)
 # to reserve the return value for a return status, if it becomes needed.
 # FIXME the added nodes return value is used in pod2texi
 void
-insert_nodes_for_sectioning_commands (document_in)
-        SV *document_in
+insert_nodes_for_sectioning_commands (SV *document_in, ...)
+   PROTOTYPE: $;$$
     PREINIT:
         DOCUMENT *document = 0;
     CODE:
@@ -405,8 +418,8 @@ insert_nodes_for_sectioning_commands (document_in)
 # to register in the document.  It is better to reserve the return
 # value for a return status, if it becomes needed.
 void
-nodes_tree (document_in)
-        SV *document_in
+nodes_tree (SV *document_in, ...)
+   PROTOTYPE: $$$
     PREINIT:
         DOCUMENT *document = 0;
     CODE:
@@ -421,8 +434,7 @@ nodes_tree (document_in)
 # argument could be modified.  Here, tree_in is always a container
 # that is not modified, so there is no need to return a tree.
 void
-protect_colon_in_tree (tree_in)
-        SV *tree_in
+protect_colon_in_tree (SV *tree_in)
     PREINIT:
         DOCUMENT *document = 0;
      CODE:
@@ -433,8 +445,7 @@ protect_colon_in_tree (tree_in)
           protect_colon_in_tree (document->tree);
 
 void
-protect_comma_in_tree (tree_in)
-        SV *tree_in
+protect_comma_in_tree (SV *tree_in)
     PREINIT:
         DOCUMENT *document = 0;
      CODE:
@@ -445,8 +456,7 @@ protect_comma_in_tree (tree_in)
           protect_comma_in_tree (document->tree);
 
 void
-protect_node_after_label_in_tree (tree_in)
-        SV *tree_in
+protect_node_after_label_in_tree (SV *tree_in)
     PREINIT:
         DOCUMENT *document = 0;
      CODE:
@@ -456,9 +466,9 @@ protect_node_after_label_in_tree (tree_in)
         if (document)
           protect_node_after_label_in_tree (document->tree);
 
+# TODO change order of call in perl?
 void
-protect_hashchar_at_line_beginning (tree_in)
-        SV *tree_in
+protect_hashchar_at_line_beginning (SV *registrar, SV 
*customization_information, SV *tree_in)
     PREINIT:
         DOCUMENT *document = 0;
      CODE:
@@ -469,8 +479,7 @@ protect_hashchar_at_line_beginning (tree_in)
           protect_hashchar_at_line_beginning (document);
 
 void
-protect_first_parenthesis_in_targets (tree_in)
-        SV *tree_in
+protect_first_parenthesis_in_targets (SV *tree_in)
     PREINIT:
         DOCUMENT *document = 0;
      CODE:
@@ -480,8 +489,7 @@ protect_first_parenthesis_in_targets (tree_in)
           protect_first_parenthesis_in_targets (document->tree);
 
 SV *
-split_by_node (tree_in)
-        SV *tree_in
+split_by_node (SV *tree_in)
     PREINIT:
         DOCUMENT *document = 0;
      CODE:
@@ -498,8 +506,7 @@ split_by_node (tree_in)
         RETVAL
 
 SV *
-split_by_section (tree_in)
-        SV *tree_in
+split_by_section (SV *tree_in)
     PREINIT:
         DOCUMENT *document = 0;
      CODE:
diff --git a/tp/Texinfo/XS/structuring_transfo/transformations.c 
b/tp/Texinfo/XS/structuring_transfo/transformations.c
index 9819555473..95e492a0d8 100644
--- a/tp/Texinfo/XS/structuring_transfo/transformations.c
+++ b/tp/Texinfo/XS/structuring_transfo/transformations.c
@@ -1205,8 +1205,44 @@ regenerate_master_menu (DOCUMENT *document, int 
use_sections)
           ELEMENT *entry = menu->contents.list[detailmenu_index];
           if (entry->cmd == CM_detailmenu)
             {
-              destroy_element_and_children (
-                 remove_from_contents (menu, detailmenu_index));
+              int j;
+              ELEMENT *removed = remove_from_contents (menu, detailmenu_index);
+              replace_element_in_contents (
+                 &document->global_commands->detailmenu, removed, master_menu);
+              /* FIXME are the new entries added to internal refs?
+                 Note that if they are not, it is possible that this has
+                 no impact as the associated entry in menu may be
+                 in internal refs, and maybe it is enough.
+               */
+              /* remove internal refs of removed entries */
+              for (j = 0; j < removed->contents.number; j++)
+                {
+                  ELEMENT *content = removed->contents.list[j];
+                  if (content->type == ET_menu_entry)
+                    {
+                      int k;
+                      for (k = 0; k < content->contents.number; k++)
+                        {
+                          ELEMENT *entry_content = content->contents.list[k];
+                          if (entry_content->type == ET_menu_entry_node)
+                            {
+                              ELEMENT *removed_internal_ref =
+                              remove_element_from_list (
+                                        document->internal_references,
+                                                        entry_content);
+                              if (!removed_internal_ref)
+                                {
+                                  char *removed_internal_texi
+                                     = convert_to_texinfo (entry_content);
+                                  fprintf (stderr,
+                                    "BUG: %s: not found in internal refs\n", 
+                                      removed_internal_texi);
+                                }
+                            }
+                        }
+                    }
+                }
+              destroy_element_and_children (removed);
               insert_into_contents (menu, master_menu, detailmenu_index);
               return 1;
             }
@@ -1257,6 +1293,8 @@ regenerate_master_menu (DOCUMENT *document, int 
use_sections)
     }
   /* insert master menu */
   insert_into_contents (last_menu, master_menu, index);
+  add_to_contents_as_array (&document->global_commands->detailmenu,
+                            master_menu);
   return 1;
 }
 
diff --git a/tp/t/automatic_menus.t b/tp/t/automatic_menus.t
index cb70481466..24a0b2df09 100644
--- a/tp/t/automatic_menus.t
+++ b/tp/t/automatic_menus.t
@@ -38,6 +38,9 @@ sub test($$$;$$)
   } else {
     Texinfo::Transformations::complete_tree_nodes_menus($tree, $use_sections);
   }
+
+  $tree = Texinfo::Structuring::rebuild_tree($tree);
+
   my $texi_result = Texinfo::Convert::Texinfo::convert_to_texinfo($tree);
 
   if (!defined($out)) {
diff --git a/tp/t/automatic_nodes.t b/tp/t/automatic_nodes.t
index 024b00689d..7d3ba2d3ce 100644
--- a/tp/t/automatic_nodes.t
+++ b/tp/t/automatic_nodes.t
@@ -15,6 +15,11 @@ use Data::Dumper;
 
 ok(1);
 
+my $with_XS = ((not defined($ENV{TEXINFO_XS})
+                or $ENV{TEXINFO_XS} ne 'omit')
+               and (!defined $ENV{TEXINFO_XS_PARSER}
+                    or $ENV{TEXINFO_XS_PARSER} eq '1'));
+
 # FIXME tests in test_new_node do not test the transformations XS codes,
 # see comment in the beginning of _new_node.
 sub test_new_node($$$$)
@@ -53,6 +58,9 @@ sub test_new_node($$$$)
     is ($texi_result, $out, $name);
   }
 }
+SKIP:
+{
+  skip "test perl not XS", 7 * 3, $with_XS;
 
 test_new_node ('a node', 'a-node', '@node a node
 ', 'simple');
@@ -75,16 +83,25 @@ test_new_node ('@asis{}', '-1', '@node @asis{} 1
 test_new_node ('a::b    c', 'a_003a_003ab-c', '@node a@asis{::}b@asis{ } c
 ', 'with colon and tab');
 
+}
+
 my $parser = Texinfo::Parser::parser();
 my $document = $parser->parse_texi_text('@node a node
 ');
 my $tree = $document->tree();
 my $registrar = $parser->registered_errors();
 my $line_tree = Texinfo::Parser::parse_texi_line (undef, 'a node');
-my $node = Texinfo::Transformations::_new_node($line_tree, $document);
+
+SKIP:
+{
+  skip "test perl not XS", 1, $with_XS;
+
+my $new_node = Texinfo::Transformations::_new_node($line_tree, $document);
 is ('@node a node 1
-',  Texinfo::Convert::Texinfo::convert_to_texinfo($node), 'duplicate node 
added');
-#print STDERR Texinfo::Convert::Texinfo::convert_to_texinfo($node);
+',  Texinfo::Convert::Texinfo::convert_to_texinfo($new_node),
+    'duplicate node added');
+}
+#print STDERR Texinfo::Convert::Texinfo::convert_to_texinfo($new_node);
 
 my $sections_text =
 '@top top section
@@ -156,6 +173,7 @@ 
Texinfo::Structuring::associate_internal_references($document, $registrar,
                                                     $parser);
 Texinfo::Transformations::insert_nodes_for_sectioning_commands($document,
                                                           $registrar, $parser);
+$document = Texinfo::Structuring::rebuild_document($document);
 $tree = $document->tree();
 my $result = Texinfo::Convert::Texinfo::convert_to_texinfo($tree);
 is ($result, $reference, 'add nodes');
@@ -178,9 +196,9 @@ 
Texinfo::Structuring::associate_internal_references($document, $registrar,
                                                     $parser);
 Texinfo::Transformations::insert_nodes_for_sectioning_commands($document,
                                                           $registrar, $parser);
-if (defined $ENV{TEXINFO_XS_CONVERT} and $ENV{TEXINFO_XS_CONVERT} eq '1') {
-  $document = Texinfo::Structuring::rebuild_document($document);
-}
+
+$document = Texinfo::Structuring::rebuild_document($document);
+
 my $identifier_target = $document->labels_information();
 my $indices_information = $document->indices_information();
 ok (($identifier_target->{'chap'}->{'extra'}->{'menus'}
diff --git a/tp/t/do_master_menu.t b/tp/t/do_master_menu.t
index 95aef06c41..6fc9d87a80 100644
--- a/tp/t/do_master_menu.t
+++ b/tp/t/do_master_menu.t
@@ -127,9 +127,7 @@ my $document = $parser->parse_texi_piece($in_detailmenu);
 my $registrar = $parser->registered_errors();
 Texinfo::Structuring::associate_internal_references($document, $registrar,
                                                     $parser);
-if (defined $ENV{TEXINFO_XS_CONVERT} and $ENV{TEXINFO_XS_CONVERT} eq '1') {
-  $document = Texinfo::Structuring::rebuild_document($document);
-}
+$document = Texinfo::Structuring::rebuild_document($document);
 my $identifier_target = $document->labels_information();
 my $top_node = $identifier_target->{'Top'};
 # FIXME does not test XS
@@ -178,9 +176,7 @@ $document = $parser->parse_texi_piece($no_detailmenu);
 $registrar = $parser->registered_errors();
 Texinfo::Structuring::associate_internal_references($document, $registrar,
                                                     $parser);
-if (defined $ENV{TEXINFO_XS_CONVERT} and $ENV{TEXINFO_XS_CONVERT} eq '1') {
-  $document = Texinfo::Structuring::rebuild_document($document);
-}
+$document = Texinfo::Structuring::rebuild_document($document);
 $identifier_target = $document->labels_information();
 $top_node = $identifier_target->{'Top'};
 # FIXME does not test XS
@@ -192,11 +188,12 @@ is ($out, $reference, 'master menu no detailmenu');
 
 $parser = Texinfo::Parser::parser();
 $document = $parser->parse_texi_piece($in_detailmenu);
-my $tree = $document->tree();
 $registrar = $parser->registered_errors();
 Texinfo::Structuring::associate_internal_references($document, $registrar,
                                                     $parser);
 Texinfo::Transformations::regenerate_master_menu($document, $parser);
+$document = Texinfo::Structuring::rebuild_document($document);
+my $tree = $document->tree();
 $out = Texinfo::Convert::Texinfo::convert_to_texinfo($tree);
 
 is ($out, _get_in($reference), 'regenerate with existing detailmenu');
@@ -205,11 +202,12 @@ is ($out, _get_in($reference), 'regenerate with existing 
detailmenu');
 
 $parser = Texinfo::Parser::parser();
 $document = $parser->parse_texi_piece($no_detailmenu);
-$tree = $document->tree();
 $registrar = $parser->registered_errors();
 Texinfo::Structuring::associate_internal_references($document, $registrar,
                                                     $parser);
 Texinfo::Transformations::regenerate_master_menu($document, $parser);
+$document = Texinfo::Structuring::rebuild_document($document);
+$tree = $document->tree();
 $out = Texinfo::Convert::Texinfo::convert_to_texinfo($tree);
 
 is ($out, _get_in('',"\n".$reference), 'regenerate with no detailmenu');
diff --git a/tp/t/index_before_item.t b/tp/t/index_before_item.t
index 5ae609cee7..b3c15a4ffb 100644
--- a/tp/t/index_before_item.t
+++ b/tp/t/index_before_item.t
@@ -9,6 +9,7 @@ BEGIN { plan tests => 6; }
 
 use Texinfo::Parser qw(parse_texi_piece);
 use Texinfo::Common qw(move_index_entries_after_items_in_tree);
+use Texinfo::Structuring;
 use Texinfo::Convert::Texinfo;
 use Texinfo::DebugTree;
 
@@ -26,6 +27,8 @@ sub run_test($$$)
   #print STDERR Texinfo::DebugTree::convert_tree(undef, $tree)."\n";
 
   move_index_entries_after_items_in_tree($tree);
+  $tree = Texinfo::Structuring::rebuild_tree($tree);
+
   my $texi_result = Texinfo::Convert::Texinfo::convert_to_texinfo($tree);
 
   if (!defined($out)) {
diff --git a/tp/t/protect_character_in_texinfo.t 
b/tp/t/protect_character_in_texinfo.t
index 8afa8e41fd..cb4f51827e 100644
--- a/tp/t/protect_character_in_texinfo.t
+++ b/tp/t/protect_character_in_texinfo.t
@@ -10,6 +10,7 @@ BEGIN { plan tests => 7; }
 use Texinfo::Parser qw(parse_texi_line parse_texi_piece);
 use Texinfo::Common qw(protect_comma_in_tree protect_colon_in_tree
       protect_node_after_label_in_tree);
+use Texinfo::Structuring;
 use Texinfo::Convert::Texinfo;
 
 ok(1);
@@ -36,19 +37,26 @@ sub run_test($$$$)
 
   my $document = parse_texi_piece(undef, $in);
   my $tree_as_text = $document->tree();
+
   my $tree_as_line = parse_texi_line(undef, $in);
 
   foreach my $tree ($tree_as_text, $tree_as_line) {
     if ($do->{'protect_comma'}) {
-      $tree = protect_comma_in_tree($tree);
+      protect_comma_in_tree($tree);
     }
     if ($do->{'protect_colon'}) {
-      $tree = protect_colon_in_tree($tree);
+      protect_colon_in_tree($tree);
     }
     if ($do->{'protect_node_after_label'}) {
-      $tree = protect_node_after_label_in_tree($tree);
+      protect_node_after_label_in_tree($tree);
     }
   }
+
+  $document = Texinfo::Structuring::rebuild_document($document);
+  $tree_as_text = $document->tree();
+
+  $tree_as_line = Texinfo::Structuring::rebuild_tree($tree_as_line);
+
   my $texi_result_as_text
      = Texinfo::Convert::Texinfo::convert_to_texinfo($tree_as_text);
   my $texi_result_as_line
diff --git a/tp/t/reference_to_text_in_tree.t b/tp/t/reference_to_text_in_tree.t
index 6c7999083e..83fabe763b 100644
--- a/tp/t/reference_to_text_in_tree.t
+++ b/tp/t/reference_to_text_in_tree.t
@@ -9,6 +9,7 @@ BEGIN { plan tests => 3; }
 
 use Texinfo::Parser;
 use Texinfo::Transformations;
+use Texinfo::Structuring;
 use Texinfo::Convert::Texinfo;
 
 ok(1);
@@ -24,6 +25,8 @@ sub run_test($$$)
   my $tree = $document->tree();
 
   Texinfo::Transformations::reference_to_arg_in_tree($tree);
+  $tree = Texinfo::Structuring::rebuild_tree($tree);
+
   my $texi_result = Texinfo::Convert::Texinfo::convert_to_texinfo($tree);
 
   if (!defined($out)) {
diff --git a/tp/t/test_fill_gaps_in_sectioning.t 
b/tp/t/test_fill_gaps_in_sectioning.t
index 3964efc9de..52480787c7 100644
--- a/tp/t/test_fill_gaps_in_sectioning.t
+++ b/tp/t/test_fill_gaps_in_sectioning.t
@@ -9,6 +9,7 @@ BEGIN { plan tests => 6; }
 
 use Texinfo::Transformations;
 use Texinfo::Parser qw(parse_texi_text);
+use Texinfo::Structuring;
 use Texinfo::Convert::Texinfo;
 
 ok(1, "modules loading");
@@ -41,6 +42,7 @@ sub test_correction($$$;$)
                                              $test_correct_level);
   }
 
+  $tree = Texinfo::Structuring::rebuild_tree($tree);
   {
   local $Data::Dumper::Purity = 1;
   #local $Data::Dumper::Maxdepth = 2;
@@ -48,6 +50,7 @@ sub test_correction($$$;$)
   #print STDERR Data::Dumper->Dump([$tree]);
   #print STDERR Data::Dumper->Dump([$added_sections]);
   }
+
   my $texi_result
    = Texinfo::Convert::Texinfo::convert_to_texinfo($tree);
   if (!defined($out)) {
@@ -57,10 +60,16 @@ sub test_correction($$$;$)
   }
 }
 
+my $with_XS = ((not defined($ENV{TEXINFO_XS})
+                or $ENV{TEXINFO_XS} ne 'omit')
+               and (!defined $ENV{TEXINFO_XS_PARSER}
+                    or $ENV{TEXINFO_XS_PARSER} eq '1'));
+
+
 SKIP:
 {
-  skip "incorrect for XS", 2, (defined $ENV{TEXINFO_XS_CONVERT}
-                               and !$ENV{TEXINFO_XS_CONVERT} eq '0');
+  skip "test perl not XS", 2, $with_XS;
+
 test_correction('@raisesections
 
 @section truc
diff --git a/tp/t/test_protect_contents.t b/tp/t/test_protect_contents.t
index 727cb58295..90d283eeea 100644
--- a/tp/t/test_protect_contents.t
+++ b/tp/t/test_protect_contents.t
@@ -9,6 +9,7 @@ BEGIN { plan tests => 2; }
 
 use Texinfo::Parser qw(parse_texi_line parse_texi_piece);
 use Texinfo::Common qw(protect_first_parenthesis);
+use Texinfo::Structuring;
 use Texinfo::Transformations;
 use Texinfo::Convert::Texinfo;
 
@@ -27,6 +28,9 @@ sub run_test($$$$)
 
   if ($do->{'protect_first_parenthesis'}) {
     Texinfo::Transformations::protect_first_parenthesis_in_targets($tree);
+
+    $tree = Texinfo::Structuring::rebuild_tree($tree);
+
     $texi_result
         = Texinfo::Convert::Texinfo::convert_to_texinfo($tree);
   }
diff --git a/tp/t/test_protect_hashchar_at_line_beginning.t 
b/tp/t/test_protect_hashchar_at_line_beginning.t
index d18a2ccf0b..de3f6338a4 100644
--- a/tp/t/test_protect_hashchar_at_line_beginning.t
+++ b/tp/t/test_protect_hashchar_at_line_beginning.t
@@ -9,6 +9,7 @@ BEGIN { plan tests => 9; }
 
 use Texinfo::Parser;
 use Texinfo::Transformations;
+use Texinfo::Structuring;
 use Texinfo::Convert::Texinfo;
 
 use Data::Dumper;
@@ -20,6 +21,12 @@ $ENV{LANGUAGE} = 'C';
 
 ok(1);
 
+my $with_XS = ((not defined($ENV{TEXINFO_XS})
+                or $ENV{TEXINFO_XS} ne 'omit')
+               and (!defined $ENV{TEXINFO_XS_PARSER}
+                    or $ENV{TEXINFO_XS_PARSER} eq '1'));
+
+
 sub run_test($$$;$)
 {
   my $in = shift;
@@ -33,17 +40,16 @@ sub run_test($$$;$)
 
   my $registrar = $parser->registered_errors();
 
-  my $corrected_tree = 
+  my $corrected_tree =
     Texinfo::Transformations::protect_hashchar_at_line_beginning(
                                             $registrar, $parser, $tree);
 
-  if (defined $ENV{TEXINFO_XS_CONVERT} and $ENV{TEXINFO_XS_CONVERT} eq '1') {
-    $document = Texinfo::Structuring::rebuild_document($document);
-    $corrected_tree = $document->tree();
-    if (defined($ENV{'TEXINFO_XS'}) and $ENV{'TEXINFO_XS'} eq 'require') {
-      foreach my $error (@{$document->{'errors'}}) {
-        $registrar->add_formatted_message($error);
-      }
+  $document = Texinfo::Structuring::rebuild_document($document);
+  $corrected_tree = $document->tree();
+
+  if ($with_XS) {
+    foreach my $error (@{$document->{'errors'}}) {
+      $registrar->add_formatted_message($error);
     }
   }
 
@@ -199,6 +205,6 @@ in quotation
 #{
 #  local $Data::Dumper::Purity = 1;
 #  local $Data::Dumper::Indent = 1;
-# 
+#
 #  print STDERR Data::Dumper->Dump([$tree]);
 #}
diff --git a/tp/t/test_utils.pl b/tp/t/test_utils.pl
index 5eeb4ca79f..e8c1d42ed5 100644
--- a/tp/t/test_utils.pl
+++ b/tp/t/test_utils.pl
@@ -742,6 +742,11 @@ sub output_preamble_postamble_latex($$)
   }
 }
 
+my $with_XS = ((not defined($ENV{TEXINFO_XS})
+                or $ENV{TEXINFO_XS} ne 'omit')
+               and (!defined $ENV{TEXINFO_XS_PARSER}
+                    or $ENV{TEXINFO_XS_PARSER} eq '1'));
+
 my %tested_transformations;
 
 # Run a single test case.  Each test case is an array
@@ -1077,9 +1082,7 @@ sub test($$)
   # should not actually be useful, as the same element should be reused.
   $tree = $document->tree();
 
-  if (defined $ENV{TEXINFO_XS_CONVERT}
-      and $ENV{TEXINFO_XS_CONVERT} eq '1'
-      and defined($ENV{'TEXINFO_XS'}) and $ENV{'TEXINFO_XS'} eq 'require') {
+  if ($with_XS) {
     foreach my $error (@{$document->{'errors'}}) {
       $registrar->add_formatted_message($error);
     }
diff --git a/tp/texi2any.pl b/tp/texi2any.pl
index d3deaf95e1..dbe7a1f0ed 100755
--- a/tp/texi2any.pl
+++ b/tp/texi2any.pl
@@ -1393,6 +1393,11 @@ die _encode_message(
    .sprintf(__("Try `%s --help' for more information.\n"), $real_command_name))
      unless (scalar(@input_files) >= 1);
 
+my $with_XS = ((not defined($ENV{TEXINFO_XS})
+                or $ENV{TEXINFO_XS} ne 'omit')
+               and (!defined $ENV{TEXINFO_XS_PARSER}
+                    or $ENV{TEXINFO_XS_PARSER} eq '1'));
+
 my $file_number = -1;
 my @opened_files = ();
 my %unclosed_files;
@@ -1627,9 +1632,7 @@ while(@input_files) {
 
   $document = Texinfo::Structuring::rebuild_document($document);
 
-  if (defined $ENV{TEXINFO_XS_CONVERT}
-      and $ENV{TEXINFO_XS_CONVERT} eq '1'
-      and defined($ENV{'TEXINFO_XS'}) and $ENV{'TEXINFO_XS'} eq 'require') {
+  if ($with_XS) {
     foreach my $error (@{$document->{'errors'}}) {
       $registrar->add_formatted_message($error);
     }



reply via email to

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