]> git.saurik.com Git - apple/security.git/blame - OSX/libsecurity_cdsa_plugin/lib/generator.pl
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / libsecurity_cdsa_plugin / lib / generator.pl
CommitLineData
b1ab9ed8
A
1#!/usr/bin/perl
2#
3# generator.pl - auto-generate code for the CSSM plugin interfaces
4#
5# Usage:
6# perl generator.pl input-directory h-output-dir c-output-dir
7#
8# Perry The Cynic, Fall 1999.
9#
10@API_H=("cssmapi.h");
11%SPI_H=("AC" => "cssmaci.h", "CSP" => "cssmcspi.h", "DL" => "cssmdli.h",
12 "CL" => "cssmcli.h", "TP" => "cssmtpi.h");
13
14$SOURCEPATH=$ARGV[0]; # where all the input files are
15$APICFG=$ARGV[1]; # configuration file
16$HTARGETDIR=$ARGV[2]; # where the generated headers go
17$CTARGETDIR=$ARGV[3]; # where the generated sources go
18
19
20$tabs = "\t\t\t"; # argument indentation (noncritical)
21$warning = "This file was automatically generated. Do not edit on penalty of futility!";
22
23
24#
25# Open and read the configuration file
26#
27$/=undef; # gulp file
28open(APICFG, $APICFG) or die "Cannot open $APICFG: $^E";
29$_=<APICFG>;
30close(APICFG);
31%optionals = /^\s*optional\s+(\w+:\w+)\s+(.*)$/gm;
32
33
34#
35# Pre-arranged arrays for processing below
36#
37%noDataReturnError = ( CL => "CSSMERR_CL_NO_FIELD_VALUES",
38 DL => "CSSMERR_DL_ENDOFDATA" );
39
40
41#
42# process one SPI at a time
43#
44while (($type, $header) = each %SPI_H) {
45 my(%functions, %methods, %actuals);
46 ($typelower = $type) =~ tr/A-Z/a-z/; # lowercase version of type
47
48 # start in on the $type header file
49 for my $sourcedir (split (/:/, $SOURCEPATH)) {
50 open(SPI, "$sourcedir/$header") and last;
51 }
52 SPI or die "cannot find $header in $SOURCEPATH: $^E";
53 $/=undef; # big gulp mode
54 $_ = <SPI>; # aaaaah...
55 close(SPI); # done
56 # throw away leading and trailing crud (only interested in SPI structure)
57 s/^.*struct cssm_spi.*{(.*)} CSSM_SPI.*$/$1/s
58 or die "bad format in $SPI_H{$name}";
59
60 # break up into functions (you'd do that HOW in YOUR language? :-)
61 @functions = /CSSM_RETURN \(CSSM${type}I \*([A-Za-z_]+)\)\s+\(([^)]+)\);/g;
62 %functions = @functions;
63
64 $MOREHEADERS="";
65 $MOREHEADERS .= "#include <security_cdsa_utilities/context.h>\n" if /CSSM_CONTEXT/;
66 $MOREHEADERS .= "#include <security_cdsa_utilities/cssmacl.h>\n" if /CSSM_(ACL|ACCESS)/;
67 $MOREHEADERS .= "#include <security_cdsa_utilities/cssmdb.h>\n" if /CSSM_QUERY/;
68
69 # break function arguments into many forms:
70 # functions => formal SPI arguments
71 # methods => formal C++ method arguments
72 # actuals => actual expression forms for transition layer use
73 # and (by the way) massage them into a more palatable form...
74 $nFunctions = 0;
75 while (($function, $_) = each %functions) {
76 #
77 # Turn CSSM SPI formal into method formal
78 #
79 $returntype{$function} = "void";
80 $prefix{$function} = "";
81 $postfix{$function} = ";";
82 # reshape initial argument (the module handle, more or less)
83 s/^CSSM_${type}_HANDLE ${type}Handle(,\s*\n\s*|$)//s; # remove own handle (-> this)
84 s/^CSSM_DL_DB_HANDLE DLDBHandle/CSSM_DB_HANDLE DBHandle/s; # DL_DB handle -> DB handle
85 s/CSSM_HANDLE_PTR ResultsHandle(,?)\n//m # turn ptr-to-resultshandle into fn result
86 and do {
87 $returntype{$function} = "CSSM_HANDLE";
88 $prefix{$function} = "if ((Required(ResultsHandle) = ";
89 $postfix{$function} = ") == CSSM_INVALID_HANDLE)\n return $noDataReturnError{$type};";
90 };
91 if ($function =~ /GetNext/) { # *GetNext* returns a bool
92 $returntype{$function} = "bool";
93 $prefix{$function} = "if (!";
94 $postfix{$function} = ")\n return $noDataReturnError{$type};";
95 }
96 # reshape subsequent arguments
97 s/([su]int32) \*(\w+,?)/$1 \&$2/gm; # int * -> int & (output integer)
98 s/(CSSM_\w+_PTR) \*(\w+,?)/$1 \&$2/gm; # _PTR * -> _PTR &
99 s/(CSSM_\w+)_PTR (\w+)/$1 \*$2/gm; # XYZ_PTR -> XYZ * (explicit)
100 s/(const )?CSSM_DATA \*(\w+)Bufs/$1CssmData $2Bufs\[\]/gm; # c DATA *Bufs (plural)
101 s/(const )?CSSM_(DATA|OID) \*/$1CssmData \&/gm; # c DATA * -> c Data &
102 s/(const )?CSSM_FIELD \*(\w+)Fields/$1CSSM_FIELD $2Fields\[\]/gm; # c FIELD *Fields (plural)
103 s/(const )?CSSM_FIELD \*CrlTemplate/$1CSSM_FIELD CrlTemplate\[\]/gm; # c FIELD *CrlTemplate
104 s/const CSSM_CONTEXT \*/const Context \&/gm; # c CSSM_CONTEXT * -> c Context &
105 s/(const )?CSSM_ACCESS_CREDENTIALS \*/$1AccessCredentials \&/gm; # ditto
106 s/(const )?CSSM_QUERY_SIZE_DATA \*/$1QuerySizeData \&/gm; # ditto
107 s/(const )?CSSM_CSP_OPERATIONAL_STATISTICS \*/$1CSPOperationalStatistics \&/gm; # ditto
108 s/(const )?CSSM_(WRAP_)?KEY \*/$1CssmKey \&/gm; # CSSM[WRAP]KEY * -> CssmKey &
109 s/const CSSM_QUERY \*/const CssmQuery \&/gm; # c QUERY * -> c Query &
110 s/(const )?(CSSM_[A-Z_]+) \*/$1$2 \&/gm; # c CSSM_ANY * -> c CSSM_ANY &
111 $methods{$function} = $_;
112
113 #
114 # Now turn the method formal into the transition invocation actuals
115 #
116 s/^CSSM_DB_HANDLE \w+(,?)/DLDBHandle.DBHandle$1/s; # matching change to DL_DB handles
117 s/(const )?([A-Z][a-z]\w+) &(\w+)(,?)/$2::required($3)$4/gm; # BIG_ * -> Small_ &
118 s/(const )?CssmData (\w+)Bufs\[\](,?)/\&\&CssmData::required($2Bufs)$3/gm; # c DATA *DataBufs
119 s/(const )?CSSM_FIELD (\w+)Fields\[\](,?)/$2Fields$3/gm; # c CSSM_FIELD *Fields
120 s/(const )?CSSM_FIELD CrlTemplate\[\](,?)/CrlTemplate$2/gm; # c CSSM_FIELD *CrlTemplate
121 # now remove formal arguments and clean up
122 s/^.* \&\&(\w+,?)/$tabs\&$1/gm; # && escape (to keep real &)
123 s/^.* \&(\w+)(,?)/${tabs}Required($1)$2/gm; # dereference for ref transition
124 s/^.* \**(\w+,?)/$tabs$1/gm; # otherwise, plain actual argument
125 s/^$tabs//;
126 $actuals{$function} = $_;
127
128 #
129 # Fix optional arguments
130 #
131 foreach $opt (split " ", $optionals{"$type:$function"}) {
132 $methods{$function} =~ s/\&$opt\b/\*$opt/; # turn refs back into pointers
133 $actuals{$function} =~ s/::required\($opt\)/::optional($opt)/; # optional specific
134 $actuals{$function} =~ s/Required\($opt\)/$opt/; # optional generic
135 };
136 $nFunctions++;
137 };
138
139 #
140 # Prepare to write header and source files
141 #
142 open(H, ">$HTARGETDIR/${type}abstractsession.h") or die "cannot write ${type}abstractsession.h: $^E";
143 open(C, ">$CTARGETDIR/${type}abstractsession.cpp") or die "cannot write ${type}abstractsession.cpp: $^E";
144
145 #
146 # Create header file
147 #
148 print H <<HDRHEAD;
149//
150// $type plugin transition layer.
151// $warning
152//
153#ifndef _H_${type}ABSTRACTSESSION
154#define _H_${type}ABSTRACTSESSION
155
156#include <security_cdsa_plugin/pluginsession.h>
157#include <security_cdsa_utilities/cssmdata.h>
158$MOREHEADERS
159
160namespace Security {
161
162
163//
164// A pure abstract class to define the ${type} module interface
165//
166class ${type}AbstractPluginSession {
167public:
168 virtual ~${type}AbstractPluginSession();
169HDRHEAD
170
171 $functionCount = 0;
172 while (($function, $arglist) = each %methods) {
173 # generate method declaration
174 print H " virtual $returntype{$function} $function($arglist) = 0;\n";
175 $functionCount++;
176 };
177 print H <<HDREND;
178};
179
180} // end namespace Security
181
182#endif //_H_${type}ABSTRACTSESSION
183HDREND
184
185 #
186 # Create source file
187 #
188 print C <<BODY;
189//
190// $type plugin transition layer.
191// $warning
192//
193#include <security_cdsa_plugin/${type}session.h>
194#include <security_cdsa_plugin/cssmplugin.h>
195#include <security_cdsa_utilities/cssmbridge.h>
196#include <Security/cssm${typelower}i.h>
197
198
199${type}AbstractPluginSession::~${type}AbstractPluginSession()
200{ /* virtual */ }
201
202BODY
203
204 # write transition layer functions
205 while (($function, $arglist) = each %functions) {
206 $lookupHandle = "${type}Handle";
207 $lookupHandle = "DLDBHandle.DLHandle" if $arglist =~ /DL_DB_HANDLE/;
208 print C <<SHIM;
209static CSSM_RETURN CSSM${type}I cssm_$function($arglist)
210{
211 BEGIN_API
212 ${prefix{$function}}findSession<${type}PluginSession>($lookupHandle).$function($actuals{$function})${postfix{$function}}
213 END_API($type)
214}
215
216SHIM
217 };
218
219 # generate dispatch table - in the right order, please
220 print C "\nstatic const CSSM_SPI_${type}_FUNCS ${type}FunctionStruct = {\n";
221 while ($function = shift @functions) {
222 print C " cssm_$function,\n";
223 shift @functions; # skip over arglist part
224 };
225 print C "};\n\n";
226
227 print C <<END;
228static CSSM_MODULE_FUNCS ${type}FunctionTable = {
229 CSSM_SERVICE_$type, // service type
230 $functionCount, // number of functions
231 (const CSSM_PROC_ADDR *)&${type}FunctionStruct
232};
233
234CSSM_MODULE_FUNCS_PTR ${type}PluginSession::construct()
235{
236 return &${type}FunctionTable;
237}
238END
239
240 #
241 # Done with this type
242 #
243 close(H);
244 close(C);
245
246 print "$nFunctions functions generated for $type SPI transition layer.\n";
247};