@API_H=("cssmapi.h");
%SPI_H=("AC" => "cssmaci.h", "CSP" => "cssmcspi.h", "DL" => "cssmdli.h",
"CL" => "cssmcli.h", "TP" => "cssmtpi.h");
@OIDS_H=("oidscert.h", "oidscrl.h");
@OIDS_H2=("oidsattr.h", "oidsalg.h");
$SOURCEDIR=$ARGV[0]; $APICFG=$ARGV[1]; $TARGETDIR=$ARGV[2];
$TRANSITION="$TARGETDIR/transition.gen"; $TABLES="$TARGETDIR/funcnames.gen"; $REPORT="$TARGETDIR/generator.rpt"; $EXPORTS="$TARGETDIR/cssmexports.gen";
$tabs = "\t\t\t"; $warning = "This file was automatically generated. Do not edit on penalty of futility!";
$/=undef; foreach $_ (@API_H) {
open(API_H, "$SOURCEDIR/$_") or die "Cannot open $SOURCEDIR/$_: $^E";
$_ = <API_H>; %formals = /CSSM_RETURN CSSMAPI\s*([A-Za-z_]+)\s+\(([^)]*)\)[^;]*;/gs;
while (($name, $args) = each %formals) {
$args =~ s/^.*[ *]([A-Za-z_]+,?)$/$tabs$1/gm; $args =~ s/^$tabs//o; # chop intial tabs # so now we have...
$actuals{$name} = $args; };
};
close(API_H);
$/=undef; while (($key, $file) = each %SPI_H) {
open(SPI_H, "$SOURCEDIR/$file") or die "Cannot open $SOURCEDIR/$file: $^E";
$spi{$key} = <SPI_H>;
};
close(SPI_H);
$/=undef; open(APICFG, $APICFG) or die "Cannot open $APICFG: $^E";
$_=<APICFG>;
close(APICFG);
%config = /^\s*(\w+)\s+(.*)$/gm;
open(OUT, ">$TRANSITION") or die "Cannot write $TRANSITION: $^E";
select OUT;
open(REPORT, ">$REPORT") or die "Cannot write $REPORT: $^E";
sub ignored {
my ($reason) = @_;
$ignored++;
print REPORT "$name $reason\n";
};
print "//
// $warning
//";
for $name (sort keys %formals) {
$config = $config{$name};
do { ignored "has custom implementation"; next; } if $config =~ /custom/;
($barename) = $name =~ /^CSSM.*_([A-Za-z]+$)/;
die "Can't fathom SPI name for $name" unless $barename;
$actuals = $actuals{$name};
($type, $handle) = $formals{$name} =~ /CSSM_([A-Z_]+)_HANDLE\s+([A-Za-z0-9_]+)/;
$type = "CSP" if $type eq "CC"; $type = "DL" if $type eq "DL_DB"; $type = "KR" if $type eq "KRSP"; $Type = $type . "Attachment";
do { ignored "has no module type"; next; } unless defined $SPI_H{$type};
$prefix = "";
($args) = $spi{$type} =~ /CSSM_RETURN \(CSSM${type}I \*$barename\)\s+\(([^)]*)\)[^;]*;/s
or $barename =~ s/P$// && # second chance for FooBarP() API functions
(($args) = $spi{$type} =~ /CSSM_RETURN \(CSSM${type}I \*$barename\)\s+\(([^)]*)\)[^;]*;/s)
or do { ignored "not in $SPI_H{$type}"; next; };
$handletype = $type;
$type eq "CSP" && $actuals =~ /CCHandle/ && do {
$actuals =~ s/CCHandle/context.CSPHandle, CCHandle/;
$args =~ /CSSM_CONTEXT/ &&
$actuals =~ s/CCHandle/CCHandle, &context/;
$handletype = "CC";
};
$args =~ /CSSM_PRIVILEGE/ && ! ($name =~ /P$/) && ($actuals .= ",\n${tabs}attachment.module.cssm.getPrivilege()");
$handle =~ s/DLDBHandle/DLDBHandle.DLHandle/;
print "
CSSM_RETURN CSSMAPI
$name ($formals{$name})
{
BEGIN_API";
if ($handletype eq "CC") {
print "
HandleContext &context = enterContext($handle);
CSPAttachment &attachment = context.attachment;";
} else {
print "
$Type &attachment = enterAttachment<$Type>($handle);";
};
print "
TransitLock _(attachment);
${prefix}return attachment.downcalls.$barename($actuals);
END_API($type)
}
";
$written++;
};
close(OUT);
select(STDOUT);
open(OUT, ">$TABLES") or die "Cannot write $TABLES: $^E";
select OUT;
print "//
// Standard plugin name tables
// $warning
//
";
while (($name, $_) = each %spi) {
print "extern const char *const ${name}NameTable[] = {";
s/^.*struct cssm_spi.*{(.*)} CSSM_SPI.*$/$1/s
or die "bad format in $SPI_H{$name}";
s/CSSM_RETURN \(CSSM[A-Z]*I \*([A-Za-z_]+)\)\s+\([^)]+\)[^;]*;/\t"$1",/g;
print;
print "};\n\n";
};
close(OUT);
select(STDOUT);
open(OUT, ">$EXPORTS") or die "Cannot write $EXPORTS: $^E";
select(OUT);
for $name (keys %formals) {
$symbols{$name} = 1;
};
$/=undef;
foreach $_ (@OIDS_H) {
open(OIDS_H, "$SOURCEDIR/$_") or die "Cannot open $SOURCEDIR/$_: $^E";
$_ = <OIDS_H>; s/\/\*.*\*\///gm; # remove comments
foreach $name (/\s+(CSSMOID_[A-Za-z0-9_]+)/gs) {
$symbols{$name} = 1;
};
};
close(OIDS_H);
foreach $_ (@OIDS_H2) {
open(OIDS_H2, "$SOURCEDIR/../../libsecurity_asn1/lib/$_") or die "Cannot open $SOURCEDIR/$_: $^E";
$_ = <OIDS_H2>; s/\/\*.*\*\///gm; # remove comments
foreach $name (/\s+(CSSMOID_[A-Za-z0-9_]+)/gs) {
$symbols{$name} = 1;
};
};
close(OIDS_H2);
foreach $name (keys %symbols) {
print "_$name\n";
};
close(OUT);
select(STDOUT);
close(EXPORTS);
close(REPORT);
print "$written API functions generated; $ignored ignored (see $REPORT)\n";