cApiBuilder
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:14k
- #!/usr/bin/perl
- # ====================================================================
- # The Vovida Software License, Version 1.0
- #
- # Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without
- # modification, are permitted provided that the following conditions
- # are met:
- #
- # 1. Redistributions of source code must retain the above copyright
- # notice, this list of conditions and the following disclaimer.
- #
- # 2. 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.
- #
- # 3. The names "VOCAL", "Vovida Open Communication Application Library",
- # and "Vovida Open Communication Application Library (VOCAL)" must
- # not be used to endorse or promote products derived from this
- # software without prior written permission. For written
- # permission, please contact vocal@vovida.org.
- #
- # 4. Products derived from this software may not be called "VOCAL", nor
- # may "VOCAL" appear in their name, without prior written
- # permission of Vovida Networks, Inc.
- #
- # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
- # NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
- # NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
- # IN EXCESS OF $1,000, NOR FOR ANY 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 software consists of voluntary contributions made by Vovida
- # Networks, Inc. and many individuals on behalf of Vovida Networks,
- # Inc. For more information on Vovida Networks, Inc., please see
- # <http://www.vovida.org/>.
- # $Id: cApiBuilder,v 1.11 2000/08/12 01:24:57 bogawa Exp $
- use strict 'subs';
- #use strict 'getopts.pl';
- @functions = ( ); # main data structure that holds all info about all functions
- $doCode = 1; # flag to generate CXX file, otherwise do header file
- @inclues = {}; # holds allfiles to be included in generated output
- # parse the heasder information
- for $arg ( @ARGV ) {
- &debug(" arg=",$arg,"n");
-
- if ( $arg =~ /^-c/ ) {
- $doCode = 1;
- }
-
- if ( $arg =~ /^-h/ ) {
- $doCode = 0;
- }
- if ( $arg =~ /^-d/ ) {
- $debugCode = 1;
- }
-
- if ( $arg =~ /^-i/ ) {
- # an file to include
- $arg =~ s/^-i//;
- push @includes, $arg;
- }
- }
- #generate the file header info
- print <<EOP;
- /*
- This file was generated using cApiBuilder. This filemust be
- considered a derivative work of the files from which this file was
- generated.
- */
- EOP
- # parse the input file
- while ( <STDIN> ) {
- # still need to deal with C style comments
- if ( s/^#include/#include/g > 0 ) {
- print $_ if $doCode;
- }
- else {
- chomp;
- $ignore = 1 if(/// API:ignore begin/) ;
- $ignore = 0 if(/// API:ignore end/) ;
- next if($ignore);
- s/:/ : /g;
- s/,/ , /g;
- s/(/ ( /g;
- s/)/ ) /g;
- s/{/ { /g;
- s/}/ } /g;
- s/;/ ; /g;
- s///.*$/ /g;
- s/#.*$/ /g;
- s/^t/ /g;
- s/const/ /g;
- s/virtual/ /g;
-
- $data .= $_ . " ";
- }
- }
- # remvoe C Style comments
- $data =~ s//*.*?*///gm;
- # tokenize the data
- @data = split( " " , $data );
- $inClass = 0;
- $inPublic = 0;
- for( $i=0; $i < $#data; $i++ ) {
- if ( $data[$i] eq "class" ) {
- $className = $data[$i+1];
- if ( $data[$i+2] ne ";" ) {
- while ( $data[$i] ne "{" ) { $i++; }
- $i++;
- $inClass = 1;
- $inPublic = 0;
- &debug("# in class " , $className , "n");
- }
- }
-
- if ( $data[$i] eq "}" ) {
- $inClass = 0;
- }
- if ( ($data[$i] eq "public") and $inClass ) {
- while ( $data[$i] ne ":" ) { $i++; }
- $i++;
- $inPublic = 1;
- &debug("# in public of " , $className , "n");
- }
- if ( ($data[$i] eq "private") or ($data[$i] eq "protected") ) {
- while ( $data[$i] ne ":" ) { $i++; }
- $i++;
- $inPublic = 0;
- }
-
- if ( ($data[$i] eq "(" ) and $inClass and $inPublic ) {
- #found a function
- $functionName = $data[$i-1];
- if ( $functionName eq $className ) {
- $returnType = $className . "*";
- $functionName = "constructor";
- }
- elsif ( $functionName eq ( "~" . $className ) ) {
- $returnType = "void";
- $functionName = "destructor";
- }
- else {
- $staticFunction = ( $data[$i-3] eq "static");
- $returnType = $data[$i-2];
- $returnType = "int" if ($returnType eq ";");
- $returnType = "int" if ($returnType eq ":");
- $returnType = "int" if ($returnType eq "{");
- }
- $i++;
- $rec = { };
- $rec->{name} = $functionName;
- $rec->{isStatic} = $staticFunction;
- $rec->{class} = $className;
- $rec->{return} = $returnType;
- &debug("#func ",$returnType," ",$className,"::",$functionName,"n");
- $numParam = 0;
- # get the parameters
- PARAM: while ( 1 ) {
- last PARAM if ( $data[$i] eq ")" );
- #for ( $t=$i; $t<$i+3; $t++) { print "data[",$t,"]=",$data[$t],"n"; }
-
- $type = $data[$i];
- $name = $data[$i+1];
-
- $name =~ s/=.*//g; # kill default paramters
- &debug("# param ",$numParam," ",$type," ",$name,"n");
- $rec->{"paramName",$numParam} = $name;
- $rec->{"paramType",$numParam} = $type;
- $numParam++;
- $rec->{numParam} = $numParam;
- $i = $i+2;
-
- &debug("data is ",$data[$i],"n");
-
- last PARAM if ( $data[$i] eq ")" );
-
- if ( $data[$i] eq "," ) {
- $i++;
- next PARAM;
- }
-
- print STDERR "VERY CONFUSEDn";
- print "VERY CONFUSEDn";
- for ( $j = $i-10; $j < $i+10; $j++ ) {
- print $data[$j]," ";
- }
- print "n";
-
- last PARAM;
- }
- push @functions, $rec;
- # eat rest of function
- INLINEFUNC: while ( ($data[$i] ne ";") ) {
-
- if (($data[$i] eq "{") ) {
- #Deal with inline function
- $i++;
- $depth = 1;
- while ( $depth > 0 ) {
- $depth++ if ($data[$i] eq "{");
- $depth-- if ($data[$i] eq "}");
- $i++;
- }
-
- last INLINEFUNC;
- }
-
- $i++;
- }
- }
- &debug($i,": ",$data[$i] , "n");
- }
- # print the functions
- if (0) {
- for $func ( @functions ) {
- print "static " if $func->{isStatic};
- print $func->{return}," ", $func->{class},"::",$func->{name},"(";
- for( $t=0; $t < $func->{numParam}; $t++) {
- print "," if ( $t != 0 );
- print $func->{"paramType",$t}," ",$func->{"paramName",$t};
- }
- print ");n";
- }
- }
- %definedTypes = ( "void" => 1,
- "bool" => 1,
- "char" => 1,
- "int" => 1,
- "long" => 1,
- "float" => 1,
- "double" => 1,
- "string" => 1,
- "String" => 1,
- "RtpSeqNumber" => 1,
- "RtcpHeader" => 1,
- "RtcpReport" => 1,
- "RtcpSDESItem" => 1,
- "RtcpSDESType" => 1,
- "RtcpSender" => 1,
- "RtcpType" => 1,
- "RtpHeader" => 1,
- "RtpPayloadType" => 1,
- "RtpSource" => 1,
- "RtpTime" => 1,
- "RtpSrc" => 1,
- "u_int32_t" => 1
- );
- sub addType ( $ ) {
- my $type = shift;
- &debug("adding type ",$type," -> ",&mapTypeToC($type),"n");
- $_ = $type;
- s/&//g;
- s/*//g;
- $_ = "builtin" if ( $definedTypes{$_} );
- $type = $_;
- $types{$type} = $type unless ( $type eq "builtin" );
- }
- sub mapTypeToC ( $ ) {
- $_ = shift;
- s/string&/char*/g;
- s/string/char*/g;
- s/&/*/g;
- s/bool/int/g;
- my $type = $_;
- # try to fix template classes
- s/<(w*)>/_Tmpl_$1_/;
- $type =~ s/<(w*)>/_Tmpl_$1_/;
- s/Ptr$/*/;
- s/**//g;
- &debug("check defined for " , $_ , "n");
- if ( $definedTypes{$_} ) {
- &debug("is definedn");
- #$type .= "_isCDefined";
- }
- else {
- &debug("is not definedn");
- $type =~ s/*/Ptr/; # needs work for builtin types
- # $type .= "Ptr"; # needs work for builtin types
- }
- # try to fix template classes
- s/<(w*)>/_Tmpl_$1_/;
- # s/^intPtr/int*/;
- # s/^longPtr/long*/;
- # s/^charPtr/char*/;
- # s/^shortPtr/short*/;
- # s/^floatPtr/float*/;
- # s/^doublePtr/double*/;
- # s/^voidPtr/void*/;
-
- $mapTypeToC = $type;
- }
- # compute all the type lookups
- for $func ( @functions ) {
- &addType( $func->{class} );
- &addType( $func->{return} );
- for( $t=0; $t < $func->{numParam}; $t++) {
- &addType( $func->{"paramType",$t} );
- }
- }
- # generate the file
- if (1) {
- # print "n#include <cassert>nn" if $doCode;
- print "n#include <assert.h>nn" if $doCode;
- for $include ( @includes ) {
- print "#include "$include" n";
- }
- print "n#ifdef __cplusplusnextern "C" n{n#endifn";
- print "nn";
- print " /* This file uses the types : n";
- # build the type declarations
- for $type ( sort keys %types ) {
- $type =~ s/<(w*)>/_Tmpl_$1_/;
- print "typedef void* ",$type,"Ptr;n";
- }
- print " */ n ";
- print "nn";
- print "/* these function return a string describibg any */ n";
- print "/* errors or NULL if there was no error */ nn";
- # build the prototypes
- for $func ( @functions ) {
-
- if ( $func->{class} ne $prevClass ) {
- print "n" ;
- $constructorCount=0;
- }
- $prevClass = $func->{class};
-
- if ( $func->{name} eq "constructor" ) {
- if (1) {
- $constructorCount++;
- if ( $doCode ) {
- print "n/// See ",$func->{class},"::",$func->{class},"n";
- }
- print "int ";
- print "n" if $doCode;
- print $func->{class},"_create",$constructorCount;
- print "( ",&mapTypeToC($func->{class} . "*"),"* objPtr";
- for( $t=0; $t < $func->{numParam}; $t++) {
- print ", ",&mapTypeToC($func->{"paramType",$t});
- print " ",$func->{"paramName",$t};
- }
- print ")";
- print ";" unless $doCode;
- print "n";
- if ( $doCode ) {
- print "{n";
- print " int retValue=0;n";
- print " ",$func->{class},"* obj = NULL; n";
- print " tryn";
- print " {n";
- print " ";
- print "obj = new ",$func->{class},"(";
- for( $t=0; $t < $func->{numParam}; $t++) {
- print "," if ( $t != 0 );
- $type = $func->{"paramType",$t};
-
- if ( $type eq "string" ) {
- print "string";
- print "(",$func->{"paramName",$t},")";
- }
- elsif ( $type eq "string&" ) {
- print "string";
- print "(",$func->{"paramName",$t},")";
- }
- elsif ( $type =~ /.*&$/ ) {
- # deal with a feverence type
- $type =~ s/&$//;
- print "*static_cast<",$type,"*>";
- print "(",$func->{"paramName",$t},")";
- }
- else {
- print "static_cast<",$type,">";
- print "(",$func->{"paramName",$t},")";
- }
- }
- print ")";
- print ";n";
- print " assert(objPtr); n";
- print " *objPtr = static_cast<",&mapTypeToC($func->{class} . "*"),">(obj); n";
- print " }n";
- print " catch (...)n";
- print " {n";
- print " retValue=-1; n";
- print " }n";
- print " n";
- print " return retValue;n";
- print "}nn";
- }
- }
- }
- elsif( $func->{name} eq "destructor" ) {
- if (1) {
- if ( $doCode ) {
- print "n/// See ",$func->{class},"::~",$func->{class},"n";
- }
- print "void ";
- print "n" if $doCode;
- print $func->{class},"_free";
- print "( ",&mapTypeToC($func->{class} . "*")," objPtr";
- print ")";
- if ( $doCode ) {
- print "n{n";
- print " assert(objPtr);n";
- print " ",$func->{class},"* obj = ";
- print "static_cast<",$func->{class},"*>(objPtr);n";
- print " delete obj;n";
- print "}n";
- }
- else {
- print ";n";
- }
- }
- }
- else {
- if (1) {
- if ( $doCode ) {
- print "n/// See ",$func->{class},"::",$func->{name},"n";
- }
- print "int ";
- print "n" if $doCode;
- # deal with overloaded function names
- $cName = $func->{class} . "_" . $func->{name};
- $count = 1;
- while ( $usedName{$cName} ) {
- $count++;
- $cName = $func->{class} . "_" . $func->{name} . $count;
- }
- $usedName{$cName} = 1;
- print $cName;
- print "( ";
- # do the this pointer part
- print &mapTypeToC($func->{class} . "*")," objPtr" unless $func->{isStatic};
- print ", " unless $func->{isStatic} or ( ($func->{numParam}==0) and (($func->{return} eq "void")) );
- # do the parametes
- for( $t=0; $t < $func->{numParam}; $t++) {
- print ", " unless ( $t == 0 );
- print &mapTypeToC($func->{"paramType",$t});
- print " ",$func->{"paramName",$t};
- }
- print ", " unless ($func->{return} eq "void")or($func->{numParam}==0);
- # do return value part
- if ( $func->{return} ne "void" ) {
- print &mapTypeToC($func->{return} . "*")," returnValue";
- }
- # end the first line
- print ")";
- print ";" unless $doCode;
- print "n";
- if ( $doCode ) {
- print "{n";
- print " int retValue=0;n";
- if ( !($func->{isStatic}) ) {
- print " ",$func->{class},"* obj = ";
- print "static_cast<",$func->{class},"*>(objPtr);n";
- }
- print " tryn";
- print " {n";
- print " ";
- # deal with the return type here
- if ( $func->{return} ne "void" ) {
- print "*reinterpret_cast<",$func->{return},"*>(returnValue) = ";
- }
-
- if ( $func->{isStatic} ) {
- print "$func->{class}::";
- }
- else {
- print "obj->";
- }
- print $func->{name},"(";
- for( $t=0; $t < $func->{numParam}; $t++) {
- print "," if ( $t != 0 );
- $type = $func->{"paramType",$t};
-
- if ( $type eq "string" ) {
- print "string";
- print "(",$func->{"paramName",$t},")";
- }
- elsif ( $type eq "string&" ) {
- print "string";
- print "(",$func->{"paramName",$t},")";
- }
- elsif ( $type =~ /.*&$/ ) {
- # deal with a reference type
- $type =~ s/&$//;
- print "*static_cast<",$type,"*>";
- print "(",$func->{"paramName",$t},")";
- }
- else {
- print "static_cast<",$type,">";
- print "(",$func->{"paramName",$t},")";
- }
- }
- print ")";
- print ";n";
- print " }n";
- print " catch (...)n";
- print " {n";
- print " retValue=-1; n";
- print " }n";
- print " n";
- print " return retValue;n";
- print "}nn";
- }
- }
- }
- }
- print "n#ifdef __cplusplusn} /*close extern C*/ n#endifn";
- }
- sub debug {
- if($debugCode) {
- print STDERR @_;
- }
- }