mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 02:30:03 +01:00
Fix a broken regexp which would mention `$/' when it ought to have
mentioned `$'. The result would be that it would match lines like
type some_ocaml_type = Thing | Other_Thing
but ignore everything but the type name, giving wrong answers.
Check that we check mentioned types. Otherwise if we fail to spot
some suitable thing in the ocaml, we would just omit checking this
type !
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Acked-by: Andrew Cooper <Andrew.Cooper3@citrix.com>
Acked-by: Christian Lindig <christian.lindig@citrix.com>
115 lines
3.2 KiB
Perl
Executable File
115 lines
3.2 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
|
|
use strict;
|
|
use Data::Dumper;
|
|
|
|
our %enums;
|
|
|
|
# Usage: abi-check C-file Ocaml-file
|
|
# Writes out a BUILD_BUG_ON() list to be included back into C.
|
|
#
|
|
# Ocaml-file should be the .ml file. The ocaml compiler will check
|
|
# that any declarations in a .mli correspond. We check the .ml
|
|
# rather than the .mli in case there are private types in future.
|
|
|
|
@ARGV == 2 or die;
|
|
our ($c, $o) = @ARGV;
|
|
|
|
open C_FILE, "<", $c or die $!;
|
|
|
|
our $cline = -1;
|
|
our $ei;
|
|
|
|
# Parse the C file looking for calls to:
|
|
# c_bitmap_to_ocaml_list()
|
|
# ocaml_list_to_c_bitmap()
|
|
#
|
|
# followed by anotations of the following form:
|
|
# /* ! OType OPrefix Mangle */
|
|
# /* ! CPrefix CFinal CFinalHow */
|
|
# or, for subsequent invocations for the same OType, just
|
|
# /* ! OType */
|
|
#
|
|
# The function definitions use /* ! */ which simply skips that instance.
|
|
while (<C_FILE>) {
|
|
if ($cline == -1) {
|
|
if (m/c_bitmap_to_ocaml_list|ocaml_list_to_c_bitmap/) {
|
|
$cline = 0;
|
|
$ei = { };
|
|
}
|
|
} else {
|
|
$cline++;
|
|
m{^\s+/\* \s+ ! \s+ (.*?) \s* \*/\s*$}x or
|
|
die "at line $cline of annotation, did not expect $_ ?";
|
|
my @vals = split /\s+/, $1;
|
|
if ($cline == 1 && !@vals) {
|
|
$cline = -1;
|
|
} elsif ($cline == 1 && @vals == 1) {
|
|
my ($otype) = @vals;
|
|
die "reference to undefined OType $otype" unless $enums{$otype};
|
|
$cline = -1;
|
|
} elsif ($cline == 1 && @vals == 3) {
|
|
$ei->{$_} = shift @vals foreach qw(OType OPrefix Mangle);
|
|
} elsif ($cline == 2 && @vals == 3) {
|
|
$ei->{$_} = shift @vals foreach qw(CPrefix CFinal CFinalHow);
|
|
die "redefining OType $ei->{OType}" if $enums{ $ei->{OType} };
|
|
$enums{ $ei->{OType} } = $ei;
|
|
$cline = -1;
|
|
} else {
|
|
die "$_ ?";
|
|
}
|
|
}
|
|
}
|
|
|
|
sub expect ($$) {
|
|
printf "BUILD_BUG_ON( %-30s != %-10s );\n", @_ or die $!;
|
|
}
|
|
|
|
open OCAML_FILE, "<", $o or die $!;
|
|
my $cval;
|
|
$ei = undef;
|
|
my $bitnum = 0;
|
|
while (<OCAML_FILE>) {
|
|
if (!$ei) {
|
|
if (m{^type \s+ (\w+) \s* \= \s* $}x && $enums{$1}) {
|
|
print "// found ocaml type $1 at $o:$.\n" or die $!;
|
|
$ei = $enums{$1};
|
|
$cval = '';
|
|
$bitnum = 0;
|
|
}
|
|
} else {
|
|
if (m{^\s+ \| \s* $ei->{OPrefix} (\w+) \s*$}x) {
|
|
$cval = $1;
|
|
if ($ei->{Mangle} eq 'lc') {
|
|
$cval = lc $cval;
|
|
} elsif ($ei->{Mangle} eq 'none') {
|
|
} else {
|
|
die;
|
|
}
|
|
$cval = $ei->{CPrefix}.$cval;
|
|
expect($cval, "(1u << $bitnum)");
|
|
$bitnum++;
|
|
} elsif (m/^\w|\{/) {
|
|
if ($ei->{CFinalHow} eq 'max') {
|
|
expect($ei->{CFinal}, "(1u << ".($bitnum-1).")");
|
|
} elsif ($ei->{CFinalHow} eq 'all') {
|
|
expect($ei->{CFinal}, "(1u << $bitnum)-1u");
|
|
} else {
|
|
die Dumper($ei)." ?";
|
|
}
|
|
$ei->{Checked} = 1;
|
|
$ei = undef;
|
|
} elsif (!m{\S}) {
|
|
} else {
|
|
die "$_ ?";
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach $ei (values %enums) {
|
|
next if $ei->{Checked};
|
|
die "did not find ocaml type definition for $ei->{OType} in $o";
|
|
}
|
|
|
|
close STDOUT or die $!;
|