summaryrefslogtreecommitdiffstats
path: root/src/pmdk/utils/check_whitespace
diff options
context:
space:
mode:
Diffstat (limited to 'src/pmdk/utils/check_whitespace')
-rwxr-xr-xsrc/pmdk/utils/check_whitespace210
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;