File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / axTLS / bindings / generate_interface.pl
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Fri Sep 28 11:55:55 2012 UTC (11 years, 9 months ago) by misho
Branches: v1_4_8, MAIN
CVS tags: datecs, HEAD
axTLS

    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>