4 # Copyright (c) 2007, Cameron Rich
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are met:
11 # * Redistributions of source code must retain the above copyright notice,
12 # this list of conditions and the following disclaimer.
13 # * Redistributions in binary form must reproduce the above copyright
14 # notice, this list of conditions and the following disclaimer in the
15 # documentation and/or other materials provided with the distribution.
16 # * Neither the name of the axTLS project nor the names of its
17 # contributors may be used to endorse or promote products derived
18 # from this software without specific prior written permission.
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
26 # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
28 # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #===============================================================
34 # This application transforms ssl.h into interfaces that can be used by
35 # other language bindings. It is "SWIG"-like in nature in that various
36 # files are generated based on the axTLS API.
38 # The file produced is axInterface.? (depending on the file extension).
40 #===============================================================
49 my $signature_ret_type;
51 # Transforms function signature into an Interface format
52 sub transformSignature
59 # our very basic preprocessor
60 if ($binding == $CSHARP)
62 $line =~ s/STDCALL //;
63 $line =~ s/EXP_FUNC/ [DllImport ("axtls")]\n public static extern/;
64 $line =~ s/uint32_t/uint/g;
65 $line =~ s/uint8_t \*\*/ref IntPtr /g;
66 $line =~ s/const uint8_t \* /IntPtr /g;
67 $line =~ s/const uint8_t \*/byte[] /g; # note: subtle diff
68 $line =~ s/uint8_t \* ?/byte[] /g;
69 $line =~ s/uint8_t ?/byte /g;
70 $line =~ s/const char \* ?/string /g;
71 $line =~ s/const SSL_CTX \* ?/IntPtr /g;
72 $line =~ s/SSL_CTX \* ?/IntPtr /g;
73 $line =~ s/SSLObjLoader \* ?/IntPtr /g;
74 $line =~ s/const SSL \* ?/IntPtr /g;
75 $line =~ s/SSL \* ?/IntPtr /g;
76 $line =~ s/\(void\)/()/g;
78 elsif ($binding == $VBNET)
80 if ($line =~ /EXP_FUNC/)
82 # Procedure or function?
83 my $invariant = $line =~ /void /;
85 my $proc = $invariant ? "Sub" : "Function";
86 ($signature_ret_type) = $line =~ /EXP_FUNC (.*) STDCALL/;
87 $line =~ s/EXP_FUNC .* STDCALL / <DllImport("axtls")> Public Shared $proc _\n /;
89 $signature_ret_type =~ s/const uint8_t \*/As IntPtr/;
90 $signature_ret_type =~ s/const char \*/As String/;
91 $signature_ret_type =~ s/SSL_CTX \*/As IntPtr/;
92 $signature_ret_type =~ s/SSLObjLoader \*/As IntPtr/;
93 $signature_ret_type =~ s/SSL \*/As IntPtr/;
94 $signature_ret_type =~ s/uint8_t/As Byte/;
95 $signature_ret_type =~ s/int/As Integer/;
96 $signature_ret_type =~ s/void//;
97 $signature_ret_type .= "\n End $proc\n\n";
100 $line =~ s/uint32_t (\w+)/ByVal $1 As Integer/g;
101 $line =~ s/int (\w+)/ByVal $1 As Integer/g;
102 $line =~ s/uint8_t \*\* ?(\w+)/ByRef $1 As IntPtr/g;
103 $line =~ s/const uint8_t \* ?(\w+)/ByVal $1() As Byte/g;
104 $line =~ s/uint8_t \* ?(\w+)/ByVal $1() As Byte/g;
105 $line =~ s/uint8_t ?(\w+)/ByVal $1 As Byte/g;
106 $line =~ s/const char \* ?(\w+)/ByVal $1 As String/g;
107 $line =~ s/const SSL_CTX \* ?(\w+)/ByVal $1 As IntPtr/g;
108 $line =~ s/SSL_CTX \* ?(\w+)/ByVal $1 As IntPtr/g;
109 $line =~ s/SSLObjLoader \* ?(\w+)/ByVal $1 As IntPtr/g;
110 $line =~ s/const SSL \* ?(\w+)/ByVal $1 As IntPtr/g;
111 $line =~ s/SSL \* ?(\w+)/ByVal $1 As IntPtr/g;
112 $line =~ s/void \* ?(\w+)/Byval $1 As IntPtr/g;
113 $line =~ s/\(void\)/()/g;
115 $line =~ s/;\n/ $signature_ret_type;/;
128 my $splitFunctionDeclaration;
130 my $vb_line_hack = 0;
134 foreach $line (@file)
136 next if $line =~ /sl_x509_create/; # ignore for now
139 if (!$skip && $line =~ m/^#define/)
141 $splitDefine = 1 if $line =~ m/\\$/;
143 if ($binding == $VBNET)
149 my ($name, $value) = $line =~ /#define (\w+) +([^\\]*)[\\]?\n/;
151 if (defined $name && defined $value)
153 # C# constant translation
154 if ($binding == $CSHARP)
156 $line = " public const int $name = $value";
158 # VB.NET constant translation
159 elsif ($binding == $VBNET)
161 $line = " Public Const $name As Integer = $value";
165 next if $line =~ /#define/; # ignore any other defines
167 print DATA_OUT $line;
169 # check line is not split
170 next if $splitDefine == 1;
171 print DATA_OUT ";" if $binding == $CSHARP;
175 # pick up second line of #define statement
180 $line =~ s/$/;/ if $binding == $CSHARP; # add the ";"
183 $line =~ s/ ?\| ?/ Or /g
184 if ($binding == $VBNET);
186 # check line is not split
187 $splitDefine = ($line =~ m/\\$/);
189 # ignore trailing "\"
190 $line =~ s/\\$// if $binding == $CSHARP;
191 $line =~ s/\\$/_/ if $binding == $VBNET;
192 print DATA_OUT $line;
196 # test for function declaration
197 if (!$skip && $line =~ /EXP_FUNC/ && $line !~ /\/\*/)
199 $line = transformSignature($line);
200 $splitFunctionDeclaration = $line !~ /;/;
201 $line =~ s/;// if ($binding == $VBNET);
202 $line =~ s/\n$/ _\n/ if ($binding == $VBNET) &&
203 $splitFunctionDeclaration;
204 print DATA_OUT $line;
208 if ($splitFunctionDeclaration)
210 $line = transformSignature($line);
211 $splitFunctionDeclaration = $line !~ /;/;
212 $line =~ s/;// if ($binding == $VBNET);
213 $line =~ s/\n/ _\n/ if ($binding == $VBNET) &&
214 $splitFunctionDeclaration == 1;
215 print DATA_OUT $line;
221 #===============================================================
223 # Determine which module to build from command-line options
232 if (not defined $ARGV[0])
237 if ($ARGV[0] eq "-csharp")
239 print "Generating C# interface file\n";
240 $binding_prefix = "csharp";
241 $binding_suffix = "cs";
244 elsif ($ARGV[0] eq "-vbnet")
246 print "Generating VB.NET interface file\n";
247 $binding_prefix = "vbnet";
248 $binding_suffix = "vb";
254 die "Usage: $0 [-csharp | -vbnet]\n";
257 my $interfaceFile = "$binding_prefix/axInterface.$binding_suffix";
259 # Input file required to generate interface file.
260 $data_file = "../ssl/ssl.h";
263 open(DATA_IN, $data_file) || die("Could not open file ($data_file)!");
264 @raw_data = <DATA_IN>;
268 if ($binding == $CSHARP || $binding == $VBNET)
270 open(DATA_OUT, ">$interfaceFile") || die("Cannot Open File");
273 # SPEC interface file header
274 if ($binding == $CSHARP)
276 # generate the C#/C interface file
277 print DATA_OUT << "END";
278 // The C# to C interface definition file for the axTLS project
279 // Do not modify - this file is generated
282 using System.Runtime.InteropServices;
290 elsif ($binding == $VBNET)
292 # generate the VB.NET/C interface file
293 print DATA_OUT << "END";
294 ' The VB.NET to C interface definition file for the axTLS project
295 ' Do not modify - this file is generated
298 Imports System.Runtime.InteropServices
305 parseFile(@raw_data);
308 if ($binding == $CSHARP)
310 print DATA_OUT " };\n";
311 print DATA_OUT "};\n";
313 elsif ($binding == $VBNET)
315 print DATA_OUT " End Class\nEnd Namespace\n";
321 #===============================================================