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>