xref: /openbsd-src/regress/lib/libcrypto/man/check_complete.pl (revision 33885c32518568087b794e9d76f129869894d7fd)
1441d0e04Sschwarze#!/usr/bin/perl
2441d0e04Sschwarze#
3441d0e04Sschwarze# Copyright (c) 2021 Ingo Schwarze <schwarze@openbsd.org>
4441d0e04Sschwarze#
5441d0e04Sschwarze# Permission to use, copy, modify, and distribute this software for any
6441d0e04Sschwarze# purpose with or without fee is hereby granted, provided that the above
7441d0e04Sschwarze# copyright notice and this permission notice appear in all copies.
8441d0e04Sschwarze#
9441d0e04Sschwarze# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10441d0e04Sschwarze# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11441d0e04Sschwarze# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12441d0e04Sschwarze# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13441d0e04Sschwarze# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14441d0e04Sschwarze# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15441d0e04Sschwarze# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16441d0e04Sschwarze
17441d0e04Sschwarzeuse strict;
18441d0e04Sschwarzeuse warnings;
19441d0e04Sschwarze
202f8193d4Sschwarzemy %internal = (
212f8193d4Sschwarze    asn1 => [qw(
22c0673ca7Sschwarze	ASN1_ENCODING
233e614808Stb	ASN1_STRING_FLAG_CONT
240d867e69Sschwarze	ASN1_STRING_FLAG_MSTRING ASN1_STRING_FLAG_NDEF
250d867e69Sschwarze	CHARTYPE_FIRST_ESC_2253 CHARTYPE_LAST_ESC_2253 CHARTYPE_PRINTABLESTRING
262f8193d4Sschwarze    )],
279f20cb86Sschwarze    bn => [qw(
28eca1bd36Sschwarze	BN_BITS BN_BITS4 BN_BYTES
29eca1bd36Sschwarze	BN_DEC_CONV BN_DEC_FMT1 BN_DEC_FMT2 BN_DEC_NUM BN_LLONG BN_LONG
3030e9f0bbStb	BN_MASK2 BN_MASK2h BN_MASK2h1 BN_MASK2l
3130e9f0bbStb	BN_TBIT BN_ULLONG
329f20cb86Sschwarze    )],
33bc28fcf4Sschwarze    evp => [qw(
3410e3f8f4Sschwarze	ASN1_PKEY_CTRL_CMS_ENVELOPE ASN1_PKEY_CTRL_CMS_RI_TYPE
3510e3f8f4Sschwarze	ASN1_PKEY_CTRL_CMS_SIGN
36*33885c32Sschwarze	dh_st dsa_st ec_key_st
37bc28fcf4Sschwarze	EVP_MD_CTRL_ALG_CTRL
38bc28fcf4Sschwarze	EVP_MD_CTX_FLAG_CLEANED EVP_MD_CTX_FLAG_REUSE
3922653340Sschwarze	EVP_PKEY_ALG_CTRL
40a4f89571Sschwarze	EVP_PKEY_CTRL_CMS_DECRYPT EVP_PKEY_CTRL_CMS_ENCRYPT
41a4f89571Sschwarze	EVP_PKEY_CTRL_CMS_SIGN
4222653340Sschwarze	EVP_PKEY_CTRL_DIGESTINIT
4322653340Sschwarze	EVP_PKEY_CTRL_PEER_KEY
44a4f89571Sschwarze	EVP_PKEY_CTRL_PKCS7_DECRYPT EVP_PKEY_CTRL_PKCS7_ENCRYPT
45a4f89571Sschwarze	EVP_PKEY_CTRL_PKCS7_SIGN
46*33885c32Sschwarze	rsa_st
47bc28fcf4Sschwarze    )],
482f8193d4Sschwarze    x509_vfy => [qw(
492f8193d4Sschwarze	X509_VERIFY_PARAM_ID
502f8193d4Sschwarze    )]
512f8193d4Sschwarze);
522f8193d4Sschwarze
532f8193d4Sschwarzemy %obsolete = (
542f8193d4Sschwarze    asn1 => [qw(
552f8193d4Sschwarze	ASN1_dup ASN1_d2i_bio ASN1_d2i_bio_of ASN1_d2i_fp ASN1_d2i_fp_of
562f8193d4Sschwarze	ASN1_i2d_bio ASN1_i2d_bio_of ASN1_i2d_bio_of_const
572f8193d4Sschwarze	ASN1_i2d_fp ASN1_i2d_fp_of ASN1_i2d_fp_of_const
582f8193d4Sschwarze	ASN1_LONG_UNDEF
5901ea070eSschwarze	BIT_STRING_BITNAME
600d867e69Sschwarze	V_ASN1_PRIMATIVE_TAG
610d867e69Sschwarze	X509_algor_st
622f8193d4Sschwarze    )],
63c83d4cbbSschwarze    bio => [qw(
64637dfdfcSschwarze	asn1_ps_func
652188fc5dSschwarze	BIO_C_GET_PROXY_PARAM BIO_C_GET_SOCKS
662188fc5dSschwarze	BIO_C_SET_PROXY_PARAM BIO_C_SET_SOCKS
67c83d4cbbSschwarze	BIO_get_no_connect_return BIO_get_proxies
68c83d4cbbSschwarze	BIO_get_proxy_header BIO_get_url
69c83d4cbbSschwarze	BIO_set_filter_bio BIO_set_no_connect_return BIO_set_proxies
70c83d4cbbSschwarze	BIO_set_proxy_cb BIO_set_proxy_header BIO_set_url
71c83d4cbbSschwarze    )],
72988755e7Sschwarze    bn => [qw(
7326777e57Sschwarze	BN_HEX_FMT1 BN_HEX_FMT2 BN_MASK
74988755e7Sschwarze    )],
75bc28fcf4Sschwarze    evp => [qw(
7611e77a13Sschwarze	EVP_CIPH_FLAG_FIPS EVP_CIPH_FLAG_NON_FIPS_ALLOW
7711e77a13Sschwarze	EVP_CTRL_AEAD_SET_MAC_KEY EVP_CTRL_AEAD_TLS1_AAD
786b76ac2eSschwarze	EVP_CTRL_GET_RC5_ROUNDS EVP_CTRL_GOST_SET_SBOX
796b76ac2eSschwarze	EVP_CTRL_PBE_PRF_NID EVP_CTRL_SET_RC5_ROUNDS
801b6b588eSschwarze	EVP_MD_CTRL_DIGALGID EVP_MD_CTRL_GOST_SET_SBOX EVP_MD_CTRL_SET_KEY
81bc28fcf4Sschwarze	EVP_MD_CTX_FLAG_NON_FIPS_ALLOW EVP_MD_CTX_FLAG_PAD_MASK
82bc28fcf4Sschwarze	EVP_MD_CTX_FLAG_PAD_PKCS1 EVP_MD_CTX_FLAG_PAD_PSS
8311e77a13Sschwarze	EVP_MD_FLAG_DIGALGID_MASK
846b76ac2eSschwarze	EVP_PBE_KEYGEN
851b6b588eSschwarze	EVP_PKEY_CTRL_SET_IV
869fcb7baeSschwarze	EVP_PKEY_GOSTIMIT EVP_PKEY_GOSTR01
879fcb7baeSschwarze	EVP_PKEY_GOSTR12_256 EVP_PKEY_GOSTR12_512
8811e77a13Sschwarze	EVP_PKEY_MO_DECRYPT EVP_PKEY_MO_ENCRYPT
8911e77a13Sschwarze	EVP_PKEY_MO_SIGN EVP_PKEY_MO_VERIFY
90bc28fcf4Sschwarze    )],
910d867e69Sschwarze);
920d867e69Sschwarze
932f8193d4Sschwarzemy %postponed = (
942f8193d4Sschwarze    asn1 => [qw(
95c0673ca7Sschwarze	ASN1_ITEM_EXP ASN1_ITEM_ptr ASN1_ITEM_ref ASN1_ITEM_rptr
96c0673ca7Sschwarze	ASN1_TEMPLATE ASN1_TLC
972f8193d4Sschwarze	CHECKED_D2I_OF CHECKED_I2D_OF CHECKED_NEW_OF
982f8193d4Sschwarze	CHECKED_PPTR_OF CHECKED_PTR_OF
990d867e69Sschwarze	DECLARE_ASN1_ALLOC_FUNCTIONS DECLARE_ASN1_ALLOC_FUNCTIONS_name
1000d867e69Sschwarze	DECLARE_ASN1_ENCODE_FUNCTIONS DECLARE_ASN1_ENCODE_FUNCTIONS_const
1010d867e69Sschwarze	DECLARE_ASN1_FUNCTIONS DECLARE_ASN1_FUNCTIONS_const
1020d867e69Sschwarze	DECLARE_ASN1_FUNCTIONS_fname DECLARE_ASN1_FUNCTIONS_name
1030d867e69Sschwarze	DECLARE_ASN1_ITEM
1040d867e69Sschwarze	DECLARE_ASN1_NDEF_FUNCTION
1050d867e69Sschwarze	DECLARE_ASN1_PRINT_FUNCTION DECLARE_ASN1_PRINT_FUNCTION_fname
1060d867e69Sschwarze	DECLARE_ASN1_SET_OF
1070d867e69Sschwarze	D2I_OF
1080d867e69Sschwarze	IMPLEMENT_ASN1_SET_OF
1090d867e69Sschwarze	I2D_OF I2D_OF_const
1102f8193d4Sschwarze	TYPEDEF_D2I_OF TYPEDEF_D2I2D_OF TYPEDEF_I2D_OF
1112f8193d4Sschwarze    )],
1122f8193d4Sschwarze    x509 => [qw(
1133e614808Stb	NETSCAPE_SPKAC NETSCAPE_SPKI PBEPARAM
1142f8193d4Sschwarze    )]
115441d0e04Sschwarze);
116441d0e04Sschwarze
117441d0e04Sschwarzemy $MANW = 'man -M /usr/share/man -w';
118441d0e04Sschwarzemy $srcdir = '/usr/src/lib/libcrypto/man';
119441d0e04Sschwarzemy $hfile = '/usr/include/openssl';
120441d0e04Sschwarze
121441d0e04Sschwarzemy $in_cplusplus = 0;
122441d0e04Sschwarzemy $in_comment = 0;
123441d0e04Sschwarzemy $in_define = 0;
124441d0e04Sschwarzemy $in_function = 0;
125441d0e04Sschwarzemy $in_struct = 0;
126441d0e04Sschwarzemy $in_typedef_struct = 0;
127eca1bd36Sschwarzemy %expect_undoc = ();
128eca1bd36Sschwarzemy %found_undoc = ();
129441d0e04Sschwarzemy $verbose = 0;
130441d0e04Sschwarze
131441d0e04Sschwarzeif (defined $ARGV[0] && $ARGV[0] eq '-v') {
132441d0e04Sschwarze	$verbose = 1;
133441d0e04Sschwarze	shift @ARGV;
134441d0e04Sschwarze}
135441d0e04Sschwarze$#ARGV == 0 or die "usage: $0 [-v] headername";
136441d0e04Sschwarze$hfile .= "/$ARGV[0].h";
137441d0e04Sschwarzeopen my $in_fh, '<', $hfile or die "$hfile: $!";
138441d0e04Sschwarze
139eca1bd36Sschwarze$expect_undoc{$_} = 1 foreach @{$internal{$ARGV[0]}};
140eca1bd36Sschwarze$expect_undoc{$_} = 1 foreach @{$obsolete{$ARGV[0]}};
141eca1bd36Sschwarze$expect_undoc{$_} = 1 foreach @{$postponed{$ARGV[0]}};
1422f8193d4Sschwarze
143441d0e04Sschwarzewhile (<$in_fh>) {
144441d0e04Sschwarzetry_again:
145441d0e04Sschwarze	chomp;
146441d0e04Sschwarze	my $line = $_;
147441d0e04Sschwarze
148441d0e04Sschwarze	# C language comments.
149441d0e04Sschwarze
150441d0e04Sschwarze	if ($in_comment) {
151441d0e04Sschwarze		unless (s/.*?\*\///) {
152441d0e04Sschwarze			print "-- $line\n" if $verbose;
153441d0e04Sschwarze			next;
154441d0e04Sschwarze		}
155441d0e04Sschwarze		$in_comment = 0;
156441d0e04Sschwarze	}
157441d0e04Sschwarze	while (/\/\*/) {
158c7f69c0dSschwarze		s/\s*\/\*.*?\*\/// and next;
159c7f69c0dSschwarze		s/\s*\/\*.*// and $in_comment = 1;
160441d0e04Sschwarze	}
161441d0e04Sschwarze
162441d0e04Sschwarze	# End C++ stuff.
163441d0e04Sschwarze
164441d0e04Sschwarze	if ($in_cplusplus) {
165441d0e04Sschwarze		/^#endif$/ and $in_cplusplus = 0;
166441d0e04Sschwarze		print "-- $line\n" if $verbose;
167441d0e04Sschwarze		next;
168441d0e04Sschwarze	}
169441d0e04Sschwarze
170441d0e04Sschwarze	# End declarations of structs.
171441d0e04Sschwarze
172441d0e04Sschwarze	if ($in_struct) {
173c7f69c0dSschwarze		if (/^\s*union\s+{$/) {
174c7f69c0dSschwarze			print "-s $line\n" if $verbose;
175c7f69c0dSschwarze			$in_struct++;
176c7f69c0dSschwarze			next;
177c7f69c0dSschwarze		}
178441d0e04Sschwarze		unless (s/^\s*\}//) {
179441d0e04Sschwarze			print "-s $line\n" if $verbose;
180441d0e04Sschwarze			next;
181441d0e04Sschwarze		}
182c7f69c0dSschwarze		if (--$in_struct && /^\s+\w+;$/) {
183c7f69c0dSschwarze			print "-s $line\n" if $verbose;
184c7f69c0dSschwarze			next;
185c7f69c0dSschwarze		}
186441d0e04Sschwarze		unless ($in_typedef_struct) {
187441d0e04Sschwarze			/^\s*;$/ or die "at end of struct: $_";
188441d0e04Sschwarze			print "-s $line\n" if $verbose;
189441d0e04Sschwarze			next;
190441d0e04Sschwarze		}
191441d0e04Sschwarze		$in_typedef_struct = 0;
192441d0e04Sschwarze		my ($id) = /^\s*(\w+);$/
193441d0e04Sschwarze		    or die "at end of typedef struct: $_";
194eca1bd36Sschwarze		unless (system "$MANW -k 'Vt~^$id\$' > /dev/null 2>&1") {
195441d0e04Sschwarze			print "Vt $line\n" if $verbose;
196441d0e04Sschwarze			next;
197441d0e04Sschwarze		}
198eca1bd36Sschwarze		if ($expect_undoc{$id}) {
199441d0e04Sschwarze			print "V- $line\n" if $verbose;
200eca1bd36Sschwarze			$found_undoc{$id} = 1;
201441d0e04Sschwarze			next;
202441d0e04Sschwarze		}
203441d0e04Sschwarze		if ($verbose) {
204441d0e04Sschwarze			print "XX $line\n";
205441d0e04Sschwarze		} else {
206441d0e04Sschwarze			warn "not found: typedef struct $id";
207441d0e04Sschwarze		}
208441d0e04Sschwarze		next;
209441d0e04Sschwarze	}
210441d0e04Sschwarze
211441d0e04Sschwarze	# End macro definitions.
212441d0e04Sschwarze
213441d0e04Sschwarze	if ($in_define) {
214441d0e04Sschwarze		/\\$/ or $in_define = 0;
215441d0e04Sschwarze		print "-d $line\n" if $verbose;
216441d0e04Sschwarze		next;
217441d0e04Sschwarze	}
218441d0e04Sschwarze
219441d0e04Sschwarze	# End function declarations.
220441d0e04Sschwarze
221441d0e04Sschwarze	if ($in_function) {
222441d0e04Sschwarze		/^\s/ or die "function arguments not indented: $_";
223441d0e04Sschwarze		/\);$/ and $in_function = 0;
224441d0e04Sschwarze		print "-f $line\n" if $verbose;
225441d0e04Sschwarze		next;
226441d0e04Sschwarze	}
227441d0e04Sschwarze
228441d0e04Sschwarze	# Begin C++ stuff.
229441d0e04Sschwarze
230441d0e04Sschwarze	if (/^#ifdef\s+__cplusplus$/) {
231441d0e04Sschwarze		$in_cplusplus = 1;
232441d0e04Sschwarze		print "-- $line\n" if $verbose;
233441d0e04Sschwarze		next;
234441d0e04Sschwarze	}
235441d0e04Sschwarze
236441d0e04Sschwarze	# Uninteresting lines.
237441d0e04Sschwarze
238441d0e04Sschwarze	if (/^\s*$/ ||
239441d0e04Sschwarze	    /^DECLARE_STACK_OF\(\w+\)$/ ||
240ca8f9820Sschwarze	    /^DECLARE_PKCS12_STACK_OF\(\w+\)$/ ||
241c7f69c0dSschwarze	    /^TYPEDEF_D2I2D_OF\(\w+\);$/ ||
24235e5d770Sschwarze	    /^#define __bounded__\(\w+, \w+, \w+\)$/ ||
243441d0e04Sschwarze	    /^#define HEADER_\w+_H$/ ||
244441d0e04Sschwarze	    /^#endif$/ ||
2452f8193d4Sschwarze	    /^#else$/ ||
2462274872dStb	    /^#error/ ||
247441d0e04Sschwarze	    /^extern\s+const\s+ASN1_ITEM\s+\w+_it;$/ ||
24835e5d770Sschwarze	    /^#\s*include\s/ ||
249c7f69c0dSschwarze	    /^#ifn?def\s/ ||
2509f20cb86Sschwarze	    /^#if !?defined/ ||
2519f20cb86Sschwarze	    /^#undef\s+BN_LLONG$/) {
252441d0e04Sschwarze		print "-- $line\n" if $verbose;
253441d0e04Sschwarze		next;
254441d0e04Sschwarze	}
255441d0e04Sschwarze
256441d0e04Sschwarze	# Begin declarations of structs.
257441d0e04Sschwarze
258441d0e04Sschwarze	if (/^(typedef )?(?:struct|enum)(?: \w+)? \{$/) {
259441d0e04Sschwarze		$in_struct = 1;
260441d0e04Sschwarze		$1 and $in_typedef_struct = 1;
261441d0e04Sschwarze		print "-s $line\n" if $verbose;
262441d0e04Sschwarze		next;
263441d0e04Sschwarze	}
264441d0e04Sschwarze
2656216412cSschwarze	# Handle macros.
2666216412cSschwarze
267c7f69c0dSschwarze	if (my ($id) = /^#\s*define\s+(\w+)\s+\S/) {
268441d0e04Sschwarze		/\\$/ and $in_define = 1;
269eca1bd36Sschwarze		if ($id eq 'BN_ULONG' &&
270eca1bd36Sschwarze		    not system "$MANW -k 'Vt~^$id\$' > /dev/null 2>&1") {
271eca1bd36Sschwarze			print "Vt $line\n" if $verbose;
272eca1bd36Sschwarze			next;
273eca1bd36Sschwarze		}
274eca1bd36Sschwarze		unless (system "$MANW -k 'Dv~^$id\$' > /dev/null 2>&1") {
275441d0e04Sschwarze			print "Dv $line\n" if $verbose;
276441d0e04Sschwarze			next;
277441d0e04Sschwarze		}
278441d0e04Sschwarze		unless (system "$MANW $id > /dev/null 2>&1") {
279441d0e04Sschwarze			print "Fn $line\n" if $verbose;
280441d0e04Sschwarze			next;
281441d0e04Sschwarze		}
2820d867e69Sschwarze		unless (system qw/grep -qR/, '^\.\\\\" .*\<' . $id . '\>',
283441d0e04Sschwarze		    "$srcdir/") {
284441d0e04Sschwarze			print "D- $line\n" if $verbose;
285441d0e04Sschwarze			next;
286441d0e04Sschwarze		}
2870d867e69Sschwarze		if ($id =~ /^ASN1_PCTX_FLAGS_\w+$/) {
2880d867e69Sschwarze			print "D- $line\n" if $verbose;
2890d867e69Sschwarze			next;
2900d867e69Sschwarze		}
291bc28fcf4Sschwarze		if ($id =~ /^(?:ASN1|BIO|BN|EVP|X509(?:V3)?)_[FR]_\w+$/) {
292441d0e04Sschwarze			print "D- $line\n" if $verbose;
293441d0e04Sschwarze			next;
294441d0e04Sschwarze		}
295441d0e04Sschwarze		if ($id =~ /^X509_V_ERR_\w+$/) {
296441d0e04Sschwarze			print "D- $line\n" if $verbose;
297441d0e04Sschwarze			next;
298441d0e04Sschwarze		}
2992f8193d4Sschwarze		if ($id =~ /^(?:SN|LN|NID|OBJ)_\w+$/) {
300441d0e04Sschwarze			print "D- $line\n" if $verbose;
301441d0e04Sschwarze			next;
302441d0e04Sschwarze		}
303eca1bd36Sschwarze		if ($expect_undoc{$id}) {
3042f8193d4Sschwarze			print "D- $line\n" if $verbose;
305eca1bd36Sschwarze			$found_undoc{$id} = 1;
3062f8193d4Sschwarze			next;
3072f8193d4Sschwarze		}
308441d0e04Sschwarze		if ($verbose) {
309441d0e04Sschwarze			print "XX $line\n";
310441d0e04Sschwarze		} else {
311441d0e04Sschwarze			warn "not found: #define $id";
312441d0e04Sschwarze		}
313441d0e04Sschwarze		next;
314441d0e04Sschwarze	}
315c7f69c0dSschwarze	if (my ($id) = /^#\s*define\s+(\w+)\(/) {
316441d0e04Sschwarze		/\\$/ and $in_define = 1;
317441d0e04Sschwarze		unless (system "$MANW $id > /dev/null 2>&1") {
318441d0e04Sschwarze			print "Fn $line\n" if $verbose;
319441d0e04Sschwarze			next;
320441d0e04Sschwarze		}
3212f8193d4Sschwarze		unless (system qw/grep -qR/, '^\.\\\\" .*\<' . $id . '\>',
322441d0e04Sschwarze		    "$srcdir/") {
323441d0e04Sschwarze			print "F- $line\n" if $verbose;
324441d0e04Sschwarze			next;
325441d0e04Sschwarze		}
326eca1bd36Sschwarze		if ($expect_undoc{$id}) {
3270d867e69Sschwarze			print "F- $line\n" if $verbose;
328eca1bd36Sschwarze			$found_undoc{$id} = 1;
3290d867e69Sschwarze			next;
3300d867e69Sschwarze		}
331441d0e04Sschwarze		if ($verbose) {
332441d0e04Sschwarze			print "XX $line\n";
333441d0e04Sschwarze		} else {
334441d0e04Sschwarze			warn "not found: #define $id()";
335441d0e04Sschwarze		}
336441d0e04Sschwarze		next;
337441d0e04Sschwarze	}
3389f20cb86Sschwarze	if (my ($id) = /^#\s*define\s+(\w+)$/) {
339eca1bd36Sschwarze		if ($expect_undoc{$id}) {
3409f20cb86Sschwarze			print "-- $line\n" if $verbose;
341eca1bd36Sschwarze			$found_undoc{$id} = 1;
3429f20cb86Sschwarze			next;
3439f20cb86Sschwarze		}
3449f20cb86Sschwarze		if ($verbose) {
3459f20cb86Sschwarze			print "XX $line\n";
3469f20cb86Sschwarze		} else {
3479f20cb86Sschwarze			warn "not found: #define $id";
3489f20cb86Sschwarze		}
3499f20cb86Sschwarze		next;
3509f20cb86Sschwarze	}
3516216412cSschwarze
3522f8193d4Sschwarze	# Handle global variables.
3532f8193d4Sschwarze
3542f8193d4Sschwarze	if (my ($id) = /^extern\s+int\s+(\w+);$/) {
355eca1bd36Sschwarze		unless (system "$MANW -k 'Va~^$id\$' > /dev/null 2>&1") {
3562f8193d4Sschwarze			print "Va $line\n" if $verbose;
3572f8193d4Sschwarze			next;
3582f8193d4Sschwarze		}
3592f8193d4Sschwarze		if ($verbose) {
3602f8193d4Sschwarze			print "XX $line\n";
3612f8193d4Sschwarze		} else {
3622f8193d4Sschwarze			warn "not found: extern int $id";
3632f8193d4Sschwarze		}
3642f8193d4Sschwarze		next;
3652f8193d4Sschwarze	}
3662f8193d4Sschwarze
367c7f69c0dSschwarze	# Handle variable type declarations.
3686216412cSschwarze
369c7f69c0dSschwarze	if (my ($id) = /^struct\s+(\w+);$/) {
370eca1bd36Sschwarze		unless (system "$MANW -k 'Vt~^$id\$' > /dev/null 2>&1") {
371c7f69c0dSschwarze			print "Vt $line\n" if $verbose;
372c7f69c0dSschwarze			next;
373c7f69c0dSschwarze		}
374eca1bd36Sschwarze		if ($expect_undoc{$id}) {
3750d867e69Sschwarze			print "V- $line\n" if $verbose;
376eca1bd36Sschwarze			$found_undoc{$id} = 1;
3770d867e69Sschwarze			next;
3780d867e69Sschwarze		}
379c7f69c0dSschwarze		if ($verbose) {
380c7f69c0dSschwarze			print "XX $line\n";
381c7f69c0dSschwarze		} else {
382c7f69c0dSschwarze			warn "not found: struct $id";
383c7f69c0dSschwarze		}
384c7f69c0dSschwarze		next;
385c7f69c0dSschwarze	}
386c7f69c0dSschwarze
387c7f69c0dSschwarze	if (my ($id) = /^typedef\s+(?:const\s+)?(?:struct\s+)?\S+\s+(\w+);$/) {
388eca1bd36Sschwarze		unless (system "$MANW -k 'Vt~^$id\$' > /dev/null 2>&1") {
389441d0e04Sschwarze			print "Vt $line\n" if $verbose;
390441d0e04Sschwarze			next;
391441d0e04Sschwarze		}
392eca1bd36Sschwarze		if ($expect_undoc{$id}) {
3936216412cSschwarze			print "V- $line\n" if $verbose;
394eca1bd36Sschwarze			$found_undoc{$id} = 1;
3956216412cSschwarze			next;
3966216412cSschwarze		}
397441d0e04Sschwarze		if ($verbose) {
398441d0e04Sschwarze			print "XX $line\n";
399441d0e04Sschwarze		} else {
4006216412cSschwarze			warn "not found: typedef $id";
401441d0e04Sschwarze		}
402441d0e04Sschwarze		next;
403441d0e04Sschwarze	}
4046216412cSschwarze
405c7f69c0dSschwarze	if (my ($id) =/^typedef\s+\w+(?:\s+\*)?\s+\(\*(\w+)\)\(/) {
406c7f69c0dSschwarze		/\);$/ or $in_function = 1;
407c7f69c0dSschwarze		unless (system "$MANW $id > /dev/null 2>&1") {
408c7f69c0dSschwarze			print "Fn $line\n" if $verbose;
409c7f69c0dSschwarze			next;
410c7f69c0dSschwarze		}
411c7f69c0dSschwarze		if ($verbose) {
412c7f69c0dSschwarze			print "XX $line\n";
413c7f69c0dSschwarze		} else {
414c7f69c0dSschwarze			warn "not found: function type (*$id)()";
415c7f69c0dSschwarze		}
416c7f69c0dSschwarze		next;
417c7f69c0dSschwarze	}
418c7f69c0dSschwarze
4196216412cSschwarze	# Handle function declarations.
4206216412cSschwarze
421c7f69c0dSschwarze	if (/^\w+(?:\(\w+\))?(?:\s+\w+)*\s+(?:\(?\*\s*)?(\w+)\(/) {
422441d0e04Sschwarze		my $id = $1;
423441d0e04Sschwarze		/\);$/ or $in_function = 1;
424441d0e04Sschwarze		unless (system "$MANW $id > /dev/null 2>&1") {
425441d0e04Sschwarze			print "Fn $line\n" if $verbose;
426441d0e04Sschwarze			next;
427441d0e04Sschwarze		}
4280379deddSschwarze		# These functions are still provided by OpenSSL
4290379deddSschwarze		# and still used by the Python test suite,
4300379deddSschwarze		# but intentionally undocumented because nothing
4310379deddSschwarze		# else uses them according to tb@, Dec 3, 2021.
4320379deddSschwarze		if ($id =~ /NETSCAPE_(?:CERT_SEQUENCE|SPKAC|SPKI)/) {
433441d0e04Sschwarze			print "F- $line\n" if $verbose;
434441d0e04Sschwarze			next;
435441d0e04Sschwarze		}
4360d867e69Sschwarze		unless (system qw/grep -qR/, '^\.\\\\" .*\<' . $id . '\>',
437441d0e04Sschwarze		    "$srcdir/") {
438441d0e04Sschwarze			print "F- $line\n" if $verbose;
439441d0e04Sschwarze			next;
440441d0e04Sschwarze		}
441eca1bd36Sschwarze		if ($expect_undoc{$id}) {
442441d0e04Sschwarze			print "F- $line\n" if $verbose;
443eca1bd36Sschwarze			$found_undoc{$id} = 1;
444441d0e04Sschwarze			next;
445441d0e04Sschwarze		}
4460d867e69Sschwarze		if ($id =~ /^ASN1_PCTX_\w+$/) {
4470d867e69Sschwarze			print "F- $line\n" if $verbose;
4480d867e69Sschwarze			next;
4490d867e69Sschwarze		}
450441d0e04Sschwarze		if ($verbose) {
451441d0e04Sschwarze			print "XX $line\n";
452441d0e04Sschwarze		} else {
453441d0e04Sschwarze			warn "not found: function $id()";
454441d0e04Sschwarze		}
455441d0e04Sschwarze		next;
456441d0e04Sschwarze	}
4579f20cb86Sschwarze	if (/^int$/) {
4589f20cb86Sschwarze		$_ .= ' ' . <$in_fh>;
4599f20cb86Sschwarze		goto try_again;
4609f20cb86Sschwarze	}
461441d0e04Sschwarze	if (/ \*$/) {
462441d0e04Sschwarze		$_ .= <$in_fh>;
463441d0e04Sschwarze		goto try_again;
464441d0e04Sschwarze	}
465e7ec1cdbSschwarze	# The name of the function return type is so long
466e7ec1cdbSschwarze	# that it requires a line break afterwards.
467e7ec1cdbSschwarze	if (/^\w{30,}$/) {
468e7ec1cdbSschwarze		my $next_line = <$in_fh>;
469e7ec1cdbSschwarze		if ($next_line =~ /^ {4}\w/) {
470e7ec1cdbSschwarze			$_ .= $next_line;
471e7ec1cdbSschwarze			goto try_again;
472e7ec1cdbSschwarze		}
473e7ec1cdbSschwarze	}
474441d0e04Sschwarze	die "parse error: $_";
475441d0e04Sschwarze}
476441d0e04Sschwarzeclose $in_fh;
477eca1bd36Sschwarzeforeach (keys %expect_undoc) {
478eca1bd36Sschwarze	warn "expected as undocumented but not found: $_"
479eca1bd36Sschwarze	    unless $found_undoc{$_};
480eca1bd36Sschwarze}
481441d0e04Sschwarzeexit 0;
482