+# Check that we have consistent public / internal documentation and declaration
+sub checkstate () {
+ # Collect all known names, no matter where they come from
+ my %names = map { $_ => 1 } (keys %name_map, keys %state, keys %missing);
+
+ # Check section 3, i.e. functions and macros
+ foreach ( grep { $_ =~ /\(3\)$/ } sort keys %names ) {
+ next if ( $name_map{$_} // '') eq '' || $_ =~ /$ignored/;
+
+ # If a man-page isn't recorded public or if it's recorded missing
+ # and internal, it's declared to be internal.
+ my $declared_internal =
+ ($state{$_} // 'internal') eq 'internal'
+ || ($missing{$_} // '') eq 'internal';
+ # If a man-page isn't recorded internal or if it's recorded missing
+ # and not internal, it's declared to be public
+ my $declared_public =
+ ($state{$_} // 'internal') ne 'internal'
+ || ($missing{$_} // 'internal') ne 'internal';
+
+ err("$_ is supposedly public but is documented as internal")
+ if ( $declared_public && $name_map{$_} =~ /\/internal\// );
+ err("$_ is supposedly internal but is documented as public")
+ if ( $declared_internal && $name_map{$_} !~ /\/internal\// );