1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099 |
- use strict;
- use warnings;
- my $max_column = 79;
- my $indent = 2;
- my $warnings = 0;
- my $swarnings = 0;
- my $errors = 0;
- my $serrors = 0;
- my $suppressed;
- my $file;
- my $dir=".";
- my $wlist="";
- my @alist;
- my $windows_os = $^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys';
- my $verbose;
- my %skiplist;
- my %ignore;
- my %ignore_set;
- my %ignore_used;
- my @ignore_line;
- my %warnings_extended = (
- 'COPYRIGHTYEAR' => 'copyright year incorrect',
- 'STRERROR', => 'strerror() detected',
- 'STRNCPY', => 'strncpy() detected',
- 'STDERR', => 'stderr detected',
- );
- my %warnings = (
- 'ASSIGNWITHINCONDITION' => 'assignment within conditional expression',
- 'ASTERISKNOSPACE' => 'pointer declared without space before asterisk',
- 'ASTERISKSPACE' => 'pointer declared with space after asterisk',
- 'BADCOMMAND' => 'bad !checksrc! instruction',
- 'BANNEDFUNC' => 'a banned function was used',
- 'BANNEDPREPROC' => 'a banned symbol was used on a preprocessor line',
- 'BRACEELSE' => '} else on the same line',
- 'BRACEPOS' => 'wrong position for an open brace',
- 'BRACEWHILE' => 'A single space between open brace and while',
- 'COMMANOSPACE' => 'comma without following space',
- 'COMMENTNOSPACEEND' => 'no space before */',
- 'COMMENTNOSPACESTART' => 'no space following /*',
- 'COPYRIGHT' => 'file missing a copyright statement',
- 'CPPCOMMENTS' => '// comment detected',
- 'DOBRACE' => 'A single space between do and open brace',
- 'EMPTYLINEBRACE' => 'Empty line before the open brace',
- 'EQUALSNOSPACE' => 'equals sign without following space',
- 'EQUALSNULL' => 'if/while comparison with == NULL',
- 'EXCLAMATIONSPACE' => 'Whitespace after exclamation mark in expression',
- 'FOPENMODE' => 'fopen needs a macro for the mode string',
- 'INCLUDEDUP', => 'same file is included again',
- 'INDENTATION' => 'wrong start column for code',
- 'LONGLINE' => "Line longer than $max_column",
- 'SPACEBEFORELABEL' => 'labels not at the start of the line',
- 'MULTISPACE' => 'multiple spaces used when not suitable',
- 'NOSPACEAND' => 'missing space around Logical AND operator',
- 'NOSPACEC' => 'missing space around ternary colon operator',
- 'NOSPACEEQUALS' => 'equals sign without preceding space',
- 'NOSPACEQ' => 'missing space around ternary question mark operator',
- 'NOSPACETHAN' => 'missing space around less or greater than',
- 'NOTEQUALSZERO', => 'if/while comparison with != 0',
- 'ONELINECONDITION' => 'conditional block on the same line as the if()',
- 'OPENCOMMENT' => 'file ended with a /* comment still "open"',
- 'PARENBRACE' => '){ without sufficient space',
- 'RETURNNOSPACE' => 'return without space',
- 'SEMINOSPACE' => 'semicolon without following space',
- 'SIZEOFNOPAREN' => 'use of sizeof without parentheses',
- 'SNPRINTF' => 'use of snprintf',
- 'SPACEAFTERPAREN' => 'space after open parenthesis',
- 'SPACEBEFORECLOSE' => 'space before a close parenthesis',
- 'SPACEBEFORECOMMA' => 'space before a comma',
- 'SPACEBEFOREPAREN' => 'space before an open parenthesis',
- 'SPACESEMICOLON' => 'space before semicolon',
- 'SPACESWITCHCOLON' => 'space before colon of switch label',
- "SSCANF" => 'use of sscanf',
- 'TABS' => 'TAB characters not allowed',
- 'TRAILINGSPACE' => 'Trailing whitespace on the line',
- 'TYPEDEFSTRUCT' => 'typedefed struct',
- 'UNUSEDIGNORE' => 'a warning ignore was not used',
- );
- sub readskiplist {
- open(my $W, '<', "$dir/checksrc.skip") or return;
- my @all=<$W>;
- for(@all) {
- $windows_os ? $_ =~ s/\r?\n$// : chomp;
- $skiplist{$_}=1;
- }
- close($W);
- }
- sub readlocalfile {
- my ($file) = @_;
- my $i = 0;
- my $rcfile;
- if(($dir eq ".") && $file =~ /\//) {
- my $ldir;
- if($file =~ /(.*)\//) {
- $ldir = $1;
- open($rcfile, "<", "$dir/$ldir/.checksrc") or return;
- }
- }
- else {
- open($rcfile, "<", "$dir/.checksrc") or return;
- }
- while(<$rcfile>) {
- $windows_os ? $_ =~ s/\r?\n$// : chomp;
- $i++;
-
- if (/^\s*(#.*)/) {
- next;
- }
- elsif (/^\s*enable ([A-Z]+)$/) {
- if(!defined($warnings_extended{$1})) {
- print STDERR "invalid warning specified in .checksrc: \"$1\"\n";
- next;
- }
- $warnings{$1} = $warnings_extended{$1};
- }
- elsif (/^\s*disable ([A-Z]+)$/) {
- if(!defined($warnings{$1})) {
- print STDERR "invalid warning specified in .checksrc: \"$1\"\n";
- next;
- }
-
- push @alist, $1;
- }
- else {
- die "Invalid format in $dir/.checksrc on line $i\n";
- }
- }
- close($rcfile);
- }
- sub checkwarn {
- my ($name, $num, $col, $file, $line, $msg, $error) = @_;
- my $w=$error?"error":"warning";
- my $nowarn=0;
-
-
-
-
- if($skiplist{$line}) {
- $nowarn = 1;
- }
-
- elsif($ignore{$name}) {
- $ignore{$name}--;
- $ignore_used{$name}++;
- $nowarn = 1;
- if(!$ignore{$name}) {
-
- enable_warn($name, $num, $file, $line);
- }
- }
- if($nowarn) {
- $suppressed++;
- if($w) {
- $swarnings++;
- }
- else {
- $serrors++;
- }
- return;
- }
- if($w) {
- $warnings++;
- }
- else {
- $errors++;
- }
- $col++;
- print "$file:$num:$col: $w: $msg ($name)\n";
- print " $line\n";
- if($col < 80) {
- my $pref = (' ' x $col);
- print "${pref}^\n";
- }
- }
- $file = shift @ARGV;
- while(defined $file) {
- if($file =~ /-D(.*)/) {
- $dir = $1;
- $file = shift @ARGV;
- next;
- }
- elsif($file =~ /-W(.*)/) {
- $wlist .= " $1 ";
- $file = shift @ARGV;
- next;
- }
- elsif($file =~ /-A(.+)/) {
- push @alist, $1;
- $file = shift @ARGV;
- next;
- }
- elsif($file =~ /-i([1-9])/) {
- $indent = $1 + 0;
- $file = shift @ARGV;
- next;
- }
- elsif($file =~ /-m([0-9]+)/) {
- $max_column = $1 + 0;
- $file = shift @ARGV;
- next;
- }
- elsif($file =~ /^(-h|--help)/) {
- undef $file;
- last;
- }
- last;
- }
- if(!$file) {
- print "checksrc.pl [option] <file1> [file2] ...\n";
- print " Options:\n";
- print " -A[rule] Accept this violation, can be used multiple times\n";
- print " -D[DIR] Directory to prepend file names\n";
- print " -h Show help output\n";
- print " -W[file] Skip the given file - ignore all its flaws\n";
- print " -i<n> Indent spaces. Default: 2\n";
- print " -m<n> Maximum line length. Default: 79\n";
- print "\nDetects and warns for these problems:\n";
- my @allw = keys %warnings;
- push @allw, keys %warnings_extended;
- for my $w (sort @allw) {
- if($warnings{$w}) {
- printf (" %-18s: %s\n", $w, $warnings{$w});
- }
- else {
- printf (" %-18s: %s[*]\n", $w, $warnings_extended{$w});
- }
- }
- print " [*] = disabled by default\n";
- exit;
- }
- readskiplist();
- readlocalfile($file);
- do {
- if("$wlist" !~ / $file /) {
- my $fullname = $file;
- $fullname = "$dir/$file" if ($fullname !~ '^\.?\.?/');
- scanfile($fullname);
- }
- $file = shift @ARGV;
- } while($file);
- sub accept_violations {
- for my $r (@alist) {
- if(!$warnings{$r}) {
- print "'$r' is not a warning to accept!\n";
- exit;
- }
- $ignore{$r}=999999;
- $ignore_used{$r}=0;
- }
- }
- sub checksrc_clear {
- undef %ignore;
- undef %ignore_set;
- undef @ignore_line;
- }
- sub checksrc_endoffile {
- my ($file) = @_;
- for(keys %ignore_set) {
- if($ignore_set{$_} && !$ignore_used{$_}) {
- checkwarn("UNUSEDIGNORE", $ignore_set{$_},
- length($_)+11, $file,
- $ignore_line[$ignore_set{$_}],
- "Unused ignore: $_");
- }
- }
- }
- sub enable_warn {
- my ($what, $line, $file, $l) = @_;
-
- if(!$ignore_used{$what}) {
- checkwarn("UNUSEDIGNORE",
- $line, length($what) + 11, $file, $l,
- "No warning was inhibited!");
- }
- $ignore_set{$what}=0;
- $ignore_used{$what}=0;
- $ignore{$what}=0;
- }
- sub checksrc {
- my ($cmd, $line, $file, $l) = @_;
- if($cmd =~ / *([^ ]*) *(.*)/) {
- my ($enable, $what) = ($1, $2);
- $what =~ s: *\*/$::; # cut off end of C comment
- # print "ENABLE $enable WHAT $what\n";
- if($enable eq "disable") {
- my ($warn, $scope)=($1, $2);
- if($what =~ /([^ ]*) +(.*)/) {
- ($warn, $scope)=($1, $2);
- }
- else {
- $warn = $what;
- $scope = 1;
- }
-
- if($scope eq "all") {
- $scope=999999;
- }
-
-
-
-
- if($scope eq "0") {
- checkwarn("BADCOMMAND",
- $line, 0, $file, $l,
- "Disable zero not supported, did you mean to enable?");
- }
- elsif($ignore_set{$warn}) {
- checkwarn("BADCOMMAND",
- $line, 0, $file, $l,
- "$warn already disabled from line $ignore_set{$warn}");
- }
- else {
- $ignore{$warn}=$scope;
- $ignore_set{$warn}=$line;
- $ignore_line[$line]=$l;
- }
- }
- elsif($enable eq "enable") {
- enable_warn($what, $line, $file, $l);
- }
- else {
- checkwarn("BADCOMMAND",
- $line, 0, $file, $l,
- "Illegal !checksrc! command");
- }
- }
- }
- sub nostrings {
- my ($str) = @_;
- $str =~ s/\".*\"//g;
- return $str;
- }
- sub scanfile {
- my ($file) = @_;
- my $line = 1;
- my $prevl="";
- my $prevpl="";
- my $l = "";
- my $prep = 0;
- my $prevp = 0;
- open(my $R, '<', $file) || die "failed to open $file";
- my $incomment=0;
- my @copyright=();
- my %includes;
- checksrc_clear();
- accept_violations();
- while(<$R>) {
- $windows_os ? $_ =~ s/\r?\n$// : chomp;
- my $l = $_;
- my $ol = $l;
- my $column = 0;
-
- if($l =~ /\!checksrc\! (.*)/) {
- my $cmd = $1;
- checksrc($cmd, $line, $file, $l)
- }
- if($l =~ /^#line (\d+) \"([^\"]*)\"/) {
-
- $file = $2;
- $line = $1;
- next;
- }
-
- if($l =~ /\* +copyright .* (\d\d\d\d|)/i) {
- my $count = 0;
- while($l =~ /([\d]{4})/g) {
- push @copyright, {
- year => $1,
- line => $line,
- col => index($l, $1),
- code => $l
- };
- $count++;
- }
- if(!$count) {
-
- push @copyright, {
- year => -1,
- line => $line,
- col => index($l, $1),
- code => $l
- };
- }
- }
-
- if(length($l) > $max_column) {
- checkwarn("LONGLINE", $line, length($l), $file, $l,
- "Longer than $max_column columns");
- }
-
- if($l =~ /^(.*)\t/) {
- checkwarn("TABS",
- $line, length($1), $file, $l, "Contains TAB character", 1);
- }
-
- if($l =~ /^(.*)[ \t]+\z/) {
- checkwarn("TRAILINGSPACE",
- $line, length($1), $file, $l, "Trailing whitespace");
- }
-
- if($l =~ /^(.*)\/\*\w/) {
- checkwarn("COMMENTNOSPACESTART",
- $line, length($1) + 2, $file, $l,
- "Missing space after comment start");
- }
-
- if($l =~ /^(.*)\w\*\//) {
- checkwarn("COMMENTNOSPACEEND",
- $line, length($1) + 1, $file, $l,
- "Missing space end comment end");
- }
-
-
-
-
-
- comment:
- if(!$incomment) {
- if($l =~ s/\/\*.*\*\// /g) {
-
- }
- if($l =~ s/\/\*.*//) {
-
- $incomment = 1;
- }
- }
- else {
- if($l =~ s/.*\*\///) {
-
- $incomment = 0;
- goto comment;
- }
- else {
-
- $l="";
- }
- }
-
-
-
-
-
- if($prep && ($prevpl =~ /\\ *\z/)) {
-
- $prep = 1;
- goto preproc;
- }
- $prep = 0;
-
-
- if($l =~ /^(([^"\*]*)[^:"]|)\/\//) {
- checkwarn("CPPCOMMENTS",
- $line, length($1), $file, $l, "\/\/ comment");
- }
- if($l =~ /^(\#\s*include\s+)([\">].*[>}"])/) {
- my ($pre, $path) = ($1, $2);
- if($includes{$path}) {
- checkwarn("INCLUDEDUP",
- $line, length($1), $file, $l, "duplicated include");
- }
- $includes{$path} = $l;
- }
-
- if($l =~ /^[ \t]*\#/) {
-
- $prep = 1;
- goto preproc;
- }
- my $nostr = nostrings($l);
-
- if($nostr =~ /^(.*)(for|if|while|switch| ([a-zA-Z0-9_]+)) \((.)/) {
- my ($leading, $word, $extra, $first)=($1,$2,$3,$4);
- if($1 =~ / *\#/) {
-
- }
- elsif(defined $3 && $3 eq "return") {
-
- }
- elsif(defined $3 && $3 eq "case") {
-
- }
- elsif(($first eq "*") && ($word !~ /(for|if|while|switch)/)) {
-
-
- }
- elsif($1 =~ / *typedef/) {
-
- }
- else {
- checkwarn("SPACEBEFOREPAREN", $line, length($leading)+length($word), $file, $l,
- "$word with space");
- }
- }
-
-
- if($nostr =~ /^(.*)(if|while)(\(.*?)([!=]= NULL|NULL [!=]=)/) {
- checkwarn("EQUALSNULL", $line,
- length($1) + length($2) + length($3),
- $file, $l, "we prefer !variable instead of \"== NULL\" comparisons");
- }
-
-
- if($nostr =~ /^(.*)(if|while)(\(.*[^)]) != 0[^x]/) {
- checkwarn("NOTEQUALSZERO", $line,
- length($1) + length($2) + length($3),
- $file, $l, "we prefer if(rc) instead of \"rc != 0\" comparisons");
- }
-
- if($nostr =~ /^( *)do( *)\{/ && length($2) != 1) {
- checkwarn("DOBRACE", $line, length($1) + 2, $file, $l, "one space after do before brace");
- }
-
- elsif($nostr =~ /^( *)\}( *)while/ && length($2) != 1) {
- checkwarn("BRACEWHILE", $line, length($1) + 2, $file, $l, "one space between brace and while");
- }
- if($nostr =~ /^((.*\s)(if) *\()(.*)\)(.*)/) {
- my $pos = length($1);
- my $postparen = $5;
- my $cond = $4;
- if($cond =~ / = /) {
- checkwarn("ASSIGNWITHINCONDITION",
- $line, $pos+1, $file, $l,
- "assignment within conditional expression");
- }
- my $temp = $cond;
- $temp =~ s/\(//g;
- my $openc = length($cond) - length($temp);
- $temp = $cond;
- $temp =~ s/\)//g;
- my $closec = length($cond) - length($temp);
- my $even = $openc == $closec;
- if($l =~ / *\#/) {
-
- }
- elsif($even && $postparen &&
- ($postparen !~ /^ *$/) && ($postparen !~ /^ *[,{&|\\]+/)) {
- checkwarn("ONELINECONDITION",
- $line, length($l)-length($postparen), $file, $l,
- "conditional block on the same line");
- }
- }
-
- if($l =~ /^(.*[a-z])\( /i) {
- checkwarn("SPACEAFTERPAREN",
- $line, length($1)+1, $file, $l,
- "space after open parenthesis");
- }
-
- if($nostr =~ /^(.*)\w&&/i) {
- checkwarn("NOSPACEAND",
- $line, length($1)+1, $file, $l,
- "missing space before Logical AND");
- }
-
- if($nostr =~ /^(.*&&)\w/i) {
- checkwarn("NOSPACEAND",
- $line, length($1), $file, $l,
- "missing space after Logical AND");
- }
-
- if($nostr =~ /^(.*[^']\?[^'].*)(\w|\)|\]|')\:/i) {
- my $m = $1;
- my $e = $nostr;
- $e =~ s/'(.)':'(.)'/$1:$2/g;
- $e =~ s/':'//g;
- if($e =~ /^(.*[^']\?[^'].*)(\w|\)|\]|')\:/i) {
- checkwarn("NOSPACEC",
- $line, length($m)+1, $file, $l,
- "missing space before colon");
- }
- }
-
- if($nostr =~ /^(.*[^'"]\?[^'"].*)\:(\w|\)|\]|')/i) {
- my $m = $1;
- my $e = $nostr;
- $e =~ s/'(.)':'(.)'/$1:$2/g;
- $e =~ s/':'//g;
- if($e =~ /^(.*[^'"]\?[^'"].*)\:(\w|\)|\]|')/i) {
- checkwarn("NOSPACEC",
- $line, length($m)+1, $file, $l,
- "missing space after colon");
- }
- }
-
- if($nostr =~ /^(.*)(\w|\)|\]|')\?/i) {
- my $m = $1;
- my $e = $nostr;
- $e =~ s/'?'//g;
- if($e =~ /^(.*)(\w|\)|\]|')\?/i) {
- checkwarn("NOSPACEQ",
- $line, length($m)+1, $file, $l,
- "missing space before question mark");
- }
- }
-
- if($nostr =~ /^(.*)\?\w/i) {
- checkwarn("NOSPACEQ",
- $line, length($1)+1, $file, $l,
- "missing space after question mark");
- }
-
- if($nostr =~ /^(.*)(\w|\)|\])[<>]/) {
- checkwarn("NOSPACETHAN",
- $line, length($1)+1, $file, $l,
- "missing space before less or greater than");
- }
-
- if($nostr =~ /^(.*)[^-][<>](\w|\(|\[)/) {
- checkwarn("NOSPACETHAN",
- $line, length($1)+1, $file, $l,
- "missing space after less or greater than");
- }
-
-
- if($l =~ /(.*[^\) ]) \)/) {
- checkwarn("SPACEBEFORECLOSE",
- $line, length($1)+1, $file, $l,
- "space before close parenthesis");
- }
-
- if($l =~ /(.*[^ ]) ,/) {
- checkwarn("SPACEBEFORECOMMA",
- $line, length($1)+1, $file, $l,
- "space before comma");
- }
-
- if($l =~ /^(.*\W)return\(/) {
- if($1 =~ / *\#/) {
-
- }
- else {
- checkwarn("RETURNNOSPACE", $line, length($1)+6, $file, $l,
- "return without space before paren");
- }
- }
-
- if(($l =~ /^(.*)sizeof *([ (])/) && ($2 ne "(")) {
- if($1 =~ / *\#/) {
-
- }
- else {
- checkwarn("SIZEOFNOPAREN", $line, length($1)+6, $file, $l,
- "sizeof without parenthesis");
- }
- }
-
- if($l =~ /^(.*),[^ \n]/) {
- my $pref=$1;
- my $ign=0;
- if($pref =~ / *\#/) {
-
- $ign=1;
- }
- elsif($pref =~ /\/\*/) {
-
- $ign=1;
- }
- elsif($pref =~ /[\"\']/) {
- $ign = 1;
-
-
- if($pref =~ /\"/) {
-
- }
- elsif($pref =~ /\'$/) {
-
- }
- else {
- $ign = 0;
- }
- }
- if(!$ign) {
- checkwarn("COMMANOSPACE", $line, length($pref)+1, $file, $l,
- "comma without following space");
- }
- }
-
- if($l =~ /^(.*)\} *else/) {
- checkwarn("BRACEELSE",
- $line, length($1), $file, $l, "else after closing brace on same line");
- }
-
- if($l =~ /^(.*)\)\{/) {
- checkwarn("PARENBRACE",
- $line, length($1)+1, $file, $l, "missing space after close paren");
- }
-
- if(($l =~ /^\{/) && ($prevl =~ /^[ \t]*\z/)) {
- checkwarn("EMPTYLINEBRACE",
- $line, 0, $file, $l, "empty line before open brace");
- }
-
- if($l =~ /^(.*[^ ].*) ;$/) {
- checkwarn("SPACESEMICOLON",
- $line, length($1), $file, $ol, "no space before semicolon");
- }
-
- if($l =~ /^( *(case .+|default)) :/) {
- checkwarn("SPACESWITCHCOLON",
- $line, length($1), $file, $ol, "no space before colon of switch label");
- }
- if($prevl !~ /\?\z/ && $l =~ /^ +([A-Za-z_][A-Za-z0-9_]*):$/ && $1 ne 'default') {
- checkwarn("SPACEBEFORELABEL",
- $line, length($1), $file, $ol, "no space before label");
- }
-
- if($l =~ /^(.*\W)
- (gmtime|localtime|
- gets|
- strtok|
- v?sprintf|
- (str|_mbs|_tcs|_wcs)n?cat|
- LoadLibrary(Ex)?(A|W)?|
- _?w?access)
- \s*\(
- /x) {
- checkwarn("BANNEDFUNC",
- $line, length($1), $file, $ol,
- "use of $2 is banned");
- }
-
-
- if($l =~ /^(.*\W)(sscanf)\s*\(/x) {
- if($1 !~ /^ *\#/) {
-
- checkwarn("SSCANF",
- $line, length($1), $file, $ol,
- "use of $2 is banned");
- }
- }
- if($warnings{"STRERROR"}) {
-
-
- if($l =~ /^(.*\W)(strerror)\s*\(/x) {
- if($1 !~ /^ *\#/) {
-
- checkwarn("STRERROR",
- $line, length($1), $file, $ol,
- "use of $2 is banned");
- }
- }
- }
- if($warnings{"STRNCPY"}) {
-
-
- if($l =~ /^(.*\W)(strncpy)\s*\(/x) {
- if($1 !~ /^ *\#/) {
-
- checkwarn("STRNCPY",
- $line, length($1), $file, $ol,
- "use of $2 is banned");
- }
- }
- }
- if($warnings{"STDERR"}) {
-
-
- if($l =~ /^([^\"-]*\W)(stderr)[^\"_]/x) {
- if($1 !~ /^ *\#/) {
-
- checkwarn("STDERR",
- $line, length($1), $file, $ol,
- "use of $2 is banned (use tool_stderr instead)");
- }
- }
- }
-
- if($l =~ /^(.*\W)(v?snprintf)\s*\(/x) {
- checkwarn("SNPRINTF",
- $line, length($1), $file, $ol,
- "use of $2 is banned");
- }
-
- if($l =~ /^(.*\W)fopen\s*\([^,]*, *\"([^"]*)/) {
- my $mode = $2;
- if($mode !~ /b/) {
- checkwarn("FOPENMODE",
- $line, length($1), $file, $ol,
- "use of non-binary fopen without FOPEN_* macro: $mode");
- }
- }
-
-
- if(($prevl =~ /\)\z/) && ($l =~ /^( +)\{/) && !$prevp) {
- checkwarn("BRACEPOS",
- $line, length($1), $file, $ol, "badly placed open brace");
- }
-
-
-
- if(!$prevp && ($prevl =~ /^( *)((if|while|for)\(.*\{|else)\z/)) {
- my $first = length($1);
-
- if($l =~ /^( *)[^ ]/) {
- my $second = length($1);
- my $expect = $first+$indent;
- if($expect != $second) {
- my $diff = $second - $first;
- checkwarn("INDENTATION", $line, length($1), $file, $ol,
- "not indented $indent steps (uses $diff)");
- }
- }
- }
-
-
-
-
- elsif(!$prevp && ($prevl =~ /^( *)(if|while|for)(\(.*\))\z/)) {
- my $first = length($1);
- my $op = $3;
- my $cl = $3;
- $op =~ s/[^(]//g;
- $cl =~ s/[^)]//g;
- if(length($op) == length($cl)) {
-
- if($l =~ /^( *)[^ ]/) {
- my $second = length($1);
- my $expect = $first+$indent;
- if($expect != $second) {
- my $diff = $second - $first;
- checkwarn("INDENTATION", $line, length($1), $file, $ol,
- "not indented $indent steps (uses $diff)");
- }
- }
- }
- }
-
- if(($l =~ /(^.*(char|int|long|void|CURL|CURLM|CURLMsg|[cC]url_[A-Za-z_]+|struct [a-zA-Z_]+) *(\*+)) (\w+)/) && ($4 !~ /^(const|volatile)$/)) {
- checkwarn("ASTERISKSPACE",
- $line, length($1), $file, $ol,
- "space after declarative asterisk");
- }
-
- if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost|sockaddr_in|FILE)\*)/)) {
- checkwarn("ASTERISKNOSPACE",
- $line, length($1)-1, $file, $ol,
- "no space before asterisk");
- }
-
-
- if($l =~ /^((\w).*)\{\z/) {
- my $k = $1;
- $k =~ s/const *//;
- $k =~ s/static *//;
- if($k =~ /\(.*\)/) {
- checkwarn("BRACEPOS",
- $line, length($l)-1, $file, $ol,
- "wrongly placed open brace");
- }
- }
-
- if($nostr =~ /(.*)\=[a-z0-9]/i) {
- checkwarn("EQUALSNOSPACE",
- $line, length($1)+1, $file, $ol,
- "no space after equals sign");
- }
-
- elsif($nostr =~ /(.*)[a-z0-9]\=/i) {
- checkwarn("NOSPACEEQUALS",
- $line, length($1)+1, $file, $ol,
- "no space before equals sign");
- }
-
- if($nostr =~ /(.*)[^+]\+[a-z0-9]/i) {
- checkwarn("PLUSNOSPACE",
- $line, length($1)+1, $file, $ol,
- "no space after plus sign");
- }
-
- elsif($nostr =~ /(.*)[a-z0-9]\+[^+]/i) {
- checkwarn("NOSPACEPLUS",
- $line, length($1)+1, $file, $ol,
- "no space before plus sign");
- }
-
- if($nostr =~ /(.*)\;[a-z0-9]/i) {
- checkwarn("SEMINOSPACE",
- $line, length($1)+1, $file, $ol,
- "no space after semicolon");
- }
-
- if($nostr =~ /^(.*)typedef struct.*{/) {
- checkwarn("TYPEDEFSTRUCT",
- $line, length($1)+1, $file, $ol,
- "typedef'ed struct");
- }
- if($nostr =~ /(.*)! +(\w|\()/) {
- checkwarn("EXCLAMATIONSPACE",
- $line, length($1)+1, $file, $ol,
- "space after exclamation mark");
- }
-
-
-
- if(($l eq $nostr) &&
- $nostr =~ /^(.*(\S)) + [{?]/i) {
- checkwarn("MULTISPACE",
- $line, length($1)+1, $file, $ol,
- "multiple spaces");
- }
- preproc:
- if($prep) {
-
- if($l =~ /^(^|.*\W)
- (WIN32)
- (\W|$)
- /x) {
- checkwarn("BANNEDPREPROC",
- $line, length($1), $file, $ol,
- "use of $2 is banned from preprocessor lines" .
- (($2 eq "WIN32") ? ", use _WIN32 instead" : ""));
- }
- }
- $line++;
- $prevp = $prep;
- $prevl = $ol if(!$prep);
- $prevpl = $ol if($prep);
- }
- if(!scalar(@copyright)) {
- checkwarn("COPYRIGHT", 1, 0, $file, "", "Missing copyright statement", 1);
- }
-
-
- if(defined($warnings{"COPYRIGHTYEAR"})) {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- my $commityear = undef;
- @copyright = sort {$$b{year} cmp $$a{year}} @copyright;
-
- if(`git status -s -- "$file"` =~ /^ [MARCU]/) {
- $commityear = (localtime(time))[5] + 1900;
- }
- else {
-
- my $grl = `git rev-list --max-count=1 --min-parents=1 --timestamp HEAD -- "$file"`;
- if($grl) {
- chomp $grl;
- $commityear = (localtime((split(/ /, $grl))[0]))[5] + 1900;
- }
- }
- if(defined($commityear) && scalar(@copyright) &&
- $copyright[0]{year} != $commityear) {
- checkwarn("COPYRIGHTYEAR", $copyright[0]{line}, $copyright[0]{col},
- $file, $copyright[0]{code},
- "Copyright year out of date, should be $commityear, " .
- "is $copyright[0]{year}", 1);
- }
- }
- if($incomment) {
- checkwarn("OPENCOMMENT", 1, 0, $file, "", "Missing closing comment", 1);
- }
- checksrc_endoffile($file);
- close($R);
- }
- if($errors || $warnings || $verbose) {
- printf "checksrc: %d errors and %d warnings\n", $errors, $warnings;
- if($suppressed) {
- printf "checksrc: %d errors and %d warnings suppressed\n",
- $serrors,
- $swarnings;
- }
- exit 5;
- }
|