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, 21 Oct 2023 16:23:12 -0400 (EDT)

branch: master
commit 3aa0829d7ffbbcac02a14c5c21e36d9ff0ea5902
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Sat Oct 21 22:22:11 2023 +0200

    * tp/Texinfo/XS/main/utils.h (FILE_SOURCE_INFO,
    FILE_SOURCE_INFO_LIST), tp/Texinfo/XS/convert/convert_html.h: move to
    utils.h from convert_html.h.
    
    * tp/Texinfo/Convert/HTML.pm (_prepare_units_directions_files),
    tp/Texinfo/XS/convert/ConvertXS.xs
    (html_prepare_units_directions_files),
    tp/Texinfo/XS/convert/convert_html.c
    (prepare_output_units_global_targets),
    tp/Texinfo/XS/main/build_perl_info.c (output_unit_to_perl_hash)
    (fill_output_units, build_output_units_list)
    (rebuild_output_units_list, build_html_files_source_info)
    (build_html_global_units_directions, build_file_counters)
    (build_out_filepaths, build_html_elements_in_file_count),
    tp/Texinfo/XS/main/utils.c (html_global_unit_direction_names),
    tp/Texinfo/XS/main/utils.h (HTML_GLOBAL_DIRECTIONS_LIST)
    (SPECIAL_UNIT_DIRECTION, CONVERTER): rebuild output units lists and
    get HTML perl converter state information from
    _XS_prepare_units_directions_files/html_prepare_units_directions_files
    for global_units_directions, file_counters, elements_in_file_count and
    out_filepaths.  Set self->special_units_direction_name to pass special
    units directions more easily from XS.
---
 ChangeLog                            |  25 ++++
 tp/Texinfo/Convert/HTML.pm           |  22 ++-
 tp/Texinfo/XS/convert/ConvertXS.xs   |  33 ++++-
 tp/Texinfo/XS/convert/convert_html.c | 275 ++++++++++++++++++++---------------
 tp/Texinfo/XS/convert/convert_html.h |  14 --
 tp/Texinfo/XS/main/build_perl_info.c | 267 ++++++++++++++++++++++++++++++++--
 tp/Texinfo/XS/main/build_perl_info.h |  10 ++
 tp/Texinfo/XS/main/utils.c           |   6 +
 tp/Texinfo/XS/main/utils.h           |  52 +++++--
 9 files changed, 534 insertions(+), 170 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 607235da49..6f67eb2db7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2023-10-21  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/XS/main/utils.h (FILE_SOURCE_INFO,
+       FILE_SOURCE_INFO_LIST), tp/Texinfo/XS/convert/convert_html.h: move to 
+       utils.h from convert_html.h.
+
+       * tp/Texinfo/Convert/HTML.pm (_prepare_units_directions_files),
+       tp/Texinfo/XS/convert/ConvertXS.xs
+       (html_prepare_units_directions_files),
+       tp/Texinfo/XS/convert/convert_html.c
+       (prepare_output_units_global_targets),
+       tp/Texinfo/XS/main/build_perl_info.c (output_unit_to_perl_hash)
+       (fill_output_units, build_output_units_list)
+       (rebuild_output_units_list, build_html_files_source_info)
+       (build_html_global_units_directions, build_file_counters)
+       (build_out_filepaths, build_html_elements_in_file_count),
+       tp/Texinfo/XS/main/utils.c (html_global_unit_direction_names),
+       tp/Texinfo/XS/main/utils.h (HTML_GLOBAL_DIRECTIONS_LIST)
+       (SPECIAL_UNIT_DIRECTION, CONVERTER): rebuild output units lists and
+       get HTML perl converter state information from
+       _XS_prepare_units_directions_files/html_prepare_units_directions_files
+       for global_units_directions, file_counters, elements_in_file_count and
+       out_filepaths.  Set self->special_units_direction_name to pass special
+       units directions more easily from XS.
+
 2023-10-21  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/Convert/HTML.pm (_prepare_special_units_directions):
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index c3eda4533a..f8e7d922d8 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -9215,7 +9215,6 @@ sub _prepare_conversion_units($$$)
                         sort(keys(%contents_command_special_unit_variety));
   $self->set_global_document_commands('last', \@contents_elements_options);
 
