#!/usr/bin/env perl
# warning-summary.pl
#
# Script to summarize GCC/Clang compiler warnings in a build log
# -- Daniel Richard G. <skunk@iSKUNK.ORG>
#

use strict;
use warnings;

use encoding 'utf8';

binmode(STDIN, ":utf8");

open(OUT, "| sort | uniq -c | sort -nr");
binmode(OUT, ":utf8");

while (<>)
{
	/warning:/ || next;
	/near initialization for/ && next;
	/shadowed declaration is here/ && next;
	/\(this will be reported only once per input file\)/ && next;
	/relinking `[^']+'/ && next;

	s/^.*: warning: //g;

	tr/\x{2018}\x{2019}/''/;

	s/'\d+'/'NNN'/g;
	s/\[\d+\]/[NNN]/g;
	s/\b\d+ bits?\b/NNN bit(s)/g;
	s/\b\d+ bytes?\b/NNN byte(s)/g;
	s/\blength \d+\b/length NNN/g;

	s/\barg(ument|) \d+\b/arg$1 N/g;

	s/\b(type|function|variable|enumeration value|address of|declaration of|argument N of|parameter|type of|type of bit-field|prototype for|field|a field of|data member of) '[^']+'( \(aka .+?\))?/$1 'blah'/g;

	s/"[^"]+" (is not defined)/"BLAH" $1/g;

	s/'[^']+' (defined but not used)/'blah' $1/g;

	s/array '\w+'/array 'blah'/;

	s/format '%\w+'/format '%blah'/g;

	s/'%\w+' printf format/'%blah' printf format/g;

	s/'[^']+' (declared 'static' but never defined)/'blah' $1/g;

	s/(ignoring return value of) '\w+'/$1 'blah'/g;

	s/'[^']+' (may be used uninitialized)/'blah' $1/g;

	s/(missing braces around initializer for) '\w+'/$1 'blah'/g;

	s/(missing initializer for member) '[^']+'/$1 'Foo::bar'/g;

	s/(no previous declaration for) '[^']+'/$1 'blah'/g;

	s/(conversion from) '[^']+' to '[^']+'/$1 'blarg' to 'blah'/g;

	# Clang warnings

	s/'[^']+' (has (no out-of-line|virtual functions))/'Blah' $1/;

	s/assigning to '.+' from '.+' converts/assigning to 'blah' from 'blah' converts/;

	s/cast from .+ to .+ increases/cast from 'foo' to 'bar' increases/;

	s/cast to .+ from smaller/cast to 'blah' from smaller/;

	s/(comparison of integers of different signs): .+ and [^[]+/$1: 'foo' and 'bar'/;

	s/(enumeration values) .+ (not explicitly handled in switch)/NN $1 $2/;
	s/\d+ (enumeration values not explicitly handled in switch): .+\.\.\./NN $1/;

	s/from \d+ to \d+\b/from X to Y/;

	s/(implicit conversion [^:]+): .+ to .+/$1: 'foo' to 'bar'/;

	s/(operand of \? changes signedness): .+ to .+/$1: 'foo' to 'bar'/;

	s/(padding (class|size of|struct)) '.+' with/$1 'foo' with/;
	s/(to align) '.+'/$1 'bar'/;

	s/passing .+ to parameter/passing 'blah' to parameter/;

	s/returning '.+' from/returning 'blah' from/;

	s/(shift result) \(0x[0-9A-F]+\)/$1 (0xBLAHBLAH)/;

	s/variables? .+ used in/variable(s) ... used in/;

	print OUT;
}

close(OUT);

# end warning-summary.pl
