texinfo-commits
[Top][All Lists]
Advanced

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

[no subject]


From: Patrice Dumas
Date: Sat, 9 Mar 2024 17:52:48 -0500 (EST)

branch: master
commit 2abca63a188b765c68540c4b7bd731a98bc2e460
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Sat Mar 9 16:24:39 2024 +0100

    XS override for Texinfo::Document tree
    
    * tp/Texinfo/XS/main/DocumentXS.xs (document_tree),
    tp/Texinfo/Document.pm (%XS_structure_overrides, tree): add an XS
    override for Texinfo::Document tree.  Add an optional argument to
    tree() to avoid building the Perl tree if only a handler on XS data is
    needed.
    
    * tp/texi2any.pl, tp/t/test_utils.pl (test): set the new argument of
    tree() when tree handler only is needed.
---
 ChangeLog                        | 13 +++++++++
 tp/TODO                          | 14 ---------
 tp/Texinfo/Document.pm           | 12 ++++++--
 tp/Texinfo/XS/main/DocumentXS.xs | 62 +++++++++++++++++++++++++++++++++-------
 tp/t/test_utils.pl               |  6 ++--
 tp/texi2any.pl                   | 10 +++----
 6 files changed, 81 insertions(+), 36 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9aed887e5e..239343d04b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2024-03-09  Patrice Dumas  <pertusus@free.fr>
+
+       XS override for Texinfo::Document tree
+
+       * tp/Texinfo/XS/main/DocumentXS.xs (document_tree),
+       tp/Texinfo/Document.pm (%XS_structure_overrides, tree): add an XS
+       override for Texinfo::Document tree.  Add an optional argument to
+       tree() to avoid building the Perl tree if only a handler on XS data is
+       needed.
+
+       * tp/texi2any.pl, tp/t/test_utils.pl (test): set the new argument of
+       tree() when tree handler only is needed.
+
 2024-03-09  Patrice Dumas  <pertusus@free.fr>
 
        Set document->modified_information when modified, unset when passed to
diff --git a/tp/TODO b/tp/TODO
index 9ea65e779d..d86dacc9a7 100644
--- a/tp/TODO
+++ b/tp/TODO
@@ -10,20 +10,6 @@ This is the todo list for texi2any
 Before next release
 ===================
 
-Real tree:
-* Overriden in general except if !$XS_structuring
-  Texinfo/Common.pm relate_index_entries_to_table_items_in_tree
-* Texinfo/DebugTree.pm convert $document->tree
-* Texinfo/Structuring.pm nodes_tree sectioning_structure
-* Texinfo/Transformations.pm insert_nodes_for_sectioning_commands
-* Texinfo/Convert/Converter.pm output_tree
-
-Perl only
-Texinfo/ParserNonXS.pm
-
-handle on tree:
-t/test_utils.pl all over
-
 Check if LABEL identifier should be const
 
 Bugs
diff --git a/tp/Texinfo/Document.pm b/tp/Texinfo/Document.pm
index c92f4f9217..96f73165c2 100644
--- a/tp/Texinfo/Document.pm
+++ b/tp/Texinfo/Document.pm
@@ -62,6 +62,8 @@ our %XS_structure_overrides = (
     => "Texinfo::DocumentXS::rebuild_document",
   "Texinfo::Document::rebuild_tree"
     => "Texinfo::DocumentXS::rebuild_tree",
+  "Texinfo::Document::tree"
+    => "Texinfo::DocumentXS::tree",
   "Texinfo::Document::indices_sort_strings"
     => "Texinfo::DocumentXS::indices_sort_strings",
 );
@@ -142,7 +144,7 @@ sub set_document_global_info($$$)
   $document->{'global_info'}->{$key} = $value;
 }
 
-sub tree($)
+sub tree($;$)
 {
   my $self = shift;
   return $self->{'tree'};
@@ -494,12 +496,18 @@ C<tree>:
 
 =over
 
-=item $tree = tree($document)
+=item $tree = tree($document, $handler_only)
 X<C<tree>>
 
 The I<$tree> is a hash reference.  It is described in
 L<Texinfo::Parser/TEXINFO TREE>.
 
+If I<$handler_only> is set and XS extensions are used, the returned
+tree holds a reference to the C Texinfo tree data only, but no actual
+Perl Texinfo tree.  This avoids building the Perl tree if all the
+functions called with the tree as argument have XS interfaces and
+directly use the C data and do not use the Perl tree.
+
 =back
 
 Some global information is available through C<global_information>:
diff --git a/tp/Texinfo/XS/main/DocumentXS.xs b/tp/Texinfo/XS/main/DocumentXS.xs
index 220254436c..edff5e8b79 100644
--- a/tp/Texinfo/XS/main/DocumentXS.xs
+++ b/tp/Texinfo/XS/main/DocumentXS.xs
@@ -185,6 +185,49 @@ set_document_global_info (SV *document_in, char *key, SV 
*value_sv)
               }
           }
 
