[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[no subject]
From: |
Patrice Dumas |
Date: |
Thu, 21 Dec 2023 16:36:59 -0500 (EST) |
branch: master
commit 133bd0b7a6c265236e09d2af63c165ec24c73c0f
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Wed Dec 20 14:39:21 2023 +0100
* tp/Texinfo/Convert/HTML.pm (%XS_conversion_overrides)
(_push_referred_command_stack_command, _pop_referred_command_stack)
(_command_is_in_referred_command_stack, command_text)
(_convert_xref_commands), tp/Texinfo/XS/convert/ConvertXS.xs
(html_push_referred_command_stack_command)
(html_pop_referred_command_stack)
(html_command_is_in_referred_command_stack),
tp/Texinfo/XS/convert/convert_html.c (html_command_text),
tp/Texinfo/XS/main/command_stack.c
(push_element_reference_stack_element)
(pop_element_reference_stack, command_is_in_referred_command_stack),
tp/Texinfo/XS/main/converter_types.h (ELEMENT_REFERENCE)
(ELEMENT_REFERENCE_STACK, CONVERTER): add accessors around
referred_command_stack state and override them to make sure that the
state viewed from perl and C is the same, both from C to perl and perl
to C.
* tp/Texinfo/XS/convert/build_html_perl_state.c
(build_html_formatting_state): remove the previous way to synchronize
referred_command_stack from C to perl.
* tp/Texinfo/Convert/HTML.pm (_initialize_output_state)
(_initialize_XS_NonXS_output_state): move
check_htmlxref_already_warned and referred_command_stack
initialization to _initialize_output_state.
---
ChangeLog | 28 +++++++++++++++
tp/TODO | 15 ++++++++
tp/Texinfo/Convert/HTML.pm | 50 +++++++++++++++++++++------
tp/Texinfo/XS/convert/ConvertXS.xs | 48 +++++++++++++++++++++++++
tp/Texinfo/XS/convert/build_html_perl_state.c | 27 ---------------
tp/Texinfo/XS/convert/convert_html.c | 11 +++---
tp/Texinfo/XS/main/command_stack.c | 50 +++++++++++++++++++++++++++
tp/Texinfo/XS/main/command_stack.h | 6 ++++
tp/Texinfo/XS/main/converter_types.h | 17 ++++++++-
tp/Texinfo/XS/main/utils.h | 2 +-
10 files changed, 208 insertions(+), 46 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 0c0c479efd..e40d190ac5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -29,6 +29,34 @@
Eliminate use of Texinfo::Convert::Unicode::string_width on
converted output.
+2023-12-19 Patrice Dumas <pertusus@free.fr>
+
+ * tp/Texinfo/Convert/HTML.pm (%XS_conversion_overrides)
+ (_push_referred_command_stack_command, _pop_referred_command_stack)
+ (_command_is_in_referred_command_stack, command_text)
+ (_convert_xref_commands), tp/Texinfo/XS/convert/ConvertXS.xs
+ (html_push_referred_command_stack_command)
+ (html_pop_referred_command_stack)
+ (html_command_is_in_referred_command_stack),
+ tp/Texinfo/XS/convert/convert_html.c (html_command_text),
+ tp/Texinfo/XS/main/command_stack.c
+ (push_element_reference_stack_element)
+ (pop_element_reference_stack, command_is_in_referred_command_stack),
+ tp/Texinfo/XS/main/converter_types.h (ELEMENT_REFERENCE)
+ (ELEMENT_REFERENCE_STACK, CONVERTER): add accessors around
+ referred_command_stack state and override them to make sure that the
+ state viewed from perl and C is the same, both from C to perl and perl
+ to C.
+
+ * tp/Texinfo/XS/convert/build_html_perl_state.c
+ (build_html_formatting_state): remove the previous way to synchronize
+ referred_command_stack from C to perl.
+
+ * tp/Texinfo/Convert/HTML.pm (_initialize_output_state)
+ (_initialize_XS_NonXS_output_state): move
+ check_htmlxref_already_warned and referred_command_stack
+ initialization to _initialize_output_state.
+
2023-12-19 Patrice Dumas <pertusus@free.fr>
* tp/Texinfo/Convert/HTML.pm
diff --git a/tp/TODO b/tp/TODO
index c1b797ba16..56460d3fed 100644
--- a/tp/TODO
+++ b/tp/TODO
@@ -103,6 +103,21 @@ the context command stack.
@end defun
+For HTML conversion it is possible that the conversion and caching of
+element text (in general for directions href) is done at different
+moments with conversion in perl only and conversion with a mix of perl
+code and C code. Indeed, if an element text is formatted in C and
+will be needed later on in perl it will be formatted later on in perl
+in that setup compared to the pure perl case. In general the moment
+of first conversion of element text does not matter much, but it does
+in specific cases, for instance with recursive definitions of sectioning
+commands (with a @ref in sectioning command). This is tested in test
+30sectioning.t double_recursive_self_section_reference.
+With @ref converted in perl and other parts of the conversions
+in C, an href for a direction differs for this test. If @ref is also
+converted in C, this issue is invisible.
+
+
Modules included in tp/maintain/lib/ need to be updated from time to
time.
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index ef0f3ae46f..089dfb82c1 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -215,6 +215,12 @@ my %XS_conversion_overrides = (
=>
"Texinfo::Convert::ConvertXS::html_associate_pending_formatted_inline_content",
"Texinfo::Convert::HTML::get_associated_formatted_inline_content",
=>
"Texinfo::Convert::ConvertXS::html_get_associated_formatted_inline_content",
+ "Texinfo::Convert::HTML::_push_referred_command_stack_command"
+ => "Texinfo::Convert::ConvertXS::html_push_referred_command_stack_command",
+ "Texinfo::Convert::HTML::_pop_referred_command_stack"
+ => "Texinfo::Convert::ConvertXS::html_pop_referred_command_stack",
+ "Texinfo::Convert::HTML::_command_is_in_referred_command_stack"
+ => "Texinfo::Convert::ConvertXS::html_command_is_in_referred_command_stack",
"Texinfo::Convert::HTML::_check_htmlxref_already_warned"
=> "Texinfo::Convert::ConvertXS::html_check_htmlxref_already_warned",
@@ -1261,6 +1267,27 @@ sub command_tree($$;$)
return undef;
}
+sub _push_referred_command_stack_command($$)
+{
+ my $self = shift;
+ my $command = shift;
+ push @{$self->{'referred_command_stack'}}, $command;
+}
+
+sub _pop_referred_command_stack($)
+{
+ my $self = shift;
+ pop @{$self->{'referred_command_stack'}};
+}
+
+sub _command_is_in_referred_command_stack($$)
+{
+ my $self = shift;
+ my $command = shift;
+
+ return grep {$_ eq $command} @{$self->{'referred_command_stack'}};
+}
+
# Return text to be used for a hyperlink to $COMMAND.
# $TYPE refers to the type of value returned from this function:
# 'text' - return text
@@ -1335,9 +1362,10 @@ sub command_text($$;$)
}
$self->{'ignore_notice'}++;
- push @{$self->{'referred_command_stack'}}, $command;
+
+ _push_referred_command_stack_command($self, $command);
$target->{$type} = $self->_convert($tree_root, $explanation);
- pop @{$self->{'referred_command_stack'}};
+ _pop_referred_command_stack($self);
$self->{'ignore_notice'}--;
$self->_pop_document_context();
@@ -5643,8 +5671,8 @@ sub _convert_xref_commands($$$$)
# possible to construct an infinite recursion with nodes only
# as the node must both be a reference target and refer to a specific
# target at the same time, which is not possible.
- and not grep {$_ eq $target_node->{'extra'}->{'associated_section'}}
- @{$self->{'referred_command_stack'}}) {
+ and not _command_is_in_referred_command_stack($self,
+ $target_node->{'extra'}->{'associated_section'})) {
$target_root = $target_node->{'extra'}->{'associated_section'};
$name = $self->command_text($target_root, 'text_nonumber');
} elsif ($target_node->{'cmdname'} eq 'float') {
@@ -11267,6 +11295,13 @@ sub _initialize_output_state($$)
$self->{'pending_footnotes'} = [];
$self->{'pending_closes'} = [];
+ # to avoid infinite recursions when a section refers to itself, possibly
+ # indirectly
+ $self->{'referred_command_stack'} = [];
+
+ $self->{'check_htmlxref_already_warned'} = {}
+ if ($self->get_conf('CHECK_HTMLXREF'));
+
$self->_new_document_context($context);
}
@@ -11304,13 +11339,6 @@ sub _initialize_XS_NonXS_output_state($$)
# for footnotes
$self->{'special_targets'} = {'footnote_location' => {}};
-
- # to avoid infinite recursions when a section refers to itself, possibly
- # indirectly
- $self->{'referred_command_stack'} = [];
-
- $self->{'check_htmlxref_already_warned'} = {}
- if ($self->get_conf('CHECK_HTMLXREF'));
}
sub _finalize_output_state($)
diff --git a/tp/Texinfo/XS/convert/ConvertXS.xs
b/tp/Texinfo/XS/convert/ConvertXS.xs
index 767d32e64c..b1096017c7 100644
--- a/tp/Texinfo/XS/convert/ConvertXS.xs
+++ b/tp/Texinfo/XS/convert/ConvertXS.xs
@@ -1098,6 +1098,54 @@ html_get_associated_formatted_inline_content (SV
*converter_in, SV *element_sv)
OUTPUT:
RETVAL
+# we do not increase here and decrease in pop the element_hv refcount, under
+# the assumption that there is already a reference held by the C tree on
+# the element.
+void
+html_push_referred_command_stack_command (SV *converter_in, SV *element_sv)
+ PREINIT:
+ CONVERTER *self;
+ CODE:
+ self = get_sv_converter (converter_in,
+ "html_push_referred_command_stack_command");
+ if (self)
+ {
+ const HV *element_hv = (HV *) SvRV (element_sv);
+ push_element_reference_stack_element (
+ &self->referred_command_stack, 0, (const void *)element_hv);
+ }
+
+void
+html_pop_referred_command_stack (SV *converter_in)
+ PREINIT:
+ CONVERTER *self;
+ CODE:
+ self = get_sv_converter (converter_in,
+ "html_pop_referred_command_stack");
+ if (self)
+ {
+ pop_element_reference_stack (&self->referred_command_stack);
+ }
+
+int
+html_command_is_in_referred_command_stack (SV *converter_in, SV *element_sv)
+ PREINIT:
+ CONVERTER *self;
+ int found = 0;
+ CODE:
+ self = get_sv_converter (converter_in,
+ "html_command_is_in_referred_command_stack");
+ if (self)
+ {
+ const HV *element_hv = (HV *) SvRV (element_sv);
+ found = command_is_in_referred_command_stack (
+ &self->referred_command_stack, 0,
+ (const void *)element_hv);
+ }
+ RETVAL = found;
+ OUTPUT:
+ RETVAL
+
int
html_check_htmlxref_already_warned (SV *converter_in, manual_name, SV
*source_info_sv)
char *manual_name = (char *)SvPVutf8_nolen($arg);
diff --git a/tp/Texinfo/XS/convert/build_html_perl_state.c
b/tp/Texinfo/XS/convert/build_html_perl_state.c
index 12af08aa19..bdde83acf4 100644
--- a/tp/Texinfo/XS/convert/build_html_perl_state.c
+++ b/tp/Texinfo/XS/convert/build_html_perl_state.c
@@ -755,33 +755,6 @@ build_html_formatting_state (CONVERTER *converter,
unsigned long flags)
}
}
- if (flags & HMSF_referred_command_stack)
- {
- SV **referred_command_stack_sv;
- AV *referred_command_stack_av;
-
- FETCH(referred_command_stack);
-
- if (!referred_command_stack_sv)
- {
- referred_command_stack_av = newAV ();
- STORE("referred_command_stack",
- newRV_noinc ((SV *) referred_command_stack_av));
- }
- else
- {
- referred_command_stack_av = (AV *) SvRV (*referred_command_stack_sv);
- av_clear (referred_command_stack_av);
- }
-
- for (i = 0; i < converter->referred_command_stack.top; i++)
- {
- const ELEMENT *referred_e =
converter->referred_command_stack.stack[i];
- av_push (referred_command_stack_av,
- newRV_inc ((SV *) referred_e->hv));
- }
- }
-
if (converter->added_targets.number)
{
SV **targets_sv;
diff --git a/tp/Texinfo/XS/convert/convert_html.c
b/tp/Texinfo/XS/convert/convert_html.c
index 16acf4e016..1f87491aae 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -3884,16 +3884,15 @@ html_command_text (CONVERTER *self, const ELEMENT
*command,
tree_root = selected_tree;
self->ignore_notice++;
- push_stack_element (&self->referred_command_stack, command);
- self->modified_state |= HMSF_referred_command_stack
- | HMSF_converter_state;
+ push_element_reference_stack_element (&self->referred_command_stack,
+ command, command->hv);
+ self->modified_state |= HMSF_converter_state;
target_info->command_text[type]
= html_convert_tree (self, tree_root, explanation);
free (explanation);
- pop_stack_element (&self->referred_command_stack);
+ pop_element_reference_stack (&self->referred_command_stack);
self->ignore_notice--;
- self->modified_state |= HMSF_referred_command_stack
- | HMSF_converter_state;
+ self->modified_state |= HMSF_converter_state;
html_pop_document_context (self);
diff --git a/tp/Texinfo/XS/main/command_stack.c
b/tp/Texinfo/XS/main/command_stack.c
index 150c667631..322fd6caf8 100644
--- a/tp/Texinfo/XS/main/command_stack.c
+++ b/tp/Texinfo/XS/main/command_stack.c
@@ -219,6 +219,56 @@ pop_stack_element (ELEMENT_STACK *stack)
}
+/* elements stack that can also be called from an external language (perl)
+ where there is no reference to C elements */
+void
+push_element_reference_stack_element (ELEMENT_REFERENCE_STACK *stack,
+ const ELEMENT *e, const void *hv)
+{
+ if (stack->top >= stack->space)
+ {
+ stack->stack
+ = realloc (stack->stack,
+ (stack->space += 5) * sizeof (ELEMENT_STACK));
+ }
+
+ memset (&stack->stack[stack->top], 0, sizeof (ELEMENT_STACK));
+
+ if (e)
+ stack->stack[stack->top].element = e;
+ if (hv)
+ stack->stack[stack->top].hv = hv;
+
+ stack->top++;
+}
+
+void
+pop_element_reference_stack (ELEMENT_REFERENCE_STACK *stack)
+{
+ if (stack->top == 0)
+ fatal ("element reference stack empty for top");
+
+ stack->top--;
+}
+
+int
+command_is_in_referred_command_stack (ELEMENT_REFERENCE_STACK *stack,
+ const ELEMENT *e, const void *hv)
+{
+ size_t i;
+ for (i = 0; i < stack->top; i++)
+ {
+ ELEMENT_REFERENCE *element_reference = &stack->stack[i];
+ if (e && element_reference->element == e
+ || hv && element_reference->hv == hv)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
/* HTML specific but also used to build perl */
HTML_DOCUMENT_CONTEXT *
html_top_document_context (CONVERTER *self)
diff --git a/tp/Texinfo/XS/main/command_stack.h
b/tp/Texinfo/XS/main/command_stack.h
index 18c7f6c30a..dd1d7de618 100644
--- a/tp/Texinfo/XS/main/command_stack.h
+++ b/tp/Texinfo/XS/main/command_stack.h
@@ -44,6 +44,12 @@ int top_integer_stack (INTEGER_STACK *stack);
void push_stack_element (ELEMENT_STACK *stack, const ELEMENT *e);
const ELEMENT *pop_stack_element (ELEMENT_STACK *stack);
+void push_element_reference_stack_element (ELEMENT_REFERENCE_STACK *stack,
+ const ELEMENT *e, const void *hv);
+void pop_element_reference_stack (ELEMENT_REFERENCE_STACK *stack);
+int command_is_in_referred_command_stack (ELEMENT_REFERENCE_STACK *stack,
+ const ELEMENT *e, const void *hv);
+
HTML_DOCUMENT_CONTEXT *html_top_document_context (CONVERTER *self);
HTML_FORMATTING_CONTEXT *html_top_formatting_context
diff --git a/tp/Texinfo/XS/main/converter_types.h
b/tp/Texinfo/XS/main/converter_types.h
index 350030843b..05afce8d97 100644
--- a/tp/Texinfo/XS/main/converter_types.h
+++ b/tp/Texinfo/XS/main/converter_types.h
@@ -230,6 +230,21 @@ typedef struct ELEMENT_STACK {
size_t space;
} ELEMENT_STACK;
+/* an element in C, and/or a reference to an external language (perl)
+ for stack functions called from outside of the C converter */
+typedef struct ELEMENT_REFERENCE {
+ const ELEMENT *element;
+ /* perl element. This should be HV *hv,
+ but we don't want to include the Perl headers everywhere; */
+ const void *hv;
+} ELEMENT_REFERENCE;
+
+typedef struct ELEMENT_REFERENCE_STACK {
+ ELEMENT_REFERENCE *stack;
+ size_t top;
+ size_t space;
+} ELEMENT_REFERENCE_STACK;
+
typedef struct FILE_NUMBER_NAME {
size_t file_number;
char *filename;
@@ -750,7 +765,7 @@ typedef struct CONVERTER {
STRING_STACK multiple_pass;
STRING_STACK pending_closes;
FILE_NUMBER_NAME current_filename;
- ELEMENT_STACK referred_command_stack;
+ ELEMENT_REFERENCE_STACK referred_command_stack;
HTML_SHARED_CONVERSION_STATE shared_conversion_state;
HTML_INLINE_CONTENT_STACK pending_inline_content;
HTML_PENDING_FOOTNOTE_STACK pending_footnotes;
diff --git a/tp/Texinfo/XS/main/utils.h b/tp/Texinfo/XS/main/utils.h
index d66707167e..66cfea6b9d 100644
--- a/tp/Texinfo/XS/main/utils.h
+++ b/tp/Texinfo/XS/main/utils.h
@@ -138,7 +138,7 @@ enum command_location {
#define HMSF_translations 0x4000
#define HMSF_ 0x8000
#define HMSF_added_target 0x00010000
-#define HMSF_referred_command_stack 0x00020000
+#define HMSF_ 0x00020000
typedef struct TARGET_FILENAME {
char *target;
- master updated (39b90e4bfa -> 9d9515c455), Patrice Dumas, 2023/12/21
- [no subject], Patrice Dumas, 2023/12/21
- [no subject], Patrice Dumas, 2023/12/21
- [no subject],
Patrice Dumas <=
- [no subject], Patrice Dumas, 2023/12/21
- [no subject], Patrice Dumas, 2023/12/21
- [no subject], Patrice Dumas, 2023/12/21
- [no subject], Patrice Dumas, 2023/12/21