]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_pluginlib/generator.pl
Security-163.tar.gz
[apple/security.git] / cdsa / cdsa_pluginlib / generator.pl
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 $SOURCEDIR=$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
28 open(APICFG, $APICFG) or die "Cannot open $APICFG: $^E";
29 $_=<APICFG>;
30 close(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 #
44 while (($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 open(SPI, "$SOURCEDIR/$header") or die "cannot open $SOURCEDIR/$header: $^E";
50 $/=undef; # big gulp mode
51 $_ = <SPI>; # aaaaah...
52 close(SPI); # done
53 # throw away leading and trailing crud (only interested in SPI structure)
54 s/^.*struct cssm_spi.*{(.*)} CSSM_SPI.*$/$1/s
55 or die "bad format in $SPI_H{$name}";
56
57 # break up into functions (you'd do that HOW in YOUR language? :-)
58 @functions = /CSSM_RETURN \(CSSM${type}I \*([A-Za-z_]+)\)\s+\(([^)]+)\);/g;
59 %functions = @functions;
60
61 $MOREHEADERS="";
62 $MOREHEADERS .= "#include <Security/context.h>\n" if /CSSM_CONTEXT/;
63 $MOREHEADERS .= "#include <Security/cssmacl.h>\n" if /CSSM_(ACL|ACCESS)/;
64
65 # break function arguments into many forms:
66 # functions => formal SPI arguments
67 # methods => formal C++ method arguments
68 # actuals => actual expression forms for transition layer use
69 # and (by the way) massage them into a more palatable form...
70 $nFunctions = 0;
71 while (($function, $_) = each %functions) {
72 #
73 # Turn CSSM SPI formal into method formal
74 #
75 $returntype{$function} = "void";
76 $prefix{$function} = "";
77 $postfix{$function} = ";";
78 # reshape initial argument (the module handle, more or less)
79 s/^CSSM_${type}_HANDLE ${type}Handle(,\s*\n\s*|$)//s; # remove own handle (-> this)
80 s/^CSSM_DL_DB_HANDLE DLDBHandle/CSSM_DB_HANDLE DBHandle/s; # DL_DB handle -> DB handle
81 s/CSSM_HANDLE_PTR ResultsHandle(,?)\n//m # turn ptr-to-resultshandle into fn result
82 and do {
83 $returntype{$function} = "CSSM_HANDLE";
84 $prefix{$function} = "if ((Required(ResultsHandle) = ";
85 $postfix{$function} = ") == CSSM_INVALID_HANDLE)\n return $noDataReturnError{$type};";
86 };
87 if ($function =~ /GetNext/) { # *GetNext* returns a bool
88 $returntype{$function} = "bool";
89 $prefix{$function} = "if (!";
90 $postfix{$function} = ")\n return $noDataReturnError{$type};";
91 }
92 # reshape subsequent arguments
93 s/([su]int32) \*(\w+,?)/$1 \&$2/gm; # int * -> int & (output integer)
94 s/(CSSM_\w+_PTR) \*(\w+,?)/$1 \&$2/gm; # _PTR * -> _PTR &
95 s/(CSSM_\w+)_PTR (\w+)/$1 \*$2/gm; # XYZ_PTR -> XYZ * (explicit)
96 s/(const )?CSSM_DATA \*(\w+)Bufs/$1CssmData $2Bufs\[\]/gm; # c DATA *Bufs (plural)
97 s/(const )?CSSM_(DATA|OID) \*/$1CssmData \&/gm; # c DATA * -> c Data &
98 s/(const )?CSSM_FIELD \*(\w+)Fields/$1CSSM_FIELD $2Fields\[\]/gm; # c FIELD *Fields (plural)
99 s/(const )?CSSM_FIELD \*CrlTemplate/$1CSSM_FIELD CrlTemplate\[\]/gm; # c FIELD *CrlTemplate
100 s/const CSSM_CONTEXT \*/const Context \&/gm; # c CSSM_CONTEXT * -> c Context &
101 s/(const )?CSSM_ACCESS_CREDENTIALS \*/$1AccessCredentials \&/gm; # ditto
102 s/(const )?CSSM_QUERY_SIZE_DATA \*/$1QuerySizeData \&/gm; # ditto
103 s/(const )?CSSM_CSP_OPERATIONAL_STATISTICS \*/$1CSPOperationalStatistics \&/gm; # ditto
104 s/(const )?CSSM_(WRAP_)?KEY \*/$1CssmKey \&/gm; # CSSM[WRAP]KEY * -> CssmKey &
105 s/const CSSM_QUERY \*/const DLQuery \&/gm; # c QUERY * -> c Query &
106 s/(const )?(CSSM_[A-Z_]+) \*/$1$2 \&/gm; # c CSSM_ANY * -> c CSSM_ANY &
107 $methods{$function} = $_;
108
109 #
110 # Now turn the method formal into the transition invocation actuals
111 #
112 s/^CSSM_DB_HANDLE \w+(,?)/DLDBHandle.DBHandle$1/s; # matching change to DL_DB handles
113 s/(const )?([A-Z][a-z]\w+) &(\w+)(,?)/$2::required($3)$4/gm; # BIG_ * -> Small_ &
114 s/(const )?CssmData (\w+)Bufs\[\](,?)/\&\&CssmData::required($2Bufs)$3/gm; # c DATA *DataBufs
115 s/(const )?CSSM_FIELD (\w+)Fields\[\](,?)/$2Fields$3/gm; # c CSSM_FIELD *Fields
116 s/(const )?CSSM_FIELD CrlTemplate\[\](,?)/CrlTemplate$2/gm; # c CSSM_FIELD *CrlTemplate
117 # now remove formal arguments and clean up
118 s/^.* \&\&(\w+,?)/$tabs\&$1/gm; # && escape (to keep real &)
119 s/^.* \&(\w+)(,?)/${tabs}Required($1)$2/gm; # dereference for ref transition
120 s/^.* \**(\w+,?)/$tabs$1/gm; # otherwise, plain actual argument
121 s/^$tabs//;
122 $actuals{$function} = $_;
123
124 #
125 # Fix optional arguments
126 #
127 foreach $opt (split " ", $optionals{"$type:$function"}) {
128 $methods{$function} =~ s/\&$opt\b/\*$opt/; # turn refs back into pointers
129 $actuals{$function} =~ s/::required\($opt\)/::optional($opt)/; # optional specific
130 $actuals{$function} =~ s/Required\($opt\)/$opt/; # optional generic
131 };
132 $nFunctions++;
133 };
134
135 #
136 # Prepare to write header and source files
137 #
138 open(H, ">$HTARGETDIR/${type}abstractsession.h") or die "cannot write ${type}abstractsession.h: $^E";
139 open(C, ">$CTARGETDIR/${type}abstractsession.cpp") or die "cannot write ${type}abstractsession.cpp: $^E";
140
141 #
142 # Create header file
143 #
144 print H <<HDRHEAD;
145 //
146 // $type plugin transition layer.
147 // $warning
148 //
149 #ifndef _H_${type}ABSTRACTSESSION
150 #define _H_${type}ABSTRACTSESSION
151
152 #include <Security/pluginsession.h>
153 $MOREHEADERS
154 #if defined(_CPP_${type}ABSTRACTSESSION)
155 # pragma export on
156 #endif
157
158 namespace Security
159 {
160
161 //
162 // A pure abstract class to define the ${type} module interface
163 //
164 class ${type}AbstractPluginSession {
165 public:
166 HDRHEAD
167
168 $functionCount = 0;
169 while (($function, $arglist) = each %methods) {
170 # generate method declaration
171 print H " virtual $returntype{$function} $function($arglist) = 0;\n";
172 $functionCount++;
173 };
174 print H <<HDREND;
175 };
176
177 } // end namespace Security
178
179 #if defined(_CPP_${type}ABSTRACTSESSION)
180 # pragma export off
181 #endif
182
183 #endif //_H_${type}ABSTRACTSESSION
184 HDREND
185
186 #
187 # Create source file
188 #
189 print C <<BODY;
190 //
191 // $type plugin transition layer.
192 // $warning
193 //
194 #if defined(__MWERKS__)
195 # define _CPP_${type}ABSTRACTSESSION
196 # define _CPP_${type}SESSION
197 #endif
198 #include <Security/${type}session.h>
199 #include <Security/cssmplugin.h>
200 #include <Security/cssm${typelower}i.h>
201
202 BODY
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;
209 static 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
216 SHIM
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;
228 static 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
234 CSSM_MODULE_FUNCS_PTR ${type}PluginSession::construct()
235 {
236 return &${type}FunctionTable;
237 }
238 END
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 };