texinfo-commits
[Top][All Lists]
Advanced

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

branch master updated: Gather tree information when closing incorrectly


From: Patrice Dumas
Subject: branch master updated: Gather tree information when closing incorrectly nested line command
Date: Wed, 30 Nov 2022 17:02:14 -0500

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 69fa13d0fd Gather tree information when closing incorrectly nested 
line command
69fa13d0fd is described below

commit 69fa13d0fd16a71fa3aadbd2f21ed34e737afadd
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Wed Nov 30 23:00:38 2022 +0100

    Gather tree information when closing incorrectly nested line command
    
    * tp/Texinfo/ParserNonXS.pm (_close_current, _end_line_misc_line)
    (_end_line), tp/Texinfo/XS/parsetexi/close.c (close_current),
    tp/Texinfo/XS/parsetexi/end_line.c: when closing line_arg in
    close_current, use the same code as when closing at end of line,
    such as to gather all the information in the tree, in particular
    rearranging @end in block command and output all the error messages.
---
 ChangeLog                                          |  11 +
 tp/Texinfo/ParserNonXS.pm                          | 705 +++++++++++----------
 tp/Texinfo/XS/parsetexi/close.c                    |  18 +
 tp/Texinfo/XS/parsetexi/end_line.c                 |   6 +-
 tp/Texinfo/XS/parsetexi/parser.h                   |   1 +
 tp/t/results/coverage/bye_on_end_command_line.pl   |  41 +-
 tp/t/results/invalid_nestings/ignored_text.pl      |  37 +-
 .../invalid_nestings/node_on_index_entry_line.pl   |  40 +-
 tp/t/results/invalid_nestings/raw_block_on_line.pl |  40 +-
 .../section_on_index_entry_line.pl                 |  40 +-
 .../unclosed_verb_end_of_line_on_misc_line.pl      |  14 +
 .../invalid_nestings/unclosed_verb_on_misc_line.pl |  12 +
 12 files changed, 595 insertions(+), 370 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index eee756a951..1d82b38b79 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2022-11-30  Patrice Dumas  <pertusus@free.fr>
+
+       Gather tree information when closing incorrectly nested line command
+
+       * tp/Texinfo/ParserNonXS.pm (_close_current, _end_line_misc_line)
+       (_end_line), tp/Texinfo/XS/parsetexi/close.c (close_current),
+       tp/Texinfo/XS/parsetexi/end_line.c: when closing line_arg in
+       close_current, use the same code as when closing at end of line,
+       such as to gather all the information in the tree, in particular
+       rearranging @end in block command and output all the error messages.
+
 2022-11-30  Gavin Smith  <gavinsmith0123@gmail.com>
 
        * configure.ac (AM_INIT_AUTOMAKE): Remove 'readme-alpha' option,
diff --git a/tp/Texinfo/ParserNonXS.pm b/tp/Texinfo/ParserNonXS.pm
index 19b851c752..8e2d268533 100644
--- a/tp/Texinfo/ParserNonXS.pm
+++ b/tp/Texinfo/ParserNonXS.pm
@@ -1114,6 +1114,7 @@ sub _pop_context($$$$;$)
          .join(" or ", @$expected_contexts);
     $error_message .= "; $message" if (defined($message));
     $self->_bug_message($error_message, $source_info, $current);
+    cluck;
     die;
   }
   my $popped_command = pop @{$self->{'context_command_stack'}};
@@ -1916,7 +1917,7 @@ sub _close_current($$$;$$)
       $current = $current->{'parent'};
     } else {
       # There @item and @tab commands are closed, and also line commands
-      # with invalid content
+      # with invalid content.
       $current = $current->{'parent'};
     }
   } elsif ($current->{'type'}) {
@@ -1939,8 +1940,18 @@ sub _close_current($$$;$$)
           and !@{$current->{'contents'}}) {
         pop @{$current->{'parent'}->{'contents'}};
       }
-    } elsif ($current->{'type'} eq 'line_arg'
-             or $current->{'type'} eq 'block_line_arg') {
+    } elsif ($current->{'type'} eq 'line_arg') {
+      if ($current->{'parent'}
+          and $current->{'parent'}->{'type'}
+          and $current->{'parent'}->{'type'} eq 'def_line') {
+        $self->_pop_context(['ct_def'], $source_info, $current);
+      } else {
+        #$current = _end_line_misc_line($self, $current, $source_info);
+        # We ignore the current returned $current, to be sure that
+        # we close the command too.
+        _end_line_misc_line($self, $current, $source_info);
+      }
+    } elsif ($current->{'type'} eq 'block_line_arg') {
       $self->_pop_context(['ct_line', 'ct_def'], $source_info, $current);
     }
     # empty types, not closed or associated to a command that is not closed
@@ -2906,6 +2917,354 @@ sub _convert_to_text {
   return ($text, $superfluous_arg);
 }
 
