123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- #!/usr/bin/perl -w
- #
- # Copyright (c) 2007, Cameron Rich
- #
- # All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without
- # modification, are permitted provided that the following conditions are met:
- #
- # * Redistributions of source code must retain the above copyright notice,
- # this list of conditions and the following disclaimer.
- # * Redistributions in binary form must reproduce the above copyright
- # notice, this list of conditions and the following disclaimer in the
- # documentation and/or other materials provided with the distribution.
- # * Neither the name of the axTLS project nor the names of its
- # contributors may be used to endorse or promote products derived
- # from this software without specific prior written permission.
- #
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #
- #===============================================================
- # This application transforms ssl.h into interfaces that can be used by
- # other language bindings. It is "SWIG"-like in nature in that various
- # files are generated based on the axTLS API.
- #
- # The file produced is axInterface.? (depending on the file extension).
- #
- #===============================================================
- use strict;
- my $CSHARP = 0;
- my $VBNET = 1;
- my $binding;
- my $skip = 0;
- my $signature_ret_type;
- # Transforms function signature into an Interface format
- sub transformSignature
- {
- my $item;
- my ($line) = @_;
- foreach $item ($line)
- {
- # our very basic preprocessor
- if ($binding == $CSHARP)
- {
- $line =~ s/STDCALL //;
- $line =~ s/EXP_FUNC/ [DllImport ("axtls")]\n public static extern/;
- $line =~ s/uint32_t/uint/g;
- $line =~ s/uint8_t \*\*/ref IntPtr /g;
- $line =~ s/const uint8_t \* /IntPtr /g;
- $line =~ s/const uint8_t \*/byte[] /g; # note: subtle diff
- $line =~ s/uint8_t \* ?/byte[] /g;
- $line =~ s/uint8_t ?/byte /g;
- $line =~ s/const char \* ?/string /g;
- $line =~ s/const SSL_CTX \* ?/IntPtr /g;
- $line =~ s/SSL_CTX \* ?/IntPtr /g;
- $line =~ s/SSLObjLoader \* ?/IntPtr /g;
- $line =~ s/const SSL \* ?/IntPtr /g;
- $line =~ s/SSL \* ?/IntPtr /g;
- $line =~ s/\(void\)/()/g;
- }
- elsif ($binding == $VBNET)
- {
- if ($line =~ /EXP_FUNC/)
- {
- # Procedure or function?
- my $invariant = $line =~ /void /;
- my $proc = $invariant ? "Sub" : "Function";
- ($signature_ret_type) = $line =~ /EXP_FUNC (.*) STDCALL/;
- $line =~ s/EXP_FUNC .* STDCALL / <DllImport("axtls")> Public Shared $proc _\n /;
- $signature_ret_type =~ s/const uint8_t \*/As IntPtr/;
- $signature_ret_type =~ s/const char \*/As String/;
- $signature_ret_type =~ s/SSL_CTX \*/As IntPtr/;
- $signature_ret_type =~ s/SSLObjLoader \*/As IntPtr/;
- $signature_ret_type =~ s/SSL \*/As IntPtr/;
- $signature_ret_type =~ s/uint8_t/As Byte/;
- $signature_ret_type =~ s/int/As Integer/;
- $signature_ret_type =~ s/void//;
- $signature_ret_type .= "\n End $proc\n\n";
- }
- $line =~ s/uint32_t (\w+)/ByVal $1 As Integer/g;
- $line =~ s/int (\w+)/ByVal $1 As Integer/g;
- $line =~ s/uint8_t \*\* ?(\w+)/ByRef $1 As IntPtr/g;
- $line =~ s/const uint8_t \* ?(\w+)/ByVal $1() As Byte/g;
- $line =~ s/uint8_t \* ?(\w+)/ByVal $1() As Byte/g;
- $line =~ s/uint8_t ?(\w+)/ByVal $1 As Byte/g;
- $line =~ s/const char \* ?(\w+)/ByVal $1 As String/g;
- $line =~ s/const SSL_CTX \* ?(\w+)/ByVal $1 As IntPtr/g;
- $line =~ s/SSL_CTX \* ?(\w+)/ByVal $1 As IntPtr/g;
- $line =~ s/SSLObjLoader \* ?(\w+)/ByVal $1 As IntPtr/g;
- $line =~ s/const SSL \* ?(\w+)/ByVal $1 As IntPtr/g;
- $line =~ s/SSL \* ?(\w+)/ByVal $1 As IntPtr/g;
- $line =~ s/void \* ?(\w+)/Byval $1 As IntPtr/g;
- $line =~ s/\(void\)/()/g;
- $line =~ s/void//g;
- $line =~ s/;\n/ $signature_ret_type;/;
- }
- }
- return $line;
- }
- # Parse input file
- sub parseFile
- {
- my (@file) = @_;
- my $line;
- my $splitDefine = 0;
- my $splitFunctionDeclaration;
- my $vb_hack = " ";
- my $vb_line_hack = 0;
- $skip = 0;
- foreach $line (@file)
- {
- next if $line =~ /sl_x509_create/; # ignore for now
- # test for a #define
- if (!$skip && $line =~ m/^#define/)
- {
- $splitDefine = 1 if $line =~ m/\\$/;
- if ($binding == $VBNET)
- {
- $line =~ s/\|/Or/g;
- $line =~ s/ 0x/ &H/;
- }
- my ($name, $value) = $line =~ /#define (\w+) +([^\\]*)[\\]?\n/;
- if (defined $name && defined $value)
- {
- # C# constant translation
- if ($binding == $CSHARP)
- {
- $line = " public const int $name = $value";
- }
- # VB.NET constant translation
- elsif ($binding == $VBNET)
- {
- $line = " Public Const $name As Integer = $value";
- }
- }
- next if $line =~ /#define/; # ignore any other defines
-
- print DATA_OUT $line;
- # check line is not split
- next if $splitDefine == 1;
- print DATA_OUT ";" if $binding == $CSHARP;
- print DATA_OUT "\n";
- }
- # pick up second line of #define statement
- if ($splitDefine)
- {
- if ($line !~ /\\$/)
- {
- $line =~ s/$/;/ if $binding == $CSHARP; # add the ";"
- }
- $line =~ s/ ?\| ?/ Or /g
- if ($binding == $VBNET);
- # check line is not split
- $splitDefine = ($line =~ m/\\$/);
- # ignore trailing "\"
- $line =~ s/\\$// if $binding == $CSHARP;
- $line =~ s/\\$/_/ if $binding == $VBNET;
- print DATA_OUT $line;
- next;
- }
- # test for function declaration
- if (!$skip && $line =~ /EXP_FUNC/ && $line !~ /\/\*/)
- {
- $line = transformSignature($line);
- $splitFunctionDeclaration = $line !~ /;/;
- $line =~ s/;// if ($binding == $VBNET);
- $line =~ s/\n$/ _\n/ if ($binding == $VBNET) &&
- $splitFunctionDeclaration;
- print DATA_OUT $line;
- next;
- }
- if ($splitFunctionDeclaration)
- {
- $line = transformSignature($line);
- $splitFunctionDeclaration = $line !~ /;/;
- $line =~ s/;// if ($binding == $VBNET);
- $line =~ s/\n/ _\n/ if ($binding == $VBNET) &&
- $splitFunctionDeclaration == 1;
- print DATA_OUT $line;
- next;
- }
- }
- }
- #===============================================================
- # Determine which module to build from command-line options
- use strict;
- use Getopt::Std;
- my $binding_prefix;
- my $binding_suffix;
- my $data_file;
- my @raw_data;
- if (not defined $ARGV[0])
- {
- goto ouch;
- }
- if ($ARGV[0] eq "-csharp")
- {
- print "Generating C# interface file\n";
- $binding_prefix = "csharp";
- $binding_suffix = "cs";
- $binding = $CSHARP;
- }
- elsif ($ARGV[0] eq "-vbnet")
- {
- print "Generating VB.NET interface file\n";
- $binding_prefix = "vbnet";
- $binding_suffix = "vb";
- $binding = $VBNET;
- }
- else
- {
- ouch:
- die "Usage: $0 [-csharp | -vbnet]\n";
- }
- my $interfaceFile = "$binding_prefix/axInterface.$binding_suffix";
- # Input file required to generate interface file.
- $data_file = "../ssl/ssl.h";
- # Open input files
- open(DATA_IN, $data_file) || die("Could not open file ($data_file)!");
- @raw_data = <DATA_IN>;
- # Open output file
- if ($binding == $CSHARP || $binding == $VBNET)
- {
- open(DATA_OUT, ">$interfaceFile") || die("Cannot Open File");
- }
- # SPEC interface file header
- if ($binding == $CSHARP)
- {
- # generate the C#/C interface file
- print DATA_OUT << "END";
- // The C# to C interface definition file for the axTLS project
- // Do not modify - this file is generated
- using System;
- using System.Runtime.InteropServices;
- namespace axTLS
- {
- public class axtls
- {
- END
- }
- elsif ($binding == $VBNET)
- {
- # generate the VB.NET/C interface file
- print DATA_OUT << "END";
- ' The VB.NET to C interface definition file for the axTLS project
- ' Do not modify - this file is generated
- Imports System
- Imports System.Runtime.InteropServices
- Namespace axTLSvb
- Public Class axtls
- END
- }
- parseFile(@raw_data);
- # finish up
- if ($binding == $CSHARP)
- {
- print DATA_OUT " };\n";
- print DATA_OUT "};\n";
- }
- elsif ($binding == $VBNET)
- {
- print DATA_OUT " End Class\nEnd Namespace\n";
- }
- close(DATA_IN);
- close(DATA_OUT);
- #===============================================================
|