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 (_init_context_stack)


From: Patrice Dumas
Subject: branch master updated: * tp/Texinfo/ParserNonXS.pm (_init_context_stack) (_push_context, _pop_context, _get_context_stack) (_top_context): use functions to encapsulate parser 'context_state'. Put context on context stack but also th eassociated command. Gavin idea.
Date: Fri, 20 Aug 2021 18:34:54 -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 cad513e  * tp/Texinfo/ParserNonXS.pm (_init_context_stack) 
(_push_context, _pop_context, _get_context_stack) (_top_context): use functions 
to encapsulate parser 'context_state'.  Put context on context stack but also 
th eassociated command.  Gavin idea.
cad513e is described below

commit cad513ef6087ec82abf9120e35b1fb24c3d84745
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Sat Aug 21 00:34:22 2021 +0200

    * tp/Texinfo/ParserNonXS.pm (_init_context_stack)
    (_push_context, _pop_context, _get_context_stack)
    (_top_context): use functions to encapsulate
    parser 'context_state'.  Put context on context stack but
    also th eassociated command.  Gavin idea.
---
 ChangeLog                 |   8 ++
 tp/Texinfo/ParserNonXS.pm | 286 ++++++++++++++++++++++++----------------------
 2 files changed, 156 insertions(+), 138 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index dc3bbc7..19f2c00 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2021-08-21  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/ParserNonXS.pm (_init_context_stack)
+       (_push_context, _pop_context, _get_context_stack)
+       (_top_context): use functions to encapsulate
+       parser 'context_state'.  Put context on context stack but
+       also th eassociated command.  Gavin idea.
+
 2021-08-17  Patrice Dumas  <pertusus@free.fr>
 
        * tp/init/tex4ht.pm (tex4ht_prepare, tex4ht_convert)
diff --git a/tp/Texinfo/ParserNonXS.pm b/tp/Texinfo/ParserNonXS.pm
index 8a00940..95da9f9 100644
--- a/tp/Texinfo/ParserNonXS.pm
+++ b/tp/Texinfo/ParserNonXS.pm
@@ -36,6 +36,8 @@ use Carp qw(cluck);
 
 use Data::Dumper;
 
+use List::Util;
+
 # to detect if an encoding may be used to open the files
 use Encode;
 
@@ -465,6 +467,59 @@ foreach my $no_paragraph_context ('math', 'menu', 
@preformatted_contexts,
   $no_paragraph_contexts{$no_paragraph_context} = 1;
 };
 
+# if $reuse is set, try to reuse the existing array
+# FIXME: is it useful to have $reuse?
+sub _init_context_stack($;$)
+{
+  my $self = shift;
+  my $reuse_existing = shift;
+  if (not ($reuse_existing and exists($self->{'context_stack'}))) {
+    $self->{'context_stack'} = [];
+    $self->{'context_command_stack'} = [];
+  }
+  $self->{'context_stack'}->[0] = '_root';
+  $self->{'context_command_stack'}->[0] = '';
+}
+
+sub _push_context($$$)
+{
+  my ($self, $context, $command_or_type) = @_;
+
+  push @{$self->{'context_stack'}}, $context;
+  push @{$self->{'context_command_stack'}}, $command_or_type;
+}
+
+# if needed it could be possible to guard against removing '_root' context
+sub _pop_context($;$$$$)
+{
+  my ($self, $expected_contexts, $line_nr, $current, $message) = @_;
+
+  my $error = 0;
+  my $popped_context = pop @{$self->{'context_stack'}};
+  if (defined($expected_contexts) and (
+       not List::Util::any {$_ eq $popped_context} @$expected_contexts)) {
+    my $error_message = "context $popped_context instead of "
+         .join(" or ".@$expected_contexts);
+    $error_message .= $message if (defined($message));
+    $self->_bug_message($error_message, $line_nr, $current);
+    $error = 1;
+  }
+  my $popped_command = pop @{$self->{'context_command_stack'}};
+  return $error, $popped_context, $popped_command;
+}
+
+sub _get_context_stack($)
+{
+  my $self = shift;
+  (undef, my @context_stack) = @{$self->{'context_stack'}};
+  return @context_stack;
+}
+
+sub _top_context($)
+{
+  my $self = shift;
+  return $self->{'context_stack'}->[-1];
+}
 
 
 # Format a bug message
