Annotation of embedaddon/axTLS/bindings/generate_interface.pl, revision 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>