texinfo-commits
[Top][All Lists]
Advanced

[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 (



reply via email to

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