[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[no subject]
From: |
Patrice Dumas |
Date: |
Mon, 30 Dec 2024 16:54:43 -0500 (EST) |
branch: master
commit 262f11e72287e3b054642c17776c0c78b8857d72
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Mon Dec 30 22:52:06 2024 +0100
* tp/Texinfo/XS/main/convert_utils.c (register_unclosed_file),
tp/Texinfo/XS/main/utils.c (new_output_files_information)
(allocate_file_stream): add allocate_file_stream based on
register_unclosed_file code, with code doing the allocation of a
FILE_STREAM in OUTPUT_FILES_INFORMATION unclosed_files. Add
new_output_files_information.
* tp/Texinfo/XS/convert/call_conversion_perl.c
(call_converter_output), tp/Texinfo/XS/convert/texinfo.c
(txi_converter_output), tp/Texinfo/XS/main/converter_types.h
(OUTPUT_TEXT_FILES_INFO), tp/Texinfo/XS/main/get_perl_info.c
(get_output_files_information): in call_converter_output, call also
converter->output_files_information and return both the output text
and output files information in OUTPUT_TEXT_FILES_INFO struct.
Add get_output_files_information to setup OUTPUT_FILES_INFORMATION
based on Perl data returned by converter->output_files_information.
Copy opened_files and unclosed_files returned by call_converter_output
to the converter output_files_information in txi_converter_output.
---
ChangeLog | 21 +++++
tp/Texinfo/XS/convert/call_conversion_perl.c | 38 ++++++++-
tp/Texinfo/XS/convert/call_conversion_perl.h | 4 +-
.../XS/convert/replace_call_conversion_perl.c | 2 +-
tp/Texinfo/XS/convert/texinfo.c | 32 ++++++-
tp/Texinfo/XS/main/build_perl_info.c | 2 +-
tp/Texinfo/XS/main/convert_utils.c | 25 ++----
tp/Texinfo/XS/main/convert_utils.h | 2 +
tp/Texinfo/XS/main/converter_types.h | 5 ++
tp/Texinfo/XS/main/get_perl_info.c | 97 ++++++++++++++++++++++
tp/Texinfo/XS/main/get_perl_info.h | 2 +
tp/Texinfo/XS/main/utils.c | 32 +++++++
tp/Texinfo/XS/main/utils.h | 3 +
13 files changed, 239 insertions(+), 26 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 525571edb7..f91629db46 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -60,6 +60,27 @@
(\opnr, \cpnr, \lbrb, \rbrb):
Add comments about what the names of the macros stand for.
+2024-12-30 Patrice Dumas <pertusus@free.fr>
+
+ * tp/Texinfo/XS/main/convert_utils.c (register_unclosed_file),
+ tp/Texinfo/XS/main/utils.c (new_output_files_information)
+ (allocate_file_stream): add allocate_file_stream based on
+ register_unclosed_file code, with code doing the allocation of a
+ FILE_STREAM in OUTPUT_FILES_INFORMATION unclosed_files. Add
+ new_output_files_information.
+
+ * tp/Texinfo/XS/convert/call_conversion_perl.c
+ (call_converter_output), tp/Texinfo/XS/convert/texinfo.c
+ (txi_converter_output), tp/Texinfo/XS/main/converter_types.h
+ (OUTPUT_TEXT_FILES_INFO), tp/Texinfo/XS/main/get_perl_info.c
+ (get_output_files_information): in call_converter_output, call also
+ converter->output_files_information and return both the output text
+ and output files information in OUTPUT_TEXT_FILES_INFO struct.
+ Add get_output_files_information to setup OUTPUT_FILES_INFORMATION
+ based on Perl data returned by converter->output_files_information.
+ Copy opened_files and unclosed_files returned by call_converter_output
+ to the converter output_files_information in txi_converter_output.
+
2024-12-30 Patrice Dumas <pertusus@free.fr>
* tp/Texinfo/Convert/Text.pm (converter_line_error)
diff --git a/tp/Texinfo/XS/convert/call_conversion_perl.c
b/tp/Texinfo/XS/convert/call_conversion_perl.c
index 1f21a2a826..139a60b8b8 100644
--- a/tp/Texinfo/XS/convert/call_conversion_perl.c
+++ b/tp/Texinfo/XS/convert/call_conversion_perl.c
@@ -219,16 +219,19 @@ call_convert_converter (const char *module_name,
return result;
}
+/* call both converter->output and converter->output_files_information and
+ return an OUTPUT_TEXT_FILES_INFO which contains both the resulting text
+ and the output files information. */
/* FIXME it would probably be better to be able to keep the converter
SV to keep the blessing information instead of needing the module name */
-char *
+OUTPUT_TEXT_FILES_INFO *
call_converter_output (const char *module_name, CONVERTER *self,
DOCUMENT *document)
{
SV *document_sv;
SV *converter_sv;
int count;
- char *result;
+ OUTPUT_TEXT_FILES_INFO *result;
const char *result_ret;
STRLEN len;
SV *result_sv;
@@ -245,6 +248,9 @@ call_converter_output (const char *module_name, CONVERTER
*self,
hv_stash = gv_stashpv (module_name, 0);
sv_bless (converter_sv, hv_stash);
+ result = (OUTPUT_TEXT_FILES_INFO *)
+ non_perl_malloc (sizeof (OUTPUT_TEXT_FILES_INFO));
+
dSP;
ENTER;
@@ -267,7 +273,32 @@ call_converter_output (const char *module_name, CONVERTER
*self,
result_sv = POPs;
result_ret = SvPVutf8 (result_sv, len);
- result = non_perl_strndup (result_ret, len);
+ result->text = non_perl_strndup (result_ret, len);
+
+ PUTBACK;
+
+ FREETMPS;
+ LEAVE;
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK(SP);
+ EXTEND(SP, 1);
+
+ PUSHs(sv_2mortal (converter_sv));
+ PUTBACK;
+
+ count = call_method ("output_files_information",
+ G_SCALAR);
+
+ SPAGAIN;
+
+ if (count != 1)
+ croak ("call_output should return 1 item\n");
+
+ result_sv = POPs;
+ result->output_files_information = get_output_files_information (result_sv);
PUTBACK;
@@ -277,6 +308,7 @@ call_converter_output (const char *module_name, CONVERTER
*self,
return result;
}
+
/* following is used to embed a Perl interpreter */
static PerlInterpreter *my_perl;
diff --git a/tp/Texinfo/XS/convert/call_conversion_perl.h
b/tp/Texinfo/XS/convert/call_conversion_perl.h
index 863994fab0..ace80b2200 100644
--- a/tp/Texinfo/XS/convert/call_conversion_perl.h
+++ b/tp/Texinfo/XS/convert/call_conversion_perl.h
@@ -15,8 +15,8 @@ CONVERTER_INITIALIZATION_INFO
*call_converter_converter_defaults (
CONVERTER *call_convert_converter (const char *module_name,
const CONVERTER_INITIALIZATION_INFO *conf);
-char *call_converter_output (const char *module_name, CONVERTER *self,
- DOCUMENT *document);
+OUTPUT_TEXT_FILES_INFO *call_converter_output (const char *module_name,
+ CONVERTER *self, DOCUMENT *document);
int call_config_GNUT_load_init_file (const char *file_path);
diff --git a/tp/Texinfo/XS/convert/replace_call_conversion_perl.c
b/tp/Texinfo/XS/convert/replace_call_conversion_perl.c
index b3377ecd7c..4a740920a3 100644
--- a/tp/Texinfo/XS/convert/replace_call_conversion_perl.c
+++ b/tp/Texinfo/XS/convert/replace_call_conversion_perl.c
@@ -31,7 +31,7 @@ call_convert_converter (const char *module_name,
return 0;
}
-char *
+OUTPUT_TEXT_FILES_INFO *
call_converter_output (const char *module_name, CONVERTER *self,
DOCUMENT *document)
{
diff --git a/tp/Texinfo/XS/convert/texinfo.c b/tp/Texinfo/XS/convert/texinfo.c
index a6c3ff997b..39ed65336d 100644
--- a/tp/Texinfo/XS/convert/texinfo.c
+++ b/tp/Texinfo/XS/convert/texinfo.c
@@ -43,6 +43,7 @@
#include "translations.h"
#include "structuring.h"
#include "transformations.h"
+#include "convert_utils.h"
#include "converter.h"
#include "html_converter_api.h"
#include "call_conversion_perl.h"
@@ -510,9 +511,36 @@ txi_converter_output (const char *external_module,
{
if (external_module)
{
- char *result = call_converter_output (external_module,
+ size_t i;
+ OUTPUT_TEXT_FILES_INFO *output_text_files_info
+ = call_converter_output (external_module,
converter, document);
- return result;
+ OUTPUT_FILES_INFORMATION *output_files_information
+ = output_text_files_info->output_files_information;
+ FILE_STREAM_LIST *unclosed_files
+ = &output_files_information->unclosed_files;
+
+ char *text_result = 0;
+ if (output_text_files_info->text)
+ {
+ text_result = strdup (output_text_files_info->text);
+ free (output_text_files_info->text);
+ }
+
+ copy_strings (&converter->output_files_information.opened_files,
+ &output_files_information->opened_files);
+ /* copy unclosed files */
+ for (i = 0; i < unclosed_files->number; i++)
+ {
+ register_unclosed_file (
+ &converter->output_files_information,
+ unclosed_files->list[i].file_path,
+ unclosed_files->list[i].stream);
+ }
+ free_output_files_information (output_files_information);
+ free (output_files_information);
+ free (output_text_files_info);
+ return text_result;
}
return converter_output (converter, document);
}
diff --git a/tp/Texinfo/XS/main/build_perl_info.c
b/tp/Texinfo/XS/main/build_perl_info.c
index 02efc3ef42..cabb931c68 100644
--- a/tp/Texinfo/XS/main/build_perl_info.c
+++ b/tp/Texinfo/XS/main/build_perl_info.c
@@ -3238,7 +3238,7 @@ pass_output_unit_files (SV *converter_sv,
-/* Texinfo::Common output_files_information API */
+/* Texinfo::Convert::Utils output_files_information API */
static void
build_output_files_unclosed_files (HV *hv,
const OUTPUT_FILES_INFORMATION *output_files_information)
diff --git a/tp/Texinfo/XS/main/convert_utils.c
b/tp/Texinfo/XS/main/convert_utils.c
index 6e5db18540..563ba8e370 100644
--- a/tp/Texinfo/XS/main/convert_utils.c
+++ b/tp/Texinfo/XS/main/convert_utils.c
@@ -687,20 +687,20 @@ translated_command_tree (CONVERTER *self, enum command_id
cmd)
API to open, set encoding and register files.
*/
-/* in Texinfo::Common (because it is also used by main program) */
+/* in Texinfo::Convert::Utils (also used by main program) */
/* in contrast with perl, we do not handle conversion to output encoding
in output_files_open_out, but in the caller program */
-static void
+void
register_unclosed_file (OUTPUT_FILES_INFORMATION *self, const char *file_path,
FILE *stream)
{
- FILE_STREAM *file_stream;
- int slot_found = 0;
+ FILE_STREAM *file_stream = 0;
size_t file_stream_index;
if (self->unclosed_files.number)
{
+ int slot_found = 0;
size_t i;
for (i = 0; i < self->unclosed_files.number; i++)
{
@@ -718,24 +718,15 @@ register_unclosed_file (OUTPUT_FILES_INFORMATION *self,
const char *file_path,
}
else if (!slot_found)
{
- file_stream_index = i;
slot_found = 1;
+ file_stream_index = i;
+ file_stream = &self->unclosed_files.list[file_stream_index];
}
}
}
- if (!slot_found)
- {
- if (self->unclosed_files.number == self->unclosed_files.space)
- {
- self->unclosed_files.list = realloc (self->unclosed_files.list,
- (self->unclosed_files.space += 5) * sizeof (FILE_STREAM));
- }
- file_stream_index = self->unclosed_files.number;
- self->unclosed_files.number++;
- }
-
- file_stream = &self->unclosed_files.list[file_stream_index];
+ if (!file_stream)
+ file_stream = allocate_file_stream (self);
file_stream->file_path = strdup (file_path);
file_stream->stream = stream;
diff --git a/tp/Texinfo/XS/main/convert_utils.h
b/tp/Texinfo/XS/main/convert_utils.h
index bd71b2c57b..61b7546096 100644
--- a/tp/Texinfo/XS/main/convert_utils.h
+++ b/tp/Texinfo/XS/main/convert_utils.h
@@ -72,6 +72,8 @@ void output_files_register_closed (OUTPUT_FILES_INFORMATION
*self,
const char *file_path);
void free_output_files_information (OUTPUT_FILES_INFORMATION *self);
void clear_output_files_information (OUTPUT_FILES_INFORMATION *self);
+void register_unclosed_file (OUTPUT_FILES_INFORMATION *self,
+ const char *file_path, FILE *stream);
const ELEMENT *find_root_command_next_heading_command (const ELEMENT *root,
const EXPANDED_FORMAT *formats,
diff --git a/tp/Texinfo/XS/main/converter_types.h
b/tp/Texinfo/XS/main/converter_types.h
index 686b80d8c1..56351fcd98 100644
--- a/tp/Texinfo/XS/main/converter_types.h
+++ b/tp/Texinfo/XS/main/converter_types.h
@@ -995,6 +995,11 @@ typedef struct ENCODING_CONVERSION {
iconv_t iconv;
} ENCODING_CONVERSION;
+typedef struct OUTPUT_TEXT_FILES_INFO {
+ OUTPUT_FILES_INFORMATION *output_files_information;
+ char *text;
+} OUTPUT_TEXT_FILES_INFO;
+
#endif
diff --git a/tp/Texinfo/XS/main/get_perl_info.c
b/tp/Texinfo/XS/main/get_perl_info.c
index ad6f5b72c8..a35d72b1e2 100644
--- a/tp/Texinfo/XS/main/get_perl_info.c
+++ b/tp/Texinfo/XS/main/get_perl_info.c
@@ -1345,6 +1345,103 @@ get_language_document_hv_sorted_indices (HV
*document_hv, const char *key,
return 0;
}
+
+
+/* Note that it is not really possible to get FILE from a filehandle associated
+ to a file to be closed in unclosed_files. See comment in
+ build_output_files_unclosed_files */
+OUTPUT_FILES_INFORMATION *
+get_output_files_information (SV *output_files_sv)
+{
+ OUTPUT_FILES_INFORMATION *output_files_information;
+ SV **unclosed_files_sv;
+ SV **opened_files_sv;
+ HV *hv;
+
+ dTHX;
+
+ if (!SvOK (output_files_sv))
+ return 0;
+
+ output_files_information = new_output_files_information ();
+
+ hv = (HV *) SvRV (output_files_sv);
+
+ opened_files_sv = hv_fetch (hv, "opened_files",
+ strlen ("opened_files"), 0);
+
+ if (opened_files_sv)
+ {
+ HV *opened_files_hv = (HV *) SvRV (*opened_files_sv);
+ I32 hv_number;
+ I32 i;
+
+ hv_number = hv_iterinit (opened_files_hv);
+
+ for (i = 0; i < hv_number; i++)
+ {
+ HE *next = hv_iternext (opened_files_hv);
+ SV *file_name_sv = hv_iterkeysv (next);
+ const char *file_name = (char *) SvPVutf8_nolen (file_name_sv);
+ add_string (file_name, &output_files_information->opened_files);
+ /* no real need for the value, still check that it is 1 */
+ SV *value_sv = HeVAL(next);
+ if (!SvOK (value_sv) || !looks_like_number (value_sv)
+ || SvIV (value_sv) != 1)
+ {
+ fprintf (stderr, "BUG? Unexpected opened_files value for `%s'\n",
+ file_name);
+ }
+ }
+ }
+ unclosed_files_sv = hv_fetch (hv, "unclosed_files",
+ strlen ("unclosed_files"), 0);
+
+ if (unclosed_files_sv)
+ {
+ HV *unclosed_files_hv = (HV *) SvRV (*unclosed_files_sv);
+ I32 hv_number;
+ I32 i;
+
+ hv_number = hv_iterinit (unclosed_files_hv);
+
+ for (i = 0; i < hv_number; i++)
+ {
+ FILE_STREAM *file_stream;
+ HE *next = hv_iternext (unclosed_files_hv);
+ SV *file_name_sv = hv_iterkeysv (next);
+ const char *file_name = (char *) SvPVutf8_nolen (file_name_sv);
+ /* Should be two possibilities, undef meaning the a FILE was opened
+ in C, or Perl file handle.
+ In case of undef, it could be possible to find the FILE, by adding
+ a converter argument to the function, and using code similar
+ to get_unclosed_stream.
+ However, from Perl it is not possible to do the same, so we
+ do not try to do it in either case.
+ */
+ SV *value_sv = HeVAL(next);
+ if (!SvOK (value_sv))
+ {
+ fprintf (stderr, "REMARK: unclosed C stream for `%s'\n",
+ file_name);
+ }
+ else
+ {/* SvTYPE(SvRV(value_sv)) should be SVt_PVGV,
+ Glob (possibly a file handle) */
+ fprintf (stderr,
+ "REMARK: unclosed SV: %d (expected %d) for `%s'\n",
+ SvTYPE(SvRV(value_sv)), SVt_PVGV, file_name);
+ }
+ file_stream = allocate_file_stream (output_files_information);
+ file_stream->file_path = strdup (file_name);
+ file_stream->stream = 0;
+ }
+ }
+ return output_files_information;
+}
+
+
+
/* the following is only needed in converters, but we still define here
such that it is available for functions called from C */
static void
diff --git a/tp/Texinfo/XS/main/get_perl_info.h
b/tp/Texinfo/XS/main/get_perl_info.h
index 7758c2e6ad..ab3e94a603 100644
--- a/tp/Texinfo/XS/main/get_perl_info.h
+++ b/tp/Texinfo/XS/main/get_perl_info.h
@@ -64,6 +64,8 @@ const ELEMENT *find_element_from_sv (const CONVERTER
*converter,
SV *get_language_document_hv_sorted_indices (HV *document_hv, const char *key,
const char *language, HV **out_sorted_indices_hv);
+OUTPUT_FILES_INFORMATION *get_output_files_information (SV *output_files_sv);
+
CONVERTER *get_sv_converter (SV *sv_in, const char *warn_string);
CONVERTER_INITIALIZATION_INFO * get_converter_info_from_sv (SV *conf_sv,
const char *class, CONVERTER *converter);
diff --git a/tp/Texinfo/XS/main/utils.c b/tp/Texinfo/XS/main/utils.c
index 03a2621966..b9ec6fcfc8 100644
--- a/tp/Texinfo/XS/main/utils.c
+++ b/tp/Texinfo/XS/main/utils.c
@@ -660,6 +660,38 @@ clear_translated_commands (TRANSLATED_COMMAND_LIST
*translated_commands)
+/* in Texinfo::Convert::Utils in Perl. Most of the API is in convert_utils.c,
+ this is here to be used in code related to XS */
+
+/* not used a lot, as in general the OUTPUT_FILES_INFORMATION is not allocated
+ as a pointer, but used in code related to XS */
+
+OUTPUT_FILES_INFORMATION *
+new_output_files_information (void)
+{
+ OUTPUT_FILES_INFORMATION *result = (OUTPUT_FILES_INFORMATION *)
+ malloc (sizeof (OUTPUT_FILES_INFORMATION));
+ memset (result, 0, sizeof (OUTPUT_FILES_INFORMATION));
+ return result;
+}
+
+FILE_STREAM *
+allocate_file_stream (OUTPUT_FILES_INFORMATION *self)
+{
+ size_t file_stream_index;
+ if (self->unclosed_files.number == self->unclosed_files.space)
+ {
+ self->unclosed_files.list = realloc (self->unclosed_files.list,
+ (self->unclosed_files.space += 5) * sizeof (FILE_STREAM));
+ }
+ file_stream_index = self->unclosed_files.number;
+ self->unclosed_files.number++;
+
+ return &self->unclosed_files.list[file_stream_index];
+}
+
+
+
/* Return the parent if in an item_line command, @*table */
ELEMENT *
item_line_parent (ELEMENT *current)
diff --git a/tp/Texinfo/XS/main/utils.h b/tp/Texinfo/XS/main/utils.h
index 49de666420..f7278f1899 100644
--- a/tp/Texinfo/XS/main/utils.h
+++ b/tp/Texinfo/XS/main/utils.h
@@ -208,6 +208,9 @@ void add_translated_command (TRANSLATED_COMMAND_LIST
*translated_commands,
const char *translation);
void clear_translated_commands (TRANSLATED_COMMAND_LIST *translated_commands);
+OUTPUT_FILES_INFORMATION *new_output_files_information (void);
+FILE_STREAM *allocate_file_stream (OUTPUT_FILES_INFORMATION *self);
+
char *enumerate_item_representation (char *specification, int number);
const ELEMENT *get_global_document_command (