Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a1d94aa5 authored by Randy Dunlap's avatar Randy Dunlap Committed by Sam Ravnborg
Browse files

kernel-doc: check for extra kernel-doc notations



Add functionality to check for function parameters or structure (or
union/typedef/enum) field members that are described in kernel-doc but
are not part of the expected (declared) parameters or structure.
These generate warnings that are called "Excess" descriptions.

Signed-off-by: default avatarRandy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
parent 179efcb4
Loading
Loading
Loading
Loading
+66 −1
Original line number Diff line number Diff line
@@ -289,6 +289,8 @@ my %parameterdescs;
my @parameterlist;
my %sections;
my @sectionlist;
my $sectcheck;
my $struct_actual;

my $contents = "";
my $section_default = "Description";	# default section
@@ -378,10 +380,12 @@ sub dump_section {
#	print STDERR "parameter def '$1' = '$contents'\n";
	$name = $1;
	$parameterdescs{$name} = $contents;
	$sectcheck = $sectcheck . $name . " ";
    } elsif ($name eq "@\.\.\.") {
#	print STDERR "parameter def '...' = '$contents'\n";
	$name = "...";
	$parameterdescs{$name} = $contents;
	$sectcheck = $sectcheck . $name . " ";
    } else {
#	print STDERR "other section '$name' = '$contents'\n";
	if (defined($sections{$name}) && ($sections{$name} ne "")) {
@@ -1405,21 +1409,25 @@ sub dump_union($$) {
sub dump_struct($$) {
    my $x = shift;
    my $file = shift;
    my $nested;

    if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) {
	$declaration_name = $2;
	my $members = $3;

	# ignore embedded structs or unions
	$members =~ s/{.*}//g;
	$members =~ s/({.*})//g;
	$nested = $1;

	# ignore members marked private:
	$members =~ s/\/\*.*?private:.*?public:.*?\*\///gos;
	$members =~ s/\/\*.*?private:.*//gos;
	# strip comments:
	$members =~ s/\/\*.*?\*\///gos;
	$nested =~ s/\/\*.*?\*\///gos;

	create_parameterlist($members, ';', $file);
	check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested);

	output_declaration($declaration_name,
			   'struct',
@@ -1505,6 +1513,14 @@ sub dump_typedef($$) {
    }
}

sub save_struct_actual($) {
    my $actual = shift;

    # strip all spaces from the actual param so that it looks like one string item
    $actual =~ s/\s*//g;
    $struct_actual = $struct_actual . $actual . " ";
}

sub create_parameterlist($$$) {
    my $args = shift;
    my $splitter = shift;
@@ -1537,6 +1553,7 @@ sub create_parameterlist($$$) {
	    $param = $1;
	    $type = $arg;
	    $type =~ s/([^\(]+\(\*?)\s*$param/$1/;
	    save_struct_actual($param);
	    push_parameter($param, $type, $file);
	} elsif ($arg) {
	    $arg =~ s/\s*:\s*/:/g;
@@ -1561,14 +1578,17 @@ sub create_parameterlist($$$) {

	    foreach $param (@args) {
		if ($param =~ m/^(\*+)\s*(.*)/) {
		    save_struct_actual($2);
		    push_parameter($2, "$type $1", $file);
		}
		elsif ($param =~ m/(.*?):(\d+)/) {
		    if ($type ne "") { # skip unnamed bit-fields
			save_struct_actual($1);
			push_parameter($1, "$type:$2", $file)
		    }
		}
		else {
		    save_struct_actual($param);
		    push_parameter($param, $type, $file);
		}
	    }
@@ -1634,6 +1654,46 @@ sub push_parameter($$$) {
	$parametertypes{$param} = $type;
}

sub check_sections($$$$$$) {
	my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck, $nested) = @_;
	my @sects = split ' ', $sectcheck;
	my @prms = split ' ', $prmscheck;
	my $err;
	my ($px, $sx);
	my $prm_clean;		# strip trailing "[array size]" and/or beginning "*"

	foreach $sx (0 .. $#sects) {
		$err = 1;
		foreach $px (0 .. $#prms) {
			$prm_clean = $prms[$px];
			$prm_clean =~ s/\[.*\]//;
			$prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//;
			##$prm_clean =~ s/^\**//;
			if ($prm_clean eq $sects[$sx]) {
				$err = 0;
				last;
			}
		}
		if ($err) {
			if ($decl_type eq "function") {
				print STDERR "Warning(${file}:$.): " .
					"Excess function parameter " .
					"'$sects[$sx]' " .
					"description in '$decl_name'\n";
				++$warnings;
			} else {
				if ($nested !~ m/\Q$sects[$sx]\E/) {
				    print STDERR "Warning(${file}:$.): " .
					"Excess struct/union/enum/typedef member " .
					"'$sects[$sx]' " .
					"description in '$decl_name'\n";
				    ++$warnings;
				}
			}
		}
	}
}

##
# takes a function prototype and the name of the current file being
# processed and spits out all the details stored in the global
@@ -1699,6 +1759,9 @@ sub dump_function($$) {
	return;
    }

	my $prms = join " ", @parameterlist;
	check_sections($file, $declaration_name, "function", $sectcheck, $prms, "");

    output_declaration($declaration_name,
		       'function',
		       {'function' => $declaration_name,
@@ -1757,6 +1820,8 @@ sub reset_state {
    @parameterlist = ();
    %sections = ();
    @sectionlist = ();
    $sectcheck = "";
    $struct_actual = "";
    $prototype = "";

    $state = 0;