[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);
}