#!/usr/bin/env perl # # bracket-spacing.pl: Report any usage of 'function (..args..)' # Also check for other syntax issues, such as correct use of ';' # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library 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 # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library. If not, see # . # # Authors: # Daniel P. Berrange use strict; use warnings; my $ret = 0; my $incomment = 0; foreach my $file (@ARGV) { open FILE, $file; while (defined (my $line = )) { my $data = $line; # Kill any quoted , ; or " $data =~ s/'[";,]'/'X'/g; # Kill any quoted strings $data =~ s,"([^\\\"]|\\.)*","XXX",g; # Kill any C++ style comments $data =~ s,//.*$,//,; next if $data =~ /^#/; # Kill contents of multi-line comments # and detect end of multi-line comments if ($incomment) { if ($data =~ m,\*/,) { $incomment = 0; $data =~ s,^.*\*/,*/,; } else { $data = ""; } } # Kill single line comments, and detect # start of multi-line comments if ($data =~ m,/\*.*\*/,) { $data =~ s,/\*.*\*/,/* */,; } elsif ($data =~ m,/\*,) { $incomment = 1; $data =~ s,/\*.*,/*,; } # We need to match things like # # int foo (int bar, bool wizz); # foo (bar, wizz); # # but not match things like: # # typedef int (*foo)(bar wizz) # # we can't do this (efficiently) without # missing things like # # foo (*bar, wizz); # while ($data =~ /(\w+)\s\((?!\*)/) { my $kw = $1; # Allow space after keywords only if ($kw =~ /^(if|for|while|switch|return)$/) { $data =~ s/($kw\s\()/XXX(/; } else { print "$file:$.: $line"; $ret = 1; last; } } # Require whitespace immediately after keywords, # but none after the opening bracket while ($data =~ /\b(if|for|while|switch|return)\(/ || $data =~ /\b(if|for|while|switch|return)\s+\(\s/) { print "$file:$.: $line"; $ret = 1; last; } # Forbid whitespace between )( of a function typedef while ($data =~ /\(\*\w+\)\s+\(/) { print "$file:$.: $line"; $ret = 1; last; } # Forbid whitespace following ( or prior to ) while ($data =~ /\S\s+\)/ || $data =~ /\(\s+\S/) { print "$file:$.: $line"; $ret = 1; last; } # Forbid whitespace before ";" or ",". Things like below are allowed: # # 1) The expression is empty for "for" loop. E.g. # for (i = 0; ; i++) # # 2) An empty statement. E.g. # while (write(statuswrite, &status, 1) == -1 && # errno == EINTR) # ; # while ($data =~ /[^;\s]\s+[;,]/) { print "$file:$.: $line"; $ret = 1; last; } # Require EOL, macro line continuation, or whitespace after ";". # Allow "for (;;)" as an exception. while ($data =~ /;[^ \\\n;)]/) { print "$file:$.: $line"; $ret = 1; last; } # Require EOL, space, or enum/struct end after comma. while ($data =~ /,[^ \\\n)}]/) { print "$file:$.: $line"; $ret = 1; last; } # Require spaces around assignment '=', compounds and '==' # with the exception of virAssertCmpInt() while ($data =~ /[^!<>&|\-+*\/%\^'= ]=\+[^=]/ || $data =~ /[^!<>&|\-+*\/%\^'=]=[^= \\\n]/ || $data =~ /[\S]==/ || ($data =~ /==[^\s,]/ && $data !~ /[\s]virAssertCmpInt\(/)) { print "$file:$.: $line"; $ret = 1; last; } } close FILE; } exit $ret;