texinfo-commits
[Top][All Lists]
Advanced

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

branch master updated: * tp/Texinfo/ParserNonXS.pm: check that autovivif


From: Patrice Dumas
Subject: branch master updated: * tp/Texinfo/ParserNonXS.pm: check that autovivification does not create unexpected structures, and hides missing initializations.
Date: Tue, 27 Sep 2022 15:35:42 -0400

This is an automated email from the git hooks/post-receive script.

pertusus pushed a commit to branch master
in repository texinfo.

The following commit(s) were added to refs/heads/master by this push:
     new a63f5acaac * tp/Texinfo/ParserNonXS.pm: check that autovivification 
does not create unexpected structures, and hides missing initializations.
a63f5acaac is described below

commit a63f5acaaccea763a1b2d26ab150ec22043b3840
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Tue Sep 27 21:35:29 2022 +0200

    * tp/Texinfo/ParserNonXS.pm: check that autovivification does not
    create unexpected structures, and hides missing initializations.
---
 ChangeLog                 |   7 ++-
 tp/Texinfo/ParserNonXS.pm | 116 +++++++++++++++++++++++++++++++++-------------
 2 files changed, 90 insertions(+), 33 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4d84ae39b8..7f8c55f31b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2022-09-27  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/ParserNonXS.pm: check that autovivification does not
+       create unexpected structures, and hides missing initializations.
+
 2022-09-27  Patrice Dumas  <pertusus@free.fr>
 
        * Pod-Simple-Texinfo/lib/Pod/Simple/Texinfo.p (_convert_pod): fix
@@ -22,7 +27,7 @@
        %commands_args_number, and add the number of arguments of node too,
        matching the XS parser.
 
-       * tp/Texinfo/Common.pm (_process_remaining_on_line),
+       * tp/Texinfo/ParserNonXS.pm (_process_remaining_on_line),
        tp/Texinfo/XS/parsetexi/handle_commands.c (handle_line_command):
        Use the number of arguments of node more like other commands
        both in the perl and the XS parser.
diff --git a/tp/Texinfo/ParserNonXS.pm b/tp/Texinfo/ParserNonXS.pm
index bd3085d561..9dc126ed73 100644
--- a/tp/Texinfo/ParserNonXS.pm
+++ b/tp/Texinfo/ParserNonXS.pm
@@ -56,6 +56,10 @@ use strict;
 # used to match Unicode character classes.
 use if $] >= 5.014, re => '/a';
 
+# check that autovivification do not happen incorrectly.  If set,
+# need to uncomment many 'extra' key hash initialization
+#no autovivification qw(fetch delete exists store strict);
+
 # debug
 use Carp qw(cluck);
 use Data::Dumper;
@@ -583,6 +587,9 @@ sub parser(;$$)
   $parser->{'close_paragraph_commands'} = {%close_paragraph_commands};
   $parser->{'close_preformatted_commands'} = {%close_preformatted_commands};
 
+  # other initializations
+  $parser->{'definfoenclose'} = {};
+
   # handle user provided state.
 
   # Currently not done, as none of the user provided configuration
@@ -634,6 +641,7 @@ sub parser(;$$)
 
   # turn the array to a hash for speed.  Not sure it really matters for such
   # a small array.
+  $parser->{'expanded_formats_hash'} = {};
   foreach my $expanded_format(@{$parser->{'EXPANDED_FORMATS'}}) {
     $parser->{'expanded_formats_hash'}->{$expanded_format} = 1;
   }
@@ -676,6 +684,9 @@ sub simple_parser(;$)
   $parser->{'close_paragraph_commands'} = 
$simple_parser_close_paragraph_commands;
   $parser->{'close_preformatted_commands'} = 
$simple_parser_close_preformatted_commands;
 
+  # other initializations
+  $parser->{'definfoenclose'} = {};
+
   $parser->_init_context_stack();
 
   # turn the array to a hash for speed.  Not sure it really matters for such
@@ -774,7 +785,6 @@ sub parse_texi_piece($$;$$$$)
 
   my ($document_root, $before_node_section)
      = _setup_document_root_and_before_node_section();