+sub _end_line_misc_line($$$)
+{
+  my $self = shift;
+  my $current = shift;
+  my $source_info = shift;
+
+  $self->_pop_context(['ct_line'], $source_info, $current, 'in line_arg');
+  _isolate_last_space($self, $current);
+
+  # first parent is the @command, second is the parent
+  $current = $current->{'parent'};
+  my $misc_cmd = $current;
+  my $command = $current->{'cmdname'};
+  my $end_command;
+  print STDERR "MISC END \@$command: $self->{'line_commands'}->{$command}\n"
+     if ($self->{'DEBUG'});
+
+  if ($self->{'line_commands'}->{$command} eq 'specific') {
+    my $args = _parse_line_command_args($self, $current, $source_info);
+    $current->{'extra'}->{'misc_args'} = $args if (defined($args));
+  } elsif ($self->{'line_commands'}->{$command} eq 'text') {
+    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,
+                             __("\@%s missing argument"), $command);
+      }
+      # if there is superfluous arg, a more suitable error is issued below.
+      $current->{'extra'}->{'missing_argument'} = 1;
+    } else {
+      $current->{'extra'}->{'text_arg'} = $text;
+      if ($command eq 'end') {
+        # REMACRO
+        my $remaining_on_line = $text;
+        if ($remaining_on_line =~ s/^([[:alnum:]][[:alnum:]-]*)//) {
+          $end_command = $1;
+
+          if (!exists $block_commands{$end_command}) {
+            $self->_command_warn($current, $source_info,
+                                 __("unknown \@end %s"), $end_command);
+            $end_command = undef;
+          } else {
+            print STDERR "END BLOCK $end_command\n" if ($self->{'DEBUG'});
+            if ($block_commands{$end_command} eq 'conditional') {
+              if (@{$self->{'conditionals_stack'}}
+                and $self->{'conditionals_stack'}->[-1] eq $end_command) {
+                pop @{$self->{'conditionals_stack'}};
+              } else {
+                $self->_command_error($current, $source_info,
+                                  __("unmatched `%c%s'"), ord('@'), 'end');
+                $end_command = undef;
+              }
+            }
+          }
+          # non-ASCII spaces are also superfluous arguments.
+          # If there is superfluous text after @end argument, set
+          # $superfluous_arg such that the error message triggered by an
+          # unexpected @-command on the @end line is issued below.  Note
+          # that $superfluous_arg may also be true if it was set above.
+          if ($end_command and $remaining_on_line =~ /\S/) {
+            $superfluous_arg = 1;
+          }
+        # if $superfluous_arg is set there is a similar and somewhat
+        # better error message below
+        } elsif (!$superfluous_arg) {
+          $self->_command_error($current, $source_info,
+                            __("bad argument to \@%s: %s"),
+                            $command, $remaining_on_line);
+        }
+      } elsif ($superfluous_arg) {
+        # @-command effects are ignored, an error message is issued below.
+      } elsif ($command eq 'include') {
+        # We want Perl binary strings representing sequences of bytes,
+        # not character strings of codepoints in the internal perl encoding.
+        my ($file_name, $file_name_encoding) = _encode_file_name($self, $text);
+        my $file = Texinfo::Common::locate_include_file($self, $file_name);
+        if (defined($file)) {
+          my $filehandle = do { local *FH };
+          if (_open_in ($self, $filehandle, $file)) {
+            print STDERR "Included $file($filehandle)\n" if ($self->{'DEBUG'});
+            my ($directories, $suffix);
+            ($file, $directories, $suffix) = fileparse($file);
+            unshift @{$self->{'input'}}, {
+              'input_file_info' => {'file_name' => $file,
+                                    'line_nr' => 0,
+                                   },
+              'file_name_encoding' => $file_name_encoding,
+              'pending' => [],
+              'fh' => $filehandle };
+            # TODO note that it is bytes.  No reason to have it used much
+            # Make sure to document that it is bytes.
+            # TODO add $file_name_encoding information?
+            $current->{'extra'}->{'file'} = $file;
+            # we set the type to replaced to tell converters not to
+            # expand the @-command
+            $current->{'type'} = 'replaced';
+          } else {
+            # FIXME $text does not show the include directory.  Using $file
+            # would require to decode it to perl internal codepoints with
+            # $file_name_encoding
+            $self->_command_error($current, $source_info,
+                            __("\@%s: could not open %s: %s"),
+                            $command, $text, $!);
+          }
+        } else {
+          $self->_command_error($current, $source_info,
+                            __("\@%s: could not find %s"),
+                           $command, $text);
+        }
+      } elsif ($command eq 'verbatiminclude') {
+        $current->{'extra'}->{'input_perl_encoding'}
+                        = $self->{'info'}->{'input_perl_encoding'}
+          if defined $self->{'info'}->{'input_perl_encoding'};
+      } elsif ($command eq 'documentencoding') {
+        my ($texinfo_encoding, $perl_encoding, $input_encoding)
+           = _encoding_alias($text);
+        $self->_command_warn($current, $source_info,
+               __("encoding `%s' is not a canonical texinfo encoding"),
+                             $text)
+          if (!$texinfo_encoding or $texinfo_encoding ne lc($text));
+        if ($input_encoding) {
+          $current->{'extra'}->{'input_encoding_name'} = $input_encoding;
+        }
+        if (!$perl_encoding) {
+          $self->_command_warn($current, $source_info,
+               __("unrecognized encoding name `%s'"), $text);
+        } else {
+          $current->{'extra'}->{'input_perl_encoding'} = $perl_encoding;
+
+          if ($input_encoding) {
+            $self->{'info'}->{'input_encoding_name'} = $input_encoding;
+          }
+
+          $self->{'info'}->{'input_perl_encoding'} = $perl_encoding;
+          foreach my $input (@{$self->{'input'}}) {
+            binmode($input->{'fh'}, ":encoding($perl_encoding)")
+              if ($input->{'fh'});
+          }
+        }
+      } elsif ($command eq 'documentlanguage') {
+        my @messages = Texinfo::Common::warn_unknown_language($text);
+        foreach my $message(@messages) {
+          $self->_command_warn($current, $source_info, $message);
+        }
+        if (!$self->{'set'}->{'documentlanguage'}) {
+           $self->{'documentlanguage'} = $text;
+        }
+      }
+    }
+    if ($superfluous_arg) {
+      # note that the argument to expand replaced @-commands is
+      # set, such that @include that are removed from the tree
+      # with type set to replaced are still shown in error messages.
+      my $texi_line
+        = 
Texinfo::Convert::Texinfo::convert_to_texinfo($current->{'args'}->[0], 1);
+      $texi_line =~ s/^\s*//;
+      $texi_line =~ s/\s*$//;
+
+      $self->_command_error($current, $source_info,
+                     __("bad argument to \@%s: %s"),
+                     $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;
+    }
+    _check_internal_node($self, $current->{'extra'}->{'nodes_manuals'}->[0],
+                         $source_info);
+    _register_label($self->{'targets'}, $current,
+                 $current->{'extra'}->{'nodes_manuals'}->[0]);
+    if ($self->{'current_part'}) {
+      my $part = $self->{'current_part'};
+      if (not $part->{'extra'}
+         or not $part->{'extra'}->{'part_associated_section'}) {
+        # we only associate a part to the following node if the
+        # part is not already associate to a sectioning command,
+        # but the part can be associated to the sectioning command later
+        # if a sectioning command follows the node.
+        $current->{'extra'}->{'node_preceding_part'} = $part;
+        $part->{'extra'}->{'part_following_node'} = $current;
+      }
+    }
+    $self->{'current_node'} = $current;
+  } elsif ($command eq 'listoffloats') {
+    _parse_float_type($current);
+  } else {
+    # Handle all the other 'line' commands.  Here just check that they
+    # have an argument.  Empty @top is allowed
+    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')
+          and $current->{'parent'}->{'cmdname'}
+          and $self->{'command_index'}->{$current->{'parent'}->{'cmdname'}}) {
+        _enter_index_entry($self, $current->{'parent'}->{'cmdname'},
+                           $command, $current,
+                           $current->{'args'}->[0]->{'contents'},
+                           undef, $source_info);
+      } elsif ($self->{'command_index'}->{$current->{'cmdname'}}) {
+        _enter_index_entry($self, $current->{'cmdname'},
+                           $current->{'cmdname'}, $current,
+                           $current->{'args'}->[0]->{'contents'},
+                           undef, $source_info);
+        $current->{'type'} = 'index_entry_command';
+      }
+      # if there is a brace command interrupting an index or subentry
+      # command, replace the internal internal_spaces_before_brace_in_index
+      # text type with its final type depending on whether there is
+      # text after the brace command.
+      if (_is_index_element($self, $current)) {
+        if (defined($current->{'extra'}->{'sortas'})
+            or defined($current->{'extra'}->{'seealso'})
+            or defined($current->{'extra'}->{'seeentry'})) {
+          _set_non_ignored_space_in_index_before_command(
+                         $current->{'args'}->[0]->{'contents'});
+        }
+      }
+    }
+  }
+  $current = $current->{'parent'};
+  if ($end_command) {
+    print STDERR "END COMMAND $end_command\n" if ($self->{'DEBUG'});
+    # reparent to block command
+    my $end = _pop_element_from_contents($current);
+    if ($block_commands{$end_command} ne 'conditional') {
+      # here close some empty types.  Typically empty preformatted
+      # that would have been closed anyway in _close_commands, but
+      # also other types (rawpreformatted, before_item), some which
+      # may also have been closed anyway.
+      if (not defined($current->{'cmdname'}) and $current->{'type'}
+          and !$current->{'contents'}
+          and $current->{'parent'}) {
+        my $removed = pop @{$current->{'parent'}->{'contents'}};
+        print STDERR "popping at end command $end_command: 
$removed->{'type'}\n"
+         if ($self->{'DEBUG'});
+        $current = $current->{'parent'};
+      }
+      my $closed_command;
+      ($closed_command, $current)
+         = _close_commands($self, $current, $source_info, $end_command);
+      if ($closed_command) {
+        _close_command_cleanup($self, $closed_command);
+        $end->{'parent'} = $closed_command;
+        push @{$closed_command->{'contents'}}, $end;
+      } else {
+        # block command not found for @end
+      }
+      # closing a menu command, but still in a menu. Open a menu_comment
+      if ($closed_command
+          and $block_commands{$closed_command->{'cmdname'}} eq 'menu'
+          and defined($self->_top_context_command())
+          and $block_commands{$self->_top_context_command()} 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];
+      }
+
+      $current = _begin_preformatted($self, $current)
+        if ($close_preformatted_commands{$end_command});
+    }
+  } else {
+    $current = _begin_preformatted($self, $current)
+      if ($close_preformatted_commands{$command});
+  }
+  # Ignore @setfilename in included file, as said in the manual.
+  if (($command eq 'setfilename'
+         and scalar(@{$self->{'input'}}) > 1)
+    # TODO remove this condition if/when the XS parser has been updated
+    # to output @include with type replaced when the file was found
+      or ($current->{'contents'} and scalar(@{$current->{'contents'}})
+           and exists($current->{'contents'}->[-1]->{'type'})
+           and $current->{'contents'}->[-1]->{'type'} eq 'replaced')) {
+    # TODO keep the information
+    pop @{$current->{'contents'}};
+  } elsif ($command eq 'setfilename'
+           and ($self->{'current_node'} or $self->{'current_section'})) {
+    $self->_command_warn($misc_cmd, $source_info,
+             __("\@%s after the first element"), $command);
+  # columnfractions
+  } elsif ($command eq 'columnfractions') {
+    # in a multitable, we are in a block_line_arg
+    if (!$current->{'parent'} or !$current->{'parent'}->{'cmdname'}
+                 or $current->{'parent'}->{'cmdname'} ne 'multitable') {
+      $self->_command_error($current, $source_info,
+             __("\@%s only meaningful on a \@multitable line"),
+             $command);
+    } else {
+      # This is the multitable block_line_arg line context
+      $self->_pop_context(['ct_line'], $source_info, $current, 'for 
multitable');
+      $current = $current->{'parent'};
+      $current->{'extra'}->{'max_columns'} = 0;
+      if ($misc_cmd->{'extra'}
+          and defined($misc_cmd->{'extra'}->{'misc_args'})) {
+        $current->{'extra'}->{'max_columns'}
+            = scalar(@{$misc_cmd->{'extra'}->{'misc_args'}});
+        $current->{'extra'}->{'columnfractions'} = $misc_cmd;
+      }
+      push @{$current->{'contents'}}, { 'type' => 'before_item',
+                                      'contents' => [], 'parent', $current };
+      $current = $current->{'contents'}->[-1];
+    }
+  } elsif ($root_commands{$command}) {
+    $current = $current->{'contents'}->[-1];
+    delete $current->{'remaining_args'};
+
+    # associate the section (not part) with the current node.
+    if ($command ne 'node' and $command ne 'part') {
+      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'}) {
+        $current->{'extra'}->{'associated_part'} = $self->{'current_part'};
+        $self->{'current_part'}->{'extra'}->{'part_associated_section'}
+                                                 = $current;
+        if ($current->{'cmdname'} eq 'top') {
+          $self->_line_warn("\@part should not be associated with \@top",
+                           $self->{'current_part'}->{'source_info'});
+        }
+        delete $self->{'current_part'};
+      }
+      $self->{'current_section'} = $current;
+    } elsif ($command eq 'part') {
+      $self->{'current_part'} = $current;
+      if ($self->{'current_node'}
+         and !$self->{'current_node'}->{'extra'}->{'associated_section'}) {
+        $self->_line_warn(sprintf(__(
+         "\@node precedes \@%s, but parts may not be associated with nodes"),
+                                  $command), $source_info);
+      }
+    }
+  }
+  return $current;
+}
+
 # close constructs and do stuff at end of line (or end of the document)
 sub _end_line($$$);
 sub _end_line($$$)
