wireshark/tools/checkhf.pl

215 lines
5.4 KiB
Perl
Raw Normal View History

#!/usr/bin/perl -w
my $debug = 0;
# 0: off
# 1: specific debug
# 2: full debug
#
# find unbalanced hf_ variables: Compare hf_ variable usage with the hf_ variables
# declared in the hf_register_info array.
#
# Usage: checkhf.pl <file or files>
# $Id$
#
# Copyright 2005 Joerg Mayer (see AUTHORS file)
#
# Wireshark - Network traffic analyzer
# By Gerald Combs <gerald@wireshark.org>
# Copyright 1998 Gerald Combs
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Example:
# ~/work/wireshark/trunk/epan/dissectors> ../../tools/checkhf.pl packet-afs.c
# Unused entry: packet-afs.c, hf_afs_ubik_voteend
# Unused entry: packet-afs.c, hf_afs_ubik_errcode
# Unused entry: packet-afs.c, hf_afs_ubik_votetype
# NO ARRAY: packet-afs.c, hf_afs_fs_ipaddr
#
# or checkhf.pl packet-*.c, which will check all the dissector files.
#
# NOTE: This tool currently generates false positives!
#
# The "NO ARRAY" messages - if accurate - point to an error that will
# cause (t)(wire)shark to terminate with an assertion when a packet containing
# this particular element is being dissected.
#
# The "Unused entry" message indicates the opposite:
use strict;
my $D;
my %elements;
my $element;
my %skip;
my $state;
my $newstate;
# "s_unknown",
# "s_declared",
# "s_used",
# "s_array",
# "s_usedarray",
# "s_error"
my $type;
# "t_declaration";
# "t_usage";
# "t_array";
my $restofline;
my $currfile = "";
my $comment = 0;
my $brace = 0;
sub printprevfile {
my $state;
foreach $element (keys %elements) {
$state = $elements{$element};
$debug>=2 && print "$currfile, $element: PRINT $state\n";
if ($state eq "s_usedarray") {
# Everything is fine
} elsif ($state eq "s_used") {
print "NO ARRAY: $currfile, $element\n"
} elsif ($state eq "s_array") {
print "Unused entry: $currfile, $element\n"
} elsif ($state eq "s_declared") {
print "Declared only entry: $currfile, $element\n"
} elsif ($state eq "s_unknown") {
print "UNKNOWN: $currfile, $element\n"
} else {
die "Impossible: State $state for $currfile, $element\n";
}
}
}
while (<>) {
if ($currfile !~ /$ARGV/) {
&printprevfile();
# New file - reset array and state
$currfile = $ARGV;
%elements = ( );
%skip = ( "hf_register_info" => 1 );
$state = "s_unknown";
}
# opening then closing comment
if (/(.*?)\/\*.*\*\/(.*)/) {
$comment = 0;
$_ = "$1$2";
# closing then opening comment
} elsif (/.*?\*\/(.*?)\/\*/) {
$comment = 1;
$_ = "$1";
# opening comment
} elsif (/(.*?)\/\*/) {
$comment = 1;
$_ = "$1";
# closing comment
} elsif (/\*\/(.*?)/) {
$comment = 0;
$_ = "$1";
} elsif ($comment == 1) {
next;
}
# unhandled: more than one complete comment per line
chomp;
if ($debug) {
$D = " ($_)";
} else {
$D = "";
}
# Read input
if (/static\s+.*int\s+(hf_\w*)\s*=\s*-1\s*;/) {
$element = $1;
$type = "t_declaration";
# ignore: declarations without any use are detected by the compiler
next;
# Skip function parameter declarations with hf_ names
} elsif (/(int\s+?|int\s*?\*\s*?|header_field_info\s+?|header_field_info\s*?\*\s*?|hf_register_info\s+?|hf_register_info\s*?\*\s*?|->\s*?)(hf_\w*)\W(.*)/) {
$element = $2;
$restofline = $3;
$debug && print "Setting skip for $element$D\n";
$skip{$element} = 1;
# Handle functions with multiple hf_ parameters
while ($restofline =~ /(int\s+?|int\s*?\*\s*?|header_field_info\s+?|header_field_info\s*?\*\s*?|hf_register_info\s+?|hf_register_info\s*?\*\s*?|->\s*?)(hf_\w*)\W(.*)/) {
$element = $2;
$restofline = $3;
$debug && print "Setting skip for $element$D\n";
$skip{$element} = 1;
}
next;
} elsif ($brace == 1 && /^\s*?&\s*?(hf_\w*)\W+/) {
$element = $1;
$type = "t_array";
} elsif (/^\s*\{\s*?&\s*?(hf_\w*)\W+/) {
$element = $1;
$type = "t_array";
# Order matters: catch all remaining hf_ lines
} elsif (/\W(hf_\w*)\W/) {
$element = $1;
next if ($skip{$element});
$type = "t_usage";
} else {
# current line is not relevant
next;
}
# Line with only a {
if (/^\s+\{\s*$/) {
$brace = 1;
next;
} else {
$brace = 0;
}
# Get current state
if (!defined($elements{$element})) {
$state = "s_unknown";
} else {
$state = $elements{$element};
}
# current state + input ==> new state
# we currently ignore t_declaration
if ($state eq "s_error") {
$newstate = $state;
} elsif ($state eq "s_unknown" && $type eq "t_usage") {
$newstate = "s_used";
} elsif ($state eq "s_unknown" && $type eq "t_array") {
$newstate = "s_array";
} elsif ($state eq "s_used" && $type eq "t_array") {
$newstate = "s_usedarray";
} elsif ($state eq "s_array" && $type eq "t_usage") {
$newstate = "s_usedarray";
} else {
$newstate = $state;
}
$elements{$element} = $newstate;
$debug>=2 && print "$currfile, $element: SET $state + $type => $newstate$D\n";
}
&printprevfile();
exit 0;
__END__