-
   my $tree = $self->_parse_texi($document_root, $before_node_section);
 
   return $tree;
@@ -967,6 +977,7 @@ sub _setup_conf($$)
 {
   my ($parser, $conf) = @_;
 
+  $parser->{'set'} = {};
   if (defined($conf)) {
     foreach my $key (keys(%$conf)) {
       if (exists($parser_settable_configuration{$key})) {
@@ -1267,8 +1278,10 @@ sub _begin_paragraph($$;$)
     }
     push @{$current->{'contents'}},
             { 'type' => 'paragraph', 'parent' => $current };
-    $current->{'contents'}->[-1]->{'extra'}->{$indent} = 1 if ($indent);
     $current = $current->{'contents'}->[-1];
+    if ($indent) {
+      $current->{'extra'} = {$indent => 1};
+    }
     print STDERR "PARAGRAPH\n" if ($self->{'DEBUG'});
     return $current;
   }
@@ -2337,6 +2350,7 @@ sub _abort_empty_line {
       _pop_element_from_contents($current);
       my $owning_element
         = $spaces_element->{'extra'}->{'spaces_associated_command'};
+      #$owning_element->{'extra'} = {} if (! $owning_element->{'extra'});
       $owning_element->{'extra'}->{'spaces_before_argument'}
         = $spaces_element->{'text'};
     }
@@ -2358,6 +2372,7 @@ sub _isolate_last_space
       and $current->{'contents'}->[-1]->{'cmdname'}
       and ($current->{'contents'}->[-1]->{'cmdname'} eq 'c'
             or $current->{'contents'}->[-1]->{'cmdname'} eq 'comment')) {
+    #$current->{'extra'} = {} if (!$current->{'extra'});
     $current->{'extra'}->{'comment_at_end'}
                            = _pop_element_from_contents($current);
     # TODO: @c should probably not be allowed inside most brace commands
@@ -2383,6 +2398,7 @@ sub _isolate_last_space
     }
   } else {
     # Store final spaces in 'spaces_after_argument'.
+    #$current->{'extra'} = {} if (!$current->{'extra'});
     if ($current->{'contents'}->[-1]->{'text'} !~ /\S/) {
       $current->{'extra'}->{'spaces_after_argument'}
                  = $current->{'contents'}->[-1]->{'text'};
@@ -2418,6 +2434,8 @@ sub _parse_node_manual($)
 sub _parse_float_type($)
 {
   my $current = shift;
+  #$current->{'extra'} = {} if (!$current->{'extra'});
+  $current->{'extra'}->{'type'} = {};
   if ($current->{'args'} and @{$current->{'args'}}
       and $current->{'args'}->[0]->{'contents'}) {
     my $normalized
@@ -2517,7 +2535,7 @@ sub _parse_def($$$)
     # documentlanguage is set it needs to be translated during the conversion.
     if (defined($self->{'documentlanguage'})) {
       $content->{'type'} = 'untranslated';
-      $content->{'extra'}->{'documentlanguage'} = $self->{'documentlanguage'};
+      $content->{'extra'} = {'documentlanguage' => 
$self->{'documentlanguage'}};
     }
     @{$bracketed->{'contents'}} = ($content);
 
@@ -2671,6 +2689,7 @@ sub _parse_def($$$)
   }
 
   for my $pair (@result, @args_results) {
+    #$pair->[1]->{'extra'} = {} if (!$pair->[1]->{'extra'});
     $pair->[1]->{'extra'}->{'def_role'} = $pair->[0];
   }
 
@@ -2949,7 +2968,7 @@ sub _end_line($$$)
     my $arguments = _parse_def($self, $def_command, $current);
     if (scalar(@$arguments)) {
       #$current->{'parent'}->{'extra'}->{'def_args'} = $arguments;
-      my $def_parsed_hash;
+      my $def_parsed_hash = {};
       foreach my $arg (@$arguments) {
         die if (!defined($arg->[0]));
         last if ($arg->[0] eq 'arg' or $arg->[0] eq 'typearg'
@@ -3053,6 +3072,7 @@ sub _end_line($$$)
         }
       }
       my $multitable = $current->{'parent'};
+      #$multitable->{'extra'} = {} if (!$multitable->{'extra'});
       $multitable->{'extra'}->{'max_columns'} = scalar(@prototype_row);
       if (!scalar(@prototype_row)) {
         $self->_command_warn($multitable, $source_info,
@@ -3104,6 +3124,7 @@ sub _end_line($$$)
             $spec = $arg->{'text'};
           }
         }
+        #$current->{'extra'} = {} if (!$current->{'extra'});
         $current->{'extra'}->{'enumerate_specification'} = $spec;
       } elsif ($block_commands{$current->{'cmdname'}} eq 'item_line') {
         if (!$current->{'extra'}
@@ -3175,16 +3196,19 @@ sub _end_line($$$)
                            'type' => 'command_as_argument_inserted',
                            'parent' => $block_line_arg };
           unshift @{$block_line_arg->{'contents'}}, $inserted;
+          #$current->{'extra'} = {} if (!$current->{'extra'});
           $current->{'extra'}->{'command_as_argument'} = $inserted;
         }
       } elsif ($block_commands{$current->{'cmdname'}}
-               and $block_commands{$current->{'cmdname'}} eq 'item_line'
-               and !$current->{'extra'}->{'command_as_argument'}) {
-        my $inserted =  { 'cmdname' => 'asis',
-                          'type' => 'command_as_argument_inserted',
-                          'parent' => $current };
-        unshift @{$current->{'args'}}, $inserted;
-        $current->{'extra'}->{'command_as_argument'} = $inserted;
+               and $block_commands{$current->{'cmdname'}} eq 'item_line') {
+        #$current->{'extra'} = {} if (!$current->{'extra'});
+        if (!$current->{'extra'}->{'command_as_argument'}) {
+          my $inserted =  { 'cmdname' => 'asis',
+                            'type' => 'command_as_argument_inserted',
+                            'parent' => $current };
+          unshift @{$current->{'args'}}, $inserted;
+          $current->{'extra'}->{'command_as_argument'} = $inserted;
+        }
       }
       push @{$current->{'contents'}}, { 'type' => 'before_item',
                                         'parent', $current };
@@ -3231,6 +3255,7 @@ sub _end_line($$$)
       my ($text, $superfluous_arg)
         = _convert_to_text($current->{'args'}->[0]);
 
+      #$current->{'extra'} = {} if (!$current->{'extra'});
       if ($text eq '') {
         if (not $superfluous_arg) {
           $self->_command_warn($current, $source_info,
@@ -3372,6 +3397,7 @@ sub _end_line($$$)
                        $command, $texi_line);
       }
     } elsif ($command eq 'node') {
+      #$current->{'extra'} = {} if (!$current->{'extra'});
       foreach my $arg (@{$current->{'args'}}) {
         my $node = _parse_node_manual($arg);
         push @{$current->{'extra'}->{'nodes_manuals'}}, $node;
@@ -3401,6 +3427,7 @@ sub _end_line($$$)
       if (!$current->{'args'}->[0]->{'contents'} and $command ne 'top') {
         $self->_command_warn($current, $source_info,
                __("\@%s missing argument"), $command);
+        #$current->{'extra'} = {} if (!$current->{'extra'});
         $current->{'extra'}->{'missing_argument'} = 1;
       } else {
         if (($command eq 'item' or $command eq 'itemx')
@@ -3524,6 +3551,7 @@ sub _end_line($$$)
         if ($self->{'current_node'}
            and !$self->{'current_node'}->{'extra'}->{'associated_section'}) {
           $self->{'current_node'}->{'extra'}->{'associated_section'} = 
$current;
+          #$current->{'extra'} = {} if (!$current->{'extra'});
           $current->{'extra'}->{'associated_node'} = $self->{'current_node'};
         }
         if ($self->{'current_part'}) {
@@ -3598,8 +3626,8 @@ sub _start_empty_line_after_command($$$) {
                                     'parent' => $current,
                                   };
   if (defined($command)) {
-    $current->{'contents'}->[-1]->{'extra'}->{'spaces_associated_command'}
-      = $command;
+    $current->{'contents'}->[-1]->{'extra'}
+       = {'spaces_associated_command' => $command};
     $current->{'contents'}->[-1]->{'type'} = 'internal_spaces_after_command';
   }
   return $line;
@@ -3664,6 +3692,7 @@ sub _register_extra_menu_entry_information($$;$)
 
   foreach my $arg (@{$current->{'args'}}) {
     if ($arg->{'type'} eq 'menu_entry_name') {
+      #$current->{'extra'} = {} if (!$current->{'extra'});
       $current->{'extra'}->{'menu_entry_name'} = $arg;
       if (not $arg->{'contents'} or scalar(@{$arg->{'contents'}}) == 0) {
         $self->_line_warn(sprintf(__("empty menu entry name in `%s'"),
@@ -3678,9 +3707,11 @@ sub _register_extra_menu_entry_information($$;$)
         }
       } else {
         my $parsed_entry_node = _parse_node_manual($arg);
+        #$current->{'extra'} = {} if (!$current->{'extra'});
         $current->{'extra'}->{'menu_entry_node'} = $parsed_entry_node;
       }
     } elsif ($arg->{'type'} eq 'menu_entry_description') {
+      #$current->{'extra'} = {} if (!$current->{'extra'});
       $current->{'extra'}->{'menu_entry_description'} = $arg;
     }
   }
@@ -3993,6 +4024,7 @@ sub _process_remaining_on_line($$$$)
   # in @verb. type should be 'brace_command_arg'
   } elsif ($current->{'parent'} and $current->{'parent'}->{'cmdname'}
          and $current->{'parent'}->{'cmdname'} eq 'verb') {
+    #$current->{'parent'}->{'extra'} = {} if 
(!$current->{'parent'}->{'extra'});
     # collect the first character if not already done
     if (!defined($current->{'parent'}->{'extra'}->{'delimiter'})) {
       if ($line =~ /^$/) {
@@ -4154,6 +4186,9 @@ sub _process_remaining_on_line($$$$)
       $source_info->{'end_macro'} = 1;
       # first put the line that was interrupted by the macro call
       # on the input pending text with information stack
+      if (! scalar(@{$self->{'input'}})) {
+        push @{$self->{'input'}}, {'pending' => []};
+      }
       unshift @{$self->{'input'}->[0]->{'pending'}}, [$line, $source_info];
       # current line is the first from macro expansion
       my $new_text = shift @$new_lines;
@@ -4258,6 +4293,7 @@ sub _process_remaining_on_line($$$$)
            $current->{'cmdname'}), $source_info);
         $additional_newline = 1;
       }
+      #$current->{'extra'} = {} if (!$current->{'extra'});
       if (!defined($current->{'extra'}->{'spaces'})) {
         $line =~ s/^(\s+)//;
         $current->{'extra'}->{'spaces'} = $added_space;
@@ -4699,7 +4735,7 @@ sub _process_remaining_on_line($$$$)
         } elsif ($arg_spec eq 'special') {
           ($args, $has_comment)
            = _parse_special_misc_command($self, $line, $command, $source_info);
-          $misc->{'extra'}->{'arg_line'} = $line;
+          $misc->{'extra'} = {'arg_line' => $line};
         }
 
         # if using the @set txi* instead of a proper @-command, replace
@@ -4739,8 +4775,10 @@ sub _process_remaining_on_line($$$$)
                 { 'type' => 'misc_arg', 'text' => $arg,
                   'parent' => $current->{'contents'}->[-1] };
             }
-            $misc->{'extra'}->{'misc_args'} = $args
-              if (scalar(@$args) and $arg_spec ne 'skipline');
+            if (scalar(@$args) and $arg_spec ne 'skipline') {
+              #$misc->{'extra'} = {} if (!$misc->{'extra'});
+              $misc->{'extra'}->{'misc_args'} = $args;
+            }
           } else {
             $misc = undef;
           }
@@ -4798,7 +4836,7 @@ sub _process_remaining_on_line($$$$)
             if ($parent->{'cmdname'} eq 'subentry') {
               $subentry_level = $parent->{'extra'}->{'level'} + 1;
             }
-            $misc->{'extra'}->{'level'} = $subentry_level;
+            $misc->{'extra'} = {'level' => $subentry_level};
             if ($subentry_level > 2) {
               $self->_line_error(__(
           "no more than two levels of index subentry are allowed"),
@@ -4808,15 +4846,13 @@ sub _process_remaining_on_line($$$$)
             # command.  This means that spaces are preserved properly
             # when converting back to Texinfo.
             $current = _end_line($self, $current, $source_info);
-          }
-          push @{$current->{'contents'}}, $misc;
-          $misc->{'parent'} = $current;
-          if ($sectioning_heading_commands{$command}) {
+          } elsif ($sectioning_heading_commands{$command}) {
             if ($self->{'sections_level'}) {
-              $current->{'contents'}->[-1]->{'extra'}->{'sections_level'}
-                = $self->{'sections_level'};
+              $misc->{'extra'} = {'sections_level' => 
$self->{'sections_level'}};
             }
           }
+          push @{$current->{'contents'}}, $misc;
+          $misc->{'parent'} = $current;
           # def*x
           if ($def_commands{$command}) {
             my $base_command = $command;
@@ -4870,11 +4906,14 @@ sub _process_remaining_on_line($$$$)
                     and $parent->{'type'} eq 'brace_command_context');
             if ($parent->{'cmdname'}) {
               if ($parent->{'cmdname'} eq 'titlepage') {
+                #$current->{'extra'} = {} if (!$current->{'extra'});
                 $current->{'extra'}->{'titlepage'} = $parent;
                 $found = 1;
               } elsif ($parent->{'cmdname'} eq 'quotation' or
                   $parent->{'cmdname'} eq 'smallquotation') {
+                #$parent->{'extra'} = {} if (!$parent->{'extra'});
                 push @{$parent->{'extra'}->{'authors'}}, $current;
+                #$current->{'extra'} = {} if (!$current->{'extra'});
                 $current->{'extra'}->{'quotation'} = $parent;
                 $found = 1;
               }
@@ -5119,13 +5158,16 @@ sub _process_remaining_on_line($$$$)
       }
       $current = $current->{'contents'}->[-1];
       if ($command eq 'click') {
+        #$current->{'extra'} = {} if (!$current->{'extra'});
         $current->{'extra'}->{'clickstyle'} = $self->{'clickstyle'};
       } elsif ($command eq 'kbd'
                and _kbd_formatted_as_code($self, $current)) {
+        #$current->{'extra'} = {} if (!$current->{'extra'});
         $current->{'extra'}->{'code'} = 1;
       }
       if ($self->{'definfoenclose'}->{$command}) {
         $current->{'type'} = 'definfoenclose_command';
+        #$current->{'extra'} = {} if (!$current->{'extra'});
         $current->{'extra'}->{'begin'}
           = $self->{'definfoenclose'}->{$command}->[0];
         $current->{'extra'}->{'end'}
@@ -5197,6 +5239,7 @@ sub _process_remaining_on_line($$$$)
                 $self->_line_warn(sprintf(__("ignoring multiple \@%s"),
                                           $command), $source_info);
               } else {
+                #$current->{'parent'}->{'extra'} = {} if 
(!$current->{'parent'}->{'extra'});
                 $current->{'parent'}->{'extra'}->{'float'} = $float;
                 $float->{'extra'}->{$command} = $current->{'parent'};
               }
@@ -5327,6 +5370,7 @@ sub _process_remaining_on_line($$$$)
             _register_label($self->{'targets'}, $current->{'parent'},
                             $parsed_anchor);
             if (@{$self->{'regions_stack'}}) {
+              #$current->{'extra'} = {} if (!$current->{'extra'});
               $current->{'extra'}->{'region'} = $self->{'regions_stack'}->[-1];
             }
           }
@@ -5357,6 +5401,7 @@ sub _process_remaining_on_line($$$$)
                     and !$parsed_ref_node->{'manual_content'}) {
                   push @{$self->{'internal_references'}}, $ref;
                 }
+                #$ref->{'extra'} = {} if (!$ref->{'extra'});
                 $ref->{'extra'}->{'node_argument'} = $parsed_ref_node
               }
             }
@@ -5390,9 +5435,11 @@ sub _process_remaining_on_line($$$$)
             $self->_line_error(
                __("\@image missing filename argument"), $source_info);
           }
-          $image->{'extra'}->{'input_perl_encoding'}
-               = $self->{'info'}->{'input_perl_encoding'}
-                    if defined $self->{'info'}->{'input_perl_encoding'};
+          if (defined $self->{'info'}->{'input_perl_encoding'}) {
+            #$image->{'extra'} = {} if (!$image->{'extra'});
+            $image->{'extra'}->{'input_perl_encoding'}
+               = $self->{'info'}->{'input_perl_encoding'};
+          }
         } elsif($current->{'parent'}->{'cmdname'} eq 'dotless') {
           my $dotless = $current->{'parent'};
           if ($current->{'contents'}
@@ -5522,6 +5569,7 @@ sub _process_remaining_on_line($$$$)
                                  ord('}')), $source_info);
       }
     } elsif ($separator eq ','
+             and $current->{'parent'}
              and $current->{'parent'}->{'remaining_args'}) {
       _abort_empty_line ($self, $current);
       _isolate_last_space($self, $current);
@@ -5529,6 +5577,7 @@ sub _process_remaining_on_line($$$$)
       $current = $current->{'parent'};
       if ($inline_commands{$current->{'cmdname'}}) {
         my $expandp = 0;
+        #$current->{'extra'} = {} if (!$current->{'extra'});
         if (! $current->{'extra'}->{'format'}) {
           my $inline_type;
           if (defined $current->{'args'}->[0]
@@ -5899,6 +5948,7 @@ sub _parse_line_command_args($$$)
   if (!$arg->{'contents'}) {
     $self->_command_error($line_command, $source_info,
                __("\@%s missing argument"), $command);
+    #$line_command->{'extra'} = {} if (!$line_command->{'extra'});
     $line_command->{'extra'}->{'missing_argument'} = 1;
     return undef;
   }
@@ -5984,7 +6034,7 @@ sub _parse_line_command_args($$$)
           $self->{'index_names'}->{$name}->{'name'} = $name;
         }
         if (!exists($self->{'index_names'}->{$name}->{'contained_indices'})) {
-          $self->{'index_names'}->{$name}->{'contained_indices'}->{$name} = 1;
+          $self->{'index_names'}->{$name}->{'contained_indices'} = {$name => 
1};
         }
         $self->{'line_commands'}->{$name.'index'} = 'line';
         $self->{'no_paragraph_commands'}->{$name.'index'} = 1;
@@ -6022,12 +6072,14 @@ sub _parse_line_command_args($$$)
           $in_code = 1 if ($command eq 'syncodeindex');
           $self->{'merged_indices'}->{$index_from} = $current_to;
           $index_from_info->{'in_code'} = $in_code;
-          foreach my $contained_index (keys 
%{$index_from_info->{'contained_indices'}}) {
-            $index_to_info->{'contained_indices'}->{$contained_index} = 1;
-            $self->{'index_names'}->{$contained_index}->{'merged_in'} = 
$current_to;
-            $self->{'merged_indices'}->{$contained_index} = $current_to;
+          if ($index_from_info->{'contained_indices'}) {
+            foreach my $contained_index (keys 
%{$index_from_info->{'contained_indices'}}) {
+              $index_to_info->{'contained_indices'}->{$contained_index} = 1;
+              $self->{'index_names'}->{$contained_index}->{'merged_in'} = 
$current_to;
+              $self->{'merged_indices'}->{$contained_index} = $current_to;
+            }
+            delete $index_from_info->{'contained_indices'};
           }
-          delete $index_from_info->{'contained_indices'};
           $index_from_info->{'merged_in'} = $current_to;
           $index_to_info->{'contained_indices'}->{$index_from} = 1;
           $args = [$index_from, $index_to];



reply via email to

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