@@ -3352,345 +3711,7 @@ sub _end_line($$$)
   # misc command line arguments
   # Never go here if skipline/noarg/...
   } elsif ($current->{'type'} and $current->{'type'} eq 'line_arg') {
-    $self->_pop_context(['ct_line'], $source_info, $current, 'in line_arg');
-    _isolate_last_space($self, $current);
-
-    # first parent is the @command, second is the parent
-    $current = $current->{'parent'};
-    my $misc_cmd = $current;
-    my $command = $current->{'cmdname'};
-    my $end_command;
-    print STDERR "MISC END \@$command: $self->{'line_commands'}->{$command}\n"
-       if ($self->{'DEBUG'});
-
-    if ($self->{'line_commands'}->{$command} eq 'specific') {
-      my $args = _parse_line_command_args($self, $current, $source_info);
-      $current->{'extra'}->{'misc_args'} = $args if (defined($args));
-    } elsif ($self->{'line_commands'}->{$command} eq 'text') {
-      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,
-                               __("\@%s missing argument"), $command);
-        }
-        # if there is superfluous arg, a more suitable error is issued below.
-        $current->{'extra'}->{'missing_argument'} = 1;
-      } else {
-        $current->{'extra'}->{'text_arg'} = $text;
-        if ($command eq 'end') {
-          # REMACRO
-          my $remaining_on_line = $text;
-          if ($remaining_on_line =~ s/^([[:alnum:]][[:alnum:]-]*)//) {
-            $end_command = $1;
-
-            if (!exists $block_commands{$end_command}) {
-              $self->_command_warn($current, $source_info,
-                                   __("unknown \@end %s"), $end_command);
-              $end_command = undef;
-            } else {
-              print STDERR "END BLOCK $end_command\n" if ($self->{'DEBUG'});
-              if ($block_commands{$end_command} eq 'conditional') {
-                if (@{$self->{'conditionals_stack'}}
-                  and $self->{'conditionals_stack'}->[-1] eq $end_command) {
-                  pop @{$self->{'conditionals_stack'}};
-                } else {
-                  $self->_command_error($current, $source_info,
-                                    __("unmatched `%c%s'"), ord('@'), 'end');
-                  $end_command = undef;
-                }
-              }
-            }
-            # non-ASCII spaces are also superfluous arguments.
-            # If there is superfluous text after @end argument, set
-            # $superfluous_arg such that the error message triggered by an
-            # unexpected @-command on the @end line is issued below.  Note
-            # that $superfluous_arg may also be true if it was set above.
-            if ($end_command and $remaining_on_line =~ /\S/) {
-              $superfluous_arg = 1;
-            }
-          # if $superfluous_arg is set there is a similar and somewhat
-          # better error message below
-          } elsif (!$superfluous_arg) {
-            $self->_command_error($current, $source_info,
-                              __("bad argument to \@%s: %s"),
-                              $command, $remaining_on_line);
-          }
-        } elsif ($superfluous_arg) {
-          # @-command effects are ignored, an error message is issued below.
-        } elsif ($command eq 'include') {
-          # We want Perl binary strings representing sequences of bytes,
-          # not character strings of codepoints in the internal perl encoding.
-          my ($file_name, $file_name_encoding) = _encode_file_name($self, 
$text);
-          my $file = Texinfo::Common::locate_include_file($self, $file_name);
-          if (defined($file)) {
-            my $filehandle = do { local *FH };
-            if (_open_in ($self, $filehandle, $file)) {
-              print STDERR "Included $file($filehandle)\n" if 
($self->{'DEBUG'});
-              my ($directories, $suffix);
-              ($file, $directories, $suffix) = fileparse($file);
-              unshift @{$self->{'input'}}, {
-                'input_file_info' => {'file_name' => $file,
-                                      'line_nr' => 0,
-                                     },
-                'file_name_encoding' => $file_name_encoding,
-                'pending' => [],
-                'fh' => $filehandle };
-              # TODO note that it is bytes.  No reason to have it used much
-              # Make sure to document that it is bytes.
-              # TODO add $file_name_encoding information?
-              $current->{'extra'}->{'file'} = $file;
-              # we set the type to replaced to tell converters not to
-              # expand the @-command
-              $current->{'type'} = 'replaced';
-            } else {
-              # FIXME $text does not show the include directory.  Using $file
-              # would require to decode it to perl internal codepoints with
-              # $file_name_encoding
-              $self->_command_error($current, $source_info,
-                              __("\@%s: could not open %s: %s"),
-                              $command, $text, $!);
-            }
-          } else {
-            $self->_command_error($current, $source_info,
-                              __("\@%s: could not find %s"),
-                              $command, $text);
-          }
-        } elsif ($command eq 'verbatiminclude') {
-          $current->{'extra'}->{'input_perl_encoding'}
-                          = $self->{'info'}->{'input_perl_encoding'}
-            if defined $self->{'info'}->{'input_perl_encoding'};
-        } elsif ($command eq 'documentencoding') {
-          my ($texinfo_encoding, $perl_encoding, $input_encoding)
-             = _encoding_alias($text);
-          $self->_command_warn($current, $source_info,
-                 __("encoding `%s' is not a canonical texinfo encoding"),
-                               $text)
-            if (!$texinfo_encoding or $texinfo_encoding ne lc($text));
-          if ($input_encoding) {
-            $current->{'extra'}->{'input_encoding_name'} = $input_encoding;
-          }
-          if (!$perl_encoding) {
-            $self->_command_warn($current, $source_info,
-                 __("unrecognized encoding name `%s'"), $text);
-          } else {
-            $current->{'extra'}->{'input_perl_encoding'} = $perl_encoding;
-
-            if ($input_encoding) {
-              $self->{'info'}->{'input_encoding_name'} = $input_encoding;
-            }
-
-            $self->{'info'}->{'input_perl_encoding'} = $perl_encoding;
-            foreach my $input (@{$self->{'input'}}) {
-              binmode($input->{'fh'}, ":encoding($perl_encoding)")
-                if ($input->{'fh'});
-            }
-          }
-        } elsif ($command eq 'documentlanguage') {
-          my @messages = Texinfo::Common::warn_unknown_language($text);
-          foreach my $message(@messages) {
-            $self->_command_warn($current, $source_info, $message);
-          }
-          if (!$self->{'set'}->{'documentlanguage'}) {
-            $self->{'documentlanguage'} = $text;
-          }
-        }
-      }
-      if ($superfluous_arg) {
-        # note that the argument to expand replaced @-commands is
-        # set, such that @include that are removed from the tree
-        # with type set to replaced are still shown in error messages.
-        my $texi_line
-          = 
Texinfo::Convert::Texinfo::convert_to_texinfo($current->{'args'}->[0], 1);
-        $texi_line =~ s/^\s*//;
-        $texi_line =~ s/\s*$//;
-
-        $self->_command_error($current, $source_info,
-                       __("bad argument to \@%s: %s"),
-                       $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;
-      }
-      _check_internal_node($self, $current->{'extra'}->{'nodes_manuals'}->[0],
-                           $source_info);
-      _register_label($self->{'targets'}, $current,
-                   $current->{'extra'}->{'nodes_manuals'}->[0]);
-      if ($self->{'current_part'}) {
-        my $part = $self->{'current_part'};
-        if (not $part->{'extra'}
-           or not $part->{'extra'}->{'part_associated_section'}) {
-          # we only associate a part to the following node if the
-          # part is not already associate to a sectioning command,
-          # but the part can be associated to the sectioning command later
-          # if a sectioning command follows the node.
-          $current->{'extra'}->{'node_preceding_part'} = $part;
-          $part->{'extra'}->{'part_following_node'} = $current;
-        }
-      }
-      $self->{'current_node'} = $current;
-    } elsif ($command eq 'listoffloats') {
-      _parse_float_type($current);
-    } else {
-      # Handle all the other 'line' commands.  Here just check that they
-      # have an argument.  Empty @top is allowed
-      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')
-            and $current->{'parent'}->{'cmdname'}
-            and $self->{'command_index'}->{$current->{'parent'}->{'cmdname'}}) 
{
-          _enter_index_entry($self, $current->{'parent'}->{'cmdname'},
-                             $command, $current,
-                             $current->{'args'}->[0]->{'contents'},
-                             undef, $source_info);
-        } elsif ($self->{'command_index'}->{$current->{'cmdname'}}) {
-          _enter_index_entry($self, $current->{'cmdname'},
-                             $current->{'cmdname'}, $current,
-                             $current->{'args'}->[0]->{'contents'},
-                             undef, $source_info);
-          $current->{'type'} = 'index_entry_command';
-        }
-        # if there is a brace command interrupting an index or subentry
-        # command, replace the internal internal_spaces_before_brace_in_index
-        # text type with its final type depending on whether there is
-        # text after the brace command.
-        if (_is_index_element($self, $current)) {
-          if (defined($current->{'extra'}->{'sortas'})
-              or defined($current->{'extra'}->{'seealso'})
-              or defined($current->{'extra'}->{'seeentry'})) {
-            _set_non_ignored_space_in_index_before_command(
-                           $current->{'args'}->[0]->{'contents'});
-          }
-        }
-      }
-    }
-    $current = $current->{'parent'};
-    if ($end_command) {
-      print STDERR "END COMMAND $end_command\n" if ($self->{'DEBUG'});
-      # reparent to block command
-      my $end = _pop_element_from_contents($current);
-      if ($block_commands{$end_command} ne 'conditional') {
-        # here close some empty types.  Typically empty preformatted
-        # that would have been closed anyway in _close_commands, but
-        # also other types (rawpreformatted, before_item), some which
-        # may also have been closed anyway.
-        if (not defined($current->{'cmdname'}) and $current->{'type'}
-            and !$current->{'contents'}
-            and $current->{'parent'}) {
-           my $removed = pop @{$current->{'parent'}->{'contents'}};
-           print STDERR "popping at end command $end_command: 
$removed->{'type'}\n"
-              if ($self->{'DEBUG'});
-           $current = $current->{'parent'};
-        }
-        my $closed_command;
-        ($closed_command, $current)
-          = _close_commands($self, $current, $source_info, $end_command);
-        if ($closed_command) {
-          _close_command_cleanup($self, $closed_command);
-          $end->{'parent'} = $closed_command;
-
-          push @{$closed_command->{'contents'}}, $end;
-
-          # closing a menu command, but still in a menu. Open a menu_comment
-          if ($block_commands{$closed_command->{'cmdname'}} eq 'menu'
-              and defined($self->_top_context_command())
-              and $block_commands{$self->_top_context_command()} 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];
-          }
-        } else {
-          # block command not found for @end
-        }
-        $current = _begin_preformatted($self, $current)
-          if ($close_preformatted_commands{$end_command});
-      }
-    } else {
-      $current = _begin_preformatted($self, $current)
-        if ($close_preformatted_commands{$command});
-    }
-    # Ignore @setfilename in included file, as said in the manual.
-    if (($command eq 'setfilename'
-           and scalar(@{$self->{'input'}}) > 1)
-      # TODO remove this condition if/when the XS parser has been updated
-      # to output @include with type replaced when the file was found
-        or ($current->{'contents'} and scalar(@{$current->{'contents'}})
-             and exists($current->{'contents'}->[-1]->{'type'})
-             and $current->{'contents'}->[-1]->{'type'} eq 'replaced')) {
-      # TODO keep the information
-      pop @{$current->{'contents'}};
-    } elsif ($command eq 'setfilename'
-             and ($self->{'current_node'} or $self->{'current_section'})) {
-      $self->_command_warn($misc_cmd, $source_info,
-               __("\@%s after the first element"), $command);
-    # columnfractions
-    } elsif ($command eq 'columnfractions') {
-      # in a multitable, we are in a block_line_arg
-      if (!$current->{'parent'} or !$current->{'parent'}->{'cmdname'}
-                   or $current->{'parent'}->{'cmdname'} ne 'multitable') {
-        $self->_command_error($current, $source_info,
-               __("\@%s only meaningful on a \@multitable line"),
-               $command);
-      } else {
-        # This is the multitable block_line_arg line context
-        $self->_pop_context(['ct_line'], $source_info, $current, 'for 
multitable');
-        $current = $current->{'parent'};
-        $current->{'extra'}->{'max_columns'} = 0;
-        if ($misc_cmd->{'extra'}
-            and defined($misc_cmd->{'extra'}->{'misc_args'})) {
-          $current->{'extra'}->{'max_columns'}
-              = scalar(@{$misc_cmd->{'extra'}->{'misc_args'}});
-          $current->{'extra'}->{'columnfractions'} = $misc_cmd;
-        }
-        push @{$current->{'contents'}}, { 'type' => 'before_item',
-                                        'contents' => [], 'parent', $current };
-        $current = $current->{'contents'}->[-1];
-      }
-    } elsif ($root_commands{$command}) {
-      $current = $current->{'contents'}->[-1];
-      delete $current->{'remaining_args'};
-
-      # associate the section (not part) with the current node.
-      if ($command ne 'node' and $command ne 'part') {
-        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'}) {
-          $current->{'extra'}->{'associated_part'} = $self->{'current_part'};
-          $self->{'current_part'}->{'extra'}->{'part_associated_section'}
-                                                   = $current;
-          if ($current->{'cmdname'} eq 'top') {
-            $self->_line_warn("\@part should not be associated with \@top",
-                             $self->{'current_part'}->{'source_info'});
-          }
-          delete $self->{'current_part'};
-        }
-        $self->{'current_section'} = $current;
-      } elsif ($command eq 'part') {
-        $self->{'current_part'} = $current;
-        if ($self->{'current_node'}
-           and !$self->{'current_node'}->{'extra'}->{'associated_section'}) {
-          $self->_line_warn(sprintf(__(
-           "\@node precedes \@%s, but parts may not be associated with nodes"),
-                                    $command), $source_info);
-        }
-      }
-    }
+    $current = _end_line_misc_line($self, $current, $source_info);
   }
 
   # this happens if there is a nesting of line @-commands on a line.
