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>