#!/usr/bin/perl -s use warnings; use strict; use File::Which; use XML::DT; use Data::Dumper; use Archive::Extract; use File::Slurp qw/read_file/; use File::Basename; our $f; # print full report our $p; # force process as a archive (.tgz file) our $a; # enable all checks my $tmp = '/tmp'; #temporary directory my $file = shift; die unless $file; $p = 1 if $file =~ m/\.tgz$/; my $target = $file; if ($p) { mylog("Handling archive .."); my $ae = Archive::Extract->new( archive => $file ); my $ok = $ae->extract( to => $tmp ); $target = $ae->extract_path; mylog("unzip done!"); } my $cppcheck = which('cppcheck'); my $cppcheck_options = '-v --xml-version=2'; $cppcheck_options .= ' --enable=all ' if $a; my %sum; my %ids; my %files; my %handler = ( '//error' => sub { $sum{error}++; $ids{$v{id}}++; }, ); my $tmpxml = $tmp.'/'.basename($target).'.xml'; mylog("Starting cppcheck .."); my $stdout = `$cppcheck $cppcheck_options $target 2> $tmpxml`; mylog("cppcheck done!"); my @outlines = split/\n/, $stdout; foreach (@outlines) { next if $_ =~ m/Checking\s.*?:\s/; if ($_ =~ m/Checking\s(.*?)\.\.\./) { $files{$1}++; } } my $xml = read_file($tmpxml, {binmode=>':utf8'}); pathdtstring($xml, %handler); if ($f) { my $full = $xml; # TODO change XML format? print $full; } else { print toxml("results",{},"Total errors: $sum{error}, including: ".join('; ',keys %ids)), toxml("results",{},"Total files processed: ".scalar(keys %files)), "\n"; } sub mylog { printf STDERR "[%s] %s\n", scalar(localtime), $_[0]; } =encoding UTF-8 =head1 NAME dmoss-cppcheck - DMOSS wrapper fot the cppcheck program =head1 SYNOPSIS $ dmoss-cppcheck [-f] [-p] =head1 DESCRIPTION Execute the cppcheck utility and produce a XML summary. Only C/CPP files extension are processed. =head1 OPTIONS -p -- treat as a package (.tgz) -f -- print full XML report -a -- enable all cppcheck tests