blob: 08c7b17e953b3d36b16d8dc17d5376555f9fbc14 [file] [log] [blame]
#!/usr/bin/env perl
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
use Pod::Usage;
use Getopt::Long;
use Data::Dumper;
use File::Spec;
use strict;
use warnings;
=head1 NAME
B<get_ereport.pl> - find error messages in c source files
=head1 SYNOPSIS
B<get_ereport.pl> [-quiet] [-lax] filename [filename...]
Options:
-help brief help message
-man full documentation
-version print version
-quiet be less verbose
-lax be very lax
-fullname print full file name (with GP_IGNORE)
-elog include elog messages as well
=head1 OPTIONS
=over 8
=item B<-help>
Print a brief help message and exits.
=item B<-man>
Prints the manual page and exits.
=item B<-version>
Prints the get_ereport.pl version
=item B<-quiet>
Prints only messages, no line numbers or summaries.
=item B<-lax>
Cleanup spaces, vertical bar (|), etc, that might effect gpdiff
comparison (if invoked via a sql script)
=item B<-fullname>
Print the full file name information in a GP_IGNORE message to
make it easier to track ereport diffs back to the original file.
=item B<-elog>
Include elog messages as well.
=back
=head1 DESCRIPTION
For each supplied file, get_ereport extracts the ereport (error message)
entries of level ERROR, WARNING, NOTICE, or FATAL.
=head1 AUTHORS
Apache HAWQ
Address bug reports and comments to: dev@hawq.apache.org
=cut
if (1)
{
my $man = 0;
my $help = 0;
my $verzion = 0;
my $pmsg = "";
my $bQuiet = 0;
my $bLax = 0;
my $bFullname = 0;
my $bElog = 0;
# check for man or help args
if (scalar(@ARGV))
{
while ($ARGV[0] =~ m/^\-/)
{
if ($ARGV[0] =~ m/^\-(\-)*(v|version)$/)
{
$verzion = 1;
goto L_wWhile;
}
elsif ($ARGV[0] =~ m/^\-(\-)*(man|h|help|\?)$/i)
{
if ($ARGV[0] =~ m/man/i)
{
$man = 1;
}
else
{
$help = 1;
}
goto L_wWhile;
}
elsif ($ARGV[0] =~ m/^\-(\-)*quiet$/i)
{
$bQuiet = 1;
goto L_wWhile;
}
elsif ($ARGV[0] =~ m/^\-(\-)*lax$/i)
{
$bLax = 1;
goto L_wWhile;
}
elsif ($ARGV[0] =~ m/^\-(\-)*fullname$/i)
{
$bFullname = 1;
goto L_wWhile;
}
elsif ($ARGV[0] =~ m/^\-(\-)*elog$/i)
{
$bElog = 1;
goto L_wWhile;
}
last;
L_wWhile:
shift @ARGV;
next;
}
}
else
{
$pmsg = "missing an operand after \`get_ereport.pl\'";
$help = 1;
}
if ((1 == scalar(@ARGV)) &&
($ARGV[0] =~ m/^\-(\-)*/) &&
(!($help || $man || $verzion)))
{
$pmsg = "unknown operand: $ARGV[0]";
$help = 1;
}
if ($verzion)
{
my $VERSION = do { my @r = (q$Revision$ =~ /\d+/g); sprintf "%d.". "%02d" x $#r, @r }; # must be all one line, for MakeMaker
print "$0 version $VERSION\n";
exit(1);
}
pod2usage(-msg => $pmsg, -exitstatus => 1) if $help;
pod2usage(-msg => $pmsg, -exitstatus => 0, -verbose => 2) if $man;
my $printname = 1;
my $linecnt = 0;
my $msgcnt = 0;
my $totmsgcnt = 0;
for my $filnam (@ARGV)
{
if ($bLax)
{
next
if ($filnam =~ m/(\/bootstrap\.)|(\/bootscanner\.)/i);
}
my $gotmsg = 0;
my $fh;
# $$$ $$$ undefine input record separator (\n")
# and slurp entire file into variable
local $/;
undef $/;
open ($fh, "<$filnam") or die "can't open $filnam: $!";
my $whole_file = <$fh>;
close $fh;
# split file into separate lines
my @lines = split(/\n/, $whole_file);
$linecnt = 1;
my $orig_filnam = $filnam;
for my $ii (0..(scalar(@lines) - 1) )
{
my $ini = $lines[$ii] . "\n"; # add the newline back...
my $regex = "ereport";
$regex = "(ereport|elog)" if ($bElog);
if ($ini =~ m/$regex/)
{
if ($ini =~ m/$regex\s*\(\s*(ERROR|WARNING|NOTICE|FATAL)\,/)
{
$gotmsg = 1;
$msgcnt++;
$totmsgcnt++;
}
else
{
# check for errSendAlert in next 10 lines
my $lookahead = (scalar(@lines) - 1);
$lookahead = $ii + 10
if (($lookahead - $ii) > 10);
for my $jj ($ii..$lookahead)
{
my $l2 = $lines[$jj];
if ($l2 =~ m/errSendAlert\(\s*true\s*\)/)
{
$gotmsg = 1;
$msgcnt++;
$totmsgcnt++;
last;
}
last # check for semicolon ending statement
if ($l2 =~ m/\;/);
}
}
}
if ($gotmsg)
{
if ($printname)
{
print "FILENAME: ", $filnam, "\n"
unless ($bQuiet);
# shorten the filename
if ($filnam =~ m/\//)
{
my @foo = split("/", $filnam);
$filnam = pop(@foo);
}
if ($bLax)
{
# avoid case-sensitive sort, plus lexical ordering for
# non-alpha characters
$filnam = lc($filnam);
$filnam =~ s/\.c$//;
$filnam =~ s/\W/x/g;
$filnam =~ s/\_/x/g;
$filnam =~ s/1/one/g;
$filnam =~ s/2/two/g;
$filnam =~ s/3/three/g;
$filnam =~ s/4/four/g;
$filnam =~ s/5/five/g;
$filnam =~ s/6/six/g;
$filnam =~ s/7/seven/g;
$filnam =~ s/8/eight/g;
$filnam =~ s/9/nine/g;
$filnam =~ s/0/zero/g;
# ugh. build a prefix which is the first char
# of the filename plus the encoded length, so
# only sort subgroups of same length (to avoid
# more collation sequence issues).
my @ww = split (//, $filnam);
my $fprefix = $ww[0];
my $flen = sprintf( "%03d", length($filnam));
$flen =~ tr/0123456789/abcdefghij/;
$filnam = $fprefix . $flen . ": " . $filnam;
}
if ($bFullname)
{
# add prefix for sorting, but still get ignored
print "aaaaa GP_IGNORE: ", $filnam, " - ",
$orig_filnam, "\n";
}
$printname = 0;
}
print $filnam, ":";
printf "%08d: ", $linecnt;
# unless ($bQuiet);
$ini =~ s/\t/ /gm
if ($bLax);
$ini =~ s/\s+/ /gm
if ($bLax);
$ini =~ s/\|/\*PIPE\*/gm
if ($bLax);
$ini .= "\n"
unless ($ini =~ m/\n$/);
print $ini;
$gotmsg = 0
if ($ini =~ m/\;\s*$/);
}
$linecnt++;
}
if ($msgcnt)
{
print "\n", $orig_filnam, ": ", $msgcnt, " messages\n\n"
unless ($bQuiet);
$msgcnt = 0;
}
$printname = 1;
} # end for filnam
if ($totmsgcnt)
{
print "\n\nfound ", $totmsgcnt, " total messages\n"
unless ($bQuiet);
}
}
exit();