@@ -482,7 +537,8 @@ sub _bug_message($$;$$)
     }
     $line_message .= "\n";
   }
-  my $message_context_stack = "context_stack: (@{$self->{'context_stack'}})\n";
+  my @context_stack = $self->_get_context_stack;
+  my $message_context_stack = "context_stack: (@context_stack)\n";
   my $current_element_message = '';
   if ($current) {
     $current_element_message = "current: ". _print_current($current);
@@ -593,7 +649,7 @@ sub _setup_parser {
       $parser->{'explained_commands'}->{$explained_command} = {};
     }
   }
-  $parser->{'context_stack'} = [ '_root' ];
+  $parser->_init_context_stack();
   $parser->{'regions_stack'} = [];
   $parser->{'macro_stack'} = [];
   $parser->{'conditionals_stack'} = [];
@@ -643,7 +699,7 @@ sub simple_parser(;$)
       $parser->{'explained_commands'}->{$explained_command} = {};
     }
   }
-  $parser->{'context_stack'} = [ '_root' ];
+  $parser->_init_context_stack();
   $parser->{'regions_stack'} = [];
   $parser->{'macro_stack'} = [];
   $parser->{'conditionals_stack'} = [];
@@ -780,6 +836,7 @@ sub parse_texi_file($$)
   while ($line = <$filehandle>) {
     $line_nr++;
     if ($line =~ /^ *\\input/ or $line =~ /^\s*$/) {
+      # DEL as comment character
       $line =~ s/\x{7F}.*\s*//;
       push @first_lines, $line;
     } else {
@@ -1058,7 +1115,7 @@ sub _begin_paragraph($$;$)
   # !$current->{'type'} is true for @-commands.  In fact it is unclear
   # that there may be cases of !$current->{'type'} and !$current->{'cmdname'}
   if ((!$current->{'type'} or $type_with_paragraph{$current->{'type'}})
-      and !$no_paragraph_contexts{$self->{'context_stack'}->[-1]}) {
+      and !$no_paragraph_contexts{$self->_top_context()}) {
     if (!defined($current->{'contents'})) {
       $self->_bug_message("contents undef", $line_nr, $current);
       die;
@@ -1097,12 +1154,13 @@ sub _begin_preformatted($$)
 {
   my ($self, $current) = @_;
 
-  if ($preformatted_contexts{$self->{'context_stack'}->[-1]}) {
-    push @{$current->{'contents'}}, 
-          { 'type' => $self->{'context_stack'}->[-1], 
+  my $top_context = $self->_top_context();
+  if ($preformatted_contexts{$top_context}) {
+    push @{$current->{'contents'}},
+          { 'type' => $top_context,
             'parent' => $current, 'contents' => [] };
     $current = $current->{'contents'}->[-1];
-    print STDERR "PREFORMATTED $self->{'context_stack'}->[-1]\n" if 
($self->{'DEBUG'});
+    print STDERR "PREFORMATTED $top_context\n" if ($self->{'DEBUG'});
   }
   return $current;
 }
@@ -1533,7 +1591,7 @@ sub _close_current($$$;$$)
   if ($current->{'cmdname'}) {
     print STDERR "CLOSING(_close_current) \@$current->{'cmdname'}\n" if 
($self->{'DEBUG'});
     if (exists($brace_commands{$current->{'cmdname'}})) {
-      pop @{$self->{'context_stack'}}
+      $self->_pop_context()
          if (exists $context_brace_commands{$current->{'cmdname'}});
       $current = _close_brace_command($self, $current, $line_nr, 
                                       $closed_command, $interrupting_command);
@@ -1557,7 +1615,7 @@ sub _close_current($$$;$$)
           or $menu_commands{$current->{'cmdname'}}
           or $format_raw_commands{$current->{'cmdname'}}
           or $math_commands{$current->{'cmdname'}}) {
-        my $context = pop @{$self->{'context_stack'}};
+        $self->_pop_context();
       }
       pop @{$self->{'regions_stack'}} 
          if ($region_commands{$current->{'cmdname'}});
@@ -1583,11 +1641,7 @@ sub _close_current($$$;$$)
 
     } elsif ($current->{'type'} eq 'menu_comment' 
           or $current->{'type'} eq 'menu_entry_description') {
-      my $context = pop @{$self->{'context_stack'}};
-      if ($context ne 'preformatted') {
-        $self->_bug_message("context $context instead of preformatted", 
-                            $line_nr, $current);
-      }
+      $self->_pop_context(['preformatted'], $line_nr, $current);
       # close empty menu_comment
       if ($current->{'type'} eq 'menu_comment'
           and !@{$current->{'contents'}}) {
@@ -1595,12 +1649,8 @@ sub _close_current($$$;$$)
       }
     } elsif ($current->{'type'} eq 'line_arg'
              or $current->{'type'} eq 'block_line_arg') {
-      my $context = pop @{$self->{'context_stack'}};
-      if ($context ne 'line' and $context ne 'def') {
-        $self->_bug_message("context $context instead of line or def", 
-                            $line_nr, $current);
-        die;
-      }
+      my ($error) = $self->_pop_context(['line', 'def'], $line_nr, $current);
+      die if ($error);
     }
     $current = $current->{'parent'};
   } else { # Should never go here.
@@ -1645,33 +1695,21 @@ sub _close_commands($$$;$$)
   }
 
   my $closed_element;
-  if ($closed_command and $current->{'cmdname'} 
+  if ($closed_command and $current->{'cmdname'}
       and $current->{'cmdname'} eq $closed_command) {
     if ($preformatted_commands{$current->{'cmdname'}}) {
-      my $context = pop @{$self->{'context_stack'}};
-      if ($context ne 'preformatted') {
-        $self->_bug_message("context $context instead of preformatted for 
$closed_command", 
-                            $line_nr, $current);
-      }
+      $self->_pop_context(['preformatted'], $line_nr, $current,
+                          "for $closed_command");
     } elsif ($format_raw_commands{$current->{'cmdname'}}) {
-      my $context = pop @{$self->{'context_stack'}};
-      if ($context ne 'rawpreformatted') {
-        $self->_bug_message("context $context instead of rawpreformatted for 
$closed_command", 
-                            $line_nr, $current);
-      }
+      $self->_pop_context(['rawpreformatted'], $line_nr, $current,
+                          "for $closed_command");
     } elsif ($menu_commands{$current->{'cmdname'}}) {
-      my $context = pop @{$self->{'context_stack'}};
       # may be in menu, but context is preformatted if in a preformatted too.
-      if ($context ne 'menu' and $context ne 'preformatted') {
-        $self->_bug_message("context $context instead of preformatted or menu 
for $closed_command", 
-                            $line_nr, $current);
-      }
+      $self->_pop_context(['menu', 'preformatted'], $line_nr, $current,
+                          "for $closed_command");
     } elsif ($math_commands{$current->{'cmdname'}}) {
-      my $context = pop @{$self->{'context_stack'}};
-      if ($context ne 'math') {
-        $self->_bug_message("context $context instead of math for 
$closed_command",
-                            $line_nr, $current);
-      }
+      $self->_pop_context(['math'], $line_nr, $current,
+                          "for $closed_command");
     }
     pop @{$self->{'regions_stack'}} 
        if ($region_commands{$current->{'cmdname'}});
@@ -1825,6 +1863,7 @@ sub _next_text($$)
         if (eof($fh) and $line !~ /\n/) {
           $line .= "\n";
         }
+        # DEL as comment character
         $line =~ s/\x{7F}.*\s*//;
         $input->{'line_nr'}++;
         return ($line, {'line_nr' => $input->{'line_nr'}, 
@@ -2022,7 +2061,7 @@ sub _abort_empty_line {
     } elsif ($spaces_element->{'type'} eq 'empty_line') {
       # exactly the same condition as to begin a paragraph
       if ((!$current->{'type'} or $type_with_paragraph{$current->{'type'}})
-         and !$no_paragraph_contexts{$self->{'context_stack'}->[-1]}) {
+         and !$no_paragraph_contexts{$self->_top_context()}) {
         $spaces_element->{'type'} = 'empty_spaces_before_paragraph';
       } else { 
         delete $spaces_element->{'type'};
@@ -2497,11 +2536,8 @@ sub _end_line($$$)
         $current = $current->{'parent'};
         pop @{$current->{'contents'}} if ($empty_preformatted);
       }
-      my $context = pop @{$self->{'context_stack'}};
-      if ($context ne 'preformatted') {
-        $self->_bug_message("context $context instead of preformatted in empty 
line after menu_entry_description", 
-                            $line_nr, $current);
-      }
+      $self->_pop_context(['preformatted'], $line_nr, $current,
+                          'in empty line after menu_entry_description');
       
       # first parent is menu_entry
       $current = $current->{'parent'}->{'parent'};
@@ -2517,9 +2553,9 @@ sub _end_line($$$)
       push @{$current->{'contents'}}, { 'type' => 'after_description_line', 
                                         'text' => $empty_line->{'text'},
                                         'parent' => $current };
-      push @{$self->{'context_stack'}}, 'preformatted';
+      $self->_push_context('preformatted', 'menu_comment');
       print STDERR "MENU: END DESCRIPTION, OPEN COMMENT\n" if 
($self->{'DEBUG'});
-    } elsif (!$no_paragraph_contexts{$self->{'context_stack'}->[-1]}) {
+    } elsif (!$no_paragraph_contexts{$self->_top_context()}) {
       $current = _end_paragraph($self, $current, $line_nr);
     }
 
@@ -2549,6 +2585,7 @@ sub _end_line($$$)
     if ($empty_menu_entry_node 
           or $current->{'type'} eq 'menu_entry_name') {
       my $description_or_menu_comment;
+      my $menu_type_reopened = 'menu_description';
       print STDERR "FINALLY NOT MENU ENTRY\n" if ($self->{'DEBUG'});
       my $menu = $current->{'parent'}->{'parent'};
       my $menu_entry = pop @{$menu->{'contents'}};
@@ -2576,6 +2613,7 @@ sub _end_line($$$)
       } elsif (@{$menu->{'contents'}} and $menu->{'contents'}->[-1]->{'type'}
          and $menu->{'contents'}->[-1]->{'type'} eq 'menu_comment') {
         $description_or_menu_comment = $menu->{'contents'}->[-1];
+        $menu_type_reopened = 'menu_comment';
       }
       if ($description_or_menu_comment) {
         $current = $description_or_menu_comment;
@@ -2591,7 +2629,7 @@ sub _end_line($$$)
                                     'contents' => [] };
           $current = $current->{'contents'}->[-1];
         }
-        push @{$self->{'context_stack'}}, 'preformatted';
+        $self->_push_context('preformatted', $menu_type_reopened);
       } else {
         push @{$menu->{'contents'}}, {'type' => 'menu_comment',
                                     'parent' => $menu,
@@ -2601,7 +2639,7 @@ sub _end_line($$$)
                                   'parent' => $current,
                                   'contents' => [] };
         $current = $current->{'contents'}->[-1];
-        push @{$self->{'context_stack'}}, 'preformatted';
+        $self->_push_context('preformatted', 'menu_comment');
         print STDERR "THEN MENU_COMMENT OPEN\n" if ($self->{'DEBUG'});
       }
       while (@{$menu_entry->{'args'}}) {
@@ -2638,12 +2676,8 @@ sub _end_line($$$)
   } elsif ($current->{'parent'}
             and $current->{'parent'}->{'type'}
             and $current->{'parent'}->{'type'} eq 'def_line') {
-    my $def_context = pop @{$self->{'context_stack'}};
-    if ($def_context ne 'def') {
-      $self->_bug_message("context $def_context instead of def", 
-                          $line_nr, $current);
-      die; 
-    }
+    my ($error) = $self->_pop_context(['def'], $line_nr, $current);
+    die if ($error);
     my $def_command = $current->{'parent'}->{'extra'}->{'def_command'};
     my $arguments = _parse_def($self, $def_command, $current);
     if (scalar(@$arguments)) {
@@ -2713,11 +2747,7 @@ sub _end_line($$$)
   } elsif ($current->{'type'}
             and $current->{'type'} eq 'block_line_arg') {
     my $empty_text;
-    my $context = pop @{$self->{'context_stack'}};
-    if ($context ne 'line') {
-      $self->_bug_message("context $context instead of line in 
block_line_arg", 
-                          $line_nr, $current);
-    }
+    $self->_pop_context(['line'], $line_nr, $current, 'in block_line_arg');
     # @multitable args
     if ($current->{'parent'}->{'cmdname'}
                and $current->{'parent'}->{'cmdname'} eq 'multitable') {
@@ -2888,7 +2918,7 @@ sub _end_line($$$)
                                        'contents' => [] };
       $current = $current->{'contents'}->[-1];
       print STDERR "MENU_COMMENT OPEN\n" if ($self->{'DEBUG'});
-      push @{$self->{'context_stack'}}, 'preformatted';
+      $self->_push_context('preformatted', 'menu_comment');
     }
     $current = _begin_preformatted($self, $current);
 
@@ -2907,11 +2937,7 @@ sub _end_line($$$)
   # Never go here if skipline/noarg/...
   } elsif ($current->{'type'} 
            and $current->{'type'} eq 'line_arg') {
-    my $context = pop @{$self->{'context_stack'}};
-    if ($context ne 'line') {
-      $self->_bug_message("context $context instead of line in line_arg", 
-                          $line_nr, $current);
-    }
+    $self->_pop_context(['line'], $line_nr, $current, 'in line_arg');
     _isolate_last_space($self, $current);
 
     # first parent is the @command, second is the parent
@@ -3113,14 +3139,14 @@ sub _end_line($$$)
 
           # closing a menu command, but still in a menu. Open a menu_comment
           if ($menu_commands{$closed_command->{'cmdname'}} 
-              and $self->{'context_stack'}->[-1] eq 'menu') {
+              and $self->_top_context() eq 'menu') {
             print STDERR "CLOSE MENU but still in menu context\n"
               if ($self->{'DEBUG'});
             push @{$current->{'contents'}}, {'type' => 'menu_comment',
                                              'parent' => $current,
                                              'contents' => [] };
             $current = $current->{'contents'}->[-1];
-            push @{$self->{'context_stack'}}, 'preformatted';
+            $self->_push_context('preformatted', 'menu_comment');
           }
         } else {
           # block command not found for @end
@@ -3151,11 +3177,7 @@ sub _end_line($$$)
                $command);
       } else {
         # This is the multitable block_line_arg line context
-        my $context = pop @{$self->{'context_stack'}};
-        if ($context ne 'line') {
-          $self->_bug_message("context $context instead of line for 
multitable", 
-                               $line_nr, $current);
-        }
+        $self->_pop_context(['line'], $line_nr, $current, 'for multitable');
         $current = $current->{'parent'};
         $current->{'extra'}->{'max_columns'} = 0;
         if (defined($misc_cmd->{'extra'}->{'misc_args'})) {
@@ -3235,11 +3257,11 @@ sub _end_line($$$)
 
   # this happens if there is a nesting of line @-commands on a line.
   # they are reprocessed here.
-  if ($self->{'context_stack'}->[-1] eq 'line' 
-            or $self->{'context_stack'}->[-1] eq 'def') {
-    print STDERR "Still opened line command 
$self->{'context_stack'}->[-1]:"._print_current($current) 
+  my $top_context = $self->_top_context();
+  if ($top_context eq 'line' or $top_context eq 'def') {
+    print STDERR "Still opened line command 
$top_context:"._print_current($current)
       if ($self->{'DEBUG'});
-    if ($self->{'context_stack'}->[-1] eq 'def') {
+    if ($top_context eq 'def') {
       while ($current->{'parent'} and !($current->{'parent'}->{'type'}
             and $current->{'parent'}->{'type'} eq 'def_line')) {
         $current = _close_current($self, $current, $line_nr);
@@ -3365,7 +3387,8 @@ sub _enter_menu_entry_node($$$)
                                    'parent' => $current,
                                    'contents' => [] };
   $current = $current->{'contents'}->[-1];
-  push @{$self->{'context_stack'}}, 'preformatted';
+  # not clear what is the correct associated command or type
+  $self->_push_context('preformatted', 'menu_entry_description');
   return $current;
 }
 
@@ -3461,7 +3484,7 @@ sub _check_valid_nesting {
                         and $current->{'type'} eq 'line_arg'))) {
         $invalid_parent = $current->{'parent'}->{'cmdname'};
       }
-    } elsif ($self->{'context_stack'}->[-1] eq 'def'
+    } elsif ($self->_top_context() eq 'def'
       # FIXME instead of hardcoding in_full_line_commands_no_refs
       # it would be better to use the parent command valid_nesting.
              and !$in_full_line_commands_no_refs{$command}) {
@@ -3501,8 +3524,8 @@ sub _parse_texi($;$)
     if ($self->{'DEBUG'}) {
       my $line_text = '';
       $line_text = "$line_nr->{'line_nr'}.$line_nr->{'macro'}" if ($line_nr);
-      print STDERR "NEW LINE(".join('|', 
@{$self->{'context_stack'}}).":@{$self->{'conditionals_stack'}}:$line_text): 
$line";
-      #print STDERR "CONTEXT_STACK 
".join('|',@{$self->{'context_stack'}})."\n";
+      print STDERR "NEW LINE(".join('|', 
$self->_get_context_stack()).":@{$self->{'conditionals_stack'}}:$line_text): 
$line";
+      #print STDERR "CONTEXT_STACK 
".join('|',$self->_get_context_stack())."\n";
     }
 
     if (not 
@@ -3516,7 +3539,7 @@ sub _parse_texi($;$)
             and $current->{'parent'}->{'cmdname'} eq 'verb')
           )
         # not def line
-        and $self->{'context_stack'}->[-1] ne 'def') {
+        and $self->_top_context() ne 'def') {
       next NEXT_LINE if _check_line_directive ($self, $line, $line_nr);
       print STDERR "BEGIN LINE\n" if ($self->{'DEBUG'});
 
@@ -3936,11 +3959,8 @@ sub _parse_texi($;$)
             }
             $current = $current->{'parent'}->{'parent'}->{'parent'};
           }
-          my $context = pop @{$self->{'context_stack'}};
-          if ($context ne 'preformatted') {
-            $self->_bug_message("context $context instead of preformatted 
after menu leading star", 
-                                $line_nr, $current);
-          }
+          $self->_pop_context(['preformatted'], $line_nr, $current,
+                              'after menu leading star');
           push @{$current->{'contents'}}, { 'type' => 'menu_entry',
                                             'parent' => $current,
                                           };
@@ -4074,7 +4094,7 @@ sub _parse_texi($;$)
         # special case with @ followed by a newline protecting end of lines
         # in @def*
         my $def_line_continuation
-          = ($self->{'context_stack'}->[-1] eq 'def' and $command eq "\n");
+          = ($self->_top_context() eq 'def' and $command eq "\n");
 
         if (not $def_line_continuation
                and not _abort_empty_line($self, $current) 
@@ -4433,7 +4453,7 @@ sub _parse_texi($;$)
                 # check that the def*x is first after @def*, no paragraph
                 # in-between.
                 my $after_paragraph = _check_no_text($current);
-                push @{$self->{'context_stack'}}, 'def';
+                $self->_push_context('def', $command);
                 $current->{'contents'}->[-1]->{'type'} = 'def_line';
                 $current->{'contents'}->[-1]->{'extra'} = 
                    {'def_command' => $base_command,
@@ -4501,7 +4521,7 @@ sub _parse_texi($;$)
             }
 
             $current = $current->{'args'}->[-1];
-            push @{$self->{'context_stack'}}, 'line' 
+            $self->_push_context('line', $command) 
               unless ($def_commands{$command});
             $line = _start_empty_line_after_command($line, $current, $misc);
           }
@@ -4602,12 +4622,8 @@ sub _parse_texi($;$)
               pop @{$menu->{'contents'}}
                 if (!@{$current->{'contents'}});
 
-              my $context = pop @{$self->{'context_stack'}};
-              if ($context ne 'preformatted') {
-                $self->_bug_message("context $context instead of preformatted 
in new menu", 
-                                   $line_nr, $current);
-              }
-              
+              $self->_pop_context(['preformatted'], $line_nr, $current,
+                                  'in new menu');
               if ($menu->{'type'} and $menu->{'type'} eq 'menu_entry') {
                 $menu = $menu->{'parent'};
               }
@@ -4618,7 +4634,7 @@ sub _parse_texi($;$)
             # definition line.  This allows to have a treatement similar
             # with def*x.
             if ($def_commands{$command}) {
-              push @{$self->{'context_stack'}}, 'def';
+              $self->_push_context('def', $command);
               $block = { 'parent' => $current,
                          'cmdname' => $command,
                          'contents' => [] };
@@ -4642,11 +4658,11 @@ sub _parse_texi($;$)
 
             if ($block_arg_commands{$command}) {
               if ($preformatted_commands{$command}) {
-                push @{$self->{'context_stack'}}, 'preformatted';
+                $self->_push_context('preformatted', $command);
               } elsif ($math_commands{$command}) {
-                push @{$self->{'context_stack'}}, 'math';
+                $self->_push_context('math', $command);
               } elsif ($format_raw_commands{$command}) {
-                push @{$self->{'context_stack'}}, 'rawpreformatted';
+                $self->_push_context('rawpreformatted', $command);
                 if (not $self->{'expanded_formats_hash'}->{$command}) {
                   push @{$current->{'contents'}}, {
                     'parent' => $current,
@@ -4681,10 +4697,10 @@ sub _parse_texi($;$)
                 push @{$self->{'regions_stack'}}, $block;
               }
               if ($menu_commands{$command}) {
-                if ($self->{'context_stack'}->[-1] eq 'preformatted') {
-                  push @{$self->{'context_stack'}}, 'preformatted';
+                if ($self->_top_context() eq 'preformatted') {
+                  $self->_push_context('preformatted', $command);
                 } else {
-                  push @{$self->{'context_stack'}}, 'menu';
+                  $self->_push_context('menu', $command);
                 }
                 push @{$self->{'info'}->{'dircategory_direntry'}}, $block
                   if ($command eq 'direntry');
@@ -4717,7 +4733,7 @@ sub _parse_texi($;$)
                 $current->{'remaining_args'} = -1; # unlimited args
               }
               $current = $current->{'args'}->[-1];
-              push @{$self->{'context_stack'}}, 'line' 
+              $self->_push_context('line', $command)
                 unless ($def_commands{$command});
             }
             $block->{'line_nr'} = $line_nr;
@@ -4743,7 +4759,7 @@ sub _parse_texi($;$)
           if ($command eq 'click') {
             $current->{'extra'}->{'clickstyle'} = $self->{'clickstyle'};
           } elsif ($command eq 'kbd') {
-            if ($self->{'context_stack'}->[-1] eq 'preformatted'
+            if ($self->_top_context() eq 'preformatted'
                 and $self->{'kbdinputstyle'} ne 'distinct') {
               $current->{'extra'}->{'code'} = 1;
             } elsif ($self->{'kbdinputstyle'} eq 'code'
@@ -4763,7 +4779,7 @@ sub _parse_texi($;$)
           push @{$current->{'contents'}},
                  { 'cmdname' => $command, 'parent' => $current };
           # FIXME generalize?
-          if ($command eq '\\' and $self->{'context_stack'}->[-1] ne 'math') {
+          if ($command eq '\\' and $self->_top_context() ne 'math') {
             $self->line_warn(sprintf(__("\@%s should only appear in math 
context"), 
                                         $command), $line_nr);
           }
@@ -4830,9 +4846,9 @@ sub _parse_texi($;$)
                 }
               }
               if ($math_commands{$command}) {
-                push @{$self->{'context_stack'}}, 'math';
+                $self->_push_context('math', $command);
               } else {
-                push @{$self->{'context_stack'}}, $command;
+                $self->_push_context($command, $command);
               }
               $line =~ s/([^\S\f\n]*)//;
               $current->{'type'} = 'brace_command_context';
@@ -4853,7 +4869,7 @@ sub _parse_texi($;$)
                             'extra' => {'command' => $current}
                                       };
               }
-              push @{$self->{'context_stack'}}, $command
+              $self->_push_context($command, $command)
                 if ($command eq 'inlineraw');
             }
             print STDERR "OPENED \@$current->{'parent'}->{'cmdname'}, 
remaining: "
@@ -4887,9 +4903,9 @@ sub _parse_texi($;$)
                                              'parent' => $current };
           # matching braces accepted in a rawpreformatted or math or ignored
           # code
-          } elsif ($self->{'context_stack'}->[-1] eq 'math'
-                   or $self->{'context_stack'}->[-1] eq 'rawpreformatted'
-                   or $self->{'context_stack'}->[-1] eq 'inlineraw') {
+          } elsif ($self->_top_context() eq 'math'
+                   or $self->_top_context() eq 'rawpreformatted'
+                   or $self->_top_context() eq 'inlineraw') {
             push @{$current->{'contents'}},
                  { 'type' => 'bracketed', 'contents' => [],
                    'parent' => $current, 'line_nr' => $line_nr };
@@ -4912,16 +4928,14 @@ sub _parse_texi($;$)
               and exists $brace_commands{$current->{'parent'}->{'cmdname'}}) {
             # for math and footnote out of paragraph
             if ($context_brace_commands{$current->{'parent'}->{'cmdname'}}) {
-              my $top_context = pop @{$self->{'context_stack'}};
               my $command_context = $current->{'parent'}->{'cmdname'};
               if ($math_commands{$current->{'parent'}->{'cmdname'}}) {
                 $command_context = 'math';
               }
-              if ($top_context ne $command_context) {
-                $self->_bug_message("context $top_context instead of brace 
command $current->{'parent'}->{'cmdname'} context $command_context",
-                                   $line_nr, $current);
-                die;
-              }
+              my ($error) = $self->_pop_context([$command_context],
+                       $line_nr, $current,
+                       "for brace command $current->{'parent'}->{'cmdname'}");
+              die if ($error);
             }
             # first is the arg.
             
@@ -5038,12 +5052,10 @@ sub _parse_texi($;$)
               my $current_command = $current->{'parent'};
               if ($inline_commands{$current_command->{'cmdname'}}) {
                 if ($current_command->{'cmdname'} eq 'inlineraw') {
-                  my $context_command = pop @{$self->{'context_stack'}};
-                  if ($context_command ne $current_command->{'cmdname'}) {
-                    $self->_bug_message("context $context_command instead of 
inlineraw $current_command->{'cmdname'}", 
-                                     $line_nr, $current);
-                    die;
-                  }
+                  my ($error) = $self->_pop_context(
+                               [$current_command->{'cmdname'}], $line_nr, 
$current,
+                                ' inlineraw');
+                  die if ($error);
                 }
               }
               if (!@{$current_command->{'args'}} 
@@ -5137,23 +5149,20 @@ sub _parse_texi($;$)
             push @{$current->{'contents'}}, {'text' => '}',
                                              'parent' => $current };
           # footnote caption closing, when there is a paragraph inside.
-          } elsif ($context_brace_commands{$self->{'context_stack'}->[-1]}) {
+          } elsif ($context_brace_commands{$self->_top_context()}) {
              # closing the context under broader situations
              $current = _end_paragraph($self, $current, $line_nr);
              if ($current->{'parent'}
                  and $current->{'parent'}->{'cmdname'}
                  and 
$context_brace_commands{$current->{'parent'}->{'cmdname'}}) {
-              #   and $current->{'parent'}->{'cmdname'} eq 
$self->{'context_stack'}->[-1]) {
-              my $top_context = pop @{$self->{'context_stack'}};
               my $command_context = $current->{'parent'}->{'cmdname'};
               if ($math_commands{$current->{'parent'}->{'cmdname'}}) {
                 $command_context = 'math';
               }
-              if ($top_context ne $command_context) {
-                $self->_bug_message("context $top_context instead of brace 
isolated $current->{'parent'}->{'cmdname'} context $command_context",
-                                   $line_nr, $current);
-                die;
-              }
+              my ($error) = $self->_pop_context([$command_context],
+                       $line_nr, $current,
+                       "for brace isolated $current->{'parent'}->{'cmdname'}");
+              die if ($error);
               print STDERR "CLOSING(context command) 
\@$current->{'parent'}->{'cmdname'}\n" if ($self->{'DEBUG'});
               my $closed_command = $current->{'parent'}->{'cmdname'};
               _register_global_command($self, $current->{'parent'}, $line_nr);
@@ -5340,14 +5349,15 @@ sub _parse_texi($;$)
   }
   $current = _close_commands($self, $current, $line_nr);
 
-  if (@{$self->{'context_stack'}} != 1) {
+  my @context_stack = $self->_get_context_stack();
+  if (scalar(@context_stack) != 0) {
     # This happens in 2 cases in the tests:
     #   @verb not closed on misc commands line
     #   def line escaped with @ ending the file
     if ($self->{'DEBUG'}) {
-      print STDERR "CONTEXT_STACK no empty end _parse_texi: ".join('|', 
@{$self->{'context_stack'}})."\n";
+      print STDERR "CONTEXT_STACK no empty end _parse_texi: ".join('|', 
@context_stack)."\n";
     }
-    @{$self->{'context_stack'}} = ('_root');
+    $self->_init_context_stack(1);
   }
 
   # Call 'labels_information' to initialize labels.



reply via email to

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