diff --git a/tp/Texinfo/XS/parsetexi/close.c b/tp/Texinfo/XS/parsetexi/close.c
index 92aacd8fb6..eea8b1e9d6 100644
--- a/tp/Texinfo/XS/parsetexi/close.c
+++ b/tp/Texinfo/XS/parsetexi/close.c
@@ -357,6 +357,24 @@ close_current (ELEMENT *current,
 
           break;
         case ET_line_arg:
+          if (current->parent && current->parent->type == ET_def_line)
+            {
+              c = pop_context ();
+              if (c != ct_def)
+                {
+                  /* error */
+                  fatal ("def context expected");
+                }
+            }
+          else
+            {
+              /* We ignore the current returned, to be sure that
+                 we close the command too. */
+              end_line_misc_line (current);
+            }
+          current = current->parent;
+
+          break;
         case ET_block_line_arg:
           c = pop_context ();
           if (c != ct_line && c != ct_def)
diff --git a/tp/Texinfo/XS/parsetexi/end_line.c 
b/tp/Texinfo/XS/parsetexi/end_line.c
index 60ba6b6c60..5ca59f736c 100644
--- a/tp/Texinfo/XS/parsetexi/end_line.c
+++ b/tp/Texinfo/XS/parsetexi/end_line.c
@@ -1298,7 +1298,7 @@ end_line_starting_block (ELEMENT *current)
 
 /* Actions to be taken at the end of an argument to a line command
    not starting a block.  @end is processed in here. */
-static ELEMENT *
+ELEMENT *
 end_line_misc_line (ELEMENT *current)
 {
   enum command_id cmd;
@@ -1318,11 +1318,11 @@ end_line_misc_line (ELEMENT *current)
 
   arg_type = command_data(cmd).data;
    
+  debug ("MISC END %s", command_name(cmd));
+
   if (pop_context () != ct_line)
     fatal ("line context expected");
 
-  debug ("MISC END %s", command_name(cmd));
-
   if (arg_type == LINE_specific)
     {
       ELEMENT *args = parse_line_command_args (current);
diff --git a/tp/Texinfo/XS/parsetexi/parser.h b/tp/Texinfo/XS/parsetexi/parser.h
index 3a329591ab..ee08412e7a 100644
--- a/tp/Texinfo/XS/parsetexi/parser.h
+++ b/tp/Texinfo/XS/parsetexi/parser.h
@@ -119,6 +119,7 @@ ELEMENT *close_current (ELEMENT *current,
 /* In end_line.c */
 NODE_SPEC_EXTRA *parse_node_manual (ELEMENT *node);
 ELEMENT *end_line (ELEMENT *current);
+ELEMENT *end_line_misc_line (ELEMENT *current);
 ELEMENT *parse_special_misc_command (char *line, enum command_id cmd,
                                      int *has_commment);
 int check_node_label (NODE_SPEC_EXTRA *nse, enum command_id cmd);
diff --git a/tp/t/results/coverage/bye_on_end_command_line.pl 
b/tp/t/results/coverage/bye_on_end_command_line.pl
index cd75a40d1e..15b24373a5 100644
--- a/tp/t/results/coverage/bye_on_end_command_line.pl
+++ b/tp/t/results/coverage/bye_on_end_command_line.pl
@@ -26,30 +26,33 @@ $result_trees{'bye_on_end_command_line'} = {
                 {
                   'text' => 'in cartouche.
 '
-                },
+                }
+              ],
+              'type' => 'paragraph'
+            },
+            {
+              'args' => [
                 {
-                  'args' => [
+                  'contents' => [
                     {
-                      'contents' => [
-                        {
-                          'text' => 'cartouche'
-                        }
-                      ],
-                      'type' => 'line_arg'
+                      'text' => 'cartouche'
                     }
                   ],
-                  'cmdname' => 'end',
-                  'info' => {
-                    'spaces_before_argument' => ' '
-                  },
-                  'source_info' => {
-                    'file_name' => '',
-                    'line_nr' => 3,
-                    'macro' => ''
-                  }
+                  'type' => 'line_arg'
                 }
               ],
-              'type' => 'paragraph'
+              'cmdname' => 'end',
+              'extra' => {
+                'text_arg' => 'cartouche'
+              },
+              'info' => {
+                'spaces_before_argument' => ' '
+              },
+              'source_info' => {
+                'file_name' => '',
+                'line_nr' => 3,
+                'macro' => ''
+              }
             }
           ],
           'source_info' => {
@@ -129,7 +132,7 @@ $result_converted{'html_text'}->{'bye_on_end_command_line'} 
= '<table class="car
 ';
 
 
-$result_converted{'xml'}->{'bye_on_end_command_line'} = '<cartouche>
+$result_converted{'xml'}->{'bye_on_end_command_line'} = '<cartouche 
endspaces=" ">
 <para>in cartouche.
 </para></cartouche><bye></bye>
 ';
diff --git a/tp/t/results/invalid_nestings/ignored_text.pl 
b/tp/t/results/invalid_nestings/ignored_text.pl
index 2123dc568b..f7462a3f55 100644
--- a/tp/t/results/invalid_nestings/ignored_text.pl
+++ b/tp/t/results/invalid_nestings/ignored_text.pl
@@ -15,13 +15,30 @@ $result_trees{'ignored_text'} = {
         {
           'contents' => [
             {
-              'text' => 'before ignore '
+              'text' => 'before ignore'
             }
           ],
+          'info' => {
+            'spaces_after_argument' => ' '
+          },
           'type' => 'line_arg'
         }
       ],
       'cmdname' => 'node',
+      'extra' => {
+        'node_content' => [
+          {}
+        ],
+        'nodes_manuals' => [
+          {
+            'node_content' => [
+              {}
+            ],
+            'normalized' => 'before-ignore'
+          }
+        ],
+        'normalized' => 'before-ignore'
+      },
       'info' => {
         'spaces_before_argument' => ' '
       },
@@ -34,12 +51,30 @@ $result_trees{'ignored_text'} = {
   ],
   'type' => 'document_root'
 };
+$result_trees{'ignored_text'}{'contents'}[1]{'extra'}{'node_content'}[0] = 
$result_trees{'ignored_text'}{'contents'}[1]{'args'}[0]{'contents'}[0];
+$result_trees{'ignored_text'}{'contents'}[1]{'extra'}{'nodes_manuals'}[0]{'node_content'}[0]
 = $result_trees{'ignored_text'}{'contents'}[1]{'args'}[0]{'contents'}[0];
 
 $result_texis{'ignored_text'} = '@node before ignore ';
 
 
 $result_texts{'ignored_text'} = '';
 
+$result_nodes{'ignored_text'} = {
+  'cmdname' => 'node',
+  'extra' => {
+    'normalized' => 'before-ignore'
+  },
+  'info' => {}
+};
+
+$result_menus{'ignored_text'} = {
+  'cmdname' => 'node',
+  'extra' => {
+    'normalized' => 'before-ignore'
+  },
+  'info' => {}
+};
+
 $result_errors{'ignored_text'} = [
   {
     'error_line' => 'warning: @ifinfo should only appear at the beginning of a 
line
diff --git a/tp/t/results/invalid_nestings/node_on_index_entry_line.pl 
b/tp/t/results/invalid_nestings/node_on_index_entry_line.pl
index 388a96603f..738709a1eb 100644
--- a/tp/t/results/invalid_nestings/node_on_index_entry_line.pl
+++ b/tp/t/results/invalid_nestings/node_on_index_entry_line.pl
@@ -19,13 +19,29 @@ $result_trees{'node_on_index_entry_line'} = {
             {
               'contents' => [
                 {
-                  'text' => 'entry '
+                  'text' => 'entry'
                 }
               ],
+              'info' => {
+                'spaces_after_argument' => ' '
+              },
               'type' => 'line_arg'
             }
           ],
           'cmdname' => 'cindex',
+          'extra' => {
+            'index_entry' => {
+              'content_normalized' => [],
+              'entry_content' => [],
+              'entry_element' => {},
+              'entry_number' => 1,
+              'in_code' => 0,
+              'index_at_command' => 'cindex',
+              'index_ignore_chars' => {},
+              'index_name' => 'cp',
+              'index_type_command' => 'cindex'
+            }
+          },
           'info' => {
             'spaces_before_argument' => ' '
           },
@@ -33,7 +49,8 @@ $result_trees{'node_on_index_entry_line'} = {
             'file_name' => '',
             'line_nr' => 2,
             'macro' => ''
-          }
+          },
+          'type' => 'index_entry_command'
         }
       ],
       'type' => 'before_node_section'
@@ -181,6 +198,9 @@ $result_trees{'node_on_index_entry_line'} = {
   ],
   'type' => 'document_root'
 };
