Add support for multiline messages to splain
authorFather Chrysostomos <sprout@cpan.org>
Tue, 27 Dec 2011 04:39:19 +0000 (20:39 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 27 Dec 2011 04:39:19 +0000 (20:39 -0800)
All the ‘Compilation failed’ messages are actually multiline mes-
sages, like "Attempt to reload foo aborted.\nCompilation failed in
require at ...".

perldiag has separate entries for each line of the message, so it
makes sense to have it look up each line.  It can’t split it into
lines by default, but must check for a possible description first, as
sometimes syntax errors quote code with line breaks in it.

I had to rip out the nasty file-wide lexical $_, as I couldn’t local-
ise it, and I undid d923656e4 in the process.

lib/diagnostics.pm
lib/diagnostics.t

index 2421c6f..b8effa8 100644 (file)
@@ -216,7 +216,7 @@ $DEBUG ||= 0;
 my $WHOAMI = ref bless [];  # nobody's business, prolly not even mine
 
 local $| = 1;
-my $_;
+local $_;
 local $.;
 
 my $standalone;
@@ -319,6 +319,7 @@ my %msg;
 {
     print STDERR "FINISHING COMPILATION for $_\n" if $DEBUG;
     local $/ = '';
+    local $_;
     my $header;
     my @headers;
     my $for_item;
@@ -587,8 +588,8 @@ my %old_diag;
 my $count;
 my $wantspace;
 sub splainthis {
-    return 0 if $TRACEONLY;
-    $_ = shift;
+  return 0 if $TRACEONLY;
+  for (my $tmp = shift) {
     local $\;
     local $!;
     ### &finish_compilation unless %msg;
@@ -623,17 +624,25 @@ sub splainthis {
        return 0 unless &transmo;
     }
 
-    $orig = shorten($orig);
+    my $short = shorten($orig);
     if ($old_diag{$_}) {
        autodescribe();
-       print THITHER "$orig (#$old_diag{$_})\n";
+       print THITHER "$short (#$old_diag{$_})\n";
        $wantspace = 1;
+    } elsif (!$msg{$_} && $orig =~ /\n./s) {
+       # A multiline message, like "Attempt to reload /
+       # Compilation failed"
+       my $found;
+       for (split /^/, $orig) {
+           splainthis($_) and $found = 1;
+       }
+       return $found;
     } else {
        autodescribe();
        $old_diag{$_} = ++$count;
        print THITHER "\n" if $wantspace;
        $wantspace = 0;
-       print THITHER "$orig (#$old_diag{$_})\n";
+       print THITHER "$short (#$old_diag{$_})\n";
        if ($msg{$_}) {
            print THITHER $msg{$_};
        } else {
@@ -646,6 +655,7 @@ sub splainthis {
        } 
     }
     return 1;
+  }
 } 
 
 sub autodescribe {
index 5283cc4..8c581b0 100644 (file)
@@ -4,7 +4,7 @@ BEGIN {
     chdir '..' if -d '../pod' && -d '../t';
     @INC = 'lib';
     require './t/test.pl';
-    plan(16);
+    plan(17);
 }
 
 BEGIN {
@@ -78,8 +78,16 @@ like $warning, qr/cybernetic version of 20 questions/s, 'strip S<>';
 # Errors ending with dots
 seek STDERR, 0,0;
 $warning = '';
-warn "Attempt to reload stuff aborted.\n";
-like $warning, qr/You tried to load a file/, 'dotty errors';
+warn "I had compilation errors.\n";
+like $warning, qr/final summary message/, 'dotty errors';
+
+# Multiline errors
+seek STDERR, 0,0;
+$warning = '';
+warn "Attempt to reload weapon aborted.\nCompilation failed in require";
+like $warning,
+     qr/You tried to load a file.*Perl could not compile/s,
+    'multiline errors';
 
 *STDERR = $old_stderr;