Annotation of embedaddon/axTLS/bindings/generate_interface.pl, revision 1.1.1.1
1.1 misho 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:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>