texinfo-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[no subject]


From: Patrice Dumas
Date: Wed, 2 Oct 2024 11:47:12 -0400 (EDT)

branch: master
commit d173df416de4e8a8c3e1c227e43cc324b0d8acdc
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Sat Aug 3 00:15:51 2024 +0200

    * tp/Texinfo/XS/main/build_perl_info.c (get_sv_conf): rename get_conf
    as get_sv_conf.  Update callers.
    
    * tp/Texinfo/XS/main/build_perl_info.c (build_translated_commands):
    add.
    
    * tp/Texinfo/XS/convert/converter.h (default_special_unit_varieties),
    tp/Texinfo/XS/convert/convert_html.h: move
    default_special_unit_varieties declaration to converter.h.
    
    * tp/Texinfo/XS/convert/converter.c (destroy_translated_commands),
    tp/Texinfo/XS/main/convert_utils.c: move destroy_translated_commands
    to converter.c.
    
    * tp/maintain/regenerate_C_options_info.pl: generate C functions to
    set converter generic options.
    
    * tp/Texinfo/Convert/Converter.pm (set_conf),
    tp/Texinfo/XS/convert/ConvertXS.xs (set_conf, force_conf),
    tp/Texinfo/XS/main/get_perl_info.c (set_sv_conf),
    tp/maintain/regenerate_C_options_info.pl: add return values to the
    get_sv_option generate function to determine if setting a
    customization variable failed and why.  Add a status return value to
    set_sv_conf and to the set_conf and force_conf XS overrides.  Take
    into account _XS_set_conf return value to determine if the
    customization option was set.
    
    * tp/Texinfo/XS/main/api_to_perl.c (get_refcount): add an unused
    function, for debugging.
    
    * tp/Texinfo/XS/main/get_perl_info.c (get_sv_options): call
    get_sv_option even for options with undef values.
    
    * tp/Texinfo/XS/main/get_perl_info.c (set_translated_commands): free
    previous translated_commands before getting new ones.
    
    * tp/Texinfo/XS/main/api_to_perl.c (unregister_perl_buttons_list)
    (register_perl_buttons_list, unregister_perl_direction_icons),
    tp/Texinfo/XS/main/get_perl_info.c
    (html_fill_button_specification_list)
    (html_get_button_specification_list, html_fill_direction_icons)
    (html_get_direction_icons_sv), tp/Texinfo/XS/main/utils.c
    (html_free_button_specification_list, html_free_direction_icons)
    (copy_option), tp/maintain/regenerate_C_options_info.pl: add icons SV
    to the direction icons lists.  Add html_fill_button_specification_list
    and html_fill_direction_icons to fill the directions information in
    buttons or icons based on the Perl references.  Own all the Perl
    objects in C by increasing refcount when registering and decreasing
    refcount when destroying the object they are registered into.
    Generate html_fill_options function in regenerate_C_options_info.pl
    that calls html_fill_button_specification_list and
    html_fill_direction_icons for all the relevant options.
    
    * tp/Texinfo/XS/main/get_perl_info.c (converter_initialize_sv): rename
    converter_initialize as converter_initialize_sv.
    
    * tp/Texinfo/Convert/Converter.pm (_internal_converter_initialize)
    (converter), tp/Texinfo/XS/main/build_perl_info.c
    (pass_generic_converter_to_converter_sv),
    tp/Texinfo/XS/convert/ConvertXS.xs (converter_initialize)
    (html_converter_initialize_sv), tp/Texinfo/XS/convert/converter.c
    (init_generic_converter, new_converter),
    tp/Texinfo/XS/main/build_perl_info.c
    (pass_generic_converter_to_converter_sv),
    tp/Texinfo/XS/main/get_perl_info.c (converter_initialize_sv):
    initialize default generic data and customizations options of generic
    converter in C, in the new init_generic_converter function.  Setup
    explicitely %format_defaults in Perl converter and pass to XS,
    together with the customization options hash.  Move converter() Perl
    code now initialized in C to _internal_converter_initialize.  Add
    pass_generic_converter_to_converter_sv to pass information from C to
    the Perl converter, based on ConvertXS.xs converter_initialize code,
    expanded to pass translated_commands and initialize output_files.
    Setup Perl customization variables, translated_commands and
    output_format in XS/C in converter_initialize_sv.  Do not set C
    customization data based on Perl data anymore.  Call html_fill_options
    in html_converter_initialize_sv.
    
    * tp/Texinfo/XS/main/converter_types.h (CONVERTER),
    tp/Texinfo/XS/convert/converter.c (free_generic_converter),
    tp/Texinfo/XS/main/get_perl_info.c (converter_initialize_sv): add
    converted_format field to converter and set it.
---
 ChangeLog                                       |  85 +++++++
 tp/Texinfo/Convert/Converter.pm                 |  68 +++---
 tp/Texinfo/XS/convert/ConvertXS.xs              |  46 ++--
 tp/Texinfo/XS/convert/convert_html.h            |   3 -
 tp/Texinfo/XS/convert/converter.c               |  55 +++++
 tp/Texinfo/XS/convert/converter.h               |   4 +
 tp/Texinfo/XS/convert/converters_defaults.c     | 282 ++++++++++++++++++++++++
 tp/Texinfo/XS/convert/converters_defaults.h     |  16 ++
 tp/Texinfo/XS/convert/get_converter_perl_info.c |   3 +
 tp/Texinfo/XS/convert/get_converter_perl_info.h |   3 +-
 tp/Texinfo/XS/main/api_to_perl.c                |  40 +++-
 tp/Texinfo/XS/main/api_to_perl.h                |   5 +
 tp/Texinfo/XS/main/build_perl_info.c            |  72 +++++-
 tp/Texinfo/XS/main/build_perl_info.h            |   6 +-
 tp/Texinfo/XS/main/convert_utils.c              |  12 -
 tp/Texinfo/XS/main/convert_utils.h              |   1 -
 tp/Texinfo/XS/main/converter_types.h            |   1 +
 tp/Texinfo/XS/main/get_perl_info.c              | 272 ++++++++++++++++++++---
 tp/Texinfo/XS/main/get_perl_info.h              |  23 +-
 tp/Texinfo/XS/main/option_types.h               |   3 +
 tp/Texinfo/XS/main/utils.c                      |  13 +-
 tp/maintain/regenerate_C_options_info.pl        |  46 +++-
 22 files changed, 940 insertions(+), 119 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 91ade40d19..292e87a9b9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,90 @@
 2024-10-02  Patrice Dumas  <pertusus@free.fr>
 
+       * tp/Texinfo/XS/main/build_perl_info.c (get_sv_conf): rename get_conf
+       as get_sv_conf.  Update callers.
+
+       * tp/Texinfo/XS/main/build_perl_info.c (build_translated_commands):
+       add.
+
+       * tp/Texinfo/XS/convert/converter.h (default_special_unit_varieties),
+       tp/Texinfo/XS/convert/convert_html.h: move
+       default_special_unit_varieties declaration to converter.h.
+
+       * tp/Texinfo/XS/convert/converter.c (destroy_translated_commands),
+       tp/Texinfo/XS/main/convert_utils.c: move destroy_translated_commands
+       to converter.c.
+
+       * tp/maintain/regenerate_C_options_info.pl: generate C functions to
+       set converter generic options.
+
+       * tp/Texinfo/Convert/Converter.pm (set_conf),
+       tp/Texinfo/XS/convert/ConvertXS.xs (set_conf, force_conf),
+       tp/Texinfo/XS/main/get_perl_info.c (set_sv_conf),
+       tp/maintain/regenerate_C_options_info.pl: add return values to the
+       get_sv_option generate function to determine if setting a
+       customization variable failed and why.  Add a status return value to
+       set_sv_conf and to the set_conf and force_conf XS overrides.  Take
+       into account _XS_set_conf return value to determine if the
+       customization option was set.
+
+       * tp/Texinfo/XS/main/api_to_perl.c (get_refcount): add an unused
+       function, for debugging.
+
+       * tp/Texinfo/XS/main/get_perl_info.c (get_sv_options): call
+       get_sv_option even for options with undef values.
+
+       * tp/Texinfo/XS/main/get_perl_info.c (set_translated_commands): free
+       previous translated_commands before getting new ones.
+
+       * tp/Texinfo/XS/main/api_to_perl.c (unregister_perl_buttons_list)
+       (register_perl_buttons_list, unregister_perl_direction_icons),
+       tp/Texinfo/XS/main/get_perl_info.c
+       (html_fill_button_specification_list)
+       (html_get_button_specification_list, html_fill_direction_icons)
+       (html_get_direction_icons_sv), tp/Texinfo/XS/main/utils.c
+       (html_free_button_specification_list, html_free_direction_icons)
+       (copy_option), tp/maintain/regenerate_C_options_info.pl: add icons SV
+       to the direction icons lists.  Add html_fill_button_specification_list
+       and html_fill_direction_icons to fill the directions information in
+       buttons or icons based on the Perl references.  Own all the Perl
+       objects in C by increasing refcount when registering and decreasing
+       refcount when destroying the object they are registered into.
+       Generate html_fill_options function in regenerate_C_options_info.pl
+       that calls html_fill_button_specification_list and
+       html_fill_direction_icons for all the relevant options.
+
+       * tp/Texinfo/XS/main/get_perl_info.c (converter_initialize_sv): rename
+       converter_initialize as converter_initialize_sv.
+
+       * tp/Texinfo/Convert/Converter.pm (_internal_converter_initialize)
+       (converter), tp/Texinfo/XS/main/build_perl_info.c
+       (pass_generic_converter_to_converter_sv),
+       tp/Texinfo/XS/convert/ConvertXS.xs (converter_initialize)
+       (html_converter_initialize_sv), tp/Texinfo/XS/convert/converter.c
+       (init_generic_converter, new_converter),
+       tp/Texinfo/XS/main/build_perl_info.c
+       (pass_generic_converter_to_converter_sv),
+       tp/Texinfo/XS/main/get_perl_info.c (converter_initialize_sv):
+       initialize default generic data and customizations options of generic
+       converter in C, in the new init_generic_converter function.  Setup
+       explicitely %format_defaults in Perl converter and pass to XS,
+       together with the customization options hash.  Move converter() Perl
+       code now initialized in C to _internal_converter_initialize.  Add
+       pass_generic_converter_to_converter_sv to pass information from C to
+       the Perl converter, based on ConvertXS.xs converter_initialize code,
+       expanded to pass translated_commands and initialize output_files.
+       Setup Perl customization variables, translated_commands and
+       output_format in XS/C in converter_initialize_sv.  Do not set C
+       customization data based on Perl data anymore.  Call html_fill_options
+       in html_converter_initialize_sv.
+
+       * tp/Texinfo/XS/main/converter_types.h (CONVERTER),
+       tp/Texinfo/XS/convert/converter.c (free_generic_converter),
+       tp/Texinfo/XS/main/get_perl_info.c (converter_initialize_sv): add
+       converted_format field to converter and set it.
+
+2024-08-02  Patrice Dumas  <pertusus@free.fr>
+
        * tp/Texinfo/Convert/HTML.pm (html_attribute_class, _convert_text),
        tp/Texinfo/Convert/Plaintext.pm (new_formatter): always access
        configuration through get_conf() in case it is in C data only.