+$result_trees{'node_on_index_entry_line'}{'contents'}[0]{'contents'}[1]{'extra'}{'index_entry'}{'content_normalized'}
 = 
$result_trees{'node_on_index_entry_line'}{'contents'}[0]{'contents'}[1]{'args'}[0]{'contents'};
+$result_trees{'node_on_index_entry_line'}{'contents'}[0]{'contents'}[1]{'extra'}{'index_entry'}{'entry_content'}
 = 
$result_trees{'node_on_index_entry_line'}{'contents'}[0]{'contents'}[1]{'args'}[0]{'contents'};
+$result_trees{'node_on_index_entry_line'}{'contents'}[0]{'contents'}[1]{'extra'}{'index_entry'}{'entry_element'}
 = $result_trees{'node_on_index_entry_line'}{'contents'}[0]{'contents'}[1];
 
$result_trees{'node_on_index_entry_line'}{'contents'}[1]{'extra'}{'node_content'}[0]
 = 
$result_trees{'node_on_index_entry_line'}{'contents'}[1]{'args'}[0]{'contents'}[0];
 
$result_trees{'node_on_index_entry_line'}{'contents'}[1]{'extra'}{'nodes_manuals'}[0]{'node_content'}[0]
 = 
$result_trees{'node_on_index_entry_line'}{'contents'}[1]{'args'}[0]{'contents'}[0];
 
