diff options
author | Jörg Mayer <jmayer@loplof.de> | 2005-08-29 14:15:32 +0000 |
---|---|---|
committer | Jörg Mayer <jmayer@loplof.de> | 2005-08-29 14:15:32 +0000 |
commit | 344fc629fc0fa91db52665af47ea0a657aa19ab4 (patch) | |
tree | 0222a7802f7413e1cb6769f9fede51ab8db978c6 /tools | |
parent | 1050f6b5f2a4c92c1e1b6c49ee41284c5d34f6c2 (diff) |
Add a tool to check the hf_ values.
svn path=/trunk/; revision=15611
Diffstat (limited to 'tools')
-rwxr-xr-x | tools/checkhf.pl | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/tools/checkhf.pl b/tools/checkhf.pl new file mode 100755 index 0000000000..1304eeeaa4 --- /dev/null +++ b/tools/checkhf.pl @@ -0,0 +1,196 @@ +#!/usr/bin/perl -w +# +# 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) +# +# Ethereal - Network traffic analyzer +# By Gerald Combs <gerald@ethereal.com> +# 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/ethereal/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)ethereal 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 $debug = 0; +# 0: off +# 1: specific debug +# 2: full debug + +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; + +sub printprevfile { + my $state; + + foreach $element (keys %elements) { + $state = $elements{$element}; + $debug>=2 && print "$currfile, $element: PRINT $state\n"; + if ($state =~ "s_usedarray") { + # Everything is fine + } elsif ($state =~ "s_used") { + print "NO ARRAY: $currfile, $element\n" + } elsif ($state =~ "s_array") { + print "Unused entry: $currfile, $element\n" + } elsif ($state =~ "s_declared") { + print "Declared only entry: $currfile, $element\n" + } elsif ($state =~ "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; + $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*?|hf_register_info\s+?|hf_register_info\s*?\*\s*?|->\s*?)(hf_\w*)\W(.*)/) { + $element = $2; + $restofline = $3; + $debug && print "Setting skip for $element\n"; + $skip{$element} = 1; + # Handle functions with multiple hf_ parameters + while ($restofline =~ /(int\s+?|int\s*?\*\s*?|->\s*?)(hf_\w*)\W(.*)/) { + $element = $2; + $restofline = $3; + $debug && print "Setting skip for $element\n"; + $skip{$element} = 1; + } + next; + } elsif (/(\{|^)\s*?&\s*?(hf_\w*)\W+/) { + $element = $2; + $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; + } + + # 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 =~ "s_unknown" && $type =~ "t_usage") { + $newstate = "s_used"; + } elsif ($state =~ "s_unknown" && $type =~ "t_array") { + $newstate = "s_array"; + } elsif ($state =~ "s_used" && $type =~ "t_array") { + $newstate = "s_usedarray"; + } elsif ($state =~ "s_array" && $type =~ "t_usage") { + $newstate = "s_usedarray"; + } else { + $newstate = $state; + } + $elements{$element} = $newstate; + $debug>=2 && print "$currfile, $element: SET $state + $type => $newstate\n"; +} +&printprevfile(); + +exit 0; + +__END__ |