Rework LuCI build system
[project/luci.git] / libs / luci-lib-nixio / axTLS / bindings / generate_interface.pl
1 #!/usr/bin/perl -w
2
3 #
4 # Copyright (c) 2007, Cameron Rich
5 #
6 # All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are met:
10 #
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.
19 #
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.
31 #
32
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.
37 #
38 # The file produced is axInterface.? (depending on the file extension).
39 #
40 #===============================================================
41
42 use strict;
43
44 my $CSHARP = 0;
45 my $VBNET = 1;
46
47 my $binding;
48 my $skip = 0;
49 my $signature_ret_type;
50
51 # Transforms function signature into an Interface format
52 sub transformSignature
53 {
54     my $item;
55     my ($line) = @_;
56
57     foreach $item ($line)
58     { 
59         # our very basic preprocessor
60         if ($binding == $CSHARP)
61         {
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;
77         }
78         elsif ($binding == $VBNET)
79         {
80             if ($line =~ /EXP_FUNC/)
81             {
82                 # Procedure or function?
83                 my $invariant = $line =~ /void /;
84
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            /;
88
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";
98             }
99
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;
114             $line =~ s/void//g;
115             $line =~ s/;\n/ $signature_ret_type;/;
116         }
117     }
118
119     return $line;
120 }
121
122 # Parse input file
123 sub parseFile
124 {
125     my (@file) = @_;
126     my $line;
127     my $splitDefine = 0;
128     my $splitFunctionDeclaration;
129     my $vb_hack = " ";
130     my $vb_line_hack = 0;
131
132     $skip = 0;
133
134     foreach $line (@file)
135     {
136         next if $line =~ /sl_x509_create/;  # ignore for now
137
138         # test for a #define
139         if (!$skip && $line =~ m/^#define/)
140         {
141             $splitDefine = 1 if $line =~ m/\\$/;
142
143             if ($binding == $VBNET)
144             {
145                 $line =~ s/\|/Or/g;
146                 $line =~ s/ 0x/ &H/;
147             }
148
149             my ($name, $value) = $line =~ /#define (\w+) +([^\\]*)[\\]?\n/;
150
151             if (defined $name && defined $value)
152             {
153                 # C# constant translation
154                 if ($binding == $CSHARP)
155                 {
156                     $line = "        public const int $name = $value";
157                 }
158                 # VB.NET constant translation
159                 elsif ($binding == $VBNET)
160                 {
161                     $line = "        Public Const $name As Integer = $value";
162                 }
163             }
164
165             next if $line =~ /#define/;  # ignore any other defines
166                
167             print DATA_OUT $line;
168
169             # check line is not split
170             next if $splitDefine == 1;
171             print DATA_OUT ";" if $binding == $CSHARP;
172             print DATA_OUT "\n";
173         }
174
175         # pick up second line of #define statement
176         if ($splitDefine) 
177         {
178             if ($line !~ /\\$/)
179             {
180                 $line =~ s/$/;/ if $binding == $CSHARP;        # add the ";"
181             }
182
183             $line =~ s/ ?\| ?/ Or /g 
184                                 if ($binding == $VBNET);
185
186             # check line is not split
187             $splitDefine = ($line =~ m/\\$/);
188
189             # ignore trailing "\"
190             $line =~ s/\\$// if $binding == $CSHARP;
191             $line =~ s/\\$/_/ if $binding == $VBNET;
192             print DATA_OUT $line;
193             next;
194         } 
195
196         # test for function declaration
197         if (!$skip && $line =~ /EXP_FUNC/ && $line !~ /\/\*/)
198         {
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;
205             next;
206         }
207
208         if ($splitFunctionDeclaration) 
209         {
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;
216             next;
217         }
218     }
219 }
220
221 #===============================================================
222
223 # Determine which module to build from command-line options
224 use strict;
225 use Getopt::Std;
226
227 my $binding_prefix;
228 my $binding_suffix;
229 my $data_file;
230 my @raw_data;
231
232 if (not defined  $ARGV[0])
233 {
234     goto ouch;
235 }
236
237 if ($ARGV[0] eq "-csharp")
238 {
239     print "Generating C# interface file\n";
240     $binding_prefix = "csharp";
241     $binding_suffix = "cs";
242     $binding = $CSHARP;
243 }
244 elsif ($ARGV[0] eq "-vbnet")
245 {
246     print "Generating VB.NET interface file\n";
247     $binding_prefix = "vbnet";
248     $binding_suffix = "vb";
249     $binding = $VBNET;
250 }
251 else
252 {
253 ouch:
254     die "Usage: $0 [-csharp | -vbnet]\n";
255 }
256
257 my $interfaceFile = "$binding_prefix/axInterface.$binding_suffix";
258
259 # Input file required to generate interface file.
260 $data_file = "../ssl/ssl.h";
261
262 # Open input files
263 open(DATA_IN, $data_file) || die("Could not open file ($data_file)!");
264 @raw_data = <DATA_IN>;
265
266
267 # Open output file
268 if ($binding == $CSHARP || $binding == $VBNET)
269 {
270     open(DATA_OUT, ">$interfaceFile") || die("Cannot Open File");
271 }
272
273 # SPEC interface file header
274 if ($binding == $CSHARP)
275 {
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
280
281 using System;
282 using System.Runtime.InteropServices;
283
284 namespace axTLS
285 {
286     public class axtls
287     {
288 END
289 }
290 elsif ($binding == $VBNET)
291 {
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
296
297 Imports System
298 Imports System.Runtime.InteropServices
299
300 Namespace axTLSvb
301     Public Class axtls
302 END
303 }
304
305 parseFile(@raw_data);
306
307 # finish up
308 if ($binding == $CSHARP)
309 {
310     print DATA_OUT "    };\n";
311     print DATA_OUT "};\n";
312 }
313 elsif ($binding == $VBNET)
314 {
315     print DATA_OUT "    End Class\nEnd Namespace\n";
316 }
317
318 close(DATA_IN);
319 close(DATA_OUT);
320
321 #===============================================================
322