diff options
Diffstat (limited to 'src/pmdk/utils/check_whitespace')
-rwxr-xr-x | src/pmdk/utils/check_whitespace | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/src/pmdk/utils/check_whitespace b/src/pmdk/utils/check_whitespace new file mode 100755 index 000000000..083b3e8ff --- /dev/null +++ b/src/pmdk/utils/check_whitespace @@ -0,0 +1,210 @@ +#!/usr/bin/env perl +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2015-2020, Intel Corporation + +# +# check_whitespace -- scrub source tree for whitespace errors +# + +use strict; +use warnings; + +use File::Basename; +use File::Find; +use Encode; +use v5.16; + +my $Me = $0; +$Me =~ s,.*/,,; + +$SIG{HUP} = $SIG{INT} = $SIG{TERM} = $SIG{__DIE__} = sub { + die @_ if $^S; + + my $errstr = shift; + + die "$Me: ERROR: $errstr"; +}; + +my $Errcount = 0; + +# +# err -- emit error, keep total error count +# +sub err { + warn @_, "\n"; + $Errcount++; +} + +# +# decode_file_as_string -- slurp an entire file into memory and decode +# +sub decode_file_as_string { + my ($full, $file) = @_; + my $fh; + open($fh, '<', $full) or die "$full $!\n"; + + local $/; + $_ = <$fh>; + close $fh; + + # check known encodings or die + my $decoded; + my @encodings = ("UTF-8", "UTF-16", "UTF-16LE", "UTF-16BE"); + + foreach my $enc (@encodings) { + eval { $decoded = decode( $enc, $_, Encode::FB_CROAK ) }; + + if (!$@) { + $decoded =~ s/\R/\n/g; + return $decoded; + } + } + + die "$Me: ERROR: Unknown file encoding"; +} + +# +# check_whitespace -- run the checks on the given file +# +sub check_whitespace { + my ($full, $file) = @_; + + my $line = 0; + my $eol; + my $nf = 0; + my $fstr = decode_file_as_string($full, $file); + my $empty = 0; + my $is_python = $full =~ /\.py$/; + + for (split /^/, $fstr) { + $line++; + if (!$is_python && /^$/) { + $empty++; + if ($empty > 1) { + err("$full:$line: ERROR duplicated empty line"); + } + } else { + $empty = 0; + } + + $eol = /[\n]/s; + if (/^\.nf$/) { + err("$full:$line: ERROR: nested .nf") if $nf; + $nf = 1; + } elsif (/^\.fi$/) { + $nf = 0; + } elsif ($nf == 0) { + chomp; + err("$full:$line: ERROR: trailing whitespace") if /\s$/; + err("$full:$line: ERROR: spaces before tabs") if / \t/; + } + } + + err("$full:$line: .nf without .fi") if $nf; + err("$full:$line: noeol") unless $eol; +} + +sub check_whitespace_with_exc { + my ($full) = @_; + + $_ = $full; + + return 0 if /^[.\/]*src\/common\/queue\.h/; + return 0 if /^[.\/]*src\/core\/valgrind\/.*\.h/; + + $_ = basename($full); + + return 0 unless /^(README.*|LICENSE.*|Makefile.*|CMakeLists.txt|.gitignore|TEST.*|RUNTESTS|check_whitespace|.*\.([chp13s]|sh|map|cpp|hpp|inc|PS1|ps1|py|md|cmake))$/; + return 0 if -z; + + check_whitespace($full, $_); + return 1; +} + +my $verbose = 0; +my $force = 0; +my $recursive = 0; + +sub check { + my ($file) = @_; + my $r; + + if ($force) { + $r = check_whitespace($file, basename($file)); + } else { + $r = check_whitespace_with_exc($file); + } + + if ($verbose) { + if ($r == 0) { + printf("skipped $file\n"); + } else { + printf("checked $file\n"); + } + } +} + +my @files = (); + +foreach my $arg (@ARGV) { + if ($arg eq '-v') { + $verbose = 1; + next; + } + if ($arg eq '-f') { + $force = 1; + next; + } + if ($arg eq '-r') { + $recursive = 1; + next; + } + if ($arg eq '-g') { + @files = `git ls-tree -r --name-only HEAD`; + chomp(@files); + next; + } + if ($arg eq '-h') { + printf "Options: + -g - check all files tracked by git + -r dir - recursively check all files in specified directory + -v verbose - print whether file was checked or not + -f force - disable blacklist\n"; + exit 1; + } + + if ($recursive == 1) { + find(sub { + my $full = $File::Find::name; + + if (!$force && + ($full eq './.git' || + $full eq './src/debug' || + $full eq './src/nondebug' || + $full eq './rpmbuild' || + $full eq './dpkgbuild')) { + $File::Find::prune = 1; + return; + } + + return unless -f; + + push @files, $full; + }, $arg); + + $recursive = 0; + next; + } + + push @files, $arg; +} + +if (!@files) { + printf "Empty file list!\n"; +} + +foreach (@files) { + check($_); +} + +exit $Errcount; |