diff --git a/tp/Texinfo/Convert/Converter.pm b/tp/Texinfo/Convert/Converter.pm
index abe74f3d16..81faaee5c4 100644
--- a/tp/Texinfo/Convert/Converter.pm
+++ b/tp/Texinfo/Convert/Converter.pm
@@ -265,36 +265,19 @@ sub set_document($$)
 }
 
 # initialization either in generic XS converter or in Perl
-sub _internal_converter_initialize($)
+sub _internal_converter_initialize($$$;$)
 {
   my $converter = shift;
-
-  # turn the array to a hash.
-  my $expanded_formats = $converter->{'conf'}->{'EXPANDED_FORMATS'};
-  $converter->{'expanded_formats'} = {};
-  if (defined($expanded_formats)) {
-    foreach my $expanded_format (@$expanded_formats) {
-      $converter->{'expanded_formats'}->{$expanded_format} = 1;
-    }
-  }
-
-  $converter->{'error_warning_messages'} = [];
-}
-
-# this function is designed so as to be used in specific Converters
-sub converter($;$)
-{
   my $class = shift;
+  my $format_defaults = shift;
   my $conf = shift;
 
-  my $converter = { 'configured' => {} };
+  my %defaults = %all_converters_defaults;
 
-  bless $converter, $class;
-
-  my %defaults = $converter->converter_defaults($conf);
-  foreach my $key (keys(%all_converters_defaults)) {
-    $defaults{$key} = $all_converters_defaults{$key}
-                          if (!exists($defaults{$key}));
+  if ($format_defaults) {
+    foreach my $key (keys(%$format_defaults)) {
+      $defaults{$key} = $format_defaults->{$key};
+    }
   }
   $converter->{'conf'} = {};
   foreach my $key (keys(%defaults)) {
@@ -304,6 +287,8 @@ sub converter($;$)
       $converter->{$key} = $defaults{$key};
     }
   }
+
+  $converter->{'configured'} = {};
   if (defined($conf)) {
     foreach my $key (keys(%$conf)) {
       if (Texinfo::Common::valid_customization_option($key)) {
@@ -328,6 +313,30 @@ sub converter($;$)
   # and not closed files.  Accessed through output_files_information()
   $converter->{'output_files'} = 
Texinfo::Convert::Utils::output_files_initialize();
 
+  # turn the array to a hash.
+  my $expanded_formats = $converter->{'conf'}->{'EXPANDED_FORMATS'};
+  $converter->{'expanded_formats'} = {};
+  if (defined($expanded_formats)) {
+    foreach my $expanded_format (@$expanded_formats) {
+      $converter->{'expanded_formats'}->{$expanded_format} = 1;
+    }
+  }
+
+  $converter->{'error_warning_messages'} = [];
+}
+
+# this function is designed so as to be used in specific Converters
+sub converter($;$)
+{
+  my $class = shift;
+  my $conf = shift;
+
+  my $converter = {};
+
+  bless $converter, $class;
+
+  my %format_defaults = $converter->converter_defaults($conf);
+
   # if with XS, XS converter initialization.
   # NOTE get_conf should not be used before that point, such that the conf is
   # initialized before it is called for the first time.
@@ -335,7 +344,7 @@ sub converter($;$)
   # some options may not be obtained.  This is the case for HTML for instance.
   # In particular the special units information need to be known before buttons
   # information can be passed to C.
-  _internal_converter_initialize($converter);
+  _internal_converter_initialize($converter, $class, \%format_defaults, $conf);
 
   $converter->converter_initialize();
 
@@ -589,11 +598,14 @@ sub set_conf($$$)
   if ($self->{'configured'}->{$conf}) {
     return 0;
   } else {
+    my $set = 1;
     if ($self->{'converter_descriptor'} and $XS_convert) {
-      _XS_set_conf($self, $conf, $value);
+      $set = _XS_set_conf($self, $conf, $value);
+    }
+    if ($set) {
+      $self->{'conf'}->{$conf} = $value;
     }
-    $self->{'conf'}->{$conf} = $value;
-    return 1;
+    return $set;
   }
 }
 
diff --git a/tp/Texinfo/XS/convert/ConvertXS.xs 
b/tp/Texinfo/XS/convert/ConvertXS.xs
index aadfed4e89..8173a03b4b 100644
--- a/tp/Texinfo/XS/convert/ConvertXS.xs
+++ b/tp/Texinfo/XS/convert/ConvertXS.xs
@@ -91,21 +91,17 @@ init (int texinfo_uninstalled, SV *pkgdatadir_sv, SV 
*tp_builddir_sv, SV *top_sr
         RETVAL
 
 void
-converter_initialize (SV *converter_in)
+converter_initialize (SV *converter_in, const char *class, SV 
*format_defaults, SV *conf=0)
       PREINIT:
          size_t converter_descriptor;
-         const CONVERTER *self;
-         HV *converter_hv;
-         HV *expanded_formats_hv;
+         CONVERTER *self;
       CODE:
-         converter_descriptor = converter_initialize (converter_in);
+         converter_descriptor = new_converter ();
          self = retrieve_converter (converter_descriptor);
-         converter_hv = (HV *)SvRV (converter_in);
-         expanded_formats_hv
-           = build_expanded_formats (self->expanded_formats);
-         hv_store (converter_hv, "expanded_formats",
-                   strlen ("expanded_formats"),
-                   newRV_inc ((SV *) expanded_formats_hv), 0);
+
+         converter_initialize_sv (converter_in, self, format_defaults, conf);
+
+         pass_generic_converter_to_converter_sv (converter_in, self);
 
 void
 converter_set_document (SV *converter_in, SV *document_in)
@@ -117,18 +113,22 @@ converter_set_document (SV *converter_in, SV *document_in)
         self = converter_set_document_from_sv (converter_in, document_in);
         pass_document_to_converter_sv (self, converter_in, document_in);
 
-void
+int
 set_conf (SV *converter_in, conf, SV *value)
          const char *conf = (char *)SvPVbyte_nolen($arg);
       PREINIT:
          CONVERTER *self;
+         int status = 0;
       CODE:
          /* Calling code checks 'converter_descriptor' is set */
          self = get_sv_converter (converter_in, 0);
          if (self)
-           set_sv_conf (self, conf, value);
+           status = set_sv_conf (self, conf, value);
+         RETVAL = status;
+    OUTPUT:
+         RETVAL
 
-void
+int
 force_conf (SV *converter_in, conf, SV *value)
          const char *conf = (char *)SvPVbyte_nolen($arg);
       PREINIT:
@@ -138,6 +138,9 @@ force_conf (SV *converter_in, conf, SV *value)
          self = get_sv_converter (converter_in, 0);
          if (self)
            force_sv_conf (self, conf, value);
+         RETVAL = 1;
+    OUTPUT:
+         RETVAL
 
 SV *
 get_conf (SV *converter_in, conf)
@@ -147,7 +150,7 @@ get_conf (SV *converter_in, conf)
       CODE:
          self = get_sv_converter (converter_in, 0);
          if (self)
-           RETVAL = get_conf (self, conf);
+           RETVAL = get_sv_conf (self, conf);
          else
            RETVAL = newSV (0);
     OUTPUT:
@@ -582,12 +585,9 @@ void
 html_converter_initialize_sv (SV *converter_in, SV 
*default_formatting_references, SV *default_css_string_formatting_references, 
SV *default_commands_open, SV *default_commands_conversion, SV 
*default_css_string_commands_conversion, SV *default_types_open, SV 
*default_types_conversion, SV *default_css_string_types_conversion, SV 
*default_output_units_conversion, SV *default_special_unit_body, SV 
*customized_upper_case_commands, SV *customized_type_formatting, SV 
*customized_accent_entiti [...]
       PREINIT:
         CONVERTER *self;
-        HV *converter_hv;
       CODE:
         self = get_sv_converter (converter_in, "html_converter_initialize_sv");
 
-        converter_hv = (HV *)SvRV (converter_in);
-
         /* initialize first the special unit info, as the special unit
            directions are needed for the remainder of initialization.
            Therefore special unit Perl customization needs to be read
@@ -616,12 +616,10 @@ html_converter_initialize_sv (SV *converter_in, SV 
*default_formatting_reference
 
         html_converter_initialize (self);
 
-   /* at that point, the format specific informations, in particular the number
-      of special elements is available, such that all the options can be
-      passed to C.  It is important to set the force argument to 1 to get
-      all the configuration, even if the configured field is set */
-        copy_converter_conf_sv (converter_hv, self,
-                                &self->conf, "conf", 1);
+   /* at that point, the format specific informations, in particular the
+      direction names is available, such that the directions can be set
+      in customization variables needing them (icons, buttons). */
+     html_fill_options (self->conf, self);
 
 
 void
diff --git a/tp/Texinfo/XS/convert/convert_html.h 
b/tp/Texinfo/XS/convert/convert_html.h
index 1f47086667..f7b796a125 100644
--- a/tp/Texinfo/XS/convert/convert_html.h
+++ b/tp/Texinfo/XS/convert/convert_html.h
@@ -19,9 +19,6 @@ enum css_info_type {
    CI_css_info_rules,
 };
 
-/* in main/conversion_data.c */
-extern const STRING_LIST default_special_unit_varieties;
-
 
 extern const char *html_conversion_context_type_names[];
 extern const char *html_global_unit_direction_names[];
diff --git a/tp/Texinfo/XS/convert/converter.c 
b/tp/Texinfo/XS/convert/converter.c
index 63e3d34409..c19c3718ad 100644
--- a/tp/Texinfo/XS/convert/converter.c
+++ b/tp/Texinfo/XS/convert/converter.c
@@ -30,12 +30,14 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#include "conversion_data.h"
 #include "text.h"
 #include "command_ids.h"
 #include "element_types.h"
 #include "tree_types.h"
 #include "option_types.h"
 #include "options_types.h"
+#include "converters_defaults.h"
 #include "tree.h"
 #include "extra.h"
 /* for COMMAND_OPTION_DEFAULT ACCENTS_STACK
@@ -102,6 +104,7 @@ PATHS_INFORMATION conversion_paths_info;
 
 const char *xml_text_entity_no_arg_commands_formatting[BUILTIN_CMD_NUMBER];
 
+/* called only once */
 void
 converter_setup (void)
 {
@@ -156,6 +159,42 @@ retrieve_converter (int converter_descriptor)
   return 0;
 }
 
+/* initialize the converter */
+static void
+init_generic_converter (CONVERTER *self)
+{
+  self->conf = new_options ();
+
+  set_converter_cmdline_regular_defaults (self->conf);
+  set_converter_customization_regular_defaults (self->conf);
+  set_unique_at_command_regular_defaults (self->conf);
+  set_multiple_at_command_regular_defaults (self->conf);
+  set_common_regular_options_defaults (self->conf);
+
+  self->init_conf = new_options ();
+
+  self->expanded_formats = new_expanded_formats ();
+
+  /* set 'translated_commands'  => {'error' => 'error@arrow{}',}, */
+
+  self->translated_commands = (TRANSLATED_COMMAND *)
+        malloc ((1 +1) * sizeof (TRANSLATED_COMMAND));
+  memset (self->translated_commands, 0,
+              (1 +1) * sizeof (TRANSLATED_COMMAND));
+
+  self->translated_commands[0].cmd = CM_error;
+  self->translated_commands[0].translation = strdup ("error@arrow{}");
+
+  /* NOTE if the special units can be customized, then
+     the self->special_unit_varieties should be set early (where?) and used
+     directly instead.
+     Also default special units and special units indices should be
+     mapped instead of assuming that they are the same when setting
+     self->special_unit_info
+  copy_strings (&self->special_unit_varieties, 
&default_special_unit_varieties);
+   */
+}
+
 /* descriptor starts at 1, 0 is not found or an error */
 size_t
 new_converter (void)
@@ -188,6 +227,8 @@ new_converter (void)
   registered_converter = (CONVERTER *) malloc (sizeof (CONVERTER));
   memset (registered_converter, 0, sizeof (CONVERTER));
 
+  init_generic_converter (registered_converter);
+
   converter_list[converter_index] = registered_converter;
   registered_converter->converter_descriptor = converter_index +1;
 
@@ -1449,6 +1490,19 @@ free_output_unit_files (FILE_NAME_PATH_COUNTER_LIST 
*output_unit_files)
 
 
 
+void
+destroy_translated_commands (TRANSLATED_COMMAND *translated_commands)
+{
+  TRANSLATED_COMMAND *translated_command;
+
+  for (translated_command = translated_commands;
+       translated_command->translation; translated_command++)
+    {
+      free (translated_command->translation);
+    }
+  free (translated_commands);
+}
+
 void
 free_generic_converter (CONVERTER *self)
 {
@@ -1458,6 +1512,7 @@ free_generic_converter (CONVERTER *self)
     }
 
   free (self->output_format);
+  free (self->converted_format);
   free (self->expanded_formats);
 
   if (self->init_conf)
diff --git a/tp/Texinfo/XS/convert/converter.h 
b/tp/Texinfo/XS/convert/converter.h
index ce24c33fa6..76d1b65928 100644
--- a/tp/Texinfo/XS/convert/converter.h
+++ b/tp/Texinfo/XS/convert/converter.h
@@ -95,6 +95,9 @@ extern enum command_id default_upper_case_commands[];
 /* in generated cmd_converter.c */
 extern const char * xml_text_entity_no_arg_commands[];
 
+/* in main/conversion_data.c */
+extern const STRING_LIST default_special_unit_varieties;
+
 /* in converter.c */
 extern const char *xml_text_entity_no_arg_commands_formatting[];
 
@@ -179,6 +182,7 @@ void set_file_path (CONVERTER *self, const char *filename, 
const char *filepath,
 void clear_output_unit_files (FILE_NAME_PATH_COUNTER_LIST *output_unit_files);
 void free_output_unit_files (FILE_NAME_PATH_COUNTER_LIST *output_unit_files);
 
+void destroy_translated_commands (TRANSLATED_COMMAND *translated_commands);
 void free_generic_converter (CONVERTER *self);
 
 void xml_format_text_with_numeric_entities (const char *text, TEXT *result);
diff --git a/tp/Texinfo/XS/convert/converters_defaults.c 
b/tp/Texinfo/XS/convert/converters_defaults.c
index 7a14071af2..491bf044e9 100644
--- a/tp/Texinfo/XS/convert/converters_defaults.c
+++ b/tp/Texinfo/XS/convert/converters_defaults.c
@@ -6,6 +6,288 @@
 #include "converter.h"
 #include "converters_defaults.h"
 
+
+/* array_cmdline */
+
+void set_array_cmdline_regular_defaults (OPTIONS *options)
+{
+  set_conf (&options->CSS_FILES, -2, 0);
+  set_conf (&options->CSS_REFS, -2, 0);
+  set_conf (&options->EXPANDED_FORMATS, -2, 0);
+  set_conf (&options->INCLUDE_DIRECTORIES, -2, 0);
+}
+
+
+/* converter_cmdline */
+
+void set_converter_cmdline_regular_defaults (OPTIONS *options)
+{
+  set_conf (&options->SPLIT_SIZE, 300000, 0);
+  set_conf (&options->FILLCOLUMN, 72, 0);
+  set_conf (&options->NUMBER_SECTIONS, 1, 0);
+  set_conf (&options->NUMBER_FOOTNOTES, 1, 0);
+  set_conf (&options->TRANSLITERATE_FILE_NAMES, 1, 0);
+  set_conf (&options->SPLIT, -2, 0);
+  set_conf (&options->HEADERS, 1, 0);
+  set_conf (&options->NODE_FILES, -1, 0);
+  set_conf (&options->VERBOSE, -1, 0);
+  set_conf (&options->OUTFILE, -2, 0);
+  set_conf (&options->SUBDIR, -2, 0);
+  set_conf (&options->ENABLE_ENCODING, 1, 0);
+}
+
+
+/* converter_customization */
+
+void set_converter_customization_regular_defaults (OPTIONS *options)
+{
+  set_conf (&options->TOP_NODE_UP, -2, "(dir)");
+  set_conf (&options->BASEFILENAME_LENGTH, 255-10, 0);
+  set_conf (&options->DOC_ENCODING_FOR_INPUT_FILE_NAME, 1, 0);
+  set_conf (&options->DOC_ENCODING_FOR_OUTPUT_FILE_NAME, 0, 0);
+  set_conf (&options->IMAGE_LINK_PREFIX, -2, 0);
+  set_conf (&options->CASE_INSENSITIVE_FILENAMES, 0, 0);
+  set_conf (&options->DEBUG, 0, 0);
+  set_conf (&options->HANDLER_FATAL_ERROR_LEVEL, 100, 0);
+  set_conf (&options->TEST, 0, 0);
+  set_conf (&options->TEXTCONTENT_COMMENT, -1, 0);
+  set_conf (&options->TEXINFO_DTD_VERSION, -2, "7.1");
+  set_conf (&options->USE_UNICODE_COLLATION, 1, 0);
+  set_conf (&options->AFTER_BODY_OPEN, -2, 0);
+  set_conf (&options->AFTER_SHORT_TOC_LINES, -2, 0);
+  set_conf (&options->AFTER_TOC_LINES, -2, 0);
+  set_conf (&options->ASCII_DASHES_AND_QUOTES, -1, 0);
+  set_conf (&options->ASCII_GLYPH, -1, 0);
+  set_conf (&options->ASCII_PUNCTUATION, -1, 0);
+  set_conf (&options->AUTO_MENU_DESCRIPTION_ALIGN_COLUMN, -1, 0);
+  set_conf (&options->AUTO_MENU_MAX_WIDTH, -1, 0);
+  set_conf (&options->BEFORE_SHORT_TOC_LINES, -2, 0);
+  set_conf (&options->BEFORE_TOC_LINES, -2, 0);
+  set_conf (&options->BIG_RULE, -2, 0);
+  set_conf (&options->BODY_ELEMENT_ATTRIBUTES, -2, 0);
+  set_conf (&options->CLASS_BEGIN_USEPACKAGE, -2, 0);
+  set_conf (&options->COPIABLE_LINKS, -1, 0);
+  set_conf (&options->CHAPTER_HEADER_LEVEL, -1, 0);
+  set_conf (&options->CHECK_HTMLXREF, -1, 0);
+  set_conf (&options->CLOSE_DOUBLE_QUOTE_SYMBOL, -2, 0);
+  set_conf (&options->CLOSE_QUOTE_SYMBOL, -2, 0);
+  set_conf (&options->COLLATION_LANGUAGE, -2, 0);
+  set_conf (&options->COMMAND_LINE_ENCODING, -2, 0);
+  set_conf (&options->INDENTED_BLOCK_COMMANDS_IN_TABLE, -1, 0);
+  set_conf (&options->CONTENTS_OUTPUT_LOCATION, -2, 0);
+  set_conf (&options->CONVERT_TO_LATEX_IN_MATH, -1, 0);
+  set_conf (&options->DATE_IN_HEADER, -1, 0);
+  set_conf (&options->DEFAULT_RULE, -2, 0);
+  set_conf (&options->DEF_TABLE, -1, 0);
+  set_conf (&options->DO_ABOUT, -1, 0);
+  set_conf (&options->DOCTYPE, -2, 0);
+  set_conf (&options->DOCUMENTLANGUAGE_COLLATION, -1, 0);
+  set_conf (&options->END_USEPACKAGE, -2, 0);
+  set_conf (&options->EPUB_CREATE_CONTAINER_FILE, -1, 0);
+  set_conf (&options->EPUB_KEEP_CONTAINER_FOLDER, -1, 0);
+  set_conf (&options->EXTENSION, -2, 0);
+  set_conf (&options->EXTERNAL_CROSSREF_EXTENSION, -2, 0);
+  set_conf (&options->EXTERNAL_CROSSREF_SPLIT, -2, 0);
+  set_conf (&options->EXTERNAL_DIR, -2, 0);
+  set_conf (&options->EXTRA_HEAD, -2, 0);
+  set_conf (&options->FOOTNOTE_END_HEADER_LEVEL, -1, 0);
+  set_conf (&options->FOOTNOTE_SEPARATE_HEADER_LEVEL, -1, 0);
+  set_conf (&options->HEADER_IN_TABLE, -1, 0);
+  set_conf (&options->HIGHLIGHT_SYNTAX, -2, 0);
+  set_conf (&options->HIGHLIGHT_SYNTAX_DEFAULT_LANGUAGE, -2, 0);
+  set_conf (&options->HTML_MATH, -2, 0);
+  set_conf (&options->HTML_ROOT_ELEMENT_ATTRIBUTES, -2, 0);
+  set_conf (&options->HTMLXREF_FILE, -2, 0);
+  set_conf (&options->HTMLXREF_MODE, -2, 0);
+  set_conf (&options->ICONS, -1, 0);
+  set_conf (&options->INDEX_ENTRY_COLON, -2, 0);
+  set_conf (&options->INDEX_SPECIAL_CHARS_WARNING, -1, 0);
+  set_conf (&options->INFO_JS_DIR, -2, 0);
+  set_conf (&options->INFO_SPECIAL_CHARS_QUOTE, -2, 0);
+  set_conf (&options->INFO_SPECIAL_CHARS_WARNING, -1, 0);
+  set_conf (&options->IGNORE_REF_TO_TOP_NODE_UP, -1, 0);
+  set_conf (&options->INLINE_CSS_STYLE, -1, 0);
+  set_conf (&options->INPUT_FILE_NAME_ENCODING, -2, 0);
+  set_conf (&options->JS_WEBLABELS, -2, 0);
+  set_conf (&options->JS_WEBLABELS_FILE, -2, 0);
+  set_conf (&options->LATEX_FLOATS_FILE_EXTENSION, -2, "tfl");
+  set_conf (&options->LOCALE_ENCODING, -2, 0);
+  set_conf (&options->L2H_CLEAN, -1, 0);
+  set_conf (&options->L2H_FILE, -2, 0);
+  set_conf (&options->L2H_HTML_VERSION, -2, 0);
+  set_conf (&options->L2H_L2H, -2, 0);
+  set_conf (&options->L2H_SKIP, -1, 0);
+  set_conf (&options->L2H_TMP, -2, 0);
+  set_conf (&options->MATHJAX_SCRIPT, -2, 0);
+  set_conf (&options->MATHJAX_SOURCE, -2, 0);
+  set_conf (&options->MAX_HEADER_LEVEL, -1, 0);
+  set_conf (&options->MENU_ENTRY_COLON, -2, 0);
+  set_conf (&options->MENU_SYMBOL, -2, 0);
+  set_conf (&options->MESSAGE_ENCODING, -2, 0);
+  set_conf (&options->MONOLITHIC, -1, 0);
+  set_conf (&options->NO_CSS, -1, 0);
+  set_conf (&options->NO_NUMBER_FOOTNOTE_SYMBOL, -2, 0);
+  set_conf (&options->NO_CUSTOM_HTML_ATTRIBUTE, -1, 0);
+  set_conf (&options->NODE_NAME_IN_INDEX, -1, 0);
+  set_conf (&options->NODE_NAME_IN_MENU, -1, 0);
+  set_conf (&options->NO_TOP_NODE_OUTPUT, -1, 0);
+  set_conf (&options->OPEN_DOUBLE_QUOTE_SYMBOL, -2, 0);
+  set_conf (&options->OPEN_QUOTE_SYMBOL, -2, 0);
+  set_conf (&options->OUTPUT_CHARACTERS, -1, 0);
+  set_conf (&options->OUTPUT_ENCODING_NAME, -2, 0);
+  set_conf (&options->OUTPUT_FILE_NAME_ENCODING, -2, 0);
+  set_conf (&options->OUTPUT_PERL_ENCODING, -2, 0);
+  set_conf (&options->PACKAGE, -2, 0);
+  set_conf (&options->PACKAGE_AND_VERSION, -2, 0);
+  set_conf (&options->PACKAGE_NAME, -2, 0);
+  set_conf (&options->PACKAGE_URL, -2, 0);
+  set_conf (&options->PACKAGE_VERSION, -2, 0);
+  set_conf (&options->PRE_BODY_CLOSE, -2, 0);
+  set_conf (&options->PREFIX, -2, 0);
+  set_conf (&options->PROGRAM, -2, 0);
+  set_conf (&options->PROGRAM_NAME_IN_ABOUT, -1, 0);
+  set_conf (&options->PROGRAM_NAME_IN_FOOTER, -1, 0);
+  set_conf (&options->SECTION_NAME_IN_TITLE, -1, 0);
+  set_conf (&options->SHORT_TOC_LINK_TO_TOC, -1, 0);
+  set_conf (&options->SHOW_TITLE, -1, 0);
+  set_conf (&options->T4H_LATEX_CONVERSION, -2, 0);
+  set_conf (&options->T4H_MATH_CONVERSION, -2, 0);
+  set_conf (&options->T4H_TEX_CONVERSION, -2, 0);
+  set_conf (&options->TEXI2HTML, -1, 0);
+  set_conf (&options->TEXINFO_OUTPUT_FORMAT, -2, 0);
+  set_conf (&options->TXI_MARKUP_NO_SECTION_EXTENT, -1, 0);
+  set_conf (&options->TOC_LINKS, -1, 0);
+  set_conf (&options->TOP_FILE, -2, 0);
+  set_conf (&options->TOP_NODE_FILE_TARGET, -2, 0);
+  set_conf (&options->TOP_NODE_UP_URL, -2, 0);
+  set_conf (&options->USE_ACCESSKEY, -1, 0);
+  set_conf (&options->USE_ISO, -1, 0);
+  set_conf (&options->USE_LINKS, -1, 0);
+  set_conf (&options->USE_NEXT_HEADING_FOR_LONE_NODE, -1, 0);
+  set_conf (&options->USE_NODES, -1, 0);
+  set_conf (&options->USE_NODE_DIRECTIONS, -1, 0);
+  set_conf (&options->USE_NUMERIC_ENTITY, -1, 0);
+  set_conf (&options->USE_REL_REV, -1, 0);
+  set_conf (&options->USE_SETFILENAME_EXTENSION, -1, 0);
+  set_conf (&options->USE_TITLEPAGE_FOR_TITLE, -1, 0);
+  set_conf (&options->USE_UNIDECODE, -1, 0);
+  set_conf (&options->USE_XML_SYNTAX, -1, 0);
+  set_conf (&options->VERTICAL_HEAD_NAVIGATION, -1, 0);
+  set_conf (&options->WORDS_IN_PAGE, -1, 0);
+  set_conf (&options->XREF_USE_FLOAT_LABEL, -1, 0);
+  set_conf (&options->XREF_USE_NODE_NAME_ARG, -1, 0);
+  set_conf (&options->XS_EXTERNAL_CONVERSION, -1, 0);
+  set_conf (&options->XS_EXTERNAL_FORMATTING, -1, 0);
+  set_conf (&options->XS_STRXFRM_COLLATION_LOCALE, -2, 0);
+}
+
+
+/* converter_other */
+
+void set_converter_other_regular_defaults (OPTIONS *options)
+{
+  set_conf (&options->LINKS_BUTTONS, -2, 0);
+  set_conf (&options->TOP_BUTTONS, -2, 0);
+  set_conf (&options->TOP_FOOTER_BUTTONS, -2, 0);
+  set_conf (&options->SECTION_BUTTONS, -2, 0);
+  set_conf (&options->CHAPTER_FOOTER_BUTTONS, -2, 0);
+  set_conf (&options->SECTION_FOOTER_BUTTONS, -2, 0);
+  set_conf (&options->NODE_FOOTER_BUTTONS, -2, 0);
+  set_conf (&options->MISC_BUTTONS, -2, 0);
+  set_conf (&options->CHAPTER_BUTTONS, -2, 0);
+  set_conf (&options->ACTIVE_ICONS, -2, 0);
+  set_conf (&options->PASSIVE_ICONS, -2, 0);
+}
+
+
+/* multiple_at_command */
+
+void set_multiple_at_command_regular_defaults (OPTIONS *options)
+{
+  set_conf (&options->allowcodebreaks, -2, "true");
+  set_conf (&options->clickstyle, -2, "@arrow");
+  set_conf (&options->codequotebacktick, -2, "off");
+  set_conf (&options->codequoteundirected, -2, "off");
+  set_conf (&options->contents, 0, 0);
+  set_conf (&options->deftypefnnewline, -2, "off");
+  set_conf (&options->documentencoding, -2, "utf-8");
+  set_conf (&options->documentlanguage, -2, 0);
+  set_conf (&options->evenfooting, -2, 0);
+  set_conf (&options->evenheading, -2, 0);
+  set_conf (&options->everyfooting, -2, 0);
+  set_conf (&options->everyheading, -2, 0);
+  set_conf (&options->exampleindent, -2, "5");
+  set_conf (&options->firstparagraphindent, -2, "none");
+  set_conf (&options->frenchspacing, -2, "off");
+  set_conf (&options->headings, -2, "on");
+  set_conf (&options->kbdinputstyle, -2, "distinct");
+  set_conf (&options->microtype, -2, 0);
+  set_conf (&options->oddheading, -2, 0);
+  set_conf (&options->oddfooting, -2, 0);
+  set_conf (&options->paragraphindent, -2, "3");
+  set_conf (&options->shortcontents, 0, 0);
+  set_conf (&options->summarycontents, 0, 0);
+  set_conf (&options->urefbreakstyle, -2, "after");
+  set_conf (&options->xrefautomaticsectiontitle, -2, "off");
+}
+
+
+/* program_cmdline */
+
+void set_program_cmdline_regular_defaults (OPTIONS *options)
+{
+  set_conf (&options->MACRO_EXPAND, -2, 0);
+  set_conf (&options->INTERNAL_LINKS, -2, 0);
+  set_conf (&options->ERROR_LIMIT, 100, 0);
+  set_conf (&options->FORCE, -1, 0);
+  set_conf (&options->NO_WARN, -1, 0);
+  set_conf (&options->SILENT, -2, 0);
+  set_conf (&options->TRACE_INCLUDES, 0, 0);
+  set_conf (&options->FORMAT_MENU, -2, "menu");
+}
+
+
+/* program_customization */
+
+void set_program_customization_regular_defaults (OPTIONS *options)
+{
+  set_conf (&options->CHECK_NORMAL_MENU_STRUCTURE, 1, 0);
+  set_conf (&options->CHECK_MISSING_MENU_ENTRY, 1, 0);
+  set_conf (&options->DUMP_TREE, -1, 0);
+  set_conf (&options->DUMP_TEXI, -1, 0);
+  set_conf (&options->SHOW_BUILTIN_CSS_RULES, 0, 0);
+  set_conf (&options->SORT_ELEMENT_COUNT, -2, 0);
+  set_conf (&options->SORT_ELEMENT_COUNT_WORDS, -1, 0);
+  set_conf (&options->TEXI2DVI, -2, "texi2dvi");
+  set_conf (&options->TREE_TRANSFORMATIONS, -2, 0);
+}
+
+
+/* unique_at_command */
+
+void set_unique_at_command_regular_defaults (OPTIONS *options)
+{
+  set_conf (&options->afivepaper, -2, 0);
+  set_conf (&options->afourpaper, -2, 0);
+  set_conf (&options->afourlatex, -2, 0);
+  set_conf (&options->afourwide, -2, 0);
+  set_conf (&options->bsixpaper, -2, 0);
+  set_conf (&options->documentdescription, -2, 0);
+  set_conf (&options->evenfootingmarks, -2, 0);
+  set_conf (&options->evenheadingmarks, -2, 0);
+  set_conf (&options->everyfootingmarks, -2, "bottom");
+  set_conf (&options->everyheadingmarks, -2, "bottom");
+  set_conf (&options->fonttextsize, 11, 0);
+  set_conf (&options->footnotestyle, -2, "end");
+  set_conf (&options->novalidate, 0, 0);
+  set_conf (&options->oddfootingmarks, -2, 0);
+  set_conf (&options->oddheadingmarks, -2, 0);
+  set_conf (&options->pagesizes, -2, 0);
+  set_conf (&options->setchapternewpage, -2, "on");
+  set_conf (&options->setfilename, -2, 0);
+  set_conf (&options->smallbook, -2, 0);
+}
+
 void set_common_regular_options_defaults (OPTIONS *options)
 {
   set_conf (&options->PACKAGE_AND_VERSION, -2, "texinfo");
diff --git a/tp/Texinfo/XS/convert/converters_defaults.h 
b/tp/Texinfo/XS/convert/converters_defaults.h
index ae67bcc304..25563a2831 100644
--- a/tp/Texinfo/XS/convert/converters_defaults.h
+++ b/tp/Texinfo/XS/convert/converters_defaults.h
@@ -12,6 +12,22 @@
 #undef PACKAGE_URL
 #undef PACKAGE_VERSION
 
+void set_array_cmdline_regular_defaults (OPTIONS *options);
+
+void set_converter_cmdline_regular_defaults (OPTIONS *options);
+
+void set_converter_customization_regular_defaults (OPTIONS *options);
+
+void set_converter_other_regular_defaults (OPTIONS *options);
+
+void set_multiple_at_command_regular_defaults (OPTIONS *options);
+
+void set_program_cmdline_regular_defaults (OPTIONS *options);
+
+void set_program_customization_regular_defaults (OPTIONS *options);
+
+void set_unique_at_command_regular_defaults (OPTIONS *options);
+
 void set_common_regular_options_defaults (OPTIONS *options);
 
 void set_converter_regular_options_defaults (OPTIONS *options);
diff --git a/tp/Texinfo/XS/convert/get_converter_perl_info.c 
b/tp/Texinfo/XS/convert/get_converter_perl_info.c
index 27cebdf60f..1751b1a2eb 100644
--- a/tp/Texinfo/XS/convert/get_converter_perl_info.c
+++ b/tp/Texinfo/XS/convert/get_converter_perl_info.c
@@ -105,6 +105,9 @@ set_translated_commands (CONVERTER *converter, HV *hv_in)
 
       hv_number = hv_iterinit (translated_commands_hv);
 
+      if (converter->translated_commands)
+        destroy_translated_commands (converter->translated_commands);
+
       converter->translated_commands = (TRANSLATED_COMMAND *)
         malloc ((hv_number +1) * sizeof (TRANSLATED_COMMAND));
       memset (converter->translated_commands, 0,
diff --git a/tp/Texinfo/XS/convert/get_converter_perl_info.h 
b/tp/Texinfo/XS/convert/get_converter_perl_info.h
index c5d045be00..1d7dc5e8db 100644
--- a/tp/Texinfo/XS/convert/get_converter_perl_info.h
+++ b/tp/Texinfo/XS/convert/get_converter_perl_info.h
@@ -10,7 +10,8 @@
 struct TEXT_OPTIONS;
 
 CONVERTER *get_sv_converter (SV *sv_in, const char *warn_string);
-int converter_initialize (SV *converter_sv);
+void converter_initialize_sv (SV *converter_sv, CONVERTER *converter,
+                              SV *format_defaults, SV *conf);
 void reset_output_init_conf (SV *sv_in);
 CONVERTER *converter_set_document_from_sv (SV *converter_in, SV *document_in);
 
diff --git a/tp/Texinfo/XS/main/api_to_perl.c b/tp/Texinfo/XS/main/api_to_perl.c
index 6b41344680..29d8b47fd8 100644
--- a/tp/Texinfo/XS/main/api_to_perl.c
+++ b/tp/Texinfo/XS/main/api_to_perl.c
@@ -40,6 +40,13 @@
  /* See the NOTE in build_perl_info.c on use of functions related to
     memory allocation */
 
+/* for debugging */
+int
+get_refcount (void *sv)
+{
+  return SvREFCNT ((SV *) sv);
+}
+
 /* to be called when a tree element is destroyed, to remove the reference
    of the association with the C tree */
 void
@@ -54,12 +61,31 @@ unregister_perl_tree_element (ELEMENT *e)
     }
 }
 
+void
+unregister_perl_buttons_list (BUTTON_SPECIFICATION_LIST *buttons_list)
+{
+  dTHX;
+
+  if (buttons_list->av)
+    SvREFCNT_dec (buttons_list->av);
+}
+
+void
+register_perl_buttons_list (BUTTON_SPECIFICATION_LIST *buttons_list)
+{
+  dTHX;
+
+  if (buttons_list->av)
+    SvREFCNT_inc (buttons_list->av);
+}
+
 void
 unregister_perl_button (BUTTON_SPECIFICATION *button)
 {
   dTHX;
 
-  SvREFCNT_dec (button->sv);
+  if (button->sv)
+    SvREFCNT_dec (button->sv);
 }
 
 void
@@ -67,7 +93,17 @@ register_perl_button (BUTTON_SPECIFICATION *button)
 {
   dTHX;
 
-  SvREFCNT_inc (button->sv);
+  if (button->sv)
+    SvREFCNT_inc (button->sv);
+}
+
+void
+unregister_perl_direction_icons (DIRECTION_ICON_LIST *direction_icons)
+{
+  dTHX;
+
+  if (direction_icons->sv)
+    SvREFCNT_dec (direction_icons->sv);
 }
 
 char *
diff --git a/tp/Texinfo/XS/main/api_to_perl.h b/tp/Texinfo/XS/main/api_to_perl.h
index ce06896382..611e5eeb70 100644
--- a/tp/Texinfo/XS/main/api_to_perl.h
+++ b/tp/Texinfo/XS/main/api_to_perl.h
@@ -5,9 +5,14 @@
 #include "tree_types.h"
 #include "converter_types.h"
 
+int get_refcount (void *sv);
+
 void unregister_perl_tree_element (ELEMENT *e);
+void unregister_perl_buttons_list (BUTTON_SPECIFICATION_LIST *buttons_list);
+void register_perl_buttons_list (BUTTON_SPECIFICATION_LIST *buttons_list);
 void unregister_perl_button (BUTTON_SPECIFICATION *button);
 void register_perl_button (BUTTON_SPECIFICATION *button);
+void unregister_perl_direction_icons (DIRECTION_ICON_LIST *direction_icons);
 void unregister_document_hv (DOCUMENT *document);
 /* HTML specific */
 void unregister_html_converter_perl_hv (CONVERTER *converter);
diff --git a/tp/Texinfo/XS/main/build_perl_info.c 
b/tp/Texinfo/XS/main/build_perl_info.c
index 3a33e551c9..18d5c2c9ba 100644
--- a/tp/Texinfo/XS/main/build_perl_info.c
+++ b/tp/Texinfo/XS/main/build_perl_info.c
@@ -2415,12 +2415,15 @@ pass_document_to_converter_sv (const CONVERTER 
*converter,
 }
 
 SV *
-get_conf (const CONVERTER *converter, const char *option_name)
+get_sv_conf (const CONVERTER *converter, const char *option_name)
 {
   dTHX;
 
   if (converter->conf)
-    return build_sv_option (converter->conf, option_name, converter);
+    {
+      SV *result = build_sv_option (converter->conf, option_name, converter);
+      return result;
+    }
   return newSV (0);
 }
 
@@ -2699,6 +2702,69 @@ build_expanded_formats (const EXPANDED_FORMAT 
*expanded_formats)
   return expanded_hv;
 }
 
+HV *
+build_translated_commands (const TRANSLATED_COMMAND *translated_commands)
+{
+  int i;
+  HV *translated_hv;
+
+  dTHX;
+
+  translated_hv = newHV ();
+  for (i = 0; translated_commands[i].cmd; i++)
+    {
+      enum command_id cmd = translated_commands[i].cmd;
+      const char *translation = translated_commands[i].translation;
+      const char *command_name = builtin_command_name (cmd);
+      hv_store (translated_hv, command_name, strlen (command_name),
+                newSVpv_utf8 (translation, 0), 0);
+    }
+  return translated_hv;
+}
+
+void
+pass_generic_converter_to_converter_sv (SV *converter_sv,
+                                        const CONVERTER *converter)
+{
+  HV *converter_hv;
+  HV *expanded_formats_hv;
+  HV *translated_commands_hv;
+  HV *output_files_hv;
+  HV *unclosed_files_hv;
+  HV *opened_files_hv;
+
+  dTHX;
+
+  converter_hv = (HV *)SvRV (converter_sv);
+
+#define STORE(key, sv) hv_store (converter_hv, key, strlen (key), sv, 0);
+  /* $converter->{'output_files'}
+        = Texinfo::Convert::Utils::output_files_initialize(); */
+  output_files_hv = newHV ();
+  STORE("output_files", newRV_noinc ((SV *) output_files_hv));
+
+  unclosed_files_hv = newHV ();
+  opened_files_hv = newHV ();
+  hv_store (output_files_hv, "unclosed_files", strlen ("unclosed_files"),
+            newRV_noinc ((SV *) unclosed_files_hv), 0);
+  hv_store (output_files_hv, "opened_files_hv",
+            strlen ("opened_files_hv"),
+            newRV_noinc ((SV *) opened_files_hv), 0);
+
+  expanded_formats_hv
+    = build_expanded_formats (converter->expanded_formats);
+  STORE("expanded_formats", newRV_noinc ((SV *) expanded_formats_hv));
+
+  translated_commands_hv
+    = build_translated_commands (converter->translated_commands);
+  STORE("translated_commands", newRV_noinc ((SV *) translated_commands_hv));
+
+  /* store converter_descriptor in perl converter */
+  STORE("converter_descriptor", newSViv ((IV)converter->converter_descriptor));
+
+#undef STORE
+}
+
 SV *
 build_convert_text_options (TEXT_OPTIONS *text_options)
 {
@@ -3078,7 +3144,7 @@ latex_build_options_for_convert_to_latex_math (const 
CONVERTER *converter)
   for (i = 0; latex_math_options[i]; i++)
     {
       const char *option_name = latex_math_options[i];
-      SV *option_sv = get_conf (converter, option_name);
+      SV *option_sv = get_sv_conf (converter, option_name);
       SvREFCNT_inc (option_sv);
       hv_store (options_latex_math_hv, option_name,
                 strlen (option_name), option_sv, 0);
diff --git a/tp/Texinfo/XS/main/build_perl_info.h 
b/tp/Texinfo/XS/main/build_perl_info.h
index 2ab285f712..e6504e183a 100644
--- a/tp/Texinfo/XS/main/build_perl_info.h
+++ b/tp/Texinfo/XS/main/build_perl_info.h
@@ -99,9 +99,13 @@ SV *html_build_direction_icons (const CONVERTER *converter,
 void pass_document_to_converter_sv (const CONVERTER *converter,
                                     SV *converter_sv, SV *document_in);
 
-SV *get_conf (const CONVERTER *converter, const char *option_name);
+SV *get_sv_conf (const CONVERTER *converter, const char *option_name);
 
 HV *build_expanded_formats (const EXPANDED_FORMAT *expanded_formats);
+HV *build_translated_commands (const TRANSLATED_COMMAND *translated_commands);
+
+void pass_generic_converter_to_converter_sv (SV *converter_sv,
+                                             const CONVERTER *converter);
 
 SV *build_convert_text_options (struct TEXT_OPTIONS *text_options);
 
diff --git a/tp/Texinfo/XS/main/convert_utils.c 
b/tp/Texinfo/XS/main/convert_utils.c
index 552fee1baf..ad3b90abb0 100644
--- a/tp/Texinfo/XS/main/convert_utils.c
+++ b/tp/Texinfo/XS/main/convert_utils.c
@@ -681,18 +681,6 @@ translated_command_tree (CONVERTER *self, enum command_id 
cmd)
   return 0;
 }
 
-void
-destroy_translated_commands (TRANSLATED_COMMAND *translated_commands)
-{
-  TRANSLATED_COMMAND *translated_command;
-
-  for (translated_command = translated_commands;
-       translated_command->translation; translated_command++)
-    {
-      free (translated_command->translation);
-    }
-  free (translated_commands);
-}
 
 /*
   API to open, set encoding and register files.
diff --git a/tp/Texinfo/XS/main/convert_utils.h 
b/tp/Texinfo/XS/main/convert_utils.h
index ce409c747f..f6c4bd0b7e 100644
--- a/tp/Texinfo/XS/main/convert_utils.h
+++ b/tp/Texinfo/XS/main/convert_utils.h
@@ -53,7 +53,6 @@ ELEMENT *cdt_tree (const char * string, CONVERTER *self,
                    const char *translation_context);
 
 ELEMENT *translated_command_tree (CONVERTER *self, enum command_id cmd);
-void destroy_translated_commands (TRANSLATED_COMMAND *translated_commands);
 
 char *encoded_input_file_name (const OPTIONS *options,
                          const GLOBAL_INFO *global_information,
diff --git a/tp/Texinfo/XS/main/converter_types.h 
b/tp/Texinfo/XS/main/converter_types.h
index 6dd88b2452..1df9ea1616 100644
--- a/tp/Texinfo/XS/main/converter_types.h
+++ b/tp/Texinfo/XS/main/converter_types.h
@@ -750,6 +750,7 @@ typedef struct CONVERTER {
     OPTIONS *conf;
     OPTIONS *init_conf;
     char *output_format;
+    char *converted_format;
     EXPANDED_FORMAT *expanded_formats;
     TRANSLATED_COMMAND *translated_commands;
 
diff --git a/tp/Texinfo/XS/main/get_perl_info.c 
b/tp/Texinfo/XS/main/get_perl_info.c
index 7af5279ca9..5b78ee4ed7 100644
--- a/tp/Texinfo/XS/main/get_perl_info.c
+++ b/tp/Texinfo/XS/main/get_perl_info.c
@@ -397,10 +397,8 @@ get_sv_options (SV *sv, OPTIONS *options, CONVERTER 
*converter,
       char *key;
       I32 retlen;
       SV *value = hv_iternextsv (hv, &key, &retlen);
-      if (value && SvOK (value))
-        {
-          get_sv_option (options, key, value, force, converter);
-        }
+
+      get_sv_option (options, key, value, force, converter);
     }
 }
 
@@ -459,6 +457,134 @@ copy_converter_conf_sv (HV *hv, CONVERTER *converter,
     }
 }
 
+/* Texinfo::Convert::Converter generic initialization for all the converters */
+/* Called early, in particuliar before any format specific code has been
+   called */
+void
+converter_initialize_sv (SV *converter_sv, CONVERTER *converter,
+                         SV *format_defaults, SV *conf)
+{
+  HV *converter_hv;
+
+  dTHX;
+
+  converter_hv = (HV *)SvRV (converter_sv);
+
+  converter->hv = converter_hv;
+
+  if (format_defaults && SvOK (format_defaults))
+    {
+      SV **output_format_sv;
+      SV **converted_format_sv;
+      HV *format_defaults_hv = (HV *)SvRV (format_defaults);
+
+      get_sv_options (format_defaults, converter->conf, converter, 0);
+
+#define FETCH(key) key##_sv = hv_fetch (format_defaults_hv, #key, strlen 
(#key), 0);
+      FETCH(output_format)
+      if (output_format_sv && SvOK (*output_format_sv))
+        {
+          converter->output_format
+            = non_perl_strdup (SvPVutf8_nolen (*output_format_sv));
+        }
+      FETCH(converted_format)
+      if (converted_format_sv && SvOK (*converted_format_sv))
+        {
+          converter->converted_format
+            = non_perl_strdup (SvPVutf8_nolen (*converted_format_sv));
+        }
+     }
+#undef FETCH
+
+  if (conf && SvOK (conf))
+    {
+      I32 hv_number;
+      I32 i;
+
+      HV *conf_hv = (HV *)SvRV (conf);
+
+      hv_number = hv_iterinit (conf_hv);
+      for (i = 0; i < hv_number; i++)
+        {
+          char *key;
+          I32 retlen;
+          SV *value = hv_iternextsv (conf_hv, &key, &retlen);
+          int status
+            = get_sv_option (converter->conf, key, value, 0, converter);
+
+          /*
+          fprintf (stderr, "CONF: format %s: set %s: %d\n",
+                           converter->output_format, key, status);
+           */
+          if (!status)
+            {
+              set_option_key_configured (converter->conf, key, 1);
+            }
+         /* TODO in defaults here means in format_defaults or
+            non customization variable
+            in Texinfo::Convert::Converter::common_converters_defaults
+      } elsif (!exists($defaults{$key})) {
+        warn "$key not a possible configuration in $class\n";
+          */
+          else if (status == -2)
+            {
+              if (!strcmp (key, "translated_commands"))
+                set_translated_commands (converter, conf_hv);
+              else if (!strcmp (key, "output_format"))
+                converter->output_format
+                  = non_perl_strdup (SvPVutf8_nolen (value));
+              else if (!strcmp (key, "converted_format"))
+                converter->converted_format
+                  = non_perl_strdup (SvPVutf8_nolen (value));
+
+              /* not a customization variable, set in converter */
+              if (SvOK (value))
+                SvREFCNT_inc (value);
+              hv_store (converter_hv, key, strlen (key), value, 0);
+            }
+          else
+            fprintf (stderr, "ERROR: %s unexpected conf error\n", key);
+        }
+    }
+
+   /*
+  fprintf (stderr, "XS|CONVERTER Init: %d; %s, %s\n",
+                   converter->converter_descriptor,
+                   converter->output_format,
+                   converter->converted_format);
+    */
+
+  /* in Perl sets converter_init_conf, but in C we use only one
+     structure for converter_init_conf and output_init_conf, which
+     is overwritten to set the similar values as output_init_conf
+     in specific converters.
+   */
+  copy_options (converter->init_conf, converter->conf);
+
+  set_expanded_formats_from_options (converter->expanded_formats,
+                                     converter->conf);
+}
+
+/* currently unused */
+/* reset output_init_conf.  Can be called after it has been modified */
+void
+reset_output_init_conf (SV *sv_in)
+{
+  CONVERTER *converter;
+
+  dTHX;
+
+  converter = get_sv_converter (sv_in, "reset_output_init_conf");
+
+  if (converter)
+    {
+      HV *hv_in = (HV *)SvRV (sv_in);
+
+      copy_converter_conf_sv (hv_in, converter, &converter->init_conf,
+                             "output_init_conf", 1);
+    }
+}
+
 INDEX_ENTRY *
 find_index_entry_sv (const SV *index_entry_sv, INDEX_LIST *indices_info,
                      const char *warn_string, const INDEX **entry_idx,
@@ -718,15 +844,20 @@ get_sv_index_entries_sorted_by_letter (INDEX_LIST 
*indices_info,
   return indices_entries_by_letter;
 }
 
-void
+int
 set_sv_conf (CONVERTER *converter, const char *conf, SV *value)
 {
   if (converter->conf)
-    get_sv_option (converter->conf, conf, value, 0, converter);
+    {
+      int status = get_sv_option (converter->conf, conf, value, 0, converter);
+      if (status == 0)
+        return 1;
+    }
    /* Too early to have options set
   else
     fprintf (stderr, "HHH no converter conf %s\n", conf);
     */
+  return 0;
 }
 
 void
@@ -747,7 +878,63 @@ static const char *button_function_type_string[] = {
   0,
 };
 
+/* set directions.  To be called after direction names have been collected */
+void
+html_fill_button_specification_list (const CONVERTER *converter,
+                                     BUTTON_SPECIFICATION_LIST *result)
+{
+  size_t i;
+  dTHX;
+
+  for (i = 0; i < result->number; i++)
+    {
+      BUTTON_SPECIFICATION *button = &result->list[i];
+
+      if (button->type == BST_direction_info)
+        {
+          AV *button_spec_info_av = (AV *) SvRV((SV *)button->sv);
+          SV **direction_sv = av_fetch (button_spec_info_av, 0, 0);
+          const char *direction_name;
+
+          if (!direction_sv || !SvOK (*direction_sv))
+            {
+              fprintf (stderr,
+                       "ERROR: missing direction in button %zu array\n",
+                       i);
+              continue;
+            }
+
+          direction_name = SvPVutf8_nolen (*direction_sv);
+          button->b.button_info->direction
+            = html_get_direction_index (converter, direction_name);
+        /* this happens in test with redefined special unit direction
+          if (button->b.button_info->direction < 0)
+            {
+              fprintf (stderr,
+                  "BUG: still unknown button %zu array direction: %d: %s\n",
+                     i, button->b.button_info->direction, direction_name);
+            }
+         */
+        }
+      else if (button->type == BST_direction)
+        {
+          const char *direction_name = SvPVutf8_nolen (button->sv);
+          button->b.direction = html_get_direction_index (converter,
+                                                          direction_name);
+        /* this would happen in test with redefined special unit direction
+          if (button->b.direction < 0)
+            fprintf (stderr,
+                     "BUG: still unknown button %zu string direction: %s\n",
+                     i, direction_name);
+         */
+        }
+    }
+}
+
 /* HTML specific, but needs to be there for options_get_perl.c */
+/* it is expected that directions are not found as the directions list
+   is not setup already.  A call of html_fill_button_specification_list
+   should be needed afterwards */
 BUTTON_SPECIFICATION_LIST *
 html_get_button_specification_list (const CONVERTER *converter,
                                     const SV *buttons_sv)
@@ -765,31 +952,30 @@ html_get_button_specification_list (const CONVERTER 
*converter,
       || SvTYPE (SvRV (buttons_sv)) != SVt_PVAV)
     return 0;
 
+  buttons_av = (AV *)SvRV (buttons_sv);
+
+  buttons_nr = av_top_index (buttons_av) +1;
+
+  if (buttons_nr == 0)
+    return 0;
+
   result = (BUTTON_SPECIFICATION_LIST *)
             malloc (sizeof (BUTTON_SPECIFICATION_LIST));
 
-  buttons_av = (AV *)SvRV (buttons_sv);
-  /* In contrast with other cases, we do not add a reference to the array
-     associated to result->av to make sure that the av is not destroyed
-     while still needed, as we assume that the Perl converter will hold
-     a reference longer than we need the av for */
   result->av = buttons_av;
+  SvREFCNT_inc ((SV *)result->av);
 
-  buttons_nr = av_top_index (buttons_av) +1;
-
-  result->BIT_user_function_number = 0;
   result->number = (size_t) buttons_nr;
 
-  if (result->number == 0)
-    return 0;
+  result->BIT_user_function_number = 0;
 
   result->list = (BUTTON_SPECIFICATION *)
     malloc (result->number * sizeof (BUTTON_SPECIFICATION));
   memset (result->list, 0, result->number * sizeof (BUTTON_SPECIFICATION));
 
-  for (i = 0; i < buttons_nr; i++)
+  for (i = 0; i < result->number; i++)
     {
-      SV **button_sv = av_fetch (buttons_av, i, 0);
+      SV **button_sv = av_fetch (result->av, i, 0);
       BUTTON_SPECIFICATION *button = &result->list[i];
 
       if (!button_sv || !SvOK (*button_sv))
@@ -842,11 +1028,11 @@ html_get_button_specification_list (const CONVERTER 
*converter,
               button_spec->direction
                 = html_get_direction_index (converter, direction_name);
                /* to debug
-              if (button_spec->direction == -2)
+              if (button_spec->direction < 0)
                 {
                   fprintf (stderr,
-                           "REMARK: unknown button %zu array direction: %s\n",
-                           i, direction_name);
+                      "REMARK: unknown button %zu array direction: %d: %s\n",
+                           i, button_spec->direction, direction_name);
                 }
                 */
 
@@ -935,28 +1121,21 @@ html_get_button_specification_list (const CONVERTER 
*converter,
             */
         }
     }
-
   return result;
 }
 
-/* HTML specific, but needs to be there for options_get_perl.c */
+/* set direction icons.
+   To be called after direction names have been collected */
 void
-html_get_direction_icons_sv (const CONVERTER *converter,
-                             DIRECTION_ICON_LIST *direction_icons,
-                             const SV *icons_sv)
+html_fill_direction_icons (const CONVERTER *converter,
+                           DIRECTION_ICON_LIST *direction_icons)
 {
   HV *icons_hv;
   int i;
 
   dTHX;
 
-  if (!SvOK (icons_sv))
-    return;
-
-  if (!converter || !converter->direction_unit_direction_name
-       /* the following is for consistency, but is not possible */
-      || converter->special_unit_varieties.number
-          + NON_SPECIAL_DIRECTIONS_NR <= 0)
+  if (!direction_icons->sv)
     return;
 
   if (direction_icons->number == 0)
@@ -968,7 +1147,7 @@ html_get_direction_icons_sv (const CONVERTER *converter,
            (direction_icons->number * sizeof (char *));
     }
 
-  icons_hv = (HV *)SvRV (icons_sv);
+  icons_hv = (HV *)SvRV ((SV *)direction_icons->sv);
 
   for (i = 0; converter->direction_unit_direction_name[i]; i++)
     {
@@ -986,6 +1165,31 @@ html_get_direction_icons_sv (const CONVERTER *converter,
     }
 }
 
+/* HTML specific, but needs to be there for options_get_perl.c */
+void
+html_get_direction_icons_sv (const CONVERTER *converter,
+                             DIRECTION_ICON_LIST *direction_icons,
+                             SV *icons_sv)
+{
+  dTHX;
+
+  if (!SvOK (icons_sv))
+    return;
+
+  /* the following is for consistency, but is not possible */
+  if (converter && converter->special_unit_varieties.number
+                     + NON_SPECIAL_DIRECTIONS_NR <= 0)
+    return;
+
+  SvREFCNT_inc ((SV *) icons_sv);
+  direction_icons->sv = icons_sv;
+
+  if (!converter || !converter->direction_unit_direction_name)
+    return;
+
+  html_fill_direction_icons (converter, direction_icons);
+}
+
 static const INDEX_ENTRY *
 find_sorted_index_names_index_entry_extra_index_entry_sv (
                                   const SORTED_INDEX_NAMES *sorted_index_names,
diff --git a/tp/Texinfo/XS/main/get_perl_info.h 
b/tp/Texinfo/XS/main/get_perl_info.h
index 4642f99c8a..db0bf4e434 100644
--- a/tp/Texinfo/XS/main/get_perl_info.h
+++ b/tp/Texinfo/XS/main/get_perl_info.h
@@ -13,12 +13,23 @@
 #include "convert_to_text.h"
 
 /* in options_get_perl.c */
-void get_sv_option (OPTIONS *options, const char *key, SV *value,
-                    int force, const CONVERTER *converter);
+/* return values:
+  0: success
+  -1: already set (only if !force)
+  -2: unknown
+  -3: type error
+ */
+int get_sv_option (OPTIONS *options, const char *key, SV *value,
+                   int force, const CONVERTER *converter);
+void html_fill_options (OPTIONS *options, const CONVERTER *converter);
+
 /* in options_init_free.c */
 void set_option_key_configured (OPTIONS *options, const char *key,
                                 int configured);
 
+void get_sv_options (SV *sv, OPTIONS *options, CONVERTER *converter,
+                     int force);
+void set_translated_commands (CONVERTER *converter, HV *hv_in);
 
 DOCUMENT *get_sv_tree_document (SV *tree_in, char *warn_string);
 DOCUMENT *get_sv_document_document (SV *document_in, char *warn_string);
@@ -40,7 +51,7 @@ OPTIONS *init_copy_sv_options (SV *sv_in, CONVERTER 
*converter, int force);
 void get_sv_configured_options (SV *configured_sv_in, OPTIONS *options);
 void copy_converter_conf_sv (HV *hv, CONVERTER *converter,
                              OPTIONS **conf, const char *conf_key, int force);
-void set_sv_conf (CONVERTER *converter, const char *conf, SV *value);
+int set_sv_conf (CONVERTER *converter, const char *conf, SV *value);
 void force_sv_conf (CONVERTER *converter, const char *conf, SV *value);
 
 INDEX_ENTRY *find_index_entry_sv (const SV *index_entry_sv,
@@ -55,9 +66,13 @@ TEXT_OPTIONS *copy_sv_options_for_convert_text (SV *sv_in);
 
 BUTTON_SPECIFICATION_LIST *html_get_button_specification_list
                                 (const CONVERTER *converter, const SV 
*buttons_sv);
+void html_fill_button_specification_list (const CONVERTER *converter,
+                                          BUTTON_SPECIFICATION_LIST *result);
+void html_fill_direction_icons (const CONVERTER *converter,
+                                DIRECTION_ICON_LIST *direction_icons);
 void html_get_direction_icons_sv (const CONVERTER *converter,
                              DIRECTION_ICON_LIST *direction_icons,
-                             const SV *icons_sv);
+                             SV *icons_sv);
 
 const ELEMENT *find_element_from_sv (const CONVERTER *converter,
                                      const DOCUMENT *document_in,
diff --git a/tp/Texinfo/XS/main/option_types.h 
b/tp/Texinfo/XS/main/option_types.h
index 4cb7a312fd..3a737dead1 100644
--- a/tp/Texinfo/XS/main/option_types.h
+++ b/tp/Texinfo/XS/main/option_types.h
@@ -147,6 +147,9 @@ typedef struct FORMATTED_BUTTON_INFO {
 } FORMATTED_BUTTON_INFO;
 
 typedef struct DIRECTION_ICON_LIST {
+  /* perl reference. This should be SV *sv,
+     but we don't want to include the Perl headers everywhere; */
+    void *sv;
     size_t number;
     char **list;
 } DIRECTION_ICON_LIST;
diff --git a/tp/Texinfo/XS/main/utils.c b/tp/Texinfo/XS/main/utils.c
index b52c7481e9..93a778b0e2 100644
--- a/tp/Texinfo/XS/main/utils.c
+++ b/tp/Texinfo/XS/main/utils.c
@@ -1639,6 +1639,7 @@ html_free_button_specification_list 
(BUTTON_SPECIFICATION_LIST *buttons)
         }
     }
   free (buttons->list);
+  unregister_perl_buttons_list (buttons);
   free (buttons);
 }
 
@@ -1668,6 +1669,7 @@ html_free_direction_icons (DIRECTION_ICON_LIST 
*direction_icons)
   free (direction_icons->list);
   direction_icons->number = 0;
   direction_icons->list = 0;
+  unregister_perl_direction_icons (direction_icons);
 }
 
 /* here because it is used in main/get_perl_info.c */
@@ -1856,6 +1858,7 @@ copy_option (OPTION *destination, const OPTION *source)
         { /* Note that the caller should adjust BIT_user_function_number
              of the options holding the buttons */
           html_free_button_specification_list (destination->o.buttons);
+          destination->o.buttons = 0;
           if (source->o.buttons)
             {
               size_t i;
@@ -1867,10 +1870,14 @@ copy_option (OPTION *destination, const OPTION *source)
               result->BIT_user_function_number
                 = s_buttons->BIT_user_function_number;
               result->number = s_buttons->number;
+
+              result->av = s_buttons->av;
+              register_perl_buttons_list (result);
+
               result->list = (BUTTON_SPECIFICATION *)
-                     malloc (result->number * sizeof (BUTTON_SPECIFICATION));
+                 malloc (result->number * sizeof (BUTTON_SPECIFICATION));
               memset (result->list, 0,
-                      result->number * sizeof (BUTTON_SPECIFICATION));
+                  result->number * sizeof (BUTTON_SPECIFICATION));
               for (i = 0; i < result->number; i++)
                 {
                   BUTTON_SPECIFICATION *button = &result->list[i];
@@ -1922,8 +1929,6 @@ copy_option (OPTION *destination, const OPTION *source)
                 }
               destination->o.buttons = result;
             }
-          else
-            destination->o.buttons = 0;
         }
         break;
 
diff --git a/tp/maintain/regenerate_C_options_info.pl 
b/tp/maintain/regenerate_C_options_info.pl
index b1ff9081c9..db04cb74c0 100755
--- a/tp/maintain/regenerate_C_options_info.pl
+++ b/tp/maintain/regenerate_C_options_info.pl
@@ -356,6 +356,21 @@ print OHDEF "#undef PACKAGE_NAME\n";
 print OHDEF "#undef PACKAGE_URL\n";
 print OHDEF "#undef PACKAGE_VERSION\n\n";
 
+foreach my $category (sort(keys(%option_categories))) {
+  print OCDEF "\n/* ${category} */\n\n";
+  my $fun = "void set_${category}_regular_defaults (OPTIONS *options)";
+
+  print OHDEF "$fun;\n\n";
+
+  print OCDEF "$fun\n{\n";
+  foreach my $option_info (@{$option_categories{$category}}) {
+    my ($option, $value, $type) = @$option_info;
+    my ($int_value, $char_value) = get_value($type, $value);
+    print OCDEF "  set_conf (&options->${option}, $int_value, $char_value);\n";
+  }
+  print OCDEF "}\n\n";
+}
+
 my @sorted_formats = sort(keys(%converter_defaults));
 
 foreach my $format (@sorted_formats) {
@@ -410,7 +425,7 @@ print GET '#include "utils.h"'."\n";
 print GET '#include "get_perl_info.h"'."\n";
 print GET '#include "build_perl_info.h"'."\n\n";
 
-print GET 'void
+print GET 'int
 get_sv_option (OPTIONS *options, const char *key, SV *value, int force, const 
CONVERTER *converter)
 {
   dTHX;
@@ -425,7 +440,7 @@ foreach my $category (sort(keys(%option_categories))) {
     print GET "  else if (!strcmp (key, \"$option\"))
     {
       if (force <= 0 && options->$option.configured > 0)
-        return;\n\n";
+        return -1;\n\n";
     if ($type eq 'char' or $type eq 'bytes') {
       my $SV_function_type = 'utf8';
       if ($type eq 'bytes') {
@@ -450,6 +465,7 @@ foreach my $category (sort(keys(%option_categories))) {
               fprintf (stderr, \"BUG: %s: not an integer: %s\\n\",
                        \"$option\", SvPVutf8_nolen (value));
               options->$option.o.integer = -1;
+              return -3;
             }
         }
       else
@@ -481,15 +497,41 @@ foreach my $category (sort(keys(%option_categories))) {
       html_get_direction_icons_sv (converter, options->$option.o.icons, value);
     }\n";
     } else {
+      print STDERR "BUG: unknown type: $type\n";
       print GET "    {}\n";
     }
   }
 }
 
+print GET '  else
+    return -2; /* unknown */
+
+  return 0;
+}
+
+';
+
+print GET 'void
+html_fill_options (OPTIONS *options, const CONVERTER *converter)
+{
+';
+foreach my $category (sort(keys(%option_categories))) {
+  foreach my $option_info (@{$option_categories{$category}}) {
+    my ($option, $value, $type) = @$option_info;
+    if ($type eq 'buttons') {
+      print GET "  if (options->$option.o.buttons)\n"
+                ."    html_fill_button_specification_list (converter, 
options->$option.o.buttons);\n\n";
+    } elsif ($type eq 'icons') {
+      print GET "  if (options->$option.o.icons)\n"
+                ."    html_fill_direction_icons (converter, 
options->$option.o.icons);\n\n";
+    }
+  }
+}
 print GET '}
 
 ';
 
+
 print GET 'SV *
 build_sv_option (const OPTIONS *options, const char *key,
                  const CONVERTER *converter)



reply via email to

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