More flexible parsing of Doxygen comments for MBEDTLS_ERR_xxx
Before this commit, definitions of error codes must match a strict pattern,
with a Doxygen comment following the definition on the same line and
starting with "/**<". Change how generate_errors.pl so that the Doxygen
comment can be before the definition instead of after, and doesn't have to
be on the same line.
Also allow spaces between "#" and "define", and allow Doxygen comments to
start with "/*!" rather than "/**". Starting with "///" or "//!" is not
supported.
This commit does not change the output of generate_errors.pl.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/scripts/generate_errors.pl b/scripts/generate_errors.pl
index e7ee579..f26c419 100755
--- a/scripts/generate_errors.pl
+++ b/scripts/generate_errors.pl
@@ -53,26 +53,46 @@
PEM PK PKCS12 PKCS5
RSA SSL X509 );
-my $line_separator = $/;
undef $/;
open(FORMAT_FILE, '<:crlf', "$error_format_file") or die "Opening error format file '$error_format_file': $!";
my $error_format = <FORMAT_FILE>;
close(FORMAT_FILE);
-$/ = $line_separator;
-
my @files = <$include_dir/*.h>;
my @necessary_include_files;
my @matches;
foreach my $file (@files) {
open(FILE, '<:crlf', "$file");
- my @grep_res = grep(/^\s*#define\s+MBEDTLS_ERR_\w+\s+\-0x[0-9A-Fa-f]+/, <FILE>);
- push(@matches, @grep_res);
+ my $content = <FILE>;
close FILE;
- my $include_name = $file;
- $include_name =~ s!.*/!!;
- push @necessary_include_files, $include_name if @grep_res;
+ my $found = 0;
+ while ($content =~ m[
+ (?:/\*[*!]([^<](?:[^*]|\*+[^*/])*)\*/)?
+ \s*\#\s*define\s+(MBEDTLS_ERR_\w+)\s+\-(0[Xx][0-9A-Fa-f]+)\s*
+ (?:/\*[*!]<((?:[^*]|\*+[^*/])*)\*/)?
+ ]gsx) {
+ my ($before, $name, $value, $after) = ($1, $2, $3, $4);
+ # Discard Doxygen comments that are coincidentally present before
+ # an error definition but not attached to it. This is ad hoc, based
+ # on what actually matters (or mattered at some point).
+ undef $before if $before =~ /\s*\\name\s/s;
+ die "Description neither before nor after $name in $file\n"
+ if !defined($before) && !defined($after);
+ die "Description both before and after $name in $file\n"
+ if defined($before) && defined($after);
+ my $description = (defined($before) ? $before : $after);
+ $description =~ s/^\s+//;
+ $description =~ s/\n( \*)?//g;
+ $description =~ s/\.?\s+$//;
+ push @matches, [$name, $value, $description];
+ ++$found;
+ }
+ if ($found) {
+ my $include_name = $file;
+ $include_name =~ s!.*/!!;
+ push @necessary_include_files, $include_name;
+ }
}
my $ll_old_define = "";
@@ -86,19 +106,14 @@
my %error_codes_seen;
-foreach my $line (@matches)
+foreach my $match (@matches)
{
- my ($error_name, $error_code) = $line =~ /(MBEDTLS_ERR_\w+)\s+\-(0x\w+)/;
- my ($description) = $line =~ /\/\*\*< (.*?)\.? \*\//;
+ my ($error_name, $error_code, $description) = @$match;
die "Duplicated error code: $error_code ($error_name)\n"
if( $error_codes_seen{$error_code}++ );
$description =~ s/\\/\\\\/g;
- if ($description eq "") {
- $description = "DESCRIPTION MISSING";
- warn "Missing description for $error_name\n";
- }
my ($module_name) = $error_name =~ /^MBEDTLS_ERR_([^_]+)/;