-  #if (0 and $self->{'converter_descriptor'}) {
   if ($self->{'converter_descriptor'}) {
     my $encoded_converter = $self->encode_converter_for_output();
     my $encoded_document_name = Encode::encode('UTF-8', $document_name);
@@ -9289,17 +9288,23 @@ sub _prepare_units_directions_files($$$$$$$$)
   my $output_filename = shift;
   my $document_name = shift;
 
-  #if (0 and $self->{'converter_descriptor'}) {
-  if ($self->{'converter_descriptor'}) {
+  if (0 and $self->{'converter_descriptor'}) {
+  #if ($self->{'converter_descriptor'}) {
     my $encoded_converter = $self->encode_converter_for_output();
     my $encoded_document_name = Encode::encode('UTF-8', $document_name);
 
-    my $XS_files_source_info
+    my ($XS_files_source_info, $global_units_directions,
+        $file_counters, $elements_in_file_count, $out_filepaths)
       = _XS_prepare_units_directions_files($encoded_converter,
            $output_units, $special_units, $associated_special_units,
            $output_file, $destination_directory, $output_filename,
            $encoded_document_name);
-    # FIXME return when the XS implementation is done
+    $self->{'global_units_directions'} = $global_units_directions;
+    $self->{'file_counters'} = $file_counters;
+    $self->{'elements_in_file_count'} = $elements_in_file_count;
+    $self->{'out_filepaths'} = $out_filepaths;
+
+    return %$XS_files_source_info;
   }
 
   $self->_prepare_output_units_global_targets($output_units, $special_units,
@@ -9317,13 +9322,13 @@ sub _prepare_units_directions_files($$$$$$$$)
                     $destination_directory, $output_filename, $document_name);
   }
 
-  # do tree units directions.
+  # do output units directions.
   Texinfo::Structuring::units_directions($self,
                                 $self->{'identifiers_target'}, $output_units);
 
   _prepare_special_units_directions($self, $special_units);
 
-  # do element directions related to files.
+  # do output units directions related to files.
   # Here such that PrevFile and NextFile can be set.
   Texinfo::Structuring::units_file_directions($output_units);
 
@@ -9676,12 +9681,13 @@ sub _prepare_output_units_global_targets($$$$)
     foreach my $global_direction (@global_directions) {
       if (defined($self->global_direction_unit($global_direction))) {
         my $global_unit = $self->global_direction_unit($global_direction);
-        print STDERR "$global_direction"
+        print STDERR " $global_direction"
             # uncomment to get the perl object name
             # ."($global_unit)"
      .': '. Texinfo::Structuring::output_unit_texi($global_unit)."\n";
       }
     }
+    print STDERR "\n";
   }
 
   foreach my $units_list ($special_units, $associated_special_units) {
diff --git a/tp/Texinfo/XS/convert/ConvertXS.xs 
b/tp/Texinfo/XS/convert/ConvertXS.xs
index 8f740a6edd..f2cb363248 100644
--- a/tp/Texinfo/XS/convert/ConvertXS.xs
+++ b/tp/Texinfo/XS/convert/ConvertXS.xs
@@ -184,7 +184,7 @@ html_prepare_conversion_units (SV *converter_in, ...)
          PUSHs(sv_2mortal(special_targets_sv));
          PUSHs(sv_2mortal(seen_ids_sv));
 
-SV *
+void
 html_prepare_units_directions_files (SV *converter_in, SV *output_units_in, SV 
*special_units_in, SV *associated_special_units_in, output_file, 
destination_directory, output_filename, document_name)
          char *output_file = (char *)SvPVbyte_nolen($arg);
          char *destination_directory = (char *)SvPVbyte_nolen($arg);
@@ -196,7 +196,12 @@ html_prepare_units_directions_files (SV *converter_in, SV 
*output_units_in, SV *
          int special_units_descriptor = 0;
          int associated_special_units_descriptor = 0;
          FILE_SOURCE_INFO_LIST *files_source_info = 0;
-     CODE:
+         SV *files_source_info_sv;
+         SV *global_units_directions_sv;
+         SV *file_counters_sv;
+         SV *elements_in_file_count_sv;
+         SV *out_filepaths_sv;
+   PPCODE:
          /* add warn string? */
          self = get_sv_converter (converter_in, 0);
          if (SvOK (output_units_in))
@@ -217,8 +222,26 @@ html_prepare_units_directions_files (SV *converter_in, SV 
*output_units_in, SV *
                     associated_special_units_descriptor, output_file,
                     destination_directory, output_filename, document_name);
 
-         RETVAL = newSV(0);
-    OUTPUT:
-         RETVAL
+         rebuild_output_units_list (output_units_in, output_units_descriptor);
+         rebuild_output_units_list (special_units_in, 
special_units_descriptor);
+         rebuild_output_units_list (associated_special_units_in,
+                                    associated_special_units_descriptor);
+
+         files_source_info_sv
+           = build_html_files_source_info (files_source_info);
+         global_units_directions_sv
+           = build_html_global_units_directions (self->global_units_directions,
+                                          self->special_units_direction_name);
+         file_counters_sv = build_file_counters (self->output_unit_files);
+         elements_in_file_count_sv
+           = build_html_elements_in_file_count (self->output_unit_files);
+         out_filepaths_sv = build_out_filepaths (self->output_unit_files);
+
+         EXTEND(SP, 5);
+         PUSHs(sv_2mortal(files_source_info_sv));
+         PUSHs(sv_2mortal(global_units_directions_sv));
+         PUSHs(sv_2mortal(file_counters_sv));
+         PUSHs(sv_2mortal(elements_in_file_count_sv));
+         PUSHs(sv_2mortal(out_filepaths_sv));
 
 
diff --git a/tp/Texinfo/XS/convert/convert_html.c 
b/tp/Texinfo/XS/convert/convert_html.c
index 43399fc73e..3c5b356d20 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -420,126 +420,6 @@ translate_names (CONVERTER *self)
     fprintf (stderr, "END TRANSLATE_NAMES\n\n");
 }
 
-/* Associate output units to the global targets, First, Last, Top, Index.
-   and special output units */
-static void
-prepare_output_units_global_targets (CONVERTER *self,
-                                     int output_units_descriptor,
-                                     int special_units_descriptor,
-                                     int associated_special_units_descriptor)
-{
-  int i;
-  OUTPUT_UNIT_LIST *output_units
-    = retrieve_output_units (output_units_descriptor);
-  ELEMENT *node_top = find_identifier_target
-                          (self->document->identifiers_target, "Top");
-  ELEMENT *section_top = self->document->global_commands->top;
-
-  int special_output_units_lists[2] = {special_units_descriptor,
-                                       associated_special_units_descriptor};
-
-  self->global_units_directions[D_First] = output_units->list[0];
-  self->global_units_directions[D_Last]
-    = output_units->list[output_units->number - 1];
-
-  if (section_top)
-    self->global_units_directions[D_Top] = section_top->associated_unit;
-  else if (node_top)
-    self->global_units_directions[D_Top] = node_top->associated_unit;
-  else
-    self->global_units_directions[D_Top] = output_units->list[0];
-
-  /* It is always the first printindex, even if it is not output (for example
-     it is in @copying and @titlepage, which are certainly wrong constructs).
-   */
-  if (self->document->global_commands->printindex.contents.number > 0)
-    {
-      ELEMENT *printindex
-        = self->document->global_commands->printindex.contents.list[0];
-      ROOT_AND_UNIT *root_unit
-        = html_get_tree_root_element (self, printindex, 0);
-      if (root_unit->output_unit)
-        {
-          OUTPUT_UNIT *document_unit = root_unit->output_unit;
-          ELEMENT *root_command = root_unit->root;
-          if (root_command && root_command->cmd == CM_node)
-            {
-              ELEMENT *associated_section
-                = lookup_extra_element (root_command, "associated_section");
-              if (associated_section)
-                root_command = associated_section;
-            }
-       /* find the first level 1 sectioning element to associate the printindex
-           with */
-          if (root_command && root_command->cmd != CM_node)
-            {
-              while (1)
-                {
-                  int status;
-                  int section_level
-                    = lookup_extra_integer (root_command, "section_level",
-                                                               &status);
-                  if (!status && section_level <= 1)
-                    break;
-
-                  ELEMENT *up_section_directions
-                    = lookup_extra_element (root_command, 
"section_directions");
-                  if (up_section_directions
-                      && up_section_directions->contents.list[D_up]
-                      && up_section_directions->contents.list[D_up]
-                                     ->associated_unit)
-                    {
-                      root_command = 
up_section_directions->contents.list[D_up];
-                      document_unit = root_command->associated_unit;
-                    }
-                  else
-                    break;
-                }
-              self->global_units_directions[D_Index] = document_unit;
-            }
-        }
-      free (root_unit);
-    }
-
-  if (self->conf->DEBUG >= 0 && self->conf->DEBUG)
-    {
-      int i;
-      fprintf (stderr, "GLOBAL DIRECTIONS:\n");
-      for (i = 0; i < D_Last+1; i++)
-        {
-          if (self->global_units_directions[i])
-            {
-              OUTPUT_UNIT *global_unit = self->global_units_directions[i];
-              char *unit_texi = output_unit_texi (global_unit);
-              fprintf (stderr, "%s: %s\n", output_unit_type_names[i],
-                                           unit_texi);
-              free (unit_texi);
-            }
-        }
-    }
-
-  for (i = 0; i < 2; i++)
-    {
-      int j;
-      int special_units_descriptor = special_output_units_lists[i];
-      OUTPUT_UNIT_LIST *units_list
-       = retrieve_output_units (special_units_descriptor);
-      if (units_list && units_list->number)
-        {
-          for (j = 0; j < units_list->number; j++)
-            {
-              OUTPUT_UNIT *special_unit = units_list->list[j];
-              char *special_unit_variety = special_unit->special_unit_variety;
-              int special_unit_direction_index
-                = special_unit_variety_direction_index (self,
-                                                special_unit_variety);
-              self->global_units_directions[special_unit_direction_index]
-                = special_unit;
-            }
-        }
-    }
-}
-
 typedef struct CMD_VARIETY {
     enum command_id cmd;
     char *variety;
@@ -1564,6 +1444,155 @@ html_prepare_conversion_units_targets (CONVERTER *self,
   translate_names (self);
 }
 
+/* Associate output units to the global targets, First, Last, Top, Index.
+   and special output units */
+static void
+prepare_output_units_global_targets (CONVERTER *self,
+                                     int output_units_descriptor,
+                                     int special_units_descriptor,
+                                     int associated_special_units_descriptor)
+{
+  int i;
+  int all_special_units_nr = 0;
+  int s = 0;
+  OUTPUT_UNIT_LIST *output_units
+    = retrieve_output_units (output_units_descriptor);
+  ELEMENT *node_top = find_identifier_target
+                          (self->document->identifiers_target, "Top");
+  ELEMENT *section_top = self->document->global_commands->top;
+
+  int special_output_units_lists[2] = {special_units_descriptor,
+                                       associated_special_units_descriptor};
+
+  self->global_units_directions[D_First] = output_units->list[0];
+  self->global_units_directions[D_Last]
+    = output_units->list[output_units->number - 1];
+
+  if (section_top)
+    self->global_units_directions[D_Top] = section_top->associated_unit;
+  else if (node_top)
+    self->global_units_directions[D_Top] = node_top->associated_unit;
+  else
+    self->global_units_directions[D_Top] = output_units->list[0];
+
+  /* It is always the first printindex, even if it is not output (for example
+     it is in @copying and @titlepage, which are certainly wrong constructs).
+   */
+  if (self->document->global_commands->printindex.contents.number > 0)
+    {
+      ELEMENT *printindex
+        = self->document->global_commands->printindex.contents.list[0];
+      ROOT_AND_UNIT *root_unit
+        = html_get_tree_root_element (self, printindex, 0);
+      if (root_unit->output_unit)
+        {
+          OUTPUT_UNIT *document_unit = root_unit->output_unit;
+          ELEMENT *root_command = root_unit->root;
+          if (root_command && root_command->cmd == CM_node)
+            {
+              ELEMENT *associated_section
+                = lookup_extra_element (root_command, "associated_section");
+              if (associated_section)
+                root_command = associated_section;
+            }
+       /* find the first level 1 sectioning element to associate the printindex
+           with */
+          if (root_command && root_command->cmd != CM_node)
+            {
+              while (1)
+                {
+                  int status;
+                  int section_level
+                    = lookup_extra_integer (root_command, "section_level",
+                                                               &status);
+                  if (!status && section_level <= 1)
+                    break;
+
+                  ELEMENT *up_section_directions
+                    = lookup_extra_element (root_command, 
"section_directions");
+                  if (up_section_directions
+                      && up_section_directions->contents.list[D_up]
+                      && up_section_directions->contents.list[D_up]
+                                     ->associated_unit)
+                    {
+                      root_command = 
up_section_directions->contents.list[D_up];
+                      document_unit = root_command->associated_unit;
+                    }
+                  else
+                    break;
+                }
+            }
+          self->global_units_directions[D_Index] = document_unit;
+        }
+      free (root_unit);
+    }
+
+  if (self->conf->DEBUG >= 0 && self->conf->DEBUG)
+    {
+      int i;
+      fprintf (stderr, "GLOBAL DIRECTIONS:\n");
+      for (i = 0; i < D_Last+1; i++)
+        {
+          if (self->global_units_directions[i])
+            {
+              OUTPUT_UNIT *global_unit = self->global_units_directions[i];
+              char *unit_texi = output_unit_texi (global_unit);
+              fprintf (stderr, " %s: %s\n", 
html_global_unit_direction_names[i],
+                                            unit_texi);
+              free (unit_texi);
+            }
+        }
+      fprintf (stderr, "\n");
+    }
+
+  /* determine total number of special output units and fill
+     special_units_directions_name_unit.  Used to simplify building perl
+     directions */
+  for (i = 0; i < 2; i++)
+    {
+      int special_units_descriptor = special_output_units_lists[i];
+      OUTPUT_UNIT_LIST *units_list
+       = retrieve_output_units (special_units_descriptor);
+      if (units_list && units_list->number)
+        all_special_units_nr += units_list->number;
+    }
+
+  self->special_units_direction_name = (SPECIAL_UNIT_DIRECTION **)
+   malloc (sizeof (SPECIAL_UNIT_DIRECTION *) * (all_special_units_nr+1));
+  memset (self->special_units_direction_name, 0,
+          sizeof (SPECIAL_UNIT_DIRECTION *) * (all_special_units_nr+1));
+
+  for (i = 0; i < 2; i++)
+    {
+      int j;
+      int special_units_descriptor = special_output_units_lists[i];
+      OUTPUT_UNIT_LIST *units_list
+       = retrieve_output_units (special_units_descriptor);
+      if (units_list && units_list->number)
+        {
+          for (j = 0; j < units_list->number; j++)
+            {
+              OUTPUT_UNIT *special_unit = units_list->list[j];
+              char *special_unit_variety = special_unit->special_unit_variety;
+              int special_unit_direction_index
+                = special_unit_variety_direction_index (self,
+                                                special_unit_variety);
+              self->global_units_directions[special_unit_direction_index]
+                = special_unit;
+
+              self->special_units_direction_name[s] =
+               (SPECIAL_UNIT_DIRECTION *)
+                malloc (sizeof (SPECIAL_UNIT_DIRECTION));
+              self->special_units_direction_name[s]->output_unit = 
special_unit;
+              self->special_units_direction_name[s]->direction
+                = special_unit_info (self, SUI_type_direction,
+                                           special_unit_variety);
+              s++;
+            }
+        }
+    }
+}
+
 static void
 set_file_source_info (FILE_SOURCE_INFO *file_source_info,
                           char *file_info_type, char *file_info_name,
@@ -2019,6 +2048,12 @@ html_set_pages_files (CONVERTER *self, OUTPUT_UNIT_LIST 
*output_units,
                      destination_directory);
     }
 
+  /*
+   to be able to associate to the output unit file the associated
+   output units will be output into, this is done after document output
+   units got files.
+   In practice only used for contents and shortcontents.
+   */
   if (associated_special_units && associated_special_units->number > 0)
     {
       int i;
diff --git a/tp/Texinfo/XS/convert/convert_html.h 
b/tp/Texinfo/XS/convert/convert_html.h
index ef14192b02..dd6c0acf99 100644
--- a/tp/Texinfo/XS/convert/convert_html.h
+++ b/tp/Texinfo/XS/convert/convert_html.h
@@ -4,20 +4,6 @@
 
 #include "utils.h"
 
-typedef struct FILE_SOURCE_INFO {
-    char *filename;
-    char *type;
-    char *name;
-    ELEMENT *element;
-    char *path;
-} FILE_SOURCE_INFO;
-
-typedef struct FILE_SOURCE_INFO_LIST {
-    size_t number;
-    size_t space;
-    FILE_SOURCE_INFO *list;
-} FILE_SOURCE_INFO_LIST;
-
 void html_initialize_output_state (CONVERTER *self);
 
 void html_prepare_conversion_units (CONVERTER *self,
diff --git a/tp/Texinfo/XS/main/build_perl_info.c 
b/tp/Texinfo/XS/main/build_perl_info.c
index 9b8ff81947..d0d52e925e 100644
--- a/tp/Texinfo/XS/main/build_perl_info.c
+++ b/tp/Texinfo/XS/main/build_perl_info.c
@@ -1177,6 +1177,7 @@ build_document (size_t document_descriptor, int no_store)
 static int
 output_unit_to_perl_hash (OUTPUT_UNIT *output_unit)
 {
+  int i;
   SV *sv;
   int status = 0;
   HV *directions_hv;
@@ -1184,9 +1185,12 @@ output_unit_to_perl_hash (OUTPUT_UNIT *output_unit)
   dTHX;
 
   /* output_unit->hv may already exist because of directions or if there was a
-     first_in_page referring to output_unit */
+     first_in_page referring to output_unit, or because the output units
+     list is being rebuilt */
   if (!output_unit->hv)
     output_unit->hv = newHV ();
+  else
+    hv_clear (output_unit->hv);
 
 #define STORE(key) hv_store (output_unit->hv, key, strlen (key), sv, 0)
   sv = newSVpv (output_unit_type_names[output_unit->unit_type], 0);
@@ -1197,6 +1201,30 @@ output_unit_to_perl_hash (OUTPUT_UNIT *output_unit)
   sv = newRV_noinc ((SV *) directions_hv);
   STORE("directions");
 
+  for (i = 0; i < RUD_type_FirstInFileNodeUp+1; i++)
+    {
+      if (output_unit->directions[i])
+        {
+          char *direction_name = relative_unit_direction_name[i];
+          OUTPUT_UNIT *direction_unit = output_unit->directions[i];
+          SV *unit_sv;
+          /* should ony happen for reference to external nodes that have
+             not yet been processed */
+          if (!direction_unit->hv)
+            {
+              int direction_status;
+              if (direction_unit->unit_type != OU_external_node_unit)
+                fprintf (stderr, "BUG: not external node but no perl ref %s\n",
+                                 output_unit_texi (direction_unit));
+              direction_status = output_unit_to_perl_hash (direction_unit);
+              status += direction_status;
+            }
+          unit_sv = newRV_inc ((SV *) direction_unit->hv);
+          hv_store (directions_hv, direction_name, strlen (direction_name),
+                    unit_sv, 0);
+        }
+    }
+
   if (output_unit->unit_command)
     {
       ELEMENT *command = output_unit->unit_command;
@@ -1316,34 +1344,48 @@ output_unit_to_perl_hash (OUTPUT_UNIT *output_unit)
   return status;
 }
 
-SV *
-build_output_units_list (size_t output_units_descriptor)
+static int
+fill_output_units (AV *av_output_units, OUTPUT_UNIT_LIST *output_units)
 {
   SV *sv;
-  AV *av_output_units;
   int i;
-  OUTPUT_UNIT_LIST *output_units
-    = retrieve_output_units (output_units_descriptor);
 
   dTHX;
 
-  if (!output_units || !output_units->number)
-    return newSV(0);
-
-  av_output_units = newAV ();
-
   for (i = 0; i < output_units->number; i++)
     {
       OUTPUT_UNIT *output_unit = output_units->list[i];
       int status = output_unit_to_perl_hash (output_unit);
       if (status)
-        return newSV(0);
+        return 0;
       /* we do not transfer the hv ref to the perl av because we consider
          that output_unit->hv still own a reference, which should only be
          released when the output_unit is destroyed in C */
       sv = newRV_inc ((SV *) output_unit->hv);
       av_push (av_output_units, sv);
     }
+  return 1;
+}
+
+SV *
+build_output_units_list (size_t output_units_descriptor)
+{
+  int status;
+  AV *av_output_units;
+  OUTPUT_UNIT_LIST *output_units
+    = retrieve_output_units (output_units_descriptor);
+
+  dTHX;
+
+  if (!output_units || !output_units->number)
+    return newSV(0);
+
+  av_output_units = newAV ();
+
+  status = fill_output_units (av_output_units, output_units);
+
+  if (!status)
+    return newSV(0);
 
   /* store in the first perl output unit of the list */
   hv_store (output_units->list[0]->hv, "output_units_descriptor",
@@ -1504,3 +1546,204 @@ pass_converter_errors (ERROR_MESSAGE_LIST 
*error_messages,
 
   wipe_error_message_list (error_messages);
 }
+
+void
+rebuild_output_units_list (SV *output_units_sv, size_t output_units_descriptor)
+{
+  AV *av_output_units;
+  int status;
+
+  OUTPUT_UNIT_LIST *output_units
+    = retrieve_output_units (output_units_descriptor);
+
+  dTHX;
+
+  if (! SvOK (output_units_sv))
+    {
+      if (output_units && output_units->number)
+        fprintf (stderr, "BUG: no input sv for %zu output units (%zu)",
+                 output_units->number, output_units_descriptor);
+      return;
+    }
+
+  av_output_units = (AV *) SvRV (output_units_sv);
+  av_clear (av_output_units);
+
+  /* TODO cannot associate output_units_descriptor. A problem? */
+  if (!output_units || !output_units->number)
+    return;
+
+  status = fill_output_units (av_output_units, output_units);
+
+  /* warn? */
+  if (!status)
+    return;
+
+  /* store in the first perl output unit of the list */
+  hv_store (output_units->list[0]->hv, "output_units_descriptor",
+            strlen ("output_units_descriptor"),
+            newSViv (output_units_descriptor), 0);
+}
+
+SV *
+build_html_files_source_info (FILE_SOURCE_INFO_LIST *files_source_info)
+{
+  int i;
+  HV *hv;
+
+  dTHX;
+
+  hv = newHV ();
+
+  if (files_source_info)
+    {
+#define STORE(key, sv) hv_store (file_source_info_hv, key, strlen (key), sv, 0)
+      for (i = 0; i < files_source_info->number; i++)
+        {
+          FILE_SOURCE_INFO * file_source_info = &files_source_info->list[i];
+          HV *file_source_info_hv;
+          SV *file_source_info_sv;
+          char *filename = file_source_info->filename;
+
+          file_source_info_hv = newHV ();
+          file_source_info_sv = newRV_noinc ((SV *) file_source_info_hv);
+
+          hv_store (hv, filename, strlen (filename), file_source_info_sv, 0);
+
+          STORE("file_info_type", newSVpv_utf8 (file_source_info->type, 0));
+          if (file_source_info->name)
+            STORE("file_info_name", newSVpv_utf8 (file_source_info->name, 0));
+          if (file_source_info->path)
+            /* FIXME check encoding */
+            STORE("file_info_path", newSVpv (file_source_info->path,
+                                             strlen (file_source_info->path)));
+          else
+            STORE("file_info_path", newSV(0));
+
+          if (file_source_info->element)
+            {
+              SV *element_sv = newRV_inc ((SV *) 
file_source_info->element->hv);
+              STORE("file_info_element", element_sv);
+            }
+        }
+#undef STORE
+    }
+  return newRV_noinc ((SV *) hv);
+}
+
+SV *
+build_html_global_units_directions (OUTPUT_UNIT **global_units_directions,
+                       SPECIAL_UNIT_DIRECTION **special_units_direction_name)
+{
+  int i;
+  SPECIAL_UNIT_DIRECTION **s;
+  SPECIAL_UNIT_DIRECTION *special_unit_direction;
+  HV *hv;
+
+  dTHX;
+
+  if (!global_units_directions)
+    return newSV(0);
+
+  hv = newHV ();
+
+  for (i = 0; i < D_Last+1; i++)
+    {
+      if (global_units_directions[i])
+        {
+          char *direction_name = html_global_unit_direction_names[i];
+          hv_store (hv, direction_name, strlen (direction_name),
+                    newRV_inc ((SV *) global_units_directions[i]->hv), 0);
+        }
+    }
+
+  for (s = special_units_direction_name; (special_unit_direction = *s) ; s++)
+    {
+      char *direction_name = special_unit_direction->direction;
+      OUTPUT_UNIT *output_unit = special_unit_direction->output_unit;
+      hv_store (hv, direction_name, strlen (direction_name),
+                  newRV_inc ((SV *) output_unit->hv), 0);
+    }
+
+  return newRV_noinc ((SV *) hv);
+}
+
+SV *
+build_file_counters (FILE_NAME_PATH_COUNTER_LIST *output_unit_files)
+{
+  int i;
+  HV *hv;
+
+  dTHX;
+
+  hv = newHV ();
+
+  if (output_unit_files)
+    {
+      for (i = 0; i < output_unit_files->number; i++)
+        {
+          FILE_NAME_PATH_COUNTER *output_unit_file
+            = &output_unit_files->list[i];
+          char *filename = output_unit_file->filename;
+
+          hv_store (hv, filename, strlen (filename),
+                    newSViv (output_unit_file->counter), 0);
+        }
+    }
+
+  return newRV_noinc ((SV *) hv);
+}
+
+SV *
+build_out_filepaths (FILE_NAME_PATH_COUNTER_LIST *output_unit_files)
+{
+  int i;
+  HV *hv;
+
+  dTHX;
+
+  hv = newHV ();
+
+  if (output_unit_files)
+    {
+      for (i = 0; i < output_unit_files->number; i++)
+        {
+          FILE_NAME_PATH_COUNTER *output_unit_file
+            = &output_unit_files->list[i];
+          char *filename = output_unit_file->filename;
+
+          hv_store (hv, filename, strlen (filename),
+                    newSVpv (output_unit_file->filepath,
+                             strlen (output_unit_file->filepath)), 0);
+        }
+    }
+
+  return newRV_noinc ((SV *) hv);
+}
+
+SV *
+build_html_elements_in_file_count (
+                 FILE_NAME_PATH_COUNTER_LIST *output_unit_files)
+{
+  int i;
+  HV *hv;
+
+  dTHX;
+
+  hv = newHV ();
+
+  if (output_unit_files)
+    {
+      for (i = 0; i < output_unit_files->number; i++)
+        {
+          FILE_NAME_PATH_COUNTER *output_unit_file
+            = &output_unit_files->list[i];
+          char *filename = output_unit_file->filename;
+
+          hv_store (hv, filename, strlen (filename),
+                    newSViv (output_unit_file->elements_in_file_count), 0);
+        }
+    }
+
+  return newRV_noinc ((SV *) hv);
+}
diff --git a/tp/Texinfo/XS/main/build_perl_info.h 
b/tp/Texinfo/XS/main/build_perl_info.h
index 1bd363129d..a7dba3f28a 100644
--- a/tp/Texinfo/XS/main/build_perl_info.h
+++ b/tp/Texinfo/XS/main/build_perl_info.h
@@ -25,6 +25,8 @@ HV *build_global_info (GLOBAL_INFO *global_info_ref);
 HV *build_global_commands (GLOBAL_COMMANDS *global_commands_ref);
 
 SV *build_output_units_list (size_t output_units_descriptor);
+void rebuild_output_units_list (SV *output_units_sv,
+                                size_t output_units_descriptor);
 
 SV *build_html_element_targets (HTML_TARGET_LIST *html_targets);
 SV *build_html_special_targets (HTML_TARGET_LIST **html_special_targets);
@@ -32,4 +34,12 @@ SV *build_html_seen_ids (STRING_LIST *seen_ids);
 
 void pass_converter_errors (ERROR_MESSAGE_LIST *error_messages,
                             HV *converter_hv);
+
+SV *build_html_files_source_info (FILE_SOURCE_INFO_LIST *files_source_info);
+SV *build_html_global_units_directions (OUTPUT_UNIT **global_units_directions,
+                       SPECIAL_UNIT_DIRECTION **special_units_direction_name);
+SV *build_file_counters (FILE_NAME_PATH_COUNTER_LIST *output_unit_files);
+SV *build_html_elements_in_file_count (
+                   FILE_NAME_PATH_COUNTER_LIST *output_unit_files);
+SV *build_out_filepaths (FILE_NAME_PATH_COUNTER_LIST *output_unit_files);
 #endif
diff --git a/tp/Texinfo/XS/main/utils.c b/tp/Texinfo/XS/main/utils.c
index 402ad94e55..9f2992ac17 100644
--- a/tp/Texinfo/XS/main/utils.c
+++ b/tp/Texinfo/XS/main/utils.c
@@ -61,6 +61,12 @@ const char *output_unit_type_names[] = {"unit",
                                         "external_node_unit",
                                         "special_unit"};
 
+char *html_global_unit_direction_names[] = {
+  #define hgdt_name(name) #name,
+   HTML_GLOBAL_DIRECTIONS_LIST
+  #undef hgdt_name
+};
+
 char *html_conversion_context_type_names[] = {
   #define cctx_type(name) #name,
     HCC_CONTEXT_TYPES_LIST
diff --git a/tp/Texinfo/XS/main/utils.h b/tp/Texinfo/XS/main/utils.h
index 106afcbedb..6a83a72a83 100644
--- a/tp/Texinfo/XS/main/utils.h
+++ b/tp/Texinfo/XS/main/utils.h
@@ -39,6 +39,7 @@ extern const char *output_unit_type_names[];
 extern const char *command_location_names[];
 
 extern char *html_conversion_context_type_names[];
+extern char *html_global_unit_direction_names[];
 
 enum error_type { MSG_error, MSG_warning,
                   MSG_document_error, MSG_document_warning };
@@ -121,18 +122,27 @@ typedef struct COMMAND_OPTION_VALUE {
 } COMMAND_OPTION_VALUE;
 
 /* CONVERTER and associated types needed for set_global_document_command */
-/* see Texinfo::HTML _prepare_output_units_global_targets */
+/* see Texinfo::HTML _prepare_output_units_global_targets
+
+   NOTE the special output units names are not actually used, the
+   special output units direction names are obtained from the perl input
+   and stored in special_unit_info and put later on in
+   special_units_direction_name
+ */
+#define HTML_GLOBAL_DIRECTIONS_LIST \
+   hgdt_name(First) \
+   hgdt_name(Top) \
+   hgdt_name(Index) \
+   hgdt_name(Last) \
+   hgdt_name(About) \
+   hgdt_name(Contents) \
+   hgdt_name(Overview) \
+   hgdt_name(Footnotes)
+
 enum global_unit_direction {
-   /* global directions */
-   D_First,
-   D_Top,
-   D_Index,
-   D_Last,
-   /* special elements */
-   D_About,
-   D_Contents,
-   D_Overview,
-   D_Footnotes,
+  #define hgdt_name(name) D_ ## name,
+   HTML_GLOBAL_DIRECTIONS_LIST
+  #undef hgdt_name
 };
 
 #define SUI_TYPES_LIST \
@@ -283,6 +293,11 @@ typedef struct FILE_NAME_PATH_COUNTER_LIST {
     FILE_NAME_PATH_COUNTER *list;
 } FILE_NAME_PATH_COUNTER_LIST;
 
+typedef struct SPECIAL_UNIT_DIRECTION {
+    OUTPUT_UNIT *output_unit;
+    char *direction;
+} SPECIAL_UNIT_DIRECTION;
+
 typedef struct CONVERTER {
     int converter_descriptor;
     OPTIONS *conf;
@@ -304,6 +319,7 @@ typedef struct CONVERTER {
 
   /* HTML specific */
     OUTPUT_UNIT **global_units_directions;
+    SPECIAL_UNIT_DIRECTION **special_units_direction_name;
     char **special_unit_info[SUI_type_heading+1];
     ELEMENT **special_unit_info_tree[SUIT_type_heading+1];
     STRING_LIST *special_unit_varieties;
@@ -328,6 +344,20 @@ typedef struct TARGET_CONTENTS_FILENAME {
     char *target_shortcontents;
 } TARGET_CONTENTS_FILENAME;
 
+typedef struct FILE_SOURCE_INFO {
+    char *filename;
+    char *type;
+    char *name;
+    ELEMENT *element;
+    char *path;
+} FILE_SOURCE_INFO;
+
+typedef struct FILE_SOURCE_INFO_LIST {
+    size_t number;
+    size_t space;
+    FILE_SOURCE_INFO *list;
+} FILE_SOURCE_INFO_LIST;
+
 /* used in get_perl_info and indices_in_conversion, in unfinished code */
 /* TODO remove? */
 typedef struct KEY_ALPHA {



reply via email to

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