+SV *
+document_tree (SV *document_in, int handler_only=0)
+    PREINIT:
+        HV *document_hv;
+        SV *result_sv = 0;
+        const char *key = "tree";
+     CODE:
+        document_hv = (HV *) SvRV (document_in);
+
+        if (!handler_only)
+          {
+            DOCUMENT *document = get_sv_document_document (document_in,
+                                                           "document_tree");
+            if (document)
+              {
+                if (document->modified_information & F_DOCM_tree)
+                  {
+                    HV *hv_tree = build_texinfo_tree (document->tree, 0);
+                    result_sv = newRV_inc ((SV *) hv_tree);
+                    hv_store (document_hv, key, strlen (key), result_sv, 0);
+                    document->modified_information &= ~F_DOCM_tree;
+                  }
+              }
+          }
+
+        if (!result_sv)
+          {
+            SV **tree_sv = hv_fetch (document_hv, key, strlen (key), 0);
+            if (tree_sv)
+              result_sv = *tree_sv;
+          }
+
+        if (result_sv)
+          {
+            RETVAL = result_sv;
+            SvREFCNT_inc (result_sv);
+          }
+        else
+          RETVAL = newSV (0);
+    OUTPUT:
+        RETVAL
+
+
 # customization_information
 SV *
 indices_sort_strings (SV *document_in, ...)
@@ -194,7 +237,7 @@ indices_sort_strings (SV *document_in, ...)
         const INDICES_SORT_STRINGS *indices_sort_strings = 0;
         HV *document_hv;
         SV *result_sv = 0;
-        const char *sort_strings_key = "index_entries_sort_strings";
+        const char *key = "index_entries_sort_strings";
      CODE:
         document = get_sv_document_document (document_in,
                                              "indices_sort_strings");
@@ -224,9 +267,7 @@ indices_sort_strings (SV *document_in, ...)
                                                    indices_information_hv);
 
                     result_sv = newRV_inc ((SV *) indices_sort_strings_hv);
-                    SvREFCNT_inc (result_sv);
-                    hv_store (document_hv, sort_strings_key,
-                              strlen (sort_strings_key), result_sv, 0);
+                    hv_store (document_hv, key, strlen (key), result_sv, 0);
                     document->modified_information
                                 &= ~F_DOCM_indices_sort_strings;
                   }
@@ -235,19 +276,18 @@ indices_sort_strings (SV *document_in, ...)
             else
               { /* retrieve previously stored result */
                 SV **index_entries_sort_strings_sv
-                  = hv_fetch (document_hv, sort_strings_key,
-                              strlen (sort_strings_key), 0);
+                  = hv_fetch (document_hv, key, strlen (key), 0);
                 if (index_entries_sort_strings_sv
                     && SvOK (*index_entries_sort_strings_sv))
-                  {
-                    result_sv = *index_entries_sort_strings_sv;
-                    SvREFCNT_inc (result_sv);
-                  }
+                  result_sv = *index_entries_sort_strings_sv;
                 /* error out if not found?  Or rebuild? */
               }
           }
         if (result_sv)
-          RETVAL = result_sv;
+          {
+            SvREFCNT_inc (result_sv);
+            RETVAL = result_sv;
+          }
         else
           RETVAL = newSV (0);
     OUTPUT:
diff --git a/tp/t/test_utils.pl b/tp/t/test_utils.pl
index f7e1db9d38..35a572c7ea 100644
--- a/tp/t/test_utils.pl
+++ b/tp/t/test_utils.pl
@@ -1033,7 +1033,7 @@ sub test($$)
     print STDERR "  TEST $test_name ($test_file)\n" if ($self->{'DEBUG'});
     $document = $parser->parse_texi_file($test_file, $XS_structuring);
   }
-  my $tree = $document->tree();
+  my $tree = $document->tree(1);
 
   if (not defined($tree)) {
     print STDERR "ERROR: parsing result undef\n";
@@ -1123,10 +1123,10 @@ sub test($$)
     foreach my $transformation (@$additional_tree_transformations) {
       my $tree_transformation_sub = $tested_transformations{$transformation};
       if ($transformation eq 'protect_hashchar_at_line_beginning') {
-        &$tree_transformation_sub($document->tree(), $document->registrar(),
+        &$tree_transformation_sub($tree, $document->registrar(),
                                   $main_configuration);
       } else {
-        &$tree_transformation_sub($document->tree());
+        &$tree_transformation_sub($tree);
       }
     }
   }
diff --git a/tp/texi2any.pl b/tp/texi2any.pl
index d876280862..5d9225b29f 100755
--- a/tp/texi2any.pl
+++ b/tp/texi2any.pl
@@ -1491,14 +1491,11 @@ while(@input_files) {
 
   my $parser = Texinfo::Parser::parser($parser_file_options);
   my $document = $parser->parse_texi_file($input_file_name, $XS_structuring);
-  my $tree;
-  if (defined($document)) {
-    $tree = $document->tree();
-  }
 
-  if (defined($tree)
+  if (defined($document)
       and (defined(get_conf('DUMP_TREE'))
            or (get_conf('DEBUG') and get_conf('DEBUG') >= 10))) {
+    my $tree = $document->tree();
     # this is very wrong, but a way to avoid a spurious warning.
     no warnings 'once';
     local $Data::Dumper::Purity = 1;
@@ -1509,7 +1506,7 @@ while(@input_files) {
     print STDERR Data::Dumper->Dump([$tree]);
   }
   # object registering errors and warnings
-  if (!defined($tree) or $format eq 'parse') {
+  if (!defined($document) or $format eq 'parse') {
     handle_errors($parser->errors(), $error_count, \@opened_files);
     goto NEXT;
   }
@@ -1526,6 +1523,7 @@ while(@input_files) {
     goto NEXT;
   }
 
+  my $tree = $document->tree(1);
   if ($tree_transformations{'fill_gaps_in_sectioning'}) {
     Texinfo::Transformations::fill_gaps_in_sectioning($tree);
   }



reply via email to

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