$result_trees{'node_on_index_entry_line'}{'contents'}[1]{'extra'}{'nodes_manuals'}[1]{'manual_content'}[0]
 = 
$result_trees{'node_on_index_entry_line'}{'contents'}[1]{'args'}[1]{'contents'}[1];
@@ -269,6 +289,15 @@ $result_errors{'node_on_index_entry_line'} = [
     'macro' => '',
     'text' => '@node should not appear in @cindex',
     'type' => 'warning'
+  },
+  {
+    'error_line' => 'warning: entry for index `cp\' outside of any node
+',
+    'file_name' => '',
+    'line_nr' => 2,
+    'macro' => '',
+    'text' => 'entry for index `cp\' outside of any node',
+    'type' => 'warning'
   }
 ];
 
@@ -276,4 +305,11 @@ $result_errors{'node_on_index_entry_line'} = [
 $result_floats{'node_on_index_entry_line'} = {};
 
 
+$result_indices_sort_strings{'node_on_index_entry_line'} = {
+  'cp' => [
+    'entry'
+  ]
+};
+
+
 1;
diff --git a/tp/t/results/invalid_nestings/raw_block_on_line.pl 
b/tp/t/results/invalid_nestings/raw_block_on_line.pl
index ab47deecd0..60058b0645 100644
--- a/tp/t/results/invalid_nestings/raw_block_on_line.pl
+++ b/tp/t/results/invalid_nestings/raw_block_on_line.pl
@@ -40,6 +40,19 @@ $result_trees{'raw_block_on_line'} = {
             }
           ],
           'cmdname' => 'cindex',
+          'extra' => {
+            'index_entry' => {
+              'content_normalized' => [],
+              'entry_content' => [],
+              'entry_element' => {},
+              'entry_number' => 1,
+              'in_code' => 0,
+              'index_at_command' => 'cindex',
+              'index_ignore_chars' => {},
+              'index_name' => 'cp',
+              'index_type_command' => 'cindex'
+            }
+          },
           'info' => {
             'spaces_before_argument' => ' '
           },
@@ -47,7 +60,8 @@ $result_trees{'raw_block_on_line'} = {
             'file_name' => '',
             'line_nr' => 1,
             'macro' => ''
-          }
+          },
+          'type' => 'index_entry_command'
         }
       ],
       'type' => 'before_node_section'
@@ -55,6 +69,9 @@ $result_trees{'raw_block_on_line'} = {
   ],
   'type' => 'document_root'
 };
+$result_trees{'raw_block_on_line'}{'contents'}[0]{'contents'}[0]{'extra'}{'index_entry'}{'content_normalized'}
 = 
$result_trees{'raw_block_on_line'}{'contents'}[0]{'contents'}[0]{'args'}[0]{'contents'};
+$result_trees{'raw_block_on_line'}{'contents'}[0]{'contents'}[0]{'extra'}{'index_entry'}{'entry_content'}
 = 
$result_trees{'raw_block_on_line'}{'contents'}[0]{'contents'}[0]{'args'}[0]{'contents'};
+$result_trees{'raw_block_on_line'}{'contents'}[0]{'contents'}[0]{'extra'}{'index_entry'}{'entry_element'}
 = $result_trees{'raw_block_on_line'}{'contents'}[0]{'contents'}[0];
 
 $result_texis{'raw_block_on_line'} = '@cindex @tex
 ';
@@ -71,6 +88,24 @@ $result_errors{'raw_block_on_line'} = [
     'macro' => '',
     'text' => 'no matching `@end tex\'',
     'type' => 'error'
+  },
+  {
+    'error_line' => 'warning: entry for index `cp\' outside of any node
+',
+    'file_name' => '',
+    'line_nr' => 1,
+    'macro' => '',
+    'text' => 'entry for index `cp\' outside of any node',
+    'type' => 'warning'
+  },
+  {
+    'error_line' => 'warning: empty index key in @cindex
+',
+    'file_name' => '',
+    'line_nr' => 1,
+    'macro' => '',
+    'text' => 'empty index key in @cindex',
+    'type' => 'warning'
   }
 ];
 
@@ -78,4 +113,7 @@ $result_errors{'raw_block_on_line'} = [
 $result_floats{'raw_block_on_line'} = {};
 
 
+$result_indices_sort_strings{'raw_block_on_line'} = {};
+
+
 1;
diff --git a/tp/t/results/invalid_nestings/section_on_index_entry_line.pl 
b/tp/t/results/invalid_nestings/section_on_index_entry_line.pl
index 77f38bfaf4..8ecea8a66f 100644
--- a/tp/t/results/invalid_nestings/section_on_index_entry_line.pl
+++ b/tp/t/results/invalid_nestings/section_on_index_entry_line.pl
@@ -14,13 +14,29 @@ $result_trees{'section_on_index_entry_line'} = {
             {
               'contents' => [
                 {
-                  'text' => 'a '
+                  'text' => 'a'
                 }
               ],
+              'info' => {
+                'spaces_after_argument' => ' '
+              },
               'type' => 'line_arg'
             }
           ],
           'cmdname' => 'cindex',
+          'extra' => {
+            'index_entry' => {
+              'content_normalized' => [],
+              'entry_content' => [],
+              'entry_element' => {},
+              'entry_number' => 1,
+              'in_code' => 0,
+              'index_at_command' => 'cindex',
+              'index_ignore_chars' => {},
+              'index_name' => 'cp',
+              'index_type_command' => 'cindex'
+            }
+          },
           'info' => {
             'spaces_before_argument' => ' '
           },
@@ -28,7 +44,8 @@ $result_trees{'section_on_index_entry_line'} = {
             'file_name' => '',
             'line_nr' => 1,
             'macro' => ''
-          }
+          },
+          'type' => 'index_entry_command'
         }
       ],
       'type' => 'before_node_section'
@@ -77,6 +94,9 @@ $result_trees{'section_on_index_entry_line'} = {
   ],
   'type' => 'document_root'
 };
+$result_trees{'section_on_index_entry_line'}{'contents'}[0]{'contents'}[0]{'extra'}{'index_entry'}{'content_normalized'}
 = 
$result_trees{'section_on_index_entry_line'}{'contents'}[0]{'contents'}[0]{'args'}[0]{'contents'};
+$result_trees{'section_on_index_entry_line'}{'contents'}[0]{'contents'}[0]{'extra'}{'index_entry'}{'entry_content'}
 = 
$result_trees{'section_on_index_entry_line'}{'contents'}[0]{'contents'}[0]{'args'}[0]{'contents'};
+$result_trees{'section_on_index_entry_line'}{'contents'}[0]{'contents'}[0]{'extra'}{'index_entry'}{'entry_element'}
 = $result_trees{'section_on_index_entry_line'}{'contents'}[0]{'contents'}[0];
 
 $result_texis{'section_on_index_entry_line'} = '@cindex a @section b
 
@@ -126,6 +146,15 @@ $result_errors{'section_on_index_entry_line'} = [
     'macro' => '',
     'text' => '@section should not appear in @cindex',
     'type' => 'warning'
+  },
+  {
+    'error_line' => 'warning: entry for index `cp\' outside of any node
+',
+    'file_name' => '',
+    'line_nr' => 1,
+    'macro' => '',
+    'text' => 'entry for index `cp\' outside of any node',
+    'type' => 'warning'
   }
 ];
 
@@ -133,4 +162,11 @@ $result_errors{'section_on_index_entry_line'} = [
 $result_floats{'section_on_index_entry_line'} = {};
 
 
+$result_indices_sort_strings{'section_on_index_entry_line'} = {
+  'cp' => [
+    'a'
+  ]
+};
+
+
 1;
diff --git 
a/tp/t/results/invalid_nestings/unclosed_verb_end_of_line_on_misc_line.pl 
b/tp/t/results/invalid_nestings/unclosed_verb_end_of_line_on_misc_line.pl
index d6e4c162e4..e0602aff55 100644
--- a/tp/t/results/invalid_nestings/unclosed_verb_end_of_line_on_misc_line.pl
+++ b/tp/t/results/invalid_nestings/unclosed_verb_end_of_line_on_misc_line.pl
@@ -44,6 +44,9 @@ $result_trees{'unclosed_verb_end_of_line_on_misc_line'} = {
             }
           ],
           'cmdname' => 'setfilename',
+          'extra' => {
+            'text_arg' => 'name '
+          },
           'info' => {
             'spaces_before_argument' => ' '
           },
@@ -93,6 +96,17 @@ $result_errors{'unclosed_verb_end_of_line_on_misc_line'} = [
     'macro' => '',
     'text' => '@verb missing closing brace',
     'type' => 'error'
+  },
+  {
+    'error_line' => 'bad argument to @setfilename: name @verb{
+}
+',
+    'file_name' => '',
+    'line_nr' => 1,
+    'macro' => '',
+    'text' => 'bad argument to @setfilename: name @verb{
+}',
+    'type' => 'error'
   }
 ];
 
diff --git a/tp/t/results/invalid_nestings/unclosed_verb_on_misc_line.pl 
b/tp/t/results/invalid_nestings/unclosed_verb_on_misc_line.pl
index beeaa072b4..1812c78394 100644
--- a/tp/t/results/invalid_nestings/unclosed_verb_on_misc_line.pl
+++ b/tp/t/results/invalid_nestings/unclosed_verb_on_misc_line.pl
@@ -43,6 +43,9 @@ $result_trees{'unclosed_verb_on_misc_line'} = {
             }
           ],
           'cmdname' => 'setfilename',
+          'extra' => {
+            'text_arg' => 'name '
+          },
           'info' => {
             'spaces_before_argument' => ' '
           },
@@ -82,6 +85,15 @@ $result_errors{'unclosed_verb_on_misc_line'} = [
     'macro' => '',
     'text' => '@verb missing closing delimiter sequence: f}',
     'type' => 'error'
+  },
+  {
+    'error_line' => 'bad argument to @setfilename: name @verb{file.texif}
+',
+    'file_name' => '',
+    'line_nr' => 1,
+    'macro' => '',
+    'text' => 'bad argument to @setfilename: name @verb{file.texif}',
+    'type' => 'error'
   }
 ];
 



reply via email to

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