From owner-freebsd-ports Sat Dec 15 6: 4:57 2001 Delivered-To: freebsd-ports@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id EAD1E37B41B for ; Sat, 15 Dec 2001 06:00:01 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id fBFE01v59480; Sat, 15 Dec 2001 06:00:01 -0800 (PST) (envelope-from gnats) Received: from darkone.comintern.net (darkone.comintern.net [213.148.1.98]) by hub.freebsd.org (Postfix) with ESMTP id 997A837B41A for ; Sat, 15 Dec 2001 05:53:43 -0800 (PST) Received: from 3wgraphics.com (ppp-9-066.comintern.ru [213.148.9.66]) by darkone.comintern.net (8.11.6/8.11.6) with ESMTP id fBFDr8Q511442 for ; Sat, 15 Dec 2001 16:53:08 +0300 (MSD) Received: from root by 3wgraphics.com with local (Exim 3.33 #1) id 16FFAy-000Jxs-00 for FreeBSD-gnats-submit@freebsd.org; Sat, 15 Dec 2001 16:48:28 +0300 Message-Id: Date: Sat, 15 Dec 2001 16:48:28 +0300 From: skv@protey.ru Reply-To: skv@protey.ru To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: ports/32869: New port: p5-Inline-CPP-0.23 Sender: owner-freebsd-ports@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >Number: 32869 >Category: ports >Synopsis: New port: p5-Inline-CPP-0.23 >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-ports >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sat Dec 15 06:00:01 PST 2001 >Closed-Date: >Last-Modified: >Originator: Sergey Skvortsov >Release: FreeBSD 4.4-STABLE i386 >Organization: >Environment: >Description: New port: p5-Inline-CPP-0.23 Write Perl subroutines and classes in C++ >How-To-Repeat: >Fix: # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # p5-Inline-CPP # p5-Inline-CPP/distinfo # p5-Inline-CPP/work # p5-Inline-CPP/work/Inline-CPP-0.23 # p5-Inline-CPP/work/Inline-CPP-0.23/README # p5-Inline-CPP/work/Inline-CPP-0.23/CPP.pod # p5-Inline-CPP/work/Inline-CPP-0.23/grammar # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/02scope.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/16varlst.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/01nherit.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/14const.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/13vararg.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/12retlst.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/10struct.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/08anon.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/06deflt.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/15stvar.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/11minhrt.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/07static.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/09purevt.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/03inline.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/05virt.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/04const.t # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/grammar.pm # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/Makefile.PL # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/pm_to_blib # p5-Inline-CPP/work/Inline-CPP-0.23/grammar/Makefile # p5-Inline-CPP/work/Inline-CPP-0.23/MANIFEST # p5-Inline-CPP/work/Inline-CPP-0.23/CPP.pm # p5-Inline-CPP/work/Inline-CPP-0.23/Changes # p5-Inline-CPP/work/Inline-CPP-0.23/Makefile.PL # p5-Inline-CPP/work/Inline-CPP-0.23/t # p5-Inline-CPP/work/Inline-CPP-0.23/t/02prefix.t # p5-Inline-CPP/work/Inline-CPP-0.23/t/01basic.t # p5-Inline-CPP/work/Inline-CPP-0.23/TESTED # p5-Inline-CPP/work/Inline-CPP-0.23/blib # p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib # p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline # p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/.exists # p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP.pod # p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP.pm # p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP # p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP/.exists # p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP/grammar.pm # p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto # p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline # p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP # p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP/.exists # p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP/grammar # p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP/grammar/.exists # p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch # p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto # p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline # p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP # p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP/.exists # p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP/grammar # p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP/grammar/.exists # p5-Inline-CPP/work/Inline-CPP-0.23/blib/man3 # p5-Inline-CPP/work/Inline-CPP-0.23/blib/man3/.exists # p5-Inline-CPP/work/Inline-CPP-0.23/blib/man3/Inline::CPP.3 # p5-Inline-CPP/work/Inline-CPP-0.23/Makefile # p5-Inline-CPP/work/Inline-CPP-0.23/pm_to_blib # p5-Inline-CPP/work/.extract_done.p5-Inline-CPP-0.23 # p5-Inline-CPP/work/.patch_done.p5-Inline-CPP-0.23 # p5-Inline-CPP/work/.configure_done.p5-Inline-CPP-0.23 # p5-Inline-CPP/work/.build_done.p5-Inline-CPP-0.23 # p5-Inline-CPP/Makefile # p5-Inline-CPP/pkg-comment # p5-Inline-CPP/pkg-descr # p5-Inline-CPP/pkg-plist # echo c - p5-Inline-CPP mkdir -p p5-Inline-CPP > /dev/null 2>&1 echo x - p5-Inline-CPP/distinfo sed 's/^X//' >p5-Inline-CPP/distinfo << 'END-of-p5-Inline-CPP/distinfo' XMD5 (Inline-CPP-0.23.tar.gz) = 2d7826f5224836f200751fc82ec165de END-of-p5-Inline-CPP/distinfo echo c - p5-Inline-CPP/work mkdir -p p5-Inline-CPP/work > /dev/null 2>&1 echo c - p5-Inline-CPP/work/Inline-CPP-0.23 mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23 > /dev/null 2>&1 echo x - p5-Inline-CPP/work/Inline-CPP-0.23/README sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/README << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/README' XINTRODUCTION: X XInline::CPP -- Write Perl subroutines and classes in C++. X XInline::CPP lets you write Perl subroutines and classes in C++. You Xdon't have to learn XS or SWIG, you can just put code right "inline" Xin your source. X XExample: X X use Inline CPP => <<'END'; X X class JAxH { X public: X JAxH(char *x); X X SV* data(); X private: X SV *dat; X }; X X JAxH::JAxH(char *x) { dat = newSVpvf("Just Another %s Hacker", x); } X SV* JAxH::data() { return dat; } X X END X X print JAxH->new('Inline')->data(), "\n"; X XWhen run, this complete program prints: X X Just Another Inline Hacker. X X----------------------------------------------------------------------------- XFEATURES: X XInline::CPP version 0.23 is a minor upgrade from previous versions. It Xincludes: X X+ Bug fix -- allow static member variables X X----------------------------------------------------------------------------- XINSTALLATION: X XThis module requires Inline::C.pm version 0.42 or higher to be installed. X XTo install Inline::CPP do this: X Xperl Makefile.PL Xmake Xmake test Xmake install X X(On ActivePerl for MSWin32, use nmake instead of make.) X XYou have to 'make install' before you can run it successfully. X X----------------------------------------------------------------------------- XINFORMATION: X X- For more information on Inline::CPP see 'perldoc Inline::CPP'. X- For information about Inline.pm, see 'perldoc Inline'. X- For information on using Perl with C or C++, see 'perldoc perlapi' X XThe Inline mailing list is inline@perl.org. Send mail to Xinline-subscribe@perl.org to subscribe. X XPlease send questions and comments to "Neil Watkiss" X XCopyright (c) 2000, Neil Watkiss. All Rights Reserved. END-of-p5-Inline-CPP/work/Inline-CPP-0.23/README echo x - p5-Inline-CPP/work/Inline-CPP-0.23/CPP.pod sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/CPP.pod << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/CPP.pod' X=head1 NAME X XInline::CPP - Write Perl subroutines and classes in C++. X X=head1 SYNOPSIS X X use Inline CPP; X X print "9 + 16 = ", add(9, 16), "\n"; X print "9 - 16 = ", subtract(9, 16), "\n"; X X __END__ X __CPP__ X X int add(int x, int y) { X return x + y; X } X X int subtract(int x, int y) { X return x - y; X } X X END_OF_CPP_CODE X X=head1 DESCRIPTION X XThe C module allows you to put C++ source code directly X"inline" in a Perl script or module. You code classes or functions in XC++, and you can use them as if they were written in Perl. X X=head1 Choosing a C++ Compiler X XInline::CPP just parses your C++ code and creates bindings to it. Like XInline::C, you will need a suitable compiler the first time you run the Xscript. Choosing a C++ compiler can prove difficult, because Perl is Xwritten in C, not C++. X XHere's the rule: use any C++ compiler that's compatible with the compiler Xwhich built perl. For instance, if perl was built with C, use C. XIf you're on a Sun or an IRIX box and the system C compiler C built perl, Xthen use the system C++ compiler, C. X XSome compilers actually compile both C and C++ with the same compiler. XMicrosoft's C is one such compiler -- you pass it the <-TP> flag Xto convince it that you want C++ mode. X X=head1 Using Inline::CPP X XInline::CPP is very similar to Inline::C. It uses a grammar to Xparse your C++ code, and binds to functions or classes which are Xrecognized. If a function is recognized, it will be available from XPerl space. If the function's signature is not recognized, it will not Xbe available from Perl space, but will be available from other Xfunctions in C++. X XFor more information about the grammar used to parse C++ code, see the Xsection called "Grammar". X XThe following example shows how C++ snippets map into the Perl Xnamespace: X XExample 1: X X use Inline CPP => <<'END'; X X int doodle() { } X X class Foo { X public: X Foo(); X ~Foo(); X X int get_data() { return data; } X void set_data(int a) { data = a; } X private: X int data; X }; X X Foo::Foo() { cout << "creating a Foo()" << endl; } X Foo::~Foo() { cout << "deleting a Foo()" << endl; } X X END X XAfter running the code above, Perl's namespace would look similar to if Xfollowing code had been run: X X sub main::doodle { } X X package main::Foo; X X sub new { print "creating a Foo()\n"; bless {}, shift } X sub DESTROY { print "deleting a Foo()\n" } X X sub get_data { my $o=shift; $o->{data} } X sub set_data { my $o=shift; $o->{data} = shift } X XThe difference, of course, is that in the latter, Perl does the work. In the XInline::CPP example, all function calls get sent off to your C++ code. That Xmeans that things like this won't work: X X my $obj = new Foo; X $obj->{extrafield} = 10; X XIt doesn't work because C<$obj> is not a blessed hash. It's a blessed Xreference to a C++ object (and anyway, C++ wouldn't let you do that either, Xsince extrafield wasn't defined). X X=head1 C++ Configuration Options X XFor information on how to specify Inline configuration options, see XL. This section describes each of the configuration options Xavailable for C. Most of the options correspond either the MakeMaker Xor XS options of the same name. See L and XL. X X=head2 ALTLIBS X XAdds a new entry to the end of the list of alternative libraries to Xbind with. MakeMaker will search through this list and use the first Xentry where all the libraries are found. X X use Inline Config => ALTLIBS => '-L/my/other/lib -lfoo'; X XSee also the LIBS config option, which appends to the last entry in Xthe list. X X=head2 AUTO_INCLUDE X XSpecifies extra statements to be automatically included. They will be Xadded on to the defaults. A newline char will automatically be added. X X use Inline Config => AUTO_INCLUDE => '#include "something.h"'; X X=head2 BOOT X XSpecifies code to be run when your code is loaded. May not contain any Xblank lines. See L for more information. X X use Inline Config => BOOT => 'foo();'; X X=head2 CC X XSpecifies which compiler to use. X X=head2 CCFLAGS X XSpecifies extra compiler flags. Corresponds to the MakeMaker option. X X=head2 FILTERS X XSpecifies one (or more, in an array ref) filter which is to be applied to Xthe code just prior to parsing. The filters are executed one after another, Xeach operating on the output of the previous one. You can pass in a code Xreference or the name of a prepackaged filter. X X use Inline Config => FILTERS => [Strip_POD => \&myfilter]; X XThe filter may do anything. The code is passed as the first argument, and Xit returns the filtered code. X X=head2 INC X XSpecifies extra include directories. Corresponds to the MakeMaker Xparameter. X X use Inline Config => INC => '-I/my/path'; X X=head2 LD X XSpecifies the linker to use. X X=head2 LDDLFLAGS X XSpecifies which linker flags to use. X XNOTE: These flags will completely override the existing flags, instead Xof just adding to them. So if you need to use those too, you must Xrespecify them here. X X=head2 LIBS X XSpecifies external libraries that should be linked into your Xcode. Corresponds to the MakeMaker parameter. X X use Inline Config => LIBS => '-L/your/path -lyourlib'; X XUnlike the LIBS configuration parameter used in Inline::C, successive Xcalls to LIBS append to the previous calls. For example, X X use Inline Config => LIBS => '-L/my/path', LIBS => '-lyourlib'; X Xwill work correctly. If you want to add a new element to the list of Xpossible libraries to link with, use the Inline::CPP configuration ALTLIBS. X X=head2 MAKE X XSpecifies the name of the 'make' utility to use. X X=head2 MYEXTLIB X XSpecifies a user compiled object that should be linked in. Corresponds Xto the MakeMaker parameter. X X use Inline Config => MYEXTLIB => '/your/path/something.o'; X X=head2 PREFIX X XSpecifies a prefix that will automatically be stripped from C++ Xfunctions when they are bound to Perl. Less useful than in C, because XC++ mangles its function names so they don't conflict with C functions Xof the same name. X X use Inline Config => PREFIX => 'ZLIB_'; X XThis only affects C++ function names, not C++ class names or methods. X X=head2 PRESERVE_ELLIPSIS X XBy default, Inline::CPP replaces C<...> in bound functions with three Xspaces, since the arguments are always passed on the Perl Stack, not on Xthe C stack. This is usually desired, since it allows functions with Xno fixed arguments (most compilers require at least one fixed argument). X X use Inline Config => PRESERVE_ELLIPSIS => 1; Xor X use Inline Config => ENABLE => PRESERVE_ELLIPSIS; X XFor an example of why PRESERVE_ELLIPSIS is normally not needed, see the Xexamples section, below. X X=head2 STD_IOSTREAM X XBy default, Inline::CPP includes C at the top of your code. This Xoption makes it include C instead, which is the ANSI-compliant Xversion of the makefile. On non-GNU implementations, these files are not Xcompatible with one another. X X use Inline CPP => Config => ENABLE => STD_IOSTREAM; X X=head2 STRUCTS X XSpecifies whether to bind C structs into Perl using Inline::Struct. XNOTE: Support for this option is experimental. Inline::CPP already binds Xto structs defined in your code. Structs and classes are treated as the Xsame construct, except that a struct's initial scope is public, not Xprivate. Inline::Struct provides autogenerated get/set methods, an Xoverloaded constructor, and several other features not available in XInline::CPP. X XYou can invoke STRUCTS in several ways: X X use Inline Config => STRUCTS => 'Foo'; Xor X use Inline Config => STRUCTS => ['Bar', 'Baz']; X XBinds the named structs to Perl. Emits warnings if a struct was requested Xbut could not be bound for some reason. X X use Inline Config => ENABLE => 'STRUCTS'; Xor X use Inline Config => STRUCTS => 1; X XEnables binding structs to Perl. All structs which can be bound, will. This Xparameter overrides all requests for particular structs. X X use Inline Config => DISABLE => 'STRUCTS'; Xor X use Inline Config => STRUCTS => 0; X XDisables binding structs to Perl. Overrides any other settings. X XSee L for more details about how C Xbinds C structs to Perl. X X=head2 TYPEMAPS X XSpecifies extra typemap files to use. These types will modify the Xbehaviour of C++ parsing. Corresponds to the MakeMaker parameter. X X use Inline Config => TYPEMAPS => '/your/path/typemap'; X X=head1 C++-Perl Bindings X XThis section describes how the C variables get mapped to C Xvariables and back again. X XPerl uses a stack to pass arguments back and forth to subroutines. When Xa sub is called, it pops off all its arguments from the stack; when it's Xdone, it pushes its return values back onto the stack. X XXS (Perl's language for creating C or C++ extensions for Perl) uses X"typemaps" to turn SVs into C types and back again. This is done through Xvarious XS macro calls, casts, and the Perl API. XS also allows you to Xdefine your own mappings. X XC uses a much simpler approach. It parses the system's Xtypemap files and only binds to functions with supported types. You Xcan tell C about custom typemap files too. X XIf you have very complicated data structures in either C++ or Perl, Xyou should just pass them as an SV* and do the conversion yourself in Xyour C++ function. X XIn C++, a struct is a class whose default scope is public, not Xprivate. Inline::CPP binds to structs with this in mind -- get/set Xmethods are not yet auto-generated (although they are scheduled to Xland in an upcoming release). X XIf you have a C struct, you can use Inline::Struct to allow Perl Xcomplete access to the internals of the struct. You can create and Xmodify structs from inside Perl, as well as pass structs into C++ Xfunctions and return them from functions. Please note that XInline::Struct does not understand any C++ features, so constructors Xand member functions are not supported. See L for more Xdetails. X X=head1 EXAMPLES X XHere are some examples. X X=head2 Example 1 - Farmer Bob X XThis example illustrates how to use a simple class (C) from XPerl. One of the new features in Inline::CPP is binding to classes Xwith inline method definitions: X X use Inline CPP; X X my $farmer = new Farmer("Ingy", 42); X my $slavedriver = 1; X while($farmer->how_tired < 420) { X $farmer->do_chores($slavedriver); X $slavedriver <<= 1; X } X X print "Wow! The farmer worked ", $farmer->how_long, " hours!\n"; X X __END__ X __CPP__ X X class Farmer { X public: X Farmer(char *name, int age); X ~Farmer(); X X int how_tired() { return tiredness; } X int how_long() { return howlong; } X void do_chores(int howlong); X X private: X char *name; X int age; X int tiredness; X int howlong; X }; X X Farmer::Farmer(char *name, int age) { X this->name = strdup(name); X this->age = age; X tiredness = 0; X howlong = 0; X } X X Farmer::~Farmer() { X free(name); X } X X void Farmer::do_chores(int hl) { X howlong += hl; X tiredness += (age * hl); X } X X=head2 Example 2 - Plane and Simple X XThis example demonstrates some new features of Inline::CPP: support for Xinheritance and abstract classes. The defined methods of the abstract Xclass C are bound to Perl, but there is no constructor or Xdestructor, meaning you cannot instantiate an C. X XThe C is a fully-bound class which can be created and Xmanipulated from Perl. X X use Inline CPP; X X my $plane = new Airplane; X $plane->print; X if ($plane->isa("Object")) { print "Plane is an Object!\n"; } X unless ($plane->can("fly")) { print "This plane sucks!\n"; } X X __END__ X __CPP__ X X /* Abstract class (interface) */ X class Object { X public: X virtual void print() { cout << "Object (" << this << ")" << endl; } X virtual void info() = 0; X virtual bool isa(char *klass) = 0; X virtual bool can(char *method) = 0; X }; X X class Airplane : public Object { X public: X Airplane() {} X ~Airplane() {} X X virtual void info() { print(); } X virtual bool isa(char *klass) { return strcmp(klass, "Object")==0; } X virtual bool can(char *method) { X bool yes = false; X yes |= strcmp(method, "print")==0; X yes |= strcmp(method, "info")==0; X yes |= strcmp(method, "isa")==0; X yes |= strcmp(method, "can")==0; X return yes; X } X }; X X=head2 Example 3 - The Ellipsis Abridged X XOne of the big advantages of Perl over C or C++ is the ability to pass an Xarbitrary number of arguments to a subroutine. You can do it in C, but it's Xmessy and difficult to get it right. All of this mess is necessary because XC doesn't give the programmer access to the stack. Perl, on the other hand, Xgives you access to everything. X XHere's a useful function written in Perl that is relatively slow: X X sub average { X my $average = 0; X for (my $i=0; $i<@_; $i++) { X $average *= $i; X $average += $_[$i]; X $average /= $i + 1; X } X return $average; X } X XHere's the same function written in C: X X double average() { X Inline_Stack_Vars; X double avg = 0.0; X for (int i=0; i C or C++ is faster than Perl. Well..., actually, Xthat wasn't really the point; that was an aside. Look at the function Xdeclaration: X X double avg(...) X XWhy didn't we need to use varargs macros to get at the arguments? Why didn't Xthe compiler complain that there were no required arguments? Because XInline::C++ actually compiled this: X X double avg( ) X XWhen it bound to the function, it noticed the ellipsis and decided to get rid Xof it. Any function bound to Perl that has an ellipsis in it will have its Xarguments passed via the Perl stack, not the C stack. That means if you write Xa function like this: X X void myprintf(char *format, ...); X Xthen you'd better be reading things from the Perl stack. If you aren't, then Xspecify the PRESERVE_ELLIPSIS option in your script. That will leave the Xellipsis in the code for the compiler to whine about. :) X X=head2 Example 4 - Stacks and Queues X XEveryone who learns C++ writes a stack and queue class sooner or Xlater. I might as well try it from Inline. But why reinvent the wheel? XPerl has a perfectly good Array type, which can easily implement both Xa Queue and a Stack. X XThis example implements a Queue and a Stack class, and shows off just Xa few more new features of Inline::CPP: default values to arguments, X X use Inline CPP; X X my $q = new Queue; X $q->q(50); X $q->q("Where am I?"); X $q->q("In a queue."); X print "There are ", $q->size, " items in the queue\n"; X while($q->size) { X print "About to dequeue: ", $q->peek, "\n"; X print "Actually dequeued: ", $q->dq, "\n"; X } X X my $s = new Stack; X $s->push(42); X $s->push("What?"); X print "There are ", $s->size, " items on the stack\n"; X while($s->size) { X print "About to pop: ", $s->peek, "\n"; X print "Actually popped: ", $s->pop, "\n"; X } X X __END__ X __CPP__ X X class Queue { X public: X Queue(int sz=0) { q = newAV(); if (sz) av_extend(q, sz-1); } X ~Queue() { av_undef(q); } X X int size() {return av_len(q) + 1; } X X int q(SV *item) { av_push(q, SvREFCNT_inc(item)); return av_len(q)+1; } X SV *dq() { return av_shift(q); } X SV *peek() { return size() ? SvREFCNT_inc(*av_fetch(q,0,0)): &PL_sv_undef;} X X private: X AV *q; X }; X X class Stack { X public: X Stack(int sz=0) { s = newAV(); if (sz) av_extend(s, sz-1); } X ~Stack() { av_undef(s); } X X int size() { return av_len(s) + 1; } X X int push(SV *i) { av_push(s, SvREFCNT_inc(i)); return av_len(s)+1; } X SV *pop() { return av_pop(s); } X SV *peek() { return size() ? SvREFCNT_inc(*av_fetch(s,size()-1,0)) : &PL_sv_undef; } X X private: X AV *s; X }; X X=head1 Grammar Details X XPerl 5.6.0 is recommended for Inline::CPP, and is required to get all the Xnew features. If you are using Perl 5.005_03 the package will build and run, Xbut you will have problems in certain circumstances: X X=head2 Inline function definitions X XFor the purposes of this discussion, inline function definitions are best Xdescribed by this example: X X class Foo { X public: X Foo() { /* Do something */ } X }; X XThis example shows a class with a constructor defined inline. Inline::CPP can Xparse this example with 5.005. But this example requires Perl 5.6.0: X X class Foo { X public: X Foo() { if(1) { /* Do something */ } } X }; X XHere's what happened: Inline::CPP saw a class, saw the method, then noticed Xit was an inline method. So it grabbed this text: X X "{ if(1) { /* Do something */ }" X XAnd then it tried to match another part of the class. But it failed because Xthe next part of the string is this (with newlines trimmed): X X "} };" X XThe remaining text doesn't parse right. There are two solutions: X X=over 4 X X=item a X XUse Perl version 5.6.0 or better; or, X X=item b X XMove the definition outside the class. X X=back X X=head2 Complex default parameters X XAgain, default parameters are best described by example: X X int root(double number, int whatroot=2); X XThis function takes one or two arguments. If the second is missing, C++ gives Xit the value 2. Inline::CPP can parse this simple example regardless of your Xperl version. But the following example requires 5.6.0: X X int root(double number, int whatroot=((2))); X XThat's because if you're using 5.005, your arguments are parsed with a regular Xexpression that looks for only one closing parenthesis. Any more than that, Xand you get a parse error. X XAgain, there are two solutions: X X=over 4 X X=item a X XUse Perl version 5.6.0 or better; or, X X=item b X XMake the strange expression a constant or macro and use that. X X=back X X=head2 Rant: Perl 5.005 is for Dummies X XI'm going to take the opportunity to rant. Everything in the rest of this Xsection can be ignored if you don't want to hear it. X XPerl 5.6.0 has been out for a long time. It's proven, stable, and people use Xit all the time. Perl 5.6.1 is the latest stable release. Unless you depend Xon one of the few modules which are only available for the ancient versions of XPerl, there is B not to upgrade today! X X=head1 SEE ALSO X XFor general information about how C binds code to Perl, see XL. X XFor information on using C with Perl, see L and XL. For C, see L, XL, L, and L. X XFor information on using C and C++ structs with Perl, see XL. X X=head1 BUGS AND DEFICIENCIES X XWhen reporting a bug, please do the following: X X - Put "use Inline REPORTBUG;" at the top of your code, or X use the command line option "perl -MInline=REPORTBUG ...". X - Run your code. X - Follow the printed instructions. X XHere are some things to watch out for: X X=over 4 X X=item 1 X XThe grammar used for parsing C++ is still quite simple, and does not allow Xseveral features of C++: X X=over 4 X X=item a X Xtemplates X X=item b X Xoperator overloading X X=item c X Xfunction overloading X X=back X XOther grammar problems will probably be noticed quickly. X X=item 2 X XIn order of relative importance, improvements planned in the near Xfuture are: X X=over 4 X X=item a X Xsupport for overloaded functions and methods X X=item b X Xbinding to constants and constant #defines X X=item c X Xbinding to unions X X=item d X Xautogenerated get/set methods on public members X X=back X X=back X X=head1 AUTHOR X XNeil Watkiss X XBrian Ingerson is the author of C, XC and C. He is known in the innermost Inline Xcircles as "Batman". ;) X X=head1 COPYRIGHT X XCopyright (c) 2000 - 2001, Neil Watkiss. X XAll Rights Reserved. This module is free software. It may be used, Xredistributed and/or modified under the same terms as Perl itself. X XSee http://www.perl.com/perl/misc/Artistic.html X X=cut END-of-p5-Inline-CPP/work/Inline-CPP-0.23/CPP.pod echo c - p5-Inline-CPP/work/Inline-CPP-0.23/grammar mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/grammar > /dev/null 2>&1 echo c - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t > /dev/null 2>&1 echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/02scope.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/02scope.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/02scope.t' Xuse Test; XBEGIN { plan tests => 2; } Xuse Inline CPP => <<'END'; X Xclass Foo { X void priv(int a) { q = a; } X int q; Xpublic: X Foo() {} X ~Foo() {} X void zippo(int quack) { printf("Hello, world!\n"); } X}; X XEND X Xok(1); XFoo->new->zippo(10); Xok(2); END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/02scope.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/16varlst.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/16varlst.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/16varlst.t' Xuse Test; X# Test declarations of multiple variables in a list XBEGIN { plan tests => 2 } Xuse Inline CPP => <<'END'; X X#define NUMBER 25 X#define FOO() 25 X Xclass Foo { X public: X Foo(double _o) : o(_o) {} X ~Foo() {} X int test() { return 10; } X private: X int a, b; X char *c, d; X char *e, *f; X char g, **h; X double i, j, *k, **m, n, &o; X X static const int aa = 10, X bb = FOO(), X cc = NUMBER, X dd = 1.25 X ; X}; X Xclass Bar { X public: X Bar() { } X ~Bar() { } X int test() { return -1; } X}; X XEND Xok(Foo->new(1.23)->test, 10); Xok(Bar->new->test, -1); END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/16varlst.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/01nherit.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/01nherit.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/01nherit.t' Xuse Test; XBEGIN { plan tests => 5 } X Xuse Inline CPP => <<'END'; X Xclass Foo { X public: X Foo() { X secret=0; X } X X ~Foo() { } X X int get_secret() { return secret; } X void set_secret(int s) { secret = s; } X X protected: X int secret; X}; X Xclass Bar : public Foo { X public: X Bar(int s) { secret = s; } X ~Bar() { } X X void set_secret(int s) { secret = s * 2; } X}; X XEND X X# If it works, it will print this. Otherwise it won't. Xok(1); X X# Test Foo Xmy $o = new Foo; Xok($o->get_secret(), 0); X$o->set_secret(539); Xok($o->get_secret(), 539); X X# Test Bar Xmy $p = new Bar(11); Xok($p->get_secret(), 11); X$p->set_secret(21); Xok($p->get_secret(), 42); X END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/01nherit.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/14const.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/14const.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/14const.t' Xuse Test; XBEGIN { plan tests => 1 } Xuse Inline CPP => <<'END'; Xclass Foo { X public: X Foo() {} X ~Foo() {} X char *data() const { return "Hello dolly!\n"; } X}; X XEND Xok(Foo->new->data, "Hello dolly!\n"); END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/14const.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/13vararg.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/13vararg.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/13vararg.t' Xuse Test; XBEGIN { plan tests => 6 } Xuse Inline CPP; X Xok(sum(), 0); Xok(sum(1), 1); Xok(sum(1, 2), 3); Xok(sum(1, 2, 3), 6); Xok(sum(1, 2, 3, 4), 10); Xok(sum(1, 2, 3, 4, 5), 15); X X__END__ X__CPP__ X Xint sum(...) { X Inline_Stack_Vars; X int s = 0; X for (int i=0; ip5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/12retlst.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/12retlst.t' Xuse Test; XBEGIN { plan tests => 3 } Xuse Inline CPP; Xuse Data::Dumper; X Xmy @list = return_list(); Xprint Dumper \@list; Xok($list[0], 1); Xok($list[1], 'Hello?'); Xok($list[2], 15.6); X Xprint Dumper return_void(); X X__END__ X__CPP__ X Xvoid return_list() { X Inline_Stack_Vars; X Inline_Stack_Reset; X Inline_Stack_Push(sv_2mortal(newSViv(1))); X Inline_Stack_Push(sv_2mortal(newSVpv("Hello?",0))); X Inline_Stack_Push(sv_2mortal(newSVnv(15.6))); X Inline_Stack_Done; X} X Xvoid return_void() { X printf("Hello!\n"); X} END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/12retlst.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/10struct.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/10struct.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/10struct.t' Xuse Test; XBEGIN { plan tests => 1 } Xuse Inline CPP => <<'END'; X Xstruct Fizzle { X int q; X double foozle; X int quack; X Fizzle(int Q=0, double Foozle=0, int Quack=0) { X q = Q; X foozle = Foozle; X quack = Quack; X } X int get_q() { return q; } X double get_foozle() { return foozle; } X int get_quack() { return quack; } X}; X XEND X Xmy $o = new Fizzle; Xok($o->get_q, 0); END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/10struct.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/08anon.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/08anon.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/08anon.t' Xuse Test; XBEGIN { plan tests => 1 } Xuse Inline CPP => <<'END'; X Xclass Foo { X public: X Foo(int, int); X}; X XFoo::Foo(int a, int b) { X X} X Xint add(int, int); Xint add(int a, int b) { return a + b; } X XEND X Xok(defined Foo->new(10, 11)); END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/08anon.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/06deflt.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/06deflt.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/06deflt.t' Xuse Test; XBEGIN { plan tests => 2 } Xuse Inline CPP => <<'END'; X Xint foo(int a=10) { return a; } Xdouble pi() { return 3.1415926; } X Xclass Freak { X public: X Freak() {} X ~Freak() {} X X int foo(int a=10, int b=13+4, double c=pi()) { return (a+b)/c; } X int foo2(int a, int b=15) { return a^b; } X int foo3(int a, int b, int c=0, int d=-5) { return 2*a - b + 2*c - d; } X int foo4(int a, char *b="hello") { return a + strlen(b); } X}; X XEND Xok(Freak->new->foo, 8); Xok(foo, 10); END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/06deflt.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/15stvar.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/15stvar.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/15stvar.t' Xuse Test; X# Test static variables XBEGIN { plan tests => 1 } Xuse Inline CPP => <<'END'; Xclass Foo { X public: X Foo() {} X ~Foo() {} X static int get_thing() { return s_thing; } X private: X static int s_thing; X}; X Xint Foo::s_thing = 10; X XEND Xok(Foo->new->get_thing, 10); END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/15stvar.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/11minhrt.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/11minhrt.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/11minhrt.t' Xuse Test; XBEGIN { plan tests => 3 } Xuse Inline CPP; X Xok(Parent1->new->do_something, 51); Xok(Parent2->new->do_another, 17); Xok(Child->new->yet_another, 3); X X__END__ X__CPP__ X Xclass Parent1 { X public: X Parent1() { } X ~Parent1() { } X X virtual int do_something() { return 51; } X}; X Xclass Parent2 { X public: X Parent2(); X ~Parent2(); X X virtual int do_another(); X}; X XParent2::Parent2() { } XParent2::~Parent2() { } Xint Parent2::do_another() { return 17; } X Xclass Child : public Parent1, public Parent2 { X public: X Child() { } X ~Child() { } X X int yet_another() { return 3; } X}; END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/11minhrt.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/07static.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/07static.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/07static.t' Xuse Test; XBEGIN { plan test => 1 } Xuse Inline CPP => <<'END'; Xclass Foo { X public: X Foo() {} X ~Foo() {} X static char *get_string() { return "Hello, world!\n"; } X}; XEND X Xok(Foo->get_string, "Hello, world!\n"); END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/07static.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/09purevt.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/09purevt.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/09purevt.t' Xuse Test; XBEGIN { plan tests => 2 } Xuse Inline CPP => <<'END'; X Xclass Abstract { X public: X virtual char *text() = 0; X virtual int greet(char *name) { X printf("Hello, %s\n", name); X return 17; X } X}; X Xclass Impl : public Abstract { X public: X Impl() {} X ~Impl() {} X virtual char *text() { return "Hello from Impl!"; } X}; X XEND X Xmy $o = new Impl; Xok($o->text, 'Hello from Impl!'); Xok($o->greet('Neil'), 17); END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/09purevt.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/03inline.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/03inline.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/03inline.t' Xuse Test; XBEGIN { plan tests => 2 } X Xuse Inline CPP; Xuse strict; X Xmy $obj = new Color; Xok(ref $obj, 'main::Color'); X X$obj->set_color(15); Xprint $obj->get_color, "\n"; X Xok($obj->get_color, 15); X X__END__ X__CPP__ Xvoid prn() { X printf("prn() called!\n"); X} X Xclass Color { X public: X Color() X { X printf("new Color object created...\n"); X } X X ~Color() X { X printf("Color object being destroyed...\n"); X } X X int get_color() X { X printf("Color::get_color called. Returning %i\n", color); X return color; X } X X void set_color(int a) X { X printf("Color::set_color(%i)\n", a); X color = a; X } X X private: X int color; X}; X X END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/03inline.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/05virt.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/05virt.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/05virt.t' Xuse Test; XBEGIN { plan tests => 1 } Xuse Inline CPP => <<'END'; Xclass Foo { X public: X Foo() { } X ~Foo() { } X X virtual const char *get_data_ro() { return "Hello Sally!\n"; } X}; XEND Xok(Foo->new->get_data_ro, "Hello Sally!\n"); END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/05virt.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/04const.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/04const.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/04const.t' Xuse Test; XBEGIN { plan tests => 1 } Xuse Inline CPP => <<'END'; Xclass Foo { X public: X Foo() {} X ~Foo() {} X const char *data() { return "Hello dolly!\n"; } X}; X XEND Xok(Foo->new->data, "Hello dolly!\n"); END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/04const.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/grammar.pm sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/grammar.pm << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/grammar.pm' Xpackage Inline::CPP::grammar; X Xuse strict; Xuse vars qw($TYPEMAP_KIND $VERSION); X$VERSION = '0.23'; X X#============================================================================ X# Regular expressions to match code blocks, numbers, strings, parenthesized X# expressions, function calls, and macros. The more complex regexes are only X# implemented in 5.6.0 and above, so they're in eval-blocks. X# X# These are all adapted from the output of Damian Conway's excellent X# Regexp::Common module. In future, Inline::CPP may depend directly on it, X# but for now I'll just duplicate the code. Xuse vars qw($code_block $string $number $parens $funccall); X#============================================================================ Xeval <<'END'; # $RE{balanced}{-parens=>q|{}()[]"'|} X$code_block = qr'(?-xism:(?-xism:(?:[{](?:(?>[^][)(}{]+)|(??{$Inline::CPP::grammar::code_block}))*[}]))|(?-xism:(?-xism:(?:[(](?:(?>[^][)(}{]+)|(??{$Inline::CPP::grammar::code_block}))*[)]))|(?-xism:(?-xism:(?:[[](?:(?>[^][)(}{]+)|(??{$Inline::CPP::grammar::code_block}))*[]]))|(?-xism:(?!)))))'; XEND X$code_block = qr'{[^}]*}' if $@; # For the stragglers: here's a lame regexp. X Xeval <<'END'; # $RE{balanced}{-parens=>q|()"'|} X$parens = qr'(?-xism:(?-xism:(?:[(](?:(?>[^)(]+)|(??{$Inline::CPP::grammar::parens}))*[)]))|(?-xism:(?!)))'; XEND X$parens = qr'\([^)]*\)' if $@; # For the stragglers: here's another X X# $RE{quoted} X$string = qr'(?:(?:\")(?:[^\\\"]*(?:\\.[^\\\"]*)*)(?:\")|(?:\')(?:[^\\\']*(?:\\.[^\\\']*)*)(?:\')|(?:\`)(?:[^\\\`]*(?:\\.[^\\\`]*)*)(?:\`))'; X X# $RE{num}{real}|$RE{num}{real}{-base=>16}|$RE{num}{int} X$number = qr'(?:(?i)(?:[+-]?)(?:(?=[0123456789]|[.])(?:[0123456789]*)(?:(?:[.])(?:[0123456789]{0,}))?)(?:(?:[E])(?:(?:[+-]?)(?:[0123456789]+))|))|(?:(?i)(?:[+-]?)(?:(?=[0123456789ABCDEF]|[.])(?:[0123456789ABCDEF]*)(?:(?:[.])(?:[0123456789ABCDEF]{0,}))?)(?:(?:[G])(?:(?:[+-]?)(?:[0123456789ABCDEF]+))|))|(?:(?:[+-]?)(?:\d+))'; X$funccall = qr/[_a-zA-Z][_a-zA-Z0-9]*(?:$Inline::CPP::grammar::parens)?/; X X#============================================================================ X# Inline::CPP's grammar X#============================================================================ Xsub grammar { X <<'END'; X X{ use Data::Dumper; } X Xcode: part(s) {1} X Xpart: comment X | class_def X { X# print "Found a class: $item[1]->[0]\n"; X my $class = $item[1]->[0]; X my @parts; X for my $part (@{$item[1]->[1]}) { push @parts, @$_ for @$part } X push @{$thisparser->{data}{classes}}, $class X unless defined $thisparser->{data}{class}{$class}; X $thisparser->{data}{class}{$class} = \@parts; X# print "Class:\n", Dumper \@parts; X Inline::CPP::grammar::typemap($thisparser, $class); X 1; X } X | function_def X { X# print "found a function: $item[1]->{name}\n"; X my $name = $item[1]->{name}; X my $i=0; X for my $arg (@{$item[1]->{args}}) { X $arg->{name} = 'dummy' . ++$i unless defined $arg->{name}; X } X Inline::CPP::grammar::strip_ellipsis($thisparser, X $item[1]->{args}); X push @{$thisparser->{data}{functions}}, $name X unless defined $thisparser->{data}{function}{$name}; X $thisparser->{data}{function}{$name} = $item[1]; X# print Dumper $item[1]; X 1; X } X | all X Xclass_def: class IDENTIFIER '{' class_part(s) '}' ';' X { X# print "Found a class definition: $item[2]\n"; X [@item[2,4]] X } X | class IDENTIFIER ':' '{' class_part(s) '}' ';' X { X# print "Found a class definition: $item[2]\n"; X push @{$item[6]}, [$item[4]]; X [@item[2,6]] X } X Xinherit: scope IDENTIFIER X { {thing => 'inherits', name => $item[2], scope => $item[1]} } X Xclass_part: comment { [ {thing => 'comment'} ] } X | scope ':' class_decl(s) X { X for my $part (@{$item[3]}) { X $_->{scope} = $item[1] for @$part; X } X $item[3] X } X | class_decl(s) X { X for my $part (@{$item[1]}) { X $_->{scope} = $thisparser->{data}{defaultscope} X for @$part; X } X $item[1] X } X Xclass_decl: comment { [{thing => 'comment'}] } X | method_def X { X $item[1]->{thing} = 'method'; X# print "class_decl found a method: $item[1]->{name}\n"; X my $i=0; X for my $arg (@{$item[1]->{args}}) { X $arg->{name} = 'dummy' . ++$i unless defined $arg->{name}; X } X Inline::CPP::grammar::strip_ellipsis($thisparser, X $item[1]->{args}); X [$item[1]]; X } X | member_def X { X# print "class_decl found one or more members:\n", Dumper(\@item); X $_->{thing} = 'member' for @{$item[1]}; X $item[1]; X } X Xfunction_def: rtype IDENTIFIER '(' (s?) ')' ';' X { X {rtype => $item[1], name => $item[2], args => $item[4]} X } X | rtype IDENTIFIER '(' (s?) ')' code_block X { X {rtype => $item[1], name => $item[2], args => $item[4]} X } X Xmethod_def: IDENTIFIER '(' (s?) ')' method_imp X { X# print "con-/de-structor found: $item[1]\n"; X {name => $item[1], args => $item[3], abstract => ${$item[5]}}; X } X | rtype IDENTIFIER '(' (s?) ')' method_imp X { X# print "method found: $item[2]\n"; X $return = X {name => $item[2], rtype => $item[1], args => $item[4], X abstract => ${$item[6]}, X rconst => $thisparser->{data}{smod}{const}, X }; X $thisparser->{data}{smod}{const} = 0; X } X X# By adding smod, we allow 'const' member functions. This would also bind to X# incorrect C++ with the word 'static' after the argument list, but we don't X# care at all because such code would never be compiled successfully. X X# By adding init, we allow constructors to initialize references. Again, we'll X# allow them anywhere, but our goal is not to enforce c++ standards -- that's X# the compiler's job. Xmethod_imp: smod(?) ';' { \0 } X | smod(?) initlist(?) code_block { \0 } X | smod(?) '=' '0' ';' { \1 } X | smod(?) '=' '0' code_block { \0 } X Xinitlist: ':' X Xmember_def: anytype ';' X { X my @retval; X for my $def (@{$item[2]}) { X my $type = join '', $item[1], @{$def->[0]}; X my $name = $def->[1]; X# print "member found: type=$type, name=$name\n"; X push @retval, { name => $name, type => $type }; X } X \@retval; X } X Xvar: star(s?) IDENTIFIER '=' expr { [@item[1,2]] } X | star(s?) IDENTIFIER { [@item[1,2]] } X Xarg: type IDENTIFIER '=' expr X { X# print "argument $item[2] found\n"; X# print "expression: $item[4]\n"; X {type => $item[1], name => $item[2], optional => 1, X offset => $thisoffset} X } X | type IDENTIFIER X { X# print "argument $item[2] found\n"; X {type => $item[1], name => $item[2], offset => $thisoffset} X } X | type { {type => $item[1]} } X | '...' X { {name => '...', type => '...', offset => $thisoffset} } X XIDENTIFIER: /[~_a-z]\w*/i X { X# print "IDENTIFIER: $item[1]\n"; X $item[1] X } X X# Parse::RecDescent is retarded in this one case: if a subrule fails, it X# gives up the entire rule. This is a stupid way to get around that. Xrtype: rtype2 | rtype1 Xrtype1: TYPE star(s?) X { X $return = $item[1]; X $return .= join '',' ',@{$item[2]} if @{$item[2]}; X# print "rtype1: $return\n"; X return undef X unless(defined$thisparser->{data}{typeconv}{valid_rtypes}{$return}); X } Xrtype2: modifier(s) TYPE star(s?) X { X $return = $item[2]; X $return = join ' ',grep{$_}@{$item[1]},$return X if @{$item[1]}; X $return .= join '',' ',@{$item[3]} if @{$item[3]}; X# print "rtype2: $return\n"; X return undef X unless(defined$thisparser->{data}{typeconv}{valid_rtypes}{$return}); X $return = 'static ' . $return X if $thisparser->{data}{smod}{static}; X $thisparser->{data}{smod}{static} = 0; X } X Xtype: type2 | type1 Xtype1: TYPE star(s?) X { X $return = $item[1]; X $return .= join '',' ',@{$item[2]} if @{$item[2]}; X return undef X unless(defined$thisparser->{data}{typeconv}{valid_types}{$return}); X } Xtype2: modifier(s) TYPE star(s?) X { X $return = $item[2]; X $return = join ' ',grep{$_}@{$item[1]},$return if @{$item[1]}; X $return .= join '',' ',@{$item[3]} if @{$item[3]}; X return undef X unless(defined$thisparser->{data}{typeconv}{valid_types}{$return}); X } X Xanytype: anytype2 | anytype1 Xanytype1: TYPE star(s?) X { X $return = $item[1]; X $return .= join '',' ',@{$item[2]} if @{$item[2]}; X } Xanytype2: modifier(s) TYPE star(s?) X { X $return = $item[2]; X $return = join ' ',grep{$_}@{$item[1]},$return if @{$item[1]}; X $return .= join '',' ',@{$item[3]} if @{$item[3]}; X } X Xcomment: m{\s* // [^\n]* \n }x X | m{\s* /\* (?:[^*]+|\*(?!/))* \*/ ([ \t]*)? }x X X# long and short aren't recognized as modifiers because they break when used X# as regular types. Another Parse::RecDescent problem is greedy matching; I X# need tmodifier to "give back" long or short in cases where keeping them would X# cause the modifier rule to fail. One side-effect is 'long long' can never X# be parsed correctly here. Xmodifier: tmod X | smod { ++$thisparser->{data}{smod}{$item[1]}; ''} X | nmod { '' } Xtmod: 'unsigned' # | 'long' | 'short' Xsmod: 'const' | 'static' Xnmod: 'extern' | 'virtual' | 'mutable' | 'volatile' | 'inline' X Xscope: 'public' | 'private' | 'protected' X Xclass: 'class' { $thisparser->{data}{defaultscope} = 'private'; $item[1] } X | 'struct' { $thisparser->{data}{defaultscope} = 'public'; $item[1] } X Xstar: '*' | '&' X Xcode_block: /$Inline::CPP::grammar::code_block/ X X# Consume expressions Xexpr: { X my $o = join '', @{$item[1]}; X# print "expr: $o\n"; X $o; X} Xsubexpr: /$Inline::CPP::grammar::funccall/ # Matches a macro, too X | /$Inline::CPP::grammar::string/ X | /$Inline::CPP::grammar::number/ X | UOP subexpr XOP: '+' | '-' | '*' | '/' | '^' | '&' | '|' | '%' | '||' | '&&' XUOP: '~' | '!' | '-' | '*' | '&' X XTYPE: /\w+/ X Xall: /.*/ X XEND X X} X X#============================================================================ X# Generate typemap code for the classes and structs we bind to. This allows X# functions declared after a class to return or accept class objects as X# parameters. X#============================================================================ X$TYPEMAP_KIND = 'O_Inline_CPP_Class'; Xsub typemap { X my $parser = shift; X my $typename = shift; X X# print "Inline::CPP::grammar::typemap(): typename=$typename\n"; X X my ($TYPEMAP, $INPUT, $OUTPUT); X $TYPEMAP = "$typename *\t\t$TYPEMAP_KIND\n"; X $INPUT = <{data}{typeconv}{input_expr}{$TYPEMAP_KIND} ||= $INPUT; X $parser->{data}{typeconv}{output_expr}{$TYPEMAP_KIND} ||= $OUTPUT; X $parser->{data}{typeconv}{type_kind}{$ctypename} = $TYPEMAP_KIND; X $parser->{data}{typeconv}{valid_types}{$ctypename}++; X $parser->{data}{typeconv}{valid_rtypes}{$ctypename}++; X} X X#============================================================================ X# Default action is to strip ellipses from the C++ code. This allows having X# _only_ a '...' in the code, just like XS. It is the default. X#============================================================================ Xsub strip_ellipsis { X my $parser = shift; X my $args = shift; X return if $parser->{ILSM}{PRESERVE_ELLIPSIS}; X for (my $i=0; $i<@$args; $i++) { X next unless $args->[$i]{name} eq '...'; X # if it's the first one, just strip it X if ($i==0) { X substr($parser->{ILSM}{code}, $args->[$i]{offset} - 3, 3) = " "; X } X else { X my $prev = $i - 1; X my $prev_offset = $args->[$prev]{offset}; X my $length = $args->[$i]{offset} - $prev_offset; X substr($parser->{ILSM}{code}, $prev_offset, $length) =~ s/\S/ /g; X } X } X} END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/grammar.pm echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/Makefile.PL sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/Makefile.PL << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/Makefile.PL' Xuse ExtUtils::MakeMaker; XWriteMakefile( X NAME => 'Inline::CPP::grammar', X VERSION_FROM => 'grammar.pm', X ); END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/Makefile.PL echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/pm_to_blib sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/pm_to_blib << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/pm_to_blib' END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/pm_to_blib echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/Makefile sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/grammar/Makefile << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/Makefile' X# This Makefile is for the Inline::CPP::grammar extension to perl. X# X# It was generated automatically by MakeMaker version X# 5.4302 (Revision: 1.222) from the contents of X# Makefile.PL. Don't edit this file, edit Makefile.PL instead. X# X# ANY CHANGES MADE HERE WILL BE LOST! X# X# MakeMaker ARGV: (q[CC=cc], q[CCFLAGS=-O -pipe ], q[PREFIX=/usr/local]) X# X# MakeMaker Parameters: X X# NAME => q[Inline::CPP::grammar] X# VERSION_FROM => q[grammar.pm] X X# --- MakeMaker post_initialize section: X X X# --- MakeMaker const_config section: X X# These definitions are from config.sh (via /usr/libdata/perl/5.00503/mach/Config.pm) X X# They may have been overridden via Makefile.PL or on the command line XAR = ar XCC = cc XCCCDLFLAGS = -DPIC -fpic XCCDLFLAGS = -Wl,-R/usr/lib XDLEXT = so XDLSRC = dl_dlopen.xs XLD = cc XLDDLFLAGS = -Wl,-E -shared -lperl -lm XLDFLAGS = -Wl,-E -lperl -lm XLIBC = XLIB_EXT = .a XOBJ_EXT = .o XOSNAME = freebsd XOSVERS = 4.0-current XRANLIB = : XSO = so XEXE_EXT = X X X# --- MakeMaker constants section: XAR_STATIC_ARGS = cr XNAME = Inline::CPP::grammar XDISTNAME = Inline-CPP-grammar XNAME_SYM = Inline_CPP_grammar XVERSION = 0.23 XVERSION_SYM = 0_23 XXS_VERSION = 0.23 XINST_BIN = ../blib/bin XINST_EXE = ../blib/script XINST_LIB = ../blib/lib XINST_ARCHLIB = ../blib/arch XINST_SCRIPT = ../blib/script XPREFIX = /usr XINSTALLDIRS = site XINSTALLPRIVLIB = /usr/libdata/perl/5.00503 XINSTALLARCHLIB = /usr/libdata/perl/5.00503/mach XINSTALLSITELIB = /usr/local/lib/perl5/site_perl/5.005 XINSTALLSITEARCH = /usr/local/lib/perl5/site_perl/5.005/i386-freebsd XINSTALLBIN = $(PREFIX)/bin XINSTALLSCRIPT = $(PREFIX)/bin XPERL_LIB = /usr/libdata/perl/5.00503 XPERL_ARCHLIB = /usr/libdata/perl/5.00503/mach XSITELIBEXP = /usr/local/lib/perl5/site_perl/5.005 XSITEARCHEXP = /usr/local/lib/perl5/site_perl/5.005/i386-freebsd XLIBPERL_A = libperl.a XFIRST_MAKEFILE = Makefile XMAKE_APERL_FILE = Makefile.aperl XPERLMAINCC = $(CC) XPERL_INC = /usr/libdata/perl/5.00503/mach/CORE XPERL = /usr/bin/perl5.00503 XFULLPERL = /usr/bin/perl5.00503 X XVERSION_MACRO = VERSION XDEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\" XXS_VERSION_MACRO = XS_VERSION XXS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\" X XMAKEMAKER = /usr/libdata/perl/5.00503/ExtUtils/MakeMaker.pm XMM_VERSION = 5.4302 X X# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle). X# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle) X# ROOTEXT = Directory part of FULLEXT with leading slash (eg /DBD) !!! Deprecated from MM 5.32 !!! X# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar) X# DLBASE = Basename part of dynamic library. May be just equal BASEEXT. XFULLEXT = Inline/CPP/grammar XBASEEXT = grammar XPARENT_NAME = Inline::CPP XDLBASE = $(BASEEXT) XVERSION_FROM = grammar.pm XOBJECT = XLDFROM = $(OBJECT) XLINKTYPE = dynamic X X# Handy lists of source code files: XXS_FILES= XC_FILES = XO_FILES = XH_FILES = XMAN1PODS = XMAN3PODS = XINST_MAN1DIR = ../blib/man1 XINSTALLMAN1DIR = /usr/local/man/man1 XMAN1EXT = 1 XINST_MAN3DIR = ../blib/man3 XINSTALLMAN3DIR = /usr/local/lib/perl5/5.00503/man/man3 XMAN3EXT = 3 XPERM_RW = 644 XPERM_RWX = 755 X X# work around a famous dec-osf make(1) feature(?): Xmakemakerdflt: all X X.SUFFIXES: .xs .c .C .cpp .cxx .cc $(OBJ_EXT) X X# Nick wanted to get rid of .PRECIOUS. I don't remember why. I seem to recall, that X# some make implementations will delete the Makefile when we rebuild it. Because X# we call false(1) when we rebuild it. So make(1) is not completely wrong when it X# does so. Our milage may vary. X# .PRECIOUS: Makefile # seems to be not necessary anymore X X.PHONY: all config static dynamic test linkext manifest X X# Where is the Config information that we are using/depend on XCONFIGDEP = $(PERL_ARCHLIB)/Config.pm $(PERL_INC)/config.h X X# Where to put things: XINST_LIBDIR = $(INST_LIB)/Inline/CPP XINST_ARCHLIBDIR = $(INST_ARCHLIB)/Inline/CPP X XINST_AUTODIR = $(INST_LIB)/auto/$(FULLEXT) XINST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT) X XINST_STATIC = XINST_DYNAMIC = XINST_BOOT = X XEXPORT_LIST = X XPERL_ARCHIVE = X XTO_INST_PM = grammar.pm X XPM_TO_BLIB = grammar.pm \ X $(INST_LIBDIR)/grammar.pm X X X# --- MakeMaker tool_autosplit section: X X# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto XAUTOSPLITFILE = $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e 'use AutoSplit;autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1) ;' X X X# --- MakeMaker tool_xsubpp section: X X X# --- MakeMaker tools_other section: X XSHELL = /bin/sh XCHMOD = chmod XCP = cp XLD = cc XMV = mv XNOOP = $(SHELL) -c true XRM_F = rm -f XRM_RF = rm -rf XTEST_F = test -f XTOUCH = touch XUMASK_NULL = umask 0 XDEV_NULL = > /dev/null 2>&1 X X# The following is a portable way to say mkdir -p X# To see which directories are created, change the if 0 to if 1 XMKPATH = $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Command -e mkpath X X# This helps us to minimize the effect of the .exists files A yet X# better solution would be to have a stable file in the perl X# distribution with a timestamp of zero. But this solution doesn't X# need any changes to the core distribution and works with older perls XEQUALIZE_TIMESTAMP = $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Command -e eqtime X X X# --- MakeMaker dist section skipped. X X# --- MakeMaker macro section: X X X# --- MakeMaker depend section: X X X# --- MakeMaker cflags section: X X X# --- MakeMaker const_loadlibs section: X X X# --- MakeMaker const_cccmd section: X X X# --- MakeMaker post_constants section: X X X# --- MakeMaker pasthru section: X XPASTHRU = LIB="$(LIB)"\ X LIBPERL_A="$(LIBPERL_A)"\ X LINKTYPE="$(LINKTYPE)"\ X PREFIX="$(PREFIX)"\ X OPTIMIZE="$(OPTIMIZE)" X X X# --- MakeMaker c_o section: X X X# --- MakeMaker xs_c section: X X X# --- MakeMaker xs_o section: X X X# --- MakeMaker top_targets section: X X#all :: config $(INST_PM) subdirs linkext manifypods X Xall :: pure_all manifypods X @$(NOOP) X Xpure_all :: config pm_to_blib subdirs linkext X @$(NOOP) X Xsubdirs :: $(MYEXTLIB) X @$(NOOP) X Xconfig :: Makefile $(INST_LIBDIR)/.exists X @$(NOOP) X Xconfig :: $(INST_ARCHAUTODIR)/.exists X @$(NOOP) X Xconfig :: $(INST_AUTODIR)/.exists X @$(NOOP) X X$(INST_AUTODIR)/.exists :: /usr/libdata/perl/5.00503/mach/CORE/perl.h X @$(MKPATH) $(INST_AUTODIR) X @$(EQUALIZE_TIMESTAMP) /usr/libdata/perl/5.00503/mach/CORE/perl.h $(INST_AUTODIR)/.exists X X -@$(CHMOD) $(PERM_RWX) $(INST_AUTODIR) X X$(INST_LIBDIR)/.exists :: /usr/libdata/perl/5.00503/mach/CORE/perl.h X @$(MKPATH) $(INST_LIBDIR) X @$(EQUALIZE_TIMESTAMP) /usr/libdata/perl/5.00503/mach/CORE/perl.h $(INST_LIBDIR)/.exists X X -@$(CHMOD) $(PERM_RWX) $(INST_LIBDIR) X X$(INST_ARCHAUTODIR)/.exists :: /usr/libdata/perl/5.00503/mach/CORE/perl.h X @$(MKPATH) $(INST_ARCHAUTODIR) X @$(EQUALIZE_TIMESTAMP) /usr/libdata/perl/5.00503/mach/CORE/perl.h $(INST_ARCHAUTODIR)/.exists X X -@$(CHMOD) $(PERM_RWX) $(INST_ARCHAUTODIR) X Xhelp: X perldoc ExtUtils::MakeMaker X XVersion_check: X @$(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) \ X -MExtUtils::MakeMaker=Version_check \ X -e "Version_check('$(MM_VERSION)')" X X X# --- MakeMaker linkext section: X Xlinkext :: $(LINKTYPE) X @$(NOOP) X X X# --- MakeMaker dlsyms section: X X X# --- MakeMaker dynamic section: X X## $(INST_PM) has been moved to the all: target. X## It remains here for awhile to allow for old usage: "make dynamic" X#dynamic :: Makefile $(INST_DYNAMIC) $(INST_BOOT) $(INST_PM) Xdynamic :: Makefile $(INST_DYNAMIC) $(INST_BOOT) X @$(NOOP) X X X# --- MakeMaker dynamic_bs section: X XBOOTSTRAP = X X X# --- MakeMaker dynamic_lib section: X X X# --- MakeMaker static section: X X## $(INST_PM) has been moved to the all: target. X## It remains here for awhile to allow for old usage: "make static" X#static :: Makefile $(INST_STATIC) $(INST_PM) Xstatic :: Makefile $(INST_STATIC) X @$(NOOP) X X X# --- MakeMaker static_lib section: X X X# --- MakeMaker manifypods section: X Xmanifypods : pure_all X @$(NOOP) X X X# --- MakeMaker processPL section: X X X# --- MakeMaker installbin section: X X X# --- MakeMaker subdirs section: X X# none X X# --- MakeMaker clean section: X X# Delete temporary files but do not touch installed files. We don't delete X# the Makefile here so a later make realclean still has a makefile to use. X Xclean :: X -rm -rf ./blib $(MAKE_APERL_FILE) $(INST_ARCHAUTODIR)/extralibs.all perlmain.c mon.out core so_locations pm_to_blib *~ */*~ */*/*~ *$(OBJ_EXT) *$(LIB_EXT) perl.exe $(BOOTSTRAP) $(BASEEXT).bso $(BASEEXT).def $(BASEEXT).exp X -mv Makefile Makefile.old $(DEV_NULL) X X X# --- MakeMaker realclean section: X X# Delete temporary files (via clean) and also delete installed files Xrealclean purge :: clean X rm -rf $(INST_AUTODIR) $(INST_ARCHAUTODIR) X rm -f $(INST_LIBDIR)/grammar.pm X rm -rf Makefile Makefile.old X X X# --- MakeMaker dist_basics section skipped. X X# --- MakeMaker dist_core section skipped. X X# --- MakeMaker dist_dir section skipped. X X# --- MakeMaker dist_test section skipped. X X# --- MakeMaker dist_ci section skipped. X X# --- MakeMaker install section skipped. X X# --- MakeMaker force section: X# Phony target to force checking subdirectories. XFORCE: X @$(NOOP) X X X# --- MakeMaker perldepend section: X X X# --- MakeMaker makefile section: X X# We take a very conservative approach here, but it\'s worth it. X# We move Makefile to Makefile.old here to avoid gnu make looping. XMakefile : Makefile.PL $(CONFIGDEP) X @echo "Makefile out-of-date with respect to $?" X @echo "Cleaning current config before rebuilding Makefile..." X -@$(RM_F) Makefile.old X -@$(MV) Makefile Makefile.old X -$(MAKE) -f Makefile.old clean $(DEV_NULL) || $(NOOP) X $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL "CC=cc" "CCFLAGS=-O -pipe " "PREFIX=/usr/local" X @echo "==> Your Makefile has been rebuilt. <==" X @echo "==> Please rerun the make command. <==" X false X X# To change behavior to :: would be nice, but would break Tk b9.02 X# so you find such a warning below the dist target. X#Makefile :: $(VERSION_FROM) X# @echo "Warning: Makefile possibly out of date with $(VERSION_FROM)" X X X# --- MakeMaker staticmake section: X X# --- MakeMaker makeaperl section --- XMAP_TARGET = ../perl XFULLPERL = /usr/bin/perl5.00503 X X X# --- MakeMaker test section: X XTEST_VERBOSE=0 XTEST_TYPE=test_$(LINKTYPE) XTEST_FILE = test.pl XTEST_FILES = t/*.t XTESTDB_SW = -d X Xtestdb :: testdb_$(LINKTYPE) X Xtest :: $(TEST_TYPE) X Xtest_dynamic :: pure_all X PERL_DL_NONLAZY=1 $(FULLPERL) -I$(INST_ARCHLIB) -I$(INST_LIB) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -e 'use Test::Harness qw(&runtests $$verbose); $$verbose=$(TEST_VERBOSE); runtests @ARGV;' $(TEST_FILES) X Xtestdb_dynamic :: pure_all X PERL_DL_NONLAZY=1 $(FULLPERL) $(TESTDB_SW) -I$(INST_ARCHLIB) -I$(INST_LIB) -I$(PERL_ARCHLIB) -I$(PERL_LIB) $(TEST_FILE) X Xtest_ : test_dynamic X Xtest_static :: test_dynamic Xtestdb_static :: testdb_dynamic X X X# --- MakeMaker ppd section: X# Creates a PPD (Perl Package Description) for a binary distribution. Xppd: X @$(PERL) -e "print qq{\n}. qq{\tInline-CPP-grammar\n}. qq{\t\n}. qq{\t\n}. qq{\t\n}. qq{\t\t\n}. qq{\t\t\n}. qq{\t\t\n}. qq{\t\n}. qq{\n}" > Inline-CPP-grammar.ppd X X# --- MakeMaker pm_to_blib section: X Xpm_to_blib: $(TO_INST_PM) X @$(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" \ X "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -MExtUtils::Install \ X -e "pm_to_blib({qw{$(PM_TO_BLIB)}},'$(INST_LIB)/auto')" X @$(TOUCH) $@ X X X# --- MakeMaker selfdocument section: X X X# --- MakeMaker postamble section: X X X# End. END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/Makefile echo x - p5-Inline-CPP/work/Inline-CPP-0.23/MANIFEST sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/MANIFEST << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/MANIFEST' XChanges XCPP.pm XCPP.pod XMANIFEST XMakefile.PL XREADME XTESTED Xgrammar/grammar.pm Xgrammar/Makefile.PL Xgrammar/t/01nherit.t Xgrammar/t/02scope.t Xgrammar/t/03inline.t Xgrammar/t/04const.t Xgrammar/t/05virt.t Xgrammar/t/06deflt.t Xgrammar/t/07static.t Xgrammar/t/08anon.t Xgrammar/t/09purevt.t Xgrammar/t/10struct.t Xgrammar/t/11minhrt.t Xgrammar/t/12retlst.t Xgrammar/t/13vararg.t Xgrammar/t/14const.t Xgrammar/t/15stvar.t Xgrammar/t/16varlst.t Xt/01basic.t Xt/02prefix.t END-of-p5-Inline-CPP/work/Inline-CPP-0.23/MANIFEST echo x - p5-Inline-CPP/work/Inline-CPP-0.23/CPP.pm sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/CPP.pm << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/CPP.pm' Xpackage Inline::CPP; X Xuse strict; Xrequire Inline::C; Xrequire Inline::CPP::grammar; Xuse Carp; X Xuse vars qw(@ISA $VERSION); X X@ISA = qw(Inline::C); X$VERSION = "0.23"; Xmy $TYPEMAP_KIND = $Inline::CPP::grammar::TYPEMAP_KIND; X X#============================================================================ X# Register Inline::CPP as an Inline language module X#============================================================================ Xsub register { X use Config; X return { X language => 'CPP', X aliases => ['cpp', 'C++', 'c++', 'Cplusplus', 'cplusplus'], X type => 'compiled', X suffix => $Config{dlext}, X }; X} X X#============================================================================ X# Validate the C++ config options: Now mostly done in Inline::C X#============================================================================ Xsub validate { X my $o = shift; X $o->{ILSM}{MAKEFILE}{CC} ||= 'g++'; # default compiler X $o->{ILSM}{MAKEFILE}{LIBS} ||= ['-lstdc++']; # default libs X X # I haven't traced it out yet, but $o->{STRUCT} gets set before getting X # properly set from Inline::C's validate(). X $o->{STRUCT} ||= { X '.macros' => '', X '.xs' => '', X '.any' => 0, X '.all' => 0, X }; X $o->{ILSM}{AUTO_INCLUDE} ||= < X#endif X#ifdef __CYGWIN__ Xextern "C" { X#endif X#include "EXTERN.h" X#include "perl.h" X#include "XSUB.h" X#include "INLINE.h" X#ifdef __CYGWIN__ X} X#endif X#ifdef bool X#undef bool X#include <%iostream%> X#endif XEND X $o->{ILSM}{PRESERVE_ELLIPSIS} = 0 X unless defined $o->{ILSM}{PRESERVE_ELLIPSIS}; X X # Filter out the parameters we treat differently than Inline::C X my @propagate; X while(@_) { X my ($key, $value) = (shift, shift); X if ($key eq 'LIBS') { X $value = [$value] unless ref $value eq 'ARRAY'; X my $num = scalar @{$o->{ILSM}{MAKEFILE}{LIBS}} - 1; X $o->{ILSM}{MAKEFILE}{LIBS}[$num] .= ' ' . $_ X for (@$value); X next; X } X if ($key eq 'ALTLIBS') { X $value = [$value] unless ref $value eq 'ARRAY'; X push @{$o->{ILSM}{MAKEFILE}{LIBS}}, ''; X my $num = scalar @{$o->{ILSM}{MAKEFILE}{LIBS}} - 1; X $o->{ILSM}{MAKEFILE}{LIBS}[$num] .= ' ' . $_ X for (@$value); X next; X } X if ($key eq 'PRESERVE_ELLIPSIS' or X $key eq 'STD_IOSTREAM') { X croak "Argument to $key must be 0 or 1" X unless $value == 0 or $value == 1; X $o->{ILSM}{$key} = $value; X next; X } X push @propagate, $key, $value; X } X X # Replace %iostream% with the correct iostream library X my $iostream = "iostream"; X $iostream .= ".h" unless (defined $o->{ILSM}{STD_IOSTREAM} and X $o->{ILSM}{STD_IOSTREAM}); X $o->{ILSM}{AUTO_INCLUDE} =~ s|%iostream%|$iostream|g; X X # Forward all unknown requests up to Inline::C X $o->SUPER::validate(@propagate) if @propagate; X} X X#============================================================================ X# Print a small report if PRINT_INFO option is set X#============================================================================ Xsub info { X my $o = shift; X my $info = ""; X X $o->parse unless $o->{ILSM}{parser}; X my $data = $o->{ILSM}{parser}{data}; X X if (defined $o->{ILSM}{parser}{data}{classes}) { X $info .= "The following C++ classes have been bound to Perl:\n"; X for my $class (sort @{$data->{classes}}) { X my @parents = grep { $_->{thing} eq 'inherits' } X @{$data->{class}{$class}}; X $info .= "\tclass $class"; X $info .= (" : " X . join (', ', X map { $_->{scope} . " " . $_->{name} } @parents) X ) if @parents; X $info .= " {\n"; X for my $thing (sort { $a->{name} cmp $b->{name} } X @{$data->{class}{$class}}) { X my ($name, $scope, $type) = @{$thing}{qw(name scope thing)}; X next unless $scope eq 'public' and $type eq 'method'; X my $rtype = $thing->{rtype} || ""; X $info .= "\t\t$rtype" . ($rtype ? " " : ""); X $info .= $class . "::$name("; X my @args = grep { $_->{name} ne '...' } @{$thing->{args}}; X my $ellipsis = (scalar @{$thing->{args}} - scalar @args) != 0; X $info .= join ', ', (map "$_->{type} $_->{name}", @args), X $ellipsis ? "..." : (); X $info .= ");\n"; X } X $info .= "\t};\n" X } X $info .= "\n"; X } X else { X $info .= "No C++ classes have been successfully bound to Perl.\n\n"; X } X if (defined $o->{ILSM}{parser}{data}{functions}) { X $info .= "The following C++ functions have been bound to Perl:\n"; X for my $function (sort @{$data->{functions}}) { X my $func = $data->{function}{$function}; X $info .= "\t" . $func->{rtype} . " "; X $info .= $func->{name} . "("; X my @args = grep { $_->{name} ne '...' } @{$func->{args}}; X my $ellipsis = (scalar @{$func->{args}} - scalar @args) != 0; X $info .= join ', ', (map "$_->{type} $_->{name}", @args), X $ellipsis ? "..." : (); X $info .= ");\n"; X } X $info .= "\n"; X } X else { X $info .= "No C++ functions have been bound to Perl.\n\n"; X } X $info .= Inline::Struct::info($o) if $o->{STRUCT}{'.any'}; X return $info; X} X X#============================================================================ X# Generate a C++ parser X#============================================================================ Xsub get_parser { X my $o = shift; X my $grammar = Inline::CPP::grammar::grammar() X or croak "Can't find C++ grammar\n"; X $::RD_HINT++; X require Parse::RecDescent; X my $parser = Parse::RecDescent->new($grammar); X $parser->{data}{typeconv} = $o->{ILSM}{typeconv}; X $parser->{ILSM} = $o->{ILSM}; # give parser access to config options X return $parser; X} X X#============================================================================ X# Intercept xs_generate and create the typemap file X#============================================================================ Xsub xs_generate { X my $o = shift; X $o->write_typemap; X $o->SUPER::xs_generate; X} X X#============================================================================ X# Return bindings for functions and classes X#============================================================================ Xsub xs_bindings { X my $o = shift; X my ($pkg, $module) = @{$o->{API}}{qw(pkg module modfname)}; X my $data = $o->{ILSM}{parser}{data}; X my $XS = ''; X X warn("Warning: No Inline C++ functions or classes bound to Perl\n" . X "Check your C++ for Inline compatibility.\n\n") X if ((not defined $data->{classes}) X and (not defined $data->{functions}) X and ($^W)); X X for my $class (@{$data->{classes}}) { X my $proper_pkg = $pkg . "::$class"; X # Set up the proper namespace X $XS .= <{class}{$class}}) { X my ($name, $scope, $type) = @{$thing}{qw|name scope thing|}; X X # Let Perl handle inheritance X if ($type eq 'inherits' and $scope eq 'public') { X $o->{ILSM}{XS}{BOOT} ||= ''; X my $ISA_name = "${pkg}::${class}::ISA"; X my $parent = "${pkg}::${name}"; X $o->{ILSM}{XS}{BOOT} .= <{abstract}); X next if ($type eq 'method' and $thing->{abstract}); X next unless ($scope eq 'public' and $type eq 'method'); X X # generate an XS wrapper X $ctor ||= ($name eq $class); X $dtor ||= ($name eq "~$class"); X $XS .= $o->wrap($thing, $name, $class); X } X X # Provide default constructor and destructor: X $XS .= <{ILSM}{XS}{PREFIX}) ? X "PREFIX = $o->{ILSM}{XS}{PREFIX}" : X ''); X $XS .= <{functions}}) { X next if $data->{function}{$function}{rtype} =~ 'static'; # special case X $XS .= $o->wrap($data->{function}{$function}, $function); X } X X return $XS; X} X X#============================================================================ X# Generate an XS wrapper around anything: a C++ method or function X#============================================================================ Xsub wrap { X my $o = shift; X my $thing = shift; X my $name = shift; X my $class = shift || ""; X X my ($XS, $PREINIT, $CODE) = ("", "", ""); X my ($ctor, $dtor) = (0, 0); X X if ($name eq $class) { # ctor X $XS .= $class . " *\n" . $class . "::new"; X $ctor = 1; X } X elsif ($name eq "~$class") { # dtor X $XS .= "void\n$class" . "::DESTROY"; X $dtor = 1; X } X elsif ($class) { # method X $XS .= "$thing->{rtype}\n$class" . "::$thing->{name}"; X } X else { # function X $XS .= "$thing->{rtype}\n$thing->{name}"; X } X X # Filter out optional subroutine arguments X my (@args, @opts, $ellipsis, $void); X $_->{optional} ? push@opts,$_ : push@args,$_ for @{$thing->{args}}; X $ellipsis = pop @args if (@args and $args[-1]->{name} eq '...'); X $void = ($thing->{rtype} and $thing->{rtype} eq 'void'); X $XS .= join '', X ("(", X (join ", ", (map {$_->{name}} @args), X (scalar @opts or $ellipsis) ? '...' : ()), X ")\n", X ); X X # Declare the non-optional arguments for XS type-checking X $XS .= "\t$_->{type}\t$_->{name}\n" for @args; X X # Wrap "complicated" subs in stack-checking code X if ($void or $ellipsis) { X $PREINIT .= "\tI32 *\t__temp_markstack_ptr;\n"; X $CODE .= "\t__temp_markstack_ptr = PL_markstack_ptr++;\n"; X } X X if (@opts) { X $PREINIT .= "\t$_->{type}\t$_->{name};\n" for @opts; X $CODE .= "switch(items" . ($class ? '-1' : '') . ") {\n"; X X my $offset = scalar @args; # which is the first optional? X my $total = $offset + scalar @opts; X for (my $i=$offset; $i<$total; $i++) { X $CODE .= "case " . ($i+1) . ":\n"; X my @tmp; X for (my $j=$offset; $j<=$i; $j++) { X my $targ = $opts[$j-$offset]->{name}; X my $type = $opts[$j-$offset]->{type}; X my $src = "ST($j)"; X $CODE .= $o->typeconv($targ,$src,$type,'input_expr') X . ";\n"; X push @tmp, $targ; X } X $CODE .= "\t"; X $CODE .= "RETVAL = " X unless $void; X call_or_instantiate(\$CODE, $name, $ctor, $dtor, $class, X $thing->{rconst}, $thing->{rtype}, X (map { $_->{name} } @args), @tmp); X $CODE .= "\tbreak; /* case " . ($i+1) . " */\n"; X } X $CODE .= "default:\n"; X $CODE .= "\tRETVAL = " X unless $void; X call_or_instantiate(\$CODE, $name, $ctor, $dtor, $class, X $thing->{rconst}, $thing->{rtype}, X map { $_->{name} } @args); X $CODE .= "} /* switch(items) */ \n"; X } X elsif ($void) { X $CODE .= "\t"; X call_or_instantiate(\$CODE, $name, $ctor, $dtor, $class, 0, '', X map { $_->{name} } @args); X } X elsif ($ellipsis or $thing->{rconst}) { X $CODE .= "\t"; X $CODE .= "RETVAL = "; X call_or_instantiate(\$CODE, $name, $ctor, $dtor, $class, X $thing->{rconst}, $thing->{rtype}, X map { $_->{name} } @args); X } X if ($void) { X $CODE .= <<'END'; X if (PL_markstack_ptr != __temp_markstack_ptr) { X /* truly void, because dXSARGS not invoked */ X PL_markstack_ptr = __temp_markstack_ptr; X XSRETURN_EMPTY; /* return empty stack */ X } X /* must have used dXSARGS; list context implied */ X return; /* assume stack size is correct */ XEND X } X elsif ($ellipsis) { X $CODE .= "\tPL_markstack_ptr = __temp_markstack_ptr;\n"; X } X X # The actual function: X $XS .= "PREINIT:\n$PREINIT" if length $PREINIT; X $XS .= "PP" if $void; X $XS .= "CODE:\n$CODE" if length $CODE; X $XS .= "OUTPUT:\nRETVAL\n" X if (length $CODE and not $void); X $XS .= "\n"; X return $XS; X} X Xsub call_or_instantiate { X my $text_ref = shift; X my ($name, $ctor, $dtor, $class, $const, $type, @args) = @_; X X # Create an rvalue (which might be const-casted later). X my $rval = ''; X $rval .= "new " if $ctor; X $rval .= "delete " if $dtor; X $rval .= "THIS->" if ($class and not ($ctor or $dtor)); X $rval .= "$name(" . join (',', @args) . ")"; X X $$text_ref .= const_cast($rval, $const, $type); X $$text_ref .= ";\n"; # this is a convenience X} X Xsub const_cast { X my $value = shift; X my $const = shift; X my $type = shift; X return $value unless $const and $type =~ /\*|\&/; X return "const_cast<$type>($value)"; X} X Xsub write_typemap { X my $o = shift; X my $filename = "$o->{API}{build_dir}/CPP.map"; X my $type_kind = $o->{ILSM}{typeconv}{type_kind}; X my $typemap = ""; X $typemap .= $_ . "\t"x2 . $TYPEMAP_KIND . "\n" X for grep { $type_kind->{$_} eq $TYPEMAP_KIND } keys %$type_kind; X return unless length $typemap; X open TYPEMAP, "> $filename" X or croak "Error: Can't write to $filename: $!"; X print TYPEMAP <{ILSM}{typeconv}{output_expr}{$TYPEMAP_KIND} XINPUT X$TYPEMAP_KIND X$o->{ILSM}{typeconv}{input_expr}{$TYPEMAP_KIND} XEND X close TYPEMAP; X $o->validate(TYPEMAPS => $filename); X} X X# Generate type conversion code: perl2c or c2perl. Xsub typeconv { X my $o = shift; X my $var = shift; X my $arg = shift; X my $type = shift; X my $dir = shift; X my $preproc = shift; X my $tkind = $o->{ILSM}{typeconv}{type_kind}{$type}; X my $ret = X eval qq{qq{$o->{ILSM}{typeconv}{$dir}{$tkind}}}; X chomp $ret; X $ret =~ s/\n/\\\n/g if $preproc; X return $ret; X} X X1; X X__END__ END-of-p5-Inline-CPP/work/Inline-CPP-0.23/CPP.pm echo x - p5-Inline-CPP/work/Inline-CPP-0.23/Changes sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/Changes << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/Changes' XRevision history for Perl extension Inline::CPP. X X0.23 Sun Jul 15 15:53:02 PDT 2001 X - Allow declaration lists: int a, b; X - Allow initializer lists: Foo(double _o) : o(_o) { } X - Added a test case for both of these. X X0.23 Sat Jul 7 15:00:55 PDT 2001 X - Renamed subs to use Inline::C's new naming scheme. Refactored some X common code into a new sub named call_or_instantiate(). X X0.23 Fri Jul 6 19:51:23 PDT 2001 X - Added smart-sense for Sun 2.6 (Solaris 6). Needed to include X libCrun.so. X X0.23 Wed Jun 20 00:56:58 PDT 2001 X - Fixed a grammar bug to allow modifiers on member variables. X - Added a test case for it. X X0.22 Mon Jun 11 11:35:26 PDT 2001 X - Compatible with Inline::0.42 (not backwards compatible). X X0.21 Wed Jun 6 08:55:50 PDT 2001 X - Compatible with Inline::0.40 (not backwards compatible). X - Documentation improvements. X X0.20 Wed May 2 23:00:50 PDT 2001 X - Made Inline::CPP a subclass of Inline::C. Moved most functionality X into Inline::C, and trimmed code a lot. X - Fixed bug in handling of 'LIBS' config option. Added a 'ALTLIBS' X config option which adds a new element to the list of alternate X libs. X - Added 'PRESERVE_ELLIPSIS' option, which prevents Inline::CPP from X replacing '...' arguments with nothing. X - Inline::CPP now works on Cygwin! X - Grammar improvements: X - Inline functions X - Inheritance X - Default parameters: void foo(int a=10, char *b="Hello"); X - Unnamed parameters: void foo(int, char *); X - Support for public, private and protected scopes X - 'structs' are now bound just like classes, except the X default scope is public. X - Support for no fixed arguments: void foo(...); X X0.14 Tue Mar 13 23:10:14 PST 2001 X - Moved the distribution module from CPP_pm to CPP.pm to get X Inline::CPP indexed properly. X - Fixed some minor bugs. X X0.13 Sun Mar 4 22:09:35 PST 2001 X - Added Win32-specific configuration code to add '-TP' flag to compiler X - Special case for AIX ($Config{so}) X - Added the following configuration options: 'CC', 'LD', 'CCFLAGS', 'LDDLFLAGS', 'MYEXTLIB', and 'MAKE': proxies for the MakeMaker options of the same name. X X0.12 Sun Jan 21 17:16:43 PST 2001 X - Upgraded modules to conform to Inline-0.31 X - Documentation upgrades X X0.11 Thu Nov 23 16:46:27 PST 2000 X - Created Inline::CPP. END-of-p5-Inline-CPP/work/Inline-CPP-0.23/Changes echo x - p5-Inline-CPP/work/Inline-CPP-0.23/Makefile.PL sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/Makefile.PL << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/Makefile.PL' Xuse ExtUtils::MakeMaker; Xuse Config; X Xmy %PREREQ_PM = ( X Inline => '0.43', X 'Inline::C' => '0.43', X); X#============================================================================ X# We'll do our own prerequisite checking, since MakeMaker does it X# in a way that always fails: 'use Inline::C 0.33' will never work. X#============================================================================ Xfor (sort keys %PREREQ_PM) { X eval "require $_"; X warn "Warning: prerequisite $_ version $PREREQ_PM{$_} not found" X if $@ or ${$_ . "::VERSION"} < $PREREQ_PM{$_}; X} X X#============================================================================ X# Make an intelligent guess about what compiler to use X#============================================================================ Xmy $cc_guess; Xmy $libs_guess; Xif ($Config{osname} =~ /^MSWin/) { X $cc_guess = 'cl -TP'; X $libs_guess = 'MSVCIRT.LIB'; X} Xelsif ($Config{osname} eq 'linux') { X $cc_guess = 'g++'; X $libs_guess = '-lstdc++'; X} Xelsif ($Config{osname} eq 'cygwin') { X $cc_guess = 'g++'; X $libs_guess = '-lstdc++'; X} Xelsif ($Config{osname} eq 'solaris' or $Config{osname} eq 'SunOS') { X if ($Config{cc} eq 'gcc') { X $cc_guess = 'g++'; X $libs_guess = '-lstdc++'; X } X else { X $cc_guess = 'CC'; X $libs_guess ='-lCrun'; X } X} X# Sane defaults for other (probably unix-like) operating systems Xelse { X $cc_guess = 'g++'; X $libs_guess = '-lstdc++'; X} X Xprint "This will configure and build Inline::C++.\n"; X Xmy $cpp_compiler = prompt("What default C++ compiler would you like to use?", X $cc_guess); Xmy $libs = prompt("What default libraries would you like to include?", X $libs_guess); X X# Apply the defaults: Xopen CPP, "CPP.pm"; Xmy @lines = ; Xclose CPP; X Xfor (@lines) { X s|\@COMPILER|$cpp_compiler| if m|\# default compiler|; X s|\@DEFAULTLIBS|$libs| if m|\# default libs|; X} X Xopen CPP, ">CPP.pm" X or die "Can't write to CPP.pm!"; Xprint CPP @lines; Xclose CPP; X XWriteMakefile( X NAME => 'Inline::CPP', X VERSION_FROM => 'CPP.pm', X clean => {FILES => '_Inline/ grammar/_Inline'}, X ); END-of-p5-Inline-CPP/work/Inline-CPP-0.23/Makefile.PL echo c - p5-Inline-CPP/work/Inline-CPP-0.23/t mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/t > /dev/null 2>&1 echo x - p5-Inline-CPP/work/Inline-CPP-0.23/t/02prefix.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/t/02prefix.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/t/02prefix.t' Xuse Test; XBEGIN { plan tests => 4 } X Xok(1); X Xuse Inline CPP => DATA => PREFIX => 'Foo_'; X Xok(identity("Neil"), "Neil"); Xok(identity(identity("123")), "123"); X Xok(Foo->new->dummy, "10"); X X__END__ X__CPP__ X Xstruct Foo { X int dummy() { return 10; } X}; X Xchar *Foo_identity(char *in) { return in; } X END-of-p5-Inline-CPP/work/Inline-CPP-0.23/t/02prefix.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/t/01basic.t sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/t/01basic.t << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/t/01basic.t' Xuse Test; XBEGIN { plan tests => 10 } X Xok(1); X Xmy $obj1 = Soldier->new('Benjamin', 'Private', 11111); Xmy $obj2 = Soldier->new('Sanders', 'Colonel', 22222); Xmy $obj3 = Soldier->new('Matt', 'Sergeant', 33333); X Xfor my $obj ($obj1, $obj2, $obj3) { X print $obj->get_serial, ") ", X $obj->get_name, " is a ", X $obj->get_rank, "\n"; X} X Xok($obj1->get_serial, 11111); Xok($obj1->get_name, 'Benjamin'); Xok($obj1->get_rank, 'Private'); X Xok($obj2->get_serial, 22222); Xok($obj2->get_name, 'Sanders'); Xok($obj2->get_rank, 'Colonel'); X Xok($obj3->get_serial, 33333); Xok($obj3->get_name, 'Matt'); Xok($obj3->get_rank, 'Sergeant'); X X############################################################################### X Xuse Inline 'C++' => <name = name; X this->rank = rank; X this->serial = serial; X} X Xchar *Soldier::get_name() { X return name; X} X Xchar *Soldier::get_rank() { X return rank; X} X Xint Soldier::get_serial() { X return serial; X} X XEND END-of-p5-Inline-CPP/work/Inline-CPP-0.23/t/01basic.t echo x - p5-Inline-CPP/work/Inline-CPP-0.23/TESTED sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/TESTED << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/TESTED' XThis is a list I try to keep as up-to-date as possible with the state Xof the module. This list is known to be up to date with Inline::CPP Xversion 0.20. X XKey to reading this list: XACROSS: Arch/OS/Compiler -or- Arch/Compiler XDOWN: Perl Version XCELLS: PASS|FAIL(tester's initials) X X#============================================================================ X Linux/Alpha/GCC Linux/x86/GCC OpenBSD/x86/GCC X5.005 PASS(nw) PASS(nw) X5.6.0 PASS(nw) PASS(nw) X5.6.1 PASS(nw) X5.7.0 PASS(nw) X5.7.1 PASS(nw) XAP623 PASS(nw) XAP626 PASS(nw) X#============================================================================ X Sun2.5.1/GCC Sun2.5.1/Sun SunOS5.6/GCC SunOS5.6/Sun X5.005 PASS(nw) PASS(nw) X5.6.0 X5.6.1 X5.7.0 X#============================================================================ X HPUX11/GCC HPUX11/HP HPUX10.20/GCC HPUX10.20/HP X5.005 X5.6.1 X5.7.0 X#============================================================================ X AIX/GCC AIX/IBM X5.005 X5.6.1 X5.7.0 X#============================================================================ X Win32/MS Win32/Cyg XAP623 PASS(nw) X5.005 X5.6.1 PASS(nw) X5.7.0 X#============================================================================ X XSpecial Configurations: X XThis section describes special settings needed to make Inline::CPP work on Xcertain platforms. X X o On Solaris using the SUNWspro compiler, you'll need to use these settings: X compiler: 'CC' X library: '-lCrun' X Note that if you use any of the "special" C++ things like cout or cin, X you'll need to add other libraries (and I'm not sure what they are). X On my box, I needed these flags: X library: '-lCrun -L/opt/SUNWspro/WS6/lib -lCstd' X XThings to watch out for: X X o LD_LIBRARY_PATH: If your c++ compiler is intalled in /usr/local, the X libstdc++ library might not be found. You can export LD_LIBRARY_PATH on X most systems to extend the search to the nonstandard paths. See the X ldconfig manpage for more information. X X o You need to make sure the c++ compiler you use is compatible with the X version of perl you are using. For instance, when using perl built with X gcc, you should use g++ as the c++ compiler. If your perl was built with X the SUNWspro compiler, it's probably best to use the SUNWspro compiler to X build your c++ extensions. X X o If Inline::CPP fails to bind to valid C++ code and you're running Perl X 5.005, check the Inline::CPP manpage to see if you've hit one of the known X cases where Inline::CPP needs Perl 5.6.0 or better. You may be able to X adjust your code slightly to make it match. Or you can upgrade your Perl X to the current version and forget all about it forever. X XWho are the testing people? Xnw Neil Watkiss NEILW@cpan.org Xbi Brian Ingerson INGY@cpan.org Xks Ken Simpson KenS@ActiveState.com X END-of-p5-Inline-CPP/work/Inline-CPP-0.23/TESTED echo c - p5-Inline-CPP/work/Inline-CPP-0.23/blib mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/blib > /dev/null 2>&1 echo c - p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib > /dev/null 2>&1 echo c - p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline > /dev/null 2>&1 echo x - p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/.exists sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/.exists << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/.exists' END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/.exists echo x - p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP.pod sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP.pod << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP.pod' X=head1 NAME X XInline::CPP - Write Perl subroutines and classes in C++. X X=head1 SYNOPSIS X X use Inline CPP; X X print "9 + 16 = ", add(9, 16), "\n"; X print "9 - 16 = ", subtract(9, 16), "\n"; X X __END__ X __CPP__ X X int add(int x, int y) { X return x + y; X } X X int subtract(int x, int y) { X return x - y; X } X X END_OF_CPP_CODE X X=head1 DESCRIPTION X XThe C module allows you to put C++ source code directly X"inline" in a Perl script or module. You code classes or functions in XC++, and you can use them as if they were written in Perl. X X=head1 Choosing a C++ Compiler X XInline::CPP just parses your C++ code and creates bindings to it. Like XInline::C, you will need a suitable compiler the first time you run the Xscript. Choosing a C++ compiler can prove difficult, because Perl is Xwritten in C, not C++. X XHere's the rule: use any C++ compiler that's compatible with the compiler Xwhich built perl. For instance, if perl was built with C, use C. XIf you're on a Sun or an IRIX box and the system C compiler C built perl, Xthen use the system C++ compiler, C. X XSome compilers actually compile both C and C++ with the same compiler. XMicrosoft's C is one such compiler -- you pass it the <-TP> flag Xto convince it that you want C++ mode. X X=head1 Using Inline::CPP X XInline::CPP is very similar to Inline::C. It uses a grammar to Xparse your C++ code, and binds to functions or classes which are Xrecognized. If a function is recognized, it will be available from XPerl space. If the function's signature is not recognized, it will not Xbe available from Perl space, but will be available from other Xfunctions in C++. X XFor more information about the grammar used to parse C++ code, see the Xsection called "Grammar". X XThe following example shows how C++ snippets map into the Perl Xnamespace: X XExample 1: X X use Inline CPP => <<'END'; X X int doodle() { } X X class Foo { X public: X Foo(); X ~Foo(); X X int get_data() { return data; } X void set_data(int a) { data = a; } X private: X int data; X }; X X Foo::Foo() { cout << "creating a Foo()" << endl; } X Foo::~Foo() { cout << "deleting a Foo()" << endl; } X X END X XAfter running the code above, Perl's namespace would look similar to if Xfollowing code had been run: X X sub main::doodle { } X X package main::Foo; X X sub new { print "creating a Foo()\n"; bless {}, shift } X sub DESTROY { print "deleting a Foo()\n" } X X sub get_data { my $o=shift; $o->{data} } X sub set_data { my $o=shift; $o->{data} = shift } X XThe difference, of course, is that in the latter, Perl does the work. In the XInline::CPP example, all function calls get sent off to your C++ code. That Xmeans that things like this won't work: X X my $obj = new Foo; X $obj->{extrafield} = 10; X XIt doesn't work because C<$obj> is not a blessed hash. It's a blessed Xreference to a C++ object (and anyway, C++ wouldn't let you do that either, Xsince extrafield wasn't defined). X X=head1 C++ Configuration Options X XFor information on how to specify Inline configuration options, see XL. This section describes each of the configuration options Xavailable for C. Most of the options correspond either the MakeMaker Xor XS options of the same name. See L and XL. X X=head2 ALTLIBS X XAdds a new entry to the end of the list of alternative libraries to Xbind with. MakeMaker will search through this list and use the first Xentry where all the libraries are found. X X use Inline Config => ALTLIBS => '-L/my/other/lib -lfoo'; X XSee also the LIBS config option, which appends to the last entry in Xthe list. X X=head2 AUTO_INCLUDE X XSpecifies extra statements to be automatically included. They will be Xadded on to the defaults. A newline char will automatically be added. X X use Inline Config => AUTO_INCLUDE => '#include "something.h"'; X X=head2 BOOT X XSpecifies code to be run when your code is loaded. May not contain any Xblank lines. See L for more information. X X use Inline Config => BOOT => 'foo();'; X X=head2 CC X XSpecifies which compiler to use. X X=head2 CCFLAGS X XSpecifies extra compiler flags. Corresponds to the MakeMaker option. X X=head2 FILTERS X XSpecifies one (or more, in an array ref) filter which is to be applied to Xthe code just prior to parsing. The filters are executed one after another, Xeach operating on the output of the previous one. You can pass in a code Xreference or the name of a prepackaged filter. X X use Inline Config => FILTERS => [Strip_POD => \&myfilter]; X XThe filter may do anything. The code is passed as the first argument, and Xit returns the filtered code. X X=head2 INC X XSpecifies extra include directories. Corresponds to the MakeMaker Xparameter. X X use Inline Config => INC => '-I/my/path'; X X=head2 LD X XSpecifies the linker to use. X X=head2 LDDLFLAGS X XSpecifies which linker flags to use. X XNOTE: These flags will completely override the existing flags, instead Xof just adding to them. So if you need to use those too, you must Xrespecify them here. X X=head2 LIBS X XSpecifies external libraries that should be linked into your Xcode. Corresponds to the MakeMaker parameter. X X use Inline Config => LIBS => '-L/your/path -lyourlib'; X XUnlike the LIBS configuration parameter used in Inline::C, successive Xcalls to LIBS append to the previous calls. For example, X X use Inline Config => LIBS => '-L/my/path', LIBS => '-lyourlib'; X Xwill work correctly. If you want to add a new element to the list of Xpossible libraries to link with, use the Inline::CPP configuration ALTLIBS. X X=head2 MAKE X XSpecifies the name of the 'make' utility to use. X X=head2 MYEXTLIB X XSpecifies a user compiled object that should be linked in. Corresponds Xto the MakeMaker parameter. X X use Inline Config => MYEXTLIB => '/your/path/something.o'; X X=head2 PREFIX X XSpecifies a prefix that will automatically be stripped from C++ Xfunctions when they are bound to Perl. Less useful than in C, because XC++ mangles its function names so they don't conflict with C functions Xof the same name. X X use Inline Config => PREFIX => 'ZLIB_'; X XThis only affects C++ function names, not C++ class names or methods. X X=head2 PRESERVE_ELLIPSIS X XBy default, Inline::CPP replaces C<...> in bound functions with three Xspaces, since the arguments are always passed on the Perl Stack, not on Xthe C stack. This is usually desired, since it allows functions with Xno fixed arguments (most compilers require at least one fixed argument). X X use Inline Config => PRESERVE_ELLIPSIS => 1; Xor X use Inline Config => ENABLE => PRESERVE_ELLIPSIS; X XFor an example of why PRESERVE_ELLIPSIS is normally not needed, see the Xexamples section, below. X X=head2 STD_IOSTREAM X XBy default, Inline::CPP includes C at the top of your code. This Xoption makes it include C instead, which is the ANSI-compliant Xversion of the makefile. On non-GNU implementations, these files are not Xcompatible with one another. X X use Inline CPP => Config => ENABLE => STD_IOSTREAM; X X=head2 STRUCTS X XSpecifies whether to bind C structs into Perl using Inline::Struct. XNOTE: Support for this option is experimental. Inline::CPP already binds Xto structs defined in your code. Structs and classes are treated as the Xsame construct, except that a struct's initial scope is public, not Xprivate. Inline::Struct provides autogenerated get/set methods, an Xoverloaded constructor, and several other features not available in XInline::CPP. X XYou can invoke STRUCTS in several ways: X X use Inline Config => STRUCTS => 'Foo'; Xor X use Inline Config => STRUCTS => ['Bar', 'Baz']; X XBinds the named structs to Perl. Emits warnings if a struct was requested Xbut could not be bound for some reason. X X use Inline Config => ENABLE => 'STRUCTS'; Xor X use Inline Config => STRUCTS => 1; X XEnables binding structs to Perl. All structs which can be bound, will. This Xparameter overrides all requests for particular structs. X X use Inline Config => DISABLE => 'STRUCTS'; Xor X use Inline Config => STRUCTS => 0; X XDisables binding structs to Perl. Overrides any other settings. X XSee L for more details about how C Xbinds C structs to Perl. X X=head2 TYPEMAPS X XSpecifies extra typemap files to use. These types will modify the Xbehaviour of C++ parsing. Corresponds to the MakeMaker parameter. X X use Inline Config => TYPEMAPS => '/your/path/typemap'; X X=head1 C++-Perl Bindings X XThis section describes how the C variables get mapped to C Xvariables and back again. X XPerl uses a stack to pass arguments back and forth to subroutines. When Xa sub is called, it pops off all its arguments from the stack; when it's Xdone, it pushes its return values back onto the stack. X XXS (Perl's language for creating C or C++ extensions for Perl) uses X"typemaps" to turn SVs into C types and back again. This is done through Xvarious XS macro calls, casts, and the Perl API. XS also allows you to Xdefine your own mappings. X XC uses a much simpler approach. It parses the system's Xtypemap files and only binds to functions with supported types. You Xcan tell C about custom typemap files too. X XIf you have very complicated data structures in either C++ or Perl, Xyou should just pass them as an SV* and do the conversion yourself in Xyour C++ function. X XIn C++, a struct is a class whose default scope is public, not Xprivate. Inline::CPP binds to structs with this in mind -- get/set Xmethods are not yet auto-generated (although they are scheduled to Xland in an upcoming release). X XIf you have a C struct, you can use Inline::Struct to allow Perl Xcomplete access to the internals of the struct. You can create and Xmodify structs from inside Perl, as well as pass structs into C++ Xfunctions and return them from functions. Please note that XInline::Struct does not understand any C++ features, so constructors Xand member functions are not supported. See L for more Xdetails. X X=head1 EXAMPLES X XHere are some examples. X X=head2 Example 1 - Farmer Bob X XThis example illustrates how to use a simple class (C) from XPerl. One of the new features in Inline::CPP is binding to classes Xwith inline method definitions: X X use Inline CPP; X X my $farmer = new Farmer("Ingy", 42); X my $slavedriver = 1; X while($farmer->how_tired < 420) { X $farmer->do_chores($slavedriver); X $slavedriver <<= 1; X } X X print "Wow! The farmer worked ", $farmer->how_long, " hours!\n"; X X __END__ X __CPP__ X X class Farmer { X public: X Farmer(char *name, int age); X ~Farmer(); X X int how_tired() { return tiredness; } X int how_long() { return howlong; } X void do_chores(int howlong); X X private: X char *name; X int age; X int tiredness; X int howlong; X }; X X Farmer::Farmer(char *name, int age) { X this->name = strdup(name); X this->age = age; X tiredness = 0; X howlong = 0; X } X X Farmer::~Farmer() { X free(name); X } X X void Farmer::do_chores(int hl) { X howlong += hl; X tiredness += (age * hl); X } X X=head2 Example 2 - Plane and Simple X XThis example demonstrates some new features of Inline::CPP: support for Xinheritance and abstract classes. The defined methods of the abstract Xclass C are bound to Perl, but there is no constructor or Xdestructor, meaning you cannot instantiate an C. X XThe C is a fully-bound class which can be created and Xmanipulated from Perl. X X use Inline CPP; X X my $plane = new Airplane; X $plane->print; X if ($plane->isa("Object")) { print "Plane is an Object!\n"; } X unless ($plane->can("fly")) { print "This plane sucks!\n"; } X X __END__ X __CPP__ X X /* Abstract class (interface) */ X class Object { X public: X virtual void print() { cout << "Object (" << this << ")" << endl; } X virtual void info() = 0; X virtual bool isa(char *klass) = 0; X virtual bool can(char *method) = 0; X }; X X class Airplane : public Object { X public: X Airplane() {} X ~Airplane() {} X X virtual void info() { print(); } X virtual bool isa(char *klass) { return strcmp(klass, "Object")==0; } X virtual bool can(char *method) { X bool yes = false; X yes |= strcmp(method, "print")==0; X yes |= strcmp(method, "info")==0; X yes |= strcmp(method, "isa")==0; X yes |= strcmp(method, "can")==0; X return yes; X } X }; X X=head2 Example 3 - The Ellipsis Abridged X XOne of the big advantages of Perl over C or C++ is the ability to pass an Xarbitrary number of arguments to a subroutine. You can do it in C, but it's Xmessy and difficult to get it right. All of this mess is necessary because XC doesn't give the programmer access to the stack. Perl, on the other hand, Xgives you access to everything. X XHere's a useful function written in Perl that is relatively slow: X X sub average { X my $average = 0; X for (my $i=0; $i<@_; $i++) { X $average *= $i; X $average += $_[$i]; X $average /= $i + 1; X } X return $average; X } X XHere's the same function written in C: X X double average() { X Inline_Stack_Vars; X double avg = 0.0; X for (int i=0; i C or C++ is faster than Perl. Well..., actually, Xthat wasn't really the point; that was an aside. Look at the function Xdeclaration: X X double avg(...) X XWhy didn't we need to use varargs macros to get at the arguments? Why didn't Xthe compiler complain that there were no required arguments? Because XInline::C++ actually compiled this: X X double avg( ) X XWhen it bound to the function, it noticed the ellipsis and decided to get rid Xof it. Any function bound to Perl that has an ellipsis in it will have its Xarguments passed via the Perl stack, not the C stack. That means if you write Xa function like this: X X void myprintf(char *format, ...); X Xthen you'd better be reading things from the Perl stack. If you aren't, then Xspecify the PRESERVE_ELLIPSIS option in your script. That will leave the Xellipsis in the code for the compiler to whine about. :) X X=head2 Example 4 - Stacks and Queues X XEveryone who learns C++ writes a stack and queue class sooner or Xlater. I might as well try it from Inline. But why reinvent the wheel? XPerl has a perfectly good Array type, which can easily implement both Xa Queue and a Stack. X XThis example implements a Queue and a Stack class, and shows off just Xa few more new features of Inline::CPP: default values to arguments, X X use Inline CPP; X X my $q = new Queue; X $q->q(50); X $q->q("Where am I?"); X $q->q("In a queue."); X print "There are ", $q->size, " items in the queue\n"; X while($q->size) { X print "About to dequeue: ", $q->peek, "\n"; X print "Actually dequeued: ", $q->dq, "\n"; X } X X my $s = new Stack; X $s->push(42); X $s->push("What?"); X print "There are ", $s->size, " items on the stack\n"; X while($s->size) { X print "About to pop: ", $s->peek, "\n"; X print "Actually popped: ", $s->pop, "\n"; X } X X __END__ X __CPP__ X X class Queue { X public: X Queue(int sz=0) { q = newAV(); if (sz) av_extend(q, sz-1); } X ~Queue() { av_undef(q); } X X int size() {return av_len(q) + 1; } X X int q(SV *item) { av_push(q, SvREFCNT_inc(item)); return av_len(q)+1; } X SV *dq() { return av_shift(q); } X SV *peek() { return size() ? SvREFCNT_inc(*av_fetch(q,0,0)): &PL_sv_undef;} X X private: X AV *q; X }; X X class Stack { X public: X Stack(int sz=0) { s = newAV(); if (sz) av_extend(s, sz-1); } X ~Stack() { av_undef(s); } X X int size() { return av_len(s) + 1; } X X int push(SV *i) { av_push(s, SvREFCNT_inc(i)); return av_len(s)+1; } X SV *pop() { return av_pop(s); } X SV *peek() { return size() ? SvREFCNT_inc(*av_fetch(s,size()-1,0)) : &PL_sv_undef; } X X private: X AV *s; X }; X X=head1 Grammar Details X XPerl 5.6.0 is recommended for Inline::CPP, and is required to get all the Xnew features. If you are using Perl 5.005_03 the package will build and run, Xbut you will have problems in certain circumstances: X X=head2 Inline function definitions X XFor the purposes of this discussion, inline function definitions are best Xdescribed by this example: X X class Foo { X public: X Foo() { /* Do something */ } X }; X XThis example shows a class with a constructor defined inline. Inline::CPP can Xparse this example with 5.005. But this example requires Perl 5.6.0: X X class Foo { X public: X Foo() { if(1) { /* Do something */ } } X }; X XHere's what happened: Inline::CPP saw a class, saw the method, then noticed Xit was an inline method. So it grabbed this text: X X "{ if(1) { /* Do something */ }" X XAnd then it tried to match another part of the class. But it failed because Xthe next part of the string is this (with newlines trimmed): X X "} };" X XThe remaining text doesn't parse right. There are two solutions: X X=over 4 X X=item a X XUse Perl version 5.6.0 or better; or, X X=item b X XMove the definition outside the class. X X=back X X=head2 Complex default parameters X XAgain, default parameters are best described by example: X X int root(double number, int whatroot=2); X XThis function takes one or two arguments. If the second is missing, C++ gives Xit the value 2. Inline::CPP can parse this simple example regardless of your Xperl version. But the following example requires 5.6.0: X X int root(double number, int whatroot=((2))); X XThat's because if you're using 5.005, your arguments are parsed with a regular Xexpression that looks for only one closing parenthesis. Any more than that, Xand you get a parse error. X XAgain, there are two solutions: X X=over 4 X X=item a X XUse Perl version 5.6.0 or better; or, X X=item b X XMake the strange expression a constant or macro and use that. X X=back X X=head2 Rant: Perl 5.005 is for Dummies X XI'm going to take the opportunity to rant. Everything in the rest of this Xsection can be ignored if you don't want to hear it. X XPerl 5.6.0 has been out for a long time. It's proven, stable, and people use Xit all the time. Perl 5.6.1 is the latest stable release. Unless you depend Xon one of the few modules which are only available for the ancient versions of XPerl, there is B not to upgrade today! X X=head1 SEE ALSO X XFor general information about how C binds code to Perl, see XL. X XFor information on using C with Perl, see L and XL. For C, see L, XL, L, and L. X XFor information on using C and C++ structs with Perl, see XL. X X=head1 BUGS AND DEFICIENCIES X XWhen reporting a bug, please do the following: X X - Put "use Inline REPORTBUG;" at the top of your code, or X use the command line option "perl -MInline=REPORTBUG ...". X - Run your code. X - Follow the printed instructions. X XHere are some things to watch out for: X X=over 4 X X=item 1 X XThe grammar used for parsing C++ is still quite simple, and does not allow Xseveral features of C++: X X=over 4 X X=item a X Xtemplates X X=item b X Xoperator overloading X X=item c X Xfunction overloading X X=back X XOther grammar problems will probably be noticed quickly. X X=item 2 X XIn order of relative importance, improvements planned in the near Xfuture are: X X=over 4 X X=item a X Xsupport for overloaded functions and methods X X=item b X Xbinding to constants and constant #defines X X=item c X Xbinding to unions X X=item d X Xautogenerated get/set methods on public members X X=back X X=back X X=head1 AUTHOR X XNeil Watkiss X XBrian Ingerson is the author of C, XC and C. He is known in the innermost Inline Xcircles as "Batman". ;) X X=head1 COPYRIGHT X XCopyright (c) 2000 - 2001, Neil Watkiss. X XAll Rights Reserved. This module is free software. It may be used, Xredistributed and/or modified under the same terms as Perl itself. X XSee http://www.perl.com/perl/misc/Artistic.html X X=cut END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP.pod echo x - p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP.pm sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP.pm << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP.pm' Xpackage Inline::CPP; X Xuse strict; Xrequire Inline::C; Xrequire Inline::CPP::grammar; Xuse Carp; X Xuse vars qw(@ISA $VERSION); X X@ISA = qw(Inline::C); X$VERSION = "0.23"; Xmy $TYPEMAP_KIND = $Inline::CPP::grammar::TYPEMAP_KIND; X X#============================================================================ X# Register Inline::CPP as an Inline language module X#============================================================================ Xsub register { X use Config; X return { X language => 'CPP', X aliases => ['cpp', 'C++', 'c++', 'Cplusplus', 'cplusplus'], X type => 'compiled', X suffix => $Config{dlext}, X }; X} X X#============================================================================ X# Validate the C++ config options: Now mostly done in Inline::C X#============================================================================ Xsub validate { X my $o = shift; X $o->{ILSM}{MAKEFILE}{CC} ||= 'g++'; # default compiler X $o->{ILSM}{MAKEFILE}{LIBS} ||= ['-lstdc++']; # default libs X X # I haven't traced it out yet, but $o->{STRUCT} gets set before getting X # properly set from Inline::C's validate(). X $o->{STRUCT} ||= { X '.macros' => '', X '.xs' => '', X '.any' => 0, X '.all' => 0, X }; X $o->{ILSM}{AUTO_INCLUDE} ||= < X#endif X#ifdef __CYGWIN__ Xextern "C" { X#endif X#include "EXTERN.h" X#include "perl.h" X#include "XSUB.h" X#include "INLINE.h" X#ifdef __CYGWIN__ X} X#endif X#ifdef bool X#undef bool X#include <%iostream%> X#endif XEND X $o->{ILSM}{PRESERVE_ELLIPSIS} = 0 X unless defined $o->{ILSM}{PRESERVE_ELLIPSIS}; X X # Filter out the parameters we treat differently than Inline::C X my @propagate; X while(@_) { X my ($key, $value) = (shift, shift); X if ($key eq 'LIBS') { X $value = [$value] unless ref $value eq 'ARRAY'; X my $num = scalar @{$o->{ILSM}{MAKEFILE}{LIBS}} - 1; X $o->{ILSM}{MAKEFILE}{LIBS}[$num] .= ' ' . $_ X for (@$value); X next; X } X if ($key eq 'ALTLIBS') { X $value = [$value] unless ref $value eq 'ARRAY'; X push @{$o->{ILSM}{MAKEFILE}{LIBS}}, ''; X my $num = scalar @{$o->{ILSM}{MAKEFILE}{LIBS}} - 1; X $o->{ILSM}{MAKEFILE}{LIBS}[$num] .= ' ' . $_ X for (@$value); X next; X } X if ($key eq 'PRESERVE_ELLIPSIS' or X $key eq 'STD_IOSTREAM') { X croak "Argument to $key must be 0 or 1" X unless $value == 0 or $value == 1; X $o->{ILSM}{$key} = $value; X next; X } X push @propagate, $key, $value; X } X X # Replace %iostream% with the correct iostream library X my $iostream = "iostream"; X $iostream .= ".h" unless (defined $o->{ILSM}{STD_IOSTREAM} and X $o->{ILSM}{STD_IOSTREAM}); X $o->{ILSM}{AUTO_INCLUDE} =~ s|%iostream%|$iostream|g; X X # Forward all unknown requests up to Inline::C X $o->SUPER::validate(@propagate) if @propagate; X} X X#============================================================================ X# Print a small report if PRINT_INFO option is set X#============================================================================ Xsub info { X my $o = shift; X my $info = ""; X X $o->parse unless $o->{ILSM}{parser}; X my $data = $o->{ILSM}{parser}{data}; X X if (defined $o->{ILSM}{parser}{data}{classes}) { X $info .= "The following C++ classes have been bound to Perl:\n"; X for my $class (sort @{$data->{classes}}) { X my @parents = grep { $_->{thing} eq 'inherits' } X @{$data->{class}{$class}}; X $info .= "\tclass $class"; X $info .= (" : " X . join (', ', X map { $_->{scope} . " " . $_->{name} } @parents) X ) if @parents; X $info .= " {\n"; X for my $thing (sort { $a->{name} cmp $b->{name} } X @{$data->{class}{$class}}) { X my ($name, $scope, $type) = @{$thing}{qw(name scope thing)}; X next unless $scope eq 'public' and $type eq 'method'; X my $rtype = $thing->{rtype} || ""; X $info .= "\t\t$rtype" . ($rtype ? " " : ""); X $info .= $class . "::$name("; X my @args = grep { $_->{name} ne '...' } @{$thing->{args}}; X my $ellipsis = (scalar @{$thing->{args}} - scalar @args) != 0; X $info .= join ', ', (map "$_->{type} $_->{name}", @args), X $ellipsis ? "..." : (); X $info .= ");\n"; X } X $info .= "\t};\n" X } X $info .= "\n"; X } X else { X $info .= "No C++ classes have been successfully bound to Perl.\n\n"; X } X if (defined $o->{ILSM}{parser}{data}{functions}) { X $info .= "The following C++ functions have been bound to Perl:\n"; X for my $function (sort @{$data->{functions}}) { X my $func = $data->{function}{$function}; X $info .= "\t" . $func->{rtype} . " "; X $info .= $func->{name} . "("; X my @args = grep { $_->{name} ne '...' } @{$func->{args}}; X my $ellipsis = (scalar @{$func->{args}} - scalar @args) != 0; X $info .= join ', ', (map "$_->{type} $_->{name}", @args), X $ellipsis ? "..." : (); X $info .= ");\n"; X } X $info .= "\n"; X } X else { X $info .= "No C++ functions have been bound to Perl.\n\n"; X } X $info .= Inline::Struct::info($o) if $o->{STRUCT}{'.any'}; X return $info; X} X X#============================================================================ X# Generate a C++ parser X#============================================================================ Xsub get_parser { X my $o = shift; X my $grammar = Inline::CPP::grammar::grammar() X or croak "Can't find C++ grammar\n"; X $::RD_HINT++; X require Parse::RecDescent; X my $parser = Parse::RecDescent->new($grammar); X $parser->{data}{typeconv} = $o->{ILSM}{typeconv}; X $parser->{ILSM} = $o->{ILSM}; # give parser access to config options X return $parser; X} X X#============================================================================ X# Intercept xs_generate and create the typemap file X#============================================================================ Xsub xs_generate { X my $o = shift; X $o->write_typemap; X $o->SUPER::xs_generate; X} X X#============================================================================ X# Return bindings for functions and classes X#============================================================================ Xsub xs_bindings { X my $o = shift; X my ($pkg, $module) = @{$o->{API}}{qw(pkg module modfname)}; X my $data = $o->{ILSM}{parser}{data}; X my $XS = ''; X X warn("Warning: No Inline C++ functions or classes bound to Perl\n" . X "Check your C++ for Inline compatibility.\n\n") X if ((not defined $data->{classes}) X and (not defined $data->{functions}) X and ($^W)); X X for my $class (@{$data->{classes}}) { X my $proper_pkg = $pkg . "::$class"; X # Set up the proper namespace X $XS .= <{class}{$class}}) { X my ($name, $scope, $type) = @{$thing}{qw|name scope thing|}; X X # Let Perl handle inheritance X if ($type eq 'inherits' and $scope eq 'public') { X $o->{ILSM}{XS}{BOOT} ||= ''; X my $ISA_name = "${pkg}::${class}::ISA"; X my $parent = "${pkg}::${name}"; X $o->{ILSM}{XS}{BOOT} .= <{abstract}); X next if ($type eq 'method' and $thing->{abstract}); X next unless ($scope eq 'public' and $type eq 'method'); X X # generate an XS wrapper X $ctor ||= ($name eq $class); X $dtor ||= ($name eq "~$class"); X $XS .= $o->wrap($thing, $name, $class); X } X X # Provide default constructor and destructor: X $XS .= <{ILSM}{XS}{PREFIX}) ? X "PREFIX = $o->{ILSM}{XS}{PREFIX}" : X ''); X $XS .= <{functions}}) { X next if $data->{function}{$function}{rtype} =~ 'static'; # special case X $XS .= $o->wrap($data->{function}{$function}, $function); X } X X return $XS; X} X X#============================================================================ X# Generate an XS wrapper around anything: a C++ method or function X#============================================================================ Xsub wrap { X my $o = shift; X my $thing = shift; X my $name = shift; X my $class = shift || ""; X X my ($XS, $PREINIT, $CODE) = ("", "", ""); X my ($ctor, $dtor) = (0, 0); X X if ($name eq $class) { # ctor X $XS .= $class . " *\n" . $class . "::new"; X $ctor = 1; X } X elsif ($name eq "~$class") { # dtor X $XS .= "void\n$class" . "::DESTROY"; X $dtor = 1; X } X elsif ($class) { # method X $XS .= "$thing->{rtype}\n$class" . "::$thing->{name}"; X } X else { # function X $XS .= "$thing->{rtype}\n$thing->{name}"; X } X X # Filter out optional subroutine arguments X my (@args, @opts, $ellipsis, $void); X $_->{optional} ? push@opts,$_ : push@args,$_ for @{$thing->{args}}; X $ellipsis = pop @args if (@args and $args[-1]->{name} eq '...'); X $void = ($thing->{rtype} and $thing->{rtype} eq 'void'); X $XS .= join '', X ("(", X (join ", ", (map {$_->{name}} @args), X (scalar @opts or $ellipsis) ? '...' : ()), X ")\n", X ); X X # Declare the non-optional arguments for XS type-checking X $XS .= "\t$_->{type}\t$_->{name}\n" for @args; X X # Wrap "complicated" subs in stack-checking code X if ($void or $ellipsis) { X $PREINIT .= "\tI32 *\t__temp_markstack_ptr;\n"; X $CODE .= "\t__temp_markstack_ptr = PL_markstack_ptr++;\n"; X } X X if (@opts) { X $PREINIT .= "\t$_->{type}\t$_->{name};\n" for @opts; X $CODE .= "switch(items" . ($class ? '-1' : '') . ") {\n"; X X my $offset = scalar @args; # which is the first optional? X my $total = $offset + scalar @opts; X for (my $i=$offset; $i<$total; $i++) { X $CODE .= "case " . ($i+1) . ":\n"; X my @tmp; X for (my $j=$offset; $j<=$i; $j++) { X my $targ = $opts[$j-$offset]->{name}; X my $type = $opts[$j-$offset]->{type}; X my $src = "ST($j)"; X $CODE .= $o->typeconv($targ,$src,$type,'input_expr') X . ";\n"; X push @tmp, $targ; X } X $CODE .= "\t"; X $CODE .= "RETVAL = " X unless $void; X call_or_instantiate(\$CODE, $name, $ctor, $dtor, $class, X $thing->{rconst}, $thing->{rtype}, X (map { $_->{name} } @args), @tmp); X $CODE .= "\tbreak; /* case " . ($i+1) . " */\n"; X } X $CODE .= "default:\n"; X $CODE .= "\tRETVAL = " X unless $void; X call_or_instantiate(\$CODE, $name, $ctor, $dtor, $class, X $thing->{rconst}, $thing->{rtype}, X map { $_->{name} } @args); X $CODE .= "} /* switch(items) */ \n"; X } X elsif ($void) { X $CODE .= "\t"; X call_or_instantiate(\$CODE, $name, $ctor, $dtor, $class, 0, '', X map { $_->{name} } @args); X } X elsif ($ellipsis or $thing->{rconst}) { X $CODE .= "\t"; X $CODE .= "RETVAL = "; X call_or_instantiate(\$CODE, $name, $ctor, $dtor, $class, X $thing->{rconst}, $thing->{rtype}, X map { $_->{name} } @args); X } X if ($void) { X $CODE .= <<'END'; X if (PL_markstack_ptr != __temp_markstack_ptr) { X /* truly void, because dXSARGS not invoked */ X PL_markstack_ptr = __temp_markstack_ptr; X XSRETURN_EMPTY; /* return empty stack */ X } X /* must have used dXSARGS; list context implied */ X return; /* assume stack size is correct */ XEND X } X elsif ($ellipsis) { X $CODE .= "\tPL_markstack_ptr = __temp_markstack_ptr;\n"; X } X X # The actual function: X $XS .= "PREINIT:\n$PREINIT" if length $PREINIT; X $XS .= "PP" if $void; X $XS .= "CODE:\n$CODE" if length $CODE; X $XS .= "OUTPUT:\nRETVAL\n" X if (length $CODE and not $void); X $XS .= "\n"; X return $XS; X} X Xsub call_or_instantiate { X my $text_ref = shift; X my ($name, $ctor, $dtor, $class, $const, $type, @args) = @_; X X # Create an rvalue (which might be const-casted later). X my $rval = ''; X $rval .= "new " if $ctor; X $rval .= "delete " if $dtor; X $rval .= "THIS->" if ($class and not ($ctor or $dtor)); X $rval .= "$name(" . join (',', @args) . ")"; X X $$text_ref .= const_cast($rval, $const, $type); X $$text_ref .= ";\n"; # this is a convenience X} X Xsub const_cast { X my $value = shift; X my $const = shift; X my $type = shift; X return $value unless $const and $type =~ /\*|\&/; X return "const_cast<$type>($value)"; X} X Xsub write_typemap { X my $o = shift; X my $filename = "$o->{API}{build_dir}/CPP.map"; X my $type_kind = $o->{ILSM}{typeconv}{type_kind}; X my $typemap = ""; X $typemap .= $_ . "\t"x2 . $TYPEMAP_KIND . "\n" X for grep { $type_kind->{$_} eq $TYPEMAP_KIND } keys %$type_kind; X return unless length $typemap; X open TYPEMAP, "> $filename" X or croak "Error: Can't write to $filename: $!"; X print TYPEMAP <{ILSM}{typeconv}{output_expr}{$TYPEMAP_KIND} XINPUT X$TYPEMAP_KIND X$o->{ILSM}{typeconv}{input_expr}{$TYPEMAP_KIND} XEND X close TYPEMAP; X $o->validate(TYPEMAPS => $filename); X} X X# Generate type conversion code: perl2c or c2perl. Xsub typeconv { X my $o = shift; X my $var = shift; X my $arg = shift; X my $type = shift; X my $dir = shift; X my $preproc = shift; X my $tkind = $o->{ILSM}{typeconv}{type_kind}{$type}; X my $ret = X eval qq{qq{$o->{ILSM}{typeconv}{$dir}{$tkind}}}; X chomp $ret; X $ret =~ s/\n/\\\n/g if $preproc; X return $ret; X} X X1; X X__END__ END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP.pm echo c - p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP > /dev/null 2>&1 echo x - p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP/.exists sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP/.exists << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP/.exists' END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP/.exists echo x - p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP/grammar.pm sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP/grammar.pm << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP/grammar.pm' Xpackage Inline::CPP::grammar; X Xuse strict; Xuse vars qw($TYPEMAP_KIND $VERSION); X$VERSION = '0.23'; X X#============================================================================ X# Regular expressions to match code blocks, numbers, strings, parenthesized X# expressions, function calls, and macros. The more complex regexes are only X# implemented in 5.6.0 and above, so they're in eval-blocks. X# X# These are all adapted from the output of Damian Conway's excellent X# Regexp::Common module. In future, Inline::CPP may depend directly on it, X# but for now I'll just duplicate the code. Xuse vars qw($code_block $string $number $parens $funccall); X#============================================================================ Xeval <<'END'; # $RE{balanced}{-parens=>q|{}()[]"'|} X$code_block = qr'(?-xism:(?-xism:(?:[{](?:(?>[^][)(}{]+)|(??{$Inline::CPP::grammar::code_block}))*[}]))|(?-xism:(?-xism:(?:[(](?:(?>[^][)(}{]+)|(??{$Inline::CPP::grammar::code_block}))*[)]))|(?-xism:(?-xism:(?:[[](?:(?>[^][)(}{]+)|(??{$Inline::CPP::grammar::code_block}))*[]]))|(?-xism:(?!)))))'; XEND X$code_block = qr'{[^}]*}' if $@; # For the stragglers: here's a lame regexp. X Xeval <<'END'; # $RE{balanced}{-parens=>q|()"'|} X$parens = qr'(?-xism:(?-xism:(?:[(](?:(?>[^)(]+)|(??{$Inline::CPP::grammar::parens}))*[)]))|(?-xism:(?!)))'; XEND X$parens = qr'\([^)]*\)' if $@; # For the stragglers: here's another X X# $RE{quoted} X$string = qr'(?:(?:\")(?:[^\\\"]*(?:\\.[^\\\"]*)*)(?:\")|(?:\')(?:[^\\\']*(?:\\.[^\\\']*)*)(?:\')|(?:\`)(?:[^\\\`]*(?:\\.[^\\\`]*)*)(?:\`))'; X X# $RE{num}{real}|$RE{num}{real}{-base=>16}|$RE{num}{int} X$number = qr'(?:(?i)(?:[+-]?)(?:(?=[0123456789]|[.])(?:[0123456789]*)(?:(?:[.])(?:[0123456789]{0,}))?)(?:(?:[E])(?:(?:[+-]?)(?:[0123456789]+))|))|(?:(?i)(?:[+-]?)(?:(?=[0123456789ABCDEF]|[.])(?:[0123456789ABCDEF]*)(?:(?:[.])(?:[0123456789ABCDEF]{0,}))?)(?:(?:[G])(?:(?:[+-]?)(?:[0123456789ABCDEF]+))|))|(?:(?:[+-]?)(?:\d+))'; X$funccall = qr/[_a-zA-Z][_a-zA-Z0-9]*(?:$Inline::CPP::grammar::parens)?/; X X#============================================================================ X# Inline::CPP's grammar X#============================================================================ Xsub grammar { X <<'END'; X X{ use Data::Dumper; } X Xcode: part(s) {1} X Xpart: comment X | class_def X { X# print "Found a class: $item[1]->[0]\n"; X my $class = $item[1]->[0]; X my @parts; X for my $part (@{$item[1]->[1]}) { push @parts, @$_ for @$part } X push @{$thisparser->{data}{classes}}, $class X unless defined $thisparser->{data}{class}{$class}; X $thisparser->{data}{class}{$class} = \@parts; X# print "Class:\n", Dumper \@parts; X Inline::CPP::grammar::typemap($thisparser, $class); X 1; X } X | function_def X { X# print "found a function: $item[1]->{name}\n"; X my $name = $item[1]->{name}; X my $i=0; X for my $arg (@{$item[1]->{args}}) { X $arg->{name} = 'dummy' . ++$i unless defined $arg->{name}; X } X Inline::CPP::grammar::strip_ellipsis($thisparser, X $item[1]->{args}); X push @{$thisparser->{data}{functions}}, $name X unless defined $thisparser->{data}{function}{$name}; X $thisparser->{data}{function}{$name} = $item[1]; X# print Dumper $item[1]; X 1; X } X | all X Xclass_def: class IDENTIFIER '{' class_part(s) '}' ';' X { X# print "Found a class definition: $item[2]\n"; X [@item[2,4]] X } X | class IDENTIFIER ':' '{' class_part(s) '}' ';' X { X# print "Found a class definition: $item[2]\n"; X push @{$item[6]}, [$item[4]]; X [@item[2,6]] X } X Xinherit: scope IDENTIFIER X { {thing => 'inherits', name => $item[2], scope => $item[1]} } X Xclass_part: comment { [ {thing => 'comment'} ] } X | scope ':' class_decl(s) X { X for my $part (@{$item[3]}) { X $_->{scope} = $item[1] for @$part; X } X $item[3] X } X | class_decl(s) X { X for my $part (@{$item[1]}) { X $_->{scope} = $thisparser->{data}{defaultscope} X for @$part; X } X $item[1] X } X Xclass_decl: comment { [{thing => 'comment'}] } X | method_def X { X $item[1]->{thing} = 'method'; X# print "class_decl found a method: $item[1]->{name}\n"; X my $i=0; X for my $arg (@{$item[1]->{args}}) { X $arg->{name} = 'dummy' . ++$i unless defined $arg->{name}; X } X Inline::CPP::grammar::strip_ellipsis($thisparser, X $item[1]->{args}); X [$item[1]]; X } X | member_def X { X# print "class_decl found one or more members:\n", Dumper(\@item); X $_->{thing} = 'member' for @{$item[1]}; X $item[1]; X } X Xfunction_def: rtype IDENTIFIER '(' (s?) ')' ';' X { X {rtype => $item[1], name => $item[2], args => $item[4]} X } X | rtype IDENTIFIER '(' (s?) ')' code_block X { X {rtype => $item[1], name => $item[2], args => $item[4]} X } X Xmethod_def: IDENTIFIER '(' (s?) ')' method_imp X { X# print "con-/de-structor found: $item[1]\n"; X {name => $item[1], args => $item[3], abstract => ${$item[5]}}; X } X | rtype IDENTIFIER '(' (s?) ')' method_imp X { X# print "method found: $item[2]\n"; X $return = X {name => $item[2], rtype => $item[1], args => $item[4], X abstract => ${$item[6]}, X rconst => $thisparser->{data}{smod}{const}, X }; X $thisparser->{data}{smod}{const} = 0; X } X X# By adding smod, we allow 'const' member functions. This would also bind to X# incorrect C++ with the word 'static' after the argument list, but we don't X# care at all because such code would never be compiled successfully. X X# By adding init, we allow constructors to initialize references. Again, we'll X# allow them anywhere, but our goal is not to enforce c++ standards -- that's X# the compiler's job. Xmethod_imp: smod(?) ';' { \0 } X | smod(?) initlist(?) code_block { \0 } X | smod(?) '=' '0' ';' { \1 } X | smod(?) '=' '0' code_block { \0 } X Xinitlist: ':' X Xmember_def: anytype ';' X { X my @retval; X for my $def (@{$item[2]}) { X my $type = join '', $item[1], @{$def->[0]}; X my $name = $def->[1]; X# print "member found: type=$type, name=$name\n"; X push @retval, { name => $name, type => $type }; X } X \@retval; X } X Xvar: star(s?) IDENTIFIER '=' expr { [@item[1,2]] } X | star(s?) IDENTIFIER { [@item[1,2]] } X Xarg: type IDENTIFIER '=' expr X { X# print "argument $item[2] found\n"; X# print "expression: $item[4]\n"; X {type => $item[1], name => $item[2], optional => 1, X offset => $thisoffset} X } X | type IDENTIFIER X { X# print "argument $item[2] found\n"; X {type => $item[1], name => $item[2], offset => $thisoffset} X } X | type { {type => $item[1]} } X | '...' X { {name => '...', type => '...', offset => $thisoffset} } X XIDENTIFIER: /[~_a-z]\w*/i X { X# print "IDENTIFIER: $item[1]\n"; X $item[1] X } X X# Parse::RecDescent is retarded in this one case: if a subrule fails, it X# gives up the entire rule. This is a stupid way to get around that. Xrtype: rtype2 | rtype1 Xrtype1: TYPE star(s?) X { X $return = $item[1]; X $return .= join '',' ',@{$item[2]} if @{$item[2]}; X# print "rtype1: $return\n"; X return undef X unless(defined$thisparser->{data}{typeconv}{valid_rtypes}{$return}); X } Xrtype2: modifier(s) TYPE star(s?) X { X $return = $item[2]; X $return = join ' ',grep{$_}@{$item[1]},$return X if @{$item[1]}; X $return .= join '',' ',@{$item[3]} if @{$item[3]}; X# print "rtype2: $return\n"; X return undef X unless(defined$thisparser->{data}{typeconv}{valid_rtypes}{$return}); X $return = 'static ' . $return X if $thisparser->{data}{smod}{static}; X $thisparser->{data}{smod}{static} = 0; X } X Xtype: type2 | type1 Xtype1: TYPE star(s?) X { X $return = $item[1]; X $return .= join '',' ',@{$item[2]} if @{$item[2]}; X return undef X unless(defined$thisparser->{data}{typeconv}{valid_types}{$return}); X } Xtype2: modifier(s) TYPE star(s?) X { X $return = $item[2]; X $return = join ' ',grep{$_}@{$item[1]},$return if @{$item[1]}; X $return .= join '',' ',@{$item[3]} if @{$item[3]}; X return undef X unless(defined$thisparser->{data}{typeconv}{valid_types}{$return}); X } X Xanytype: anytype2 | anytype1 Xanytype1: TYPE star(s?) X { X $return = $item[1]; X $return .= join '',' ',@{$item[2]} if @{$item[2]}; X } Xanytype2: modifier(s) TYPE star(s?) X { X $return = $item[2]; X $return = join ' ',grep{$_}@{$item[1]},$return if @{$item[1]}; X $return .= join '',' ',@{$item[3]} if @{$item[3]}; X } X Xcomment: m{\s* // [^\n]* \n }x X | m{\s* /\* (?:[^*]+|\*(?!/))* \*/ ([ \t]*)? }x X X# long and short aren't recognized as modifiers because they break when used X# as regular types. Another Parse::RecDescent problem is greedy matching; I X# need tmodifier to "give back" long or short in cases where keeping them would X# cause the modifier rule to fail. One side-effect is 'long long' can never X# be parsed correctly here. Xmodifier: tmod X | smod { ++$thisparser->{data}{smod}{$item[1]}; ''} X | nmod { '' } Xtmod: 'unsigned' # | 'long' | 'short' Xsmod: 'const' | 'static' Xnmod: 'extern' | 'virtual' | 'mutable' | 'volatile' | 'inline' X Xscope: 'public' | 'private' | 'protected' X Xclass: 'class' { $thisparser->{data}{defaultscope} = 'private'; $item[1] } X | 'struct' { $thisparser->{data}{defaultscope} = 'public'; $item[1] } X Xstar: '*' | '&' X Xcode_block: /$Inline::CPP::grammar::code_block/ X X# Consume expressions Xexpr: { X my $o = join '', @{$item[1]}; X# print "expr: $o\n"; X $o; X} Xsubexpr: /$Inline::CPP::grammar::funccall/ # Matches a macro, too X | /$Inline::CPP::grammar::string/ X | /$Inline::CPP::grammar::number/ X | UOP subexpr XOP: '+' | '-' | '*' | '/' | '^' | '&' | '|' | '%' | '||' | '&&' XUOP: '~' | '!' | '-' | '*' | '&' X XTYPE: /\w+/ X Xall: /.*/ X XEND X X} X X#============================================================================ X# Generate typemap code for the classes and structs we bind to. This allows X# functions declared after a class to return or accept class objects as X# parameters. X#============================================================================ X$TYPEMAP_KIND = 'O_Inline_CPP_Class'; Xsub typemap { X my $parser = shift; X my $typename = shift; X X# print "Inline::CPP::grammar::typemap(): typename=$typename\n"; X X my ($TYPEMAP, $INPUT, $OUTPUT); X $TYPEMAP = "$typename *\t\t$TYPEMAP_KIND\n"; X $INPUT = <{data}{typeconv}{input_expr}{$TYPEMAP_KIND} ||= $INPUT; X $parser->{data}{typeconv}{output_expr}{$TYPEMAP_KIND} ||= $OUTPUT; X $parser->{data}{typeconv}{type_kind}{$ctypename} = $TYPEMAP_KIND; X $parser->{data}{typeconv}{valid_types}{$ctypename}++; X $parser->{data}{typeconv}{valid_rtypes}{$ctypename}++; X} X X#============================================================================ X# Default action is to strip ellipses from the C++ code. This allows having X# _only_ a '...' in the code, just like XS. It is the default. X#============================================================================ Xsub strip_ellipsis { X my $parser = shift; X my $args = shift; X return if $parser->{ILSM}{PRESERVE_ELLIPSIS}; X for (my $i=0; $i<@$args; $i++) { X next unless $args->[$i]{name} eq '...'; X # if it's the first one, just strip it X if ($i==0) { X substr($parser->{ILSM}{code}, $args->[$i]{offset} - 3, 3) = " "; X } X else { X my $prev = $i - 1; X my $prev_offset = $args->[$prev]{offset}; X my $length = $args->[$i]{offset} - $prev_offset; X substr($parser->{ILSM}{code}, $prev_offset, $length) =~ s/\S/ /g; X } X } X} END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/Inline/CPP/grammar.pm echo c - p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto > /dev/null 2>&1 echo c - p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline > /dev/null 2>&1 echo c - p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP > /dev/null 2>&1 echo x - p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP/.exists sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP/.exists << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP/.exists' END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP/.exists echo c - p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP/grammar mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP/grammar > /dev/null 2>&1 echo x - p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP/grammar/.exists sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP/grammar/.exists << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP/grammar/.exists' END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/lib/auto/Inline/CPP/grammar/.exists echo c - p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch > /dev/null 2>&1 echo c - p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto > /dev/null 2>&1 echo c - p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline > /dev/null 2>&1 echo c - p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP > /dev/null 2>&1 echo x - p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP/.exists sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP/.exists << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP/.exists' END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP/.exists echo c - p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP/grammar mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP/grammar > /dev/null 2>&1 echo x - p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP/grammar/.exists sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP/grammar/.exists << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP/grammar/.exists' END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/arch/auto/Inline/CPP/grammar/.exists echo c - p5-Inline-CPP/work/Inline-CPP-0.23/blib/man3 mkdir -p p5-Inline-CPP/work/Inline-CPP-0.23/blib/man3 > /dev/null 2>&1 echo x - p5-Inline-CPP/work/Inline-CPP-0.23/blib/man3/.exists sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/blib/man3/.exists << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/man3/.exists' END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/man3/.exists echo x - p5-Inline-CPP/work/Inline-CPP-0.23/blib/man3/Inline::CPP.3 sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/blib/man3/Inline::CPP.3 << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/man3/Inline::CPP.3' X.rn '' }` X''' $RCSfile$$Revision$$Date$ X''' X''' $Log$ X''' X.de Sh X.br X.if t .Sp X.ne 5 X.PP X\fB\\$1\fR X.PP X.. X.de Sp X.if t .sp .5v X.if n .sp X.. X.de Ip X.br X.ie \\n(.$>=3 .ne \\$3 X.el .ne 3 X.IP "\\$1" \\$2 X.. X.de Vb X.ft CW X.nf X.ne \\$1 X.. X.de Ve X.ft R X X.fi X.. X''' X''' X''' Set up \*(-- to give an unbreakable dash; X''' string Tr holds user defined translation string. X''' Bell System Logo is used as a dummy character. X''' X.tr \(*W-|\(bv\*(Tr X.ie n \{\ X.ds -- \(*W- X.ds PI pi X.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch X.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch X.ds L" "" X.ds R" "" X''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of X''' \*(L" and \*(R", except that they are used on ".xx" lines, X''' such as .IP and .SH, which do another additional levels of X''' double-quote interpretation X.ds M" """ X.ds S" """ X.ds N" """"" X.ds T" """"" X.ds L' ' X.ds R' ' X.ds M' ' X.ds S' ' X.ds N' ' X.ds T' ' X'br\} X.el\{\ X.ds -- \(em\| X.tr \*(Tr X.ds L" `` X.ds R" '' X.ds M" `` X.ds S" '' X.ds N" `` X.ds T" '' X.ds L' ` X.ds R' ' X.ds M' ` X.ds S' ' X.ds N' ` X.ds T' ' X.ds PI \(*p X'br\} X.\" If the F register is turned on, we'll generate X.\" index entries out stderr for the following things: X.\" TH Title X.\" SH Header X.\" Sh Subsection X.\" Ip Item X.\" X<> Xref (embedded X.\" Of course, you have to process the output yourself X.\" in some meaninful fashion. X.if \nF \{ X.de IX X.tm Index:\\$1\t\\n%\t"\\$2" X.. X.nr % 0 X.rr F X.\} X.TH CPP 1 "perl 5.005, patch 03" "8/Jul/2001" "User Contributed Perl Documentation" X.UC X.if n .hy 0 X.if n .na X.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' X.de CQ \" put $1 in typewriter font X.ft CW X'if n "\c X'if t \\&\\$1\c X'if n \\&\\$1\c X'if n \&" X\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7 X'.ft R X.. X.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2 X. \" AM - accent mark definitions X.bd B 3 X. \" fudge factors for nroff and troff X.if n \{\ X. ds #H 0 X. ds #V .8m X. ds #F .3m X. ds #[ \f1 X. ds #] \fP X.\} X.if t \{\ X. ds #H ((1u-(\\\\n(.fu%2u))*.13m) X. ds #V .6m X. ds #F 0 X. ds #[ \& X. ds #] \& X.\} X. \" simple accents for nroff and troff X.if n \{\ X. ds ' \& X. ds ` \& X. ds ^ \& X. ds , \& X. ds ~ ~ X. ds ? ? X. ds ! ! X. ds / X. ds q X.\} X.if t \{\ X. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" X. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' X. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' X. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' X. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' X. ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10' X. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m' X. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' X. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10' X.\} X. \" troff and (daisy-wheel) nroff accents X.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' X.ds 8 \h'\*(#H'\(*b\h'-\*(#H' X.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#] X.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u' X.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u' X.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#] X.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] X.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' X.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' X.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] X.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] X.ds ae a\h'-(\w'a'u*4/10)'e X.ds Ae A\h'-(\w'A'u*4/10)'E X.ds oe o\h'-(\w'o'u*4/10)'e X.ds Oe O\h'-(\w'O'u*4/10)'E X. \" corrections for vroff X.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' X.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' X. \" for low resolution devices (crt and lpr) X.if \n(.H>23 .if \n(.V>19 \ X\{\ X. ds : e X. ds 8 ss X. ds v \h'-1'\o'\(aa\(ga' X. ds _ \h'-1'^ X. ds . \h'-1'. X. ds 3 3 X. ds o a X. ds d- d\h'-1'\(ga X. ds D- D\h'-1'\(hy X. ds th \o'bp' X. ds Th \o'LP' X. ds ae ae X. ds Ae AE X. ds oe oe X. ds Oe OE X.\} X.rm #[ #] #H #V #F C X.SH "NAME" XInline::CPP \- Write Perl subroutines and classes in \*(C+. X.SH "SYNOPSIS" X.PP X.Vb 1 X\& use Inline CPP; X.Ve X.Vb 2 X\& print "9 + 16 = ", add(9, 16), "\en"; X\& print "9 - 16 = ", subtract(9, 16), "\en"; X.Ve X.Vb 2 X\& __END__ X\& __CPP__ X.Ve X.Vb 3 X\& int add(int x, int y) { X\& return x + y; X\& } X.Ve X.Vb 3 X\& int subtract(int x, int y) { X\& return x - y; X\& } X.Ve X.Vb 1 X\& END_OF_CPP_CODE X.Ve X.SH "DESCRIPTION" XThe \f(CWInline::CPP\fR module allows you to put \*(C+ source code directly X\*(L"inline\*(R" in a Perl script or module. You code classes or functions in X\*(C+, and you can use them as if they were written in Perl. X.SH "Choosing a \*(C+ Compiler" XInline::CPP just parses your \*(C+ code and creates bindings to it. Like XInline::C, you will need a suitable compiler the first time you run the Xscript. Choosing a \*(C+ compiler can prove difficult, because Perl is Xwritten in C, not \*(C+. X.PP XHere's the rule: use any \*(C+ compiler that's compatible with the compiler Xwhich built perl. For instance, if perl was built with \f(CWgcc\fR, use \f(CWg++\fR. XIf you're on a Sun or an IRIX box and the system C compiler \f(CWcc\fR built perl, Xthen use the system \*(C+ compiler, \f(CWCC\fR. X.PP XSome compilers actually compile both C and \*(C+ with the same compiler. XMicrosoft's \f(CWcl.exe\fR is one such compiler -- you pass it the <\-TP> flag Xto convince it that you want \*(C+ mode. X.SH "Using Inline::CPP" XInline::CPP is very similar to Inline::C. It uses a grammar to Xparse your \*(C+ code, and binds to functions or classes which are Xrecognized. If a function is recognized, it will be available from XPerl space. If the function's signature is not recognized, it will not Xbe available from Perl space, but will be available from other Xfunctions in \*(C+. X.PP XFor more information about the grammar used to parse \*(C+ code, see the Xsection called \*(L"Grammar\*(R". X.PP XThe following example shows how \*(C+ snippets map into the Perl Xnamespace: X.PP XExample 1: X.PP X.Vb 1 X\& use Inline CPP => <<'END'; X.Ve X.Vb 1 X\& int doodle() { } X.Ve X.Vb 4 X\& class Foo { X\& public: X\& Foo(); X\& ~Foo(); X.Ve X.Vb 5 X\& int get_data() { return data; } X\& void set_data(int a) { data = a; } X\& private: X\& int data; X\& }; X.Ve X.Vb 2 X\& Foo::Foo() { cout << "creating a Foo()" << endl; } X\& Foo::~Foo() { cout << "deleting a Foo()" << endl; } X.Ve X.Vb 1 X\& END X.Ve XAfter running the code above, Perl's namespace would look similar to if Xfollowing code had been run: X.PP X.Vb 1 X\& sub main::doodle { } X.Ve X.Vb 1 X\& package main::Foo; X.Ve X.Vb 2 X\& sub new { print "creating a Foo()\en"; bless {}, shift } X\& sub DESTROY { print "deleting a Foo()\en" } X.Ve X.Vb 2 X\& sub get_data { my $o=shift; $o->{data} } X\& sub set_data { my $o=shift; $o->{data} = shift } X.Ve XThe difference, of course, is that in the latter, Perl does the work. In the XInline::CPP example, all function calls get sent off to your \*(C+ code. That Xmeans that things like this won't work: X.PP X.Vb 2 X\& my $obj = new Foo; X\& $obj->{extrafield} = 10; X.Ve XIt doesn't work because \f(CW$obj\fR is not a blessed hash. It's a blessed Xreference to a \*(C+ object (and anyway, \*(C+ wouldn't let you do that either, Xsince extrafield wasn't defined). X.SH "\*(C+ Configuration Options" XFor information on how to specify Inline configuration options, see Xthe \fIInline\fR manpage. This section describes each of the configuration options Xavailable for C. Most of the options correspond either the MakeMaker Xor XS options of the same name. See the \fIExtUtils::MakeMaker\fR manpage and Xthe \fIperlxs\fR manpage. X.Sh "\s-1ALTLIBS\s0" XAdds a new entry to the end of the list of alternative libraries to Xbind with. MakeMaker will search through this list and use the first Xentry where all the libraries are found. X.PP X.Vb 1 X\& use Inline Config => ALTLIBS => '-L/my/other/lib -lfoo'; X.Ve XSee also the \s-1LIBS\s0 config option, which appends to the last entry in Xthe list. X.Sh "\s-1AUTO_INCLUDE\s0" XSpecifies extra statements to be automatically included. They will be Xadded on to the defaults. A newline char will automatically be added. X.PP X.Vb 1 X\& use Inline Config => AUTO_INCLUDE => '#include "something.h"'; X.Ve X.Sh "\s-1BOOT\s0" XSpecifies code to be run when your code is loaded. May not contain any Xblank lines. See the \fIperlxs\fR manpage for more information. X.PP X.Vb 1 X\& use Inline Config => BOOT => 'foo();'; X.Ve X.Sh "\s-1CC\s0" XSpecifies which compiler to use. X.Sh "\s-1CCFLAGS\s0" XSpecifies extra compiler flags. Corresponds to the MakeMaker option. X.Sh "\s-1FILTERS\s0" XSpecifies one (or more, in an array ref) filter which is to be applied to Xthe code just prior to parsing. The filters are executed one after another, Xeach operating on the output of the previous one. You can pass in a code Xreference or the name of a prepackaged filter. X.PP X.Vb 1 X\& use Inline Config => FILTERS => [Strip_POD => \e&myfilter]; X.Ve XThe filter may do anything. The code is passed as the first argument, and Xit returns the filtered code. X.Sh "\s-1INC\s0" XSpecifies extra include directories. Corresponds to the MakeMaker Xparameter. X.PP X.Vb 1 X\& use Inline Config => INC => '-I/my/path'; X.Ve X.Sh "\s-1LD\s0" XSpecifies the linker to use. X.Sh "\s-1LDDLFLAGS\s0" XSpecifies which linker flags to use. X.PP X\s-1NOTE\s0: These flags will completely override the existing flags, instead Xof just adding to them. So if you need to use those too, you must Xrespecify them here. X.Sh "\s-1LIBS\s0" XSpecifies external libraries that should be linked into your Xcode. Corresponds to the MakeMaker parameter. X.PP X.Vb 1 X\& use Inline Config => LIBS => '-L/your/path -lyourlib'; X.Ve XUnlike the \s-1LIBS\s0 configuration parameter used in Inline::C, successive Xcalls to \s-1LIBS\s0 append to the previous calls. For example, X.PP X.Vb 1 X\& use Inline Config => LIBS => '-L/my/path', LIBS => '-lyourlib'; X.Ve Xwill work correctly. If you want to add a new element to the list of Xpossible libraries to link with, use the Inline::\s-1CPP\s0 configuration \s-1ALTLIBS\s0. X.Sh "\s-1MAKE\s0" XSpecifies the name of the \*(L'make\*(R' utility to use. X.Sh "\s-1MYEXTLIB\s0" XSpecifies a user compiled object that should be linked in. Corresponds Xto the MakeMaker parameter. X.PP X.Vb 1 X\& use Inline Config => MYEXTLIB => '/your/path/something.o'; X.Ve X.Sh "\s-1PREFIX\s0" XSpecifies a prefix that will automatically be stripped from \*(C+ Xfunctions when they are bound to Perl. Less useful than in C, because X\*(C+ mangles its function names so they don't conflict with C functions Xof the same name. X.PP X.Vb 1 X\& use Inline Config => PREFIX => 'ZLIB_'; X.Ve XThis only affects \*(C+ function names, not \*(C+ class names or methods. X.Sh "\s-1PRESERVE_ELLIPSIS\s0" XBy default, Inline::\s-1CPP\s0 replaces \f(CW...\fR in bound functions with three Xspaces, since the arguments are always passed on the Perl Stack, not on Xthe C stack. This is usually desired, since it allows functions with Xno fixed arguments (most compilers require at least one fixed argument). X.PP X.Vb 3 X\& use Inline Config => PRESERVE_ELLIPSIS => 1; X\&or X\& use Inline Config => ENABLE => PRESERVE_ELLIPSIS; X.Ve XFor an example of why \s-1PRESERVE_ELLIPSIS\s0 is normally not needed, see the Xexamples section, below. X.Sh "\s-1STD_IOSTREAM\s0" XBy default, Inline::\s-1CPP\s0 includes \f(CWiostream.h\fR at the top of your code. This Xoption makes it include \f(CWiostream\fR instead, which is the \s-1ANSI\s0\-compliant Xversion of the makefile. On non-\s-1GNU\s0 implementations, these files are not Xcompatible with one another. X.PP X.Vb 1 X\& use Inline CPP => Config => ENABLE => STD_IOSTREAM; X.Ve X.Sh "\s-1STRUCTS\s0" XSpecifies whether to bind C structs into Perl using Inline::Struct. X\s-1NOTE\s0: Support for this option is experimental. Inline::\s-1CPP\s0 already binds Xto structs defined in your code. Structs and classes are treated as the Xsame construct, except that a struct's initial scope is public, not Xprivate. Inline::Struct provides autogenerated get/set methods, an Xoverloaded constructor, and several other features not available in XInline::\s-1CPP\s0. X.PP XYou can invoke \s-1STRUCTS\s0 in several ways: X.PP X.Vb 3 X\& use Inline Config => STRUCTS => 'Foo'; X\&or X\& use Inline Config => STRUCTS => ['Bar', 'Baz']; X.Ve XBinds the named structs to Perl. Emits warnings if a struct was requested Xbut could not be bound for some reason. X.PP X.Vb 3 X\& use Inline Config => ENABLE => 'STRUCTS'; X\&or X\& use Inline Config => STRUCTS => 1; X.Ve XEnables binding structs to Perl. All structs which can be bound, will. This Xparameter overrides all requests for particular structs. X.PP X.Vb 3 X\& use Inline Config => DISABLE => 'STRUCTS'; X\&or X\& use Inline Config => STRUCTS => 0; X.Ve XDisables binding structs to Perl. Overrides any other settings. X.PP XSee the \fIInline::Struct\fR manpage for more details about how \f(CWInline::Struct\fR Xbinds C structs to Perl. X.Sh "\s-1TYPEMAPS\s0" XSpecifies extra typemap files to use. These types will modify the Xbehaviour of \*(C+ parsing. Corresponds to the MakeMaker parameter. X.PP X.Vb 1 X\& use Inline Config => TYPEMAPS => '/your/path/typemap'; X.Ve X.SH "\*(C+\-Perl Bindings" XThis section describes how the \f(CWPerl\fR variables get mapped to \f(CWC++\fR Xvariables and back again. X.PP XPerl uses a stack to pass arguments back and forth to subroutines. When Xa sub is called, it pops off all its arguments from the stack; when it's Xdone, it pushes its return values back onto the stack. X.PP XXS (Perl's language for creating C or \*(C+ extensions for Perl) uses X\*(L"typemaps\*(R" to turn SVs into C types and back again. This is done through Xvarious XS macro calls, casts, and the Perl API. XS also allows you to Xdefine your own mappings. X.PP X\f(CWInline::CPP\fR uses a much simpler approach. It parses the system's Xtypemap files and only binds to functions with supported types. You Xcan tell \f(CWInline::CPP\fR about custom typemap files too. X.PP XIf you have very complicated data structures in either \*(C+ or Perl, Xyou should just pass them as an SV* and do the conversion yourself in Xyour \*(C+ function. X.PP XIn \*(C+, a struct is a class whose default scope is public, not Xprivate. Inline::CPP binds to structs with this in mind -- get/set Xmethods are not yet auto-generated (although they are scheduled to Xland in an upcoming release). X.PP XIf you have a C struct, you can use Inline::Struct to allow Perl Xcomplete access to the internals of the struct. You can create and Xmodify structs from inside Perl, as well as pass structs into \*(C+ Xfunctions and return them from functions. Please note that XInline::Struct does not understand any \*(C+ features, so constructors Xand member functions are not supported. See the \fIInline::Struct\fR manpage for more Xdetails. X.SH "EXAMPLES" XHere are some examples. X.Sh "Example 1 \- Farmer Bob" XThis example illustrates how to use a simple class (\f(CWFarmer\fR) from XPerl. One of the new features in Inline::\s-1CPP\s0 is binding to classes Xwith inline method definitions: X.PP X.Vb 1 X\& use Inline CPP; X.Ve X.Vb 6 X\& my $farmer = new Farmer("Ingy", 42); X\& my $slavedriver = 1; X\& while($farmer->how_tired < 420) { X\& $farmer->do_chores($slavedriver); X\& $slavedriver <<= 1; X\& } X.Ve X.Vb 1 X\& print "Wow! The farmer worked ", $farmer->how_long, " hours!\en"; X.Ve X.Vb 2 X\& __END__ X\& __CPP__ X.Ve X.Vb 4 X\& class Farmer { X\& public: X\& Farmer(char *name, int age); X\& ~Farmer(); X.Ve X.Vb 3 X\& int how_tired() { return tiredness; } X\& int how_long() { return howlong; } X\& void do_chores(int howlong); X.Ve X.Vb 6 X\& private: X\& char *name; X\& int age; X\& int tiredness; X\& int howlong; X\& }; X.Ve X.Vb 6 X\& Farmer::Farmer(char *name, int age) { X\& this->name = strdup(name); X\& this->age = age; X\& tiredness = 0; X\& howlong = 0; X\& } X.Ve X.Vb 3 X\& Farmer::~Farmer() { X\& free(name); X\& } X.Ve X.Vb 4 X\& void Farmer::do_chores(int hl) { X\& howlong += hl; X\& tiredness += (age * hl); X\& } X.Ve X.Sh "Example 2 \- Plane and Simple" XThis example demonstrates some new features of Inline::\s-1CPP\s0: support for Xinheritance and abstract classes. The defined methods of the abstract Xclass \f(CWObject\fR are bound to Perl, but there is no constructor or Xdestructor, meaning you cannot instantiate an \f(CWObject\fR. X.PP XThe \f(CWAirplane\fR is a fully-bound class which can be created and Xmanipulated from Perl. X.PP X.Vb 1 X\& use Inline CPP; X.Ve X.Vb 4 X\& my $plane = new Airplane; X\& $plane->print; X\& if ($plane->isa("Object")) { print "Plane is an Object!\en"; } X\& unless ($plane->can("fly")) { print "This plane sucks!\en"; } X.Ve X.Vb 2 X\& __END__ X\& __CPP__ X.Ve X.Vb 8 X\& /* Abstract class (interface) */ X\& class Object { X\& public: X\& virtual void print() { cout << "Object (" << this << ")" << endl; } X\& virtual void info() = 0; X\& virtual bool isa(char *klass) = 0; X\& virtual bool can(char *method) = 0; X\& }; X.Ve X.Vb 4 X\& class Airplane : public Object { X\& public: X\& Airplane() {} X\& ~Airplane() {} X.Ve X.Vb 11 X\& virtual void info() { print(); } X\& virtual bool isa(char *klass) { return strcmp(klass, "Object")==0; } X\& virtual bool can(char *method) { X\& bool yes = false; X\& yes |= strcmp(method, "print")==0; X\& yes |= strcmp(method, "info")==0; X\& yes |= strcmp(method, "isa")==0; X\& yes |= strcmp(method, "can")==0; X\& return yes; X\& } X\& }; X.Ve X.Sh "Example 3 \- The Ellipsis Abridged" XOne of the big advantages of Perl over C or \*(C+ is the ability to pass an Xarbitrary number of arguments to a subroutine. You can do it in C, but it's Xmessy and difficult to get it right. All of this mess is necessary because XC doesn't give the programmer access to the stack. Perl, on the other hand, Xgives you access to everything. X.PP XHere's a useful function written in Perl that is relatively slow: X.PP X.Vb 9 X\& sub average { X\& my $average = 0; X\& for (my $i=0; $i<@_; $i++) { X\& $average *= $i; X\& $average += $_[$i]; X\& $average /= $i + 1; X\& } X\& return $average; X\& } X.Ve XHere's the same function written in C: X.PP X.Vb 10 X\& double average() { X\& Inline_Stack_Vars; X\& double avg = 0.0; X\& for (int i=0; iq(50); X\& $q->q("Where am I?"); X\& $q->q("In a queue."); X\& print "There are ", $q->size, " items in the queue\en"; X\& while($q->size) { X\& print "About to dequeue: ", $q->peek, "\en"; X\& print "Actually dequeued: ", $q->dq, "\en"; X\& } X.Ve X.Vb 8 X\& my $s = new Stack; X\& $s->push(42); X\& $s->push("What?"); X\& print "There are ", $s->size, " items on the stack\en"; X\& while($s->size) { X\& print "About to pop: ", $s->peek, "\en"; X\& print "Actually popped: ", $s->pop, "\en"; X\& } X.Ve X.Vb 2 X\& __END__ X\& __CPP__ X.Ve X.Vb 4 X\& class Queue { X\& public: X\& Queue(int sz=0) { q = newAV(); if (sz) av_extend(q, sz-1); } X\& ~Queue() { av_undef(q); } X.Ve X.Vb 1 X\& int size() {return av_len(q) + 1; } X.Ve X.Vb 3 X\& int q(SV *item) { av_push(q, SvREFCNT_inc(item)); return av_len(q)+1; } X\& SV *dq() { return av_shift(q); } X\& SV *peek() { return size() ? SvREFCNT_inc(*av_fetch(q,0,0)): &PL_sv_undef;} X.Ve X.Vb 3 X\& private: X\& AV *q; X\& }; X.Ve X.Vb 4 X\& class Stack { X\& public: X\& Stack(int sz=0) { s = newAV(); if (sz) av_extend(s, sz-1); } X\& ~Stack() { av_undef(s); } X.Ve X.Vb 1 X\& int size() { return av_len(s) + 1; } X.Ve X.Vb 3 X\& int push(SV *i) { av_push(s, SvREFCNT_inc(i)); return av_len(s)+1; } X\& SV *pop() { return av_pop(s); } X\& SV *peek() { return size() ? SvREFCNT_inc(*av_fetch(s,size()-1,0)) : &PL_sv_undef; } X.Ve X.Vb 3 X\& private: X\& AV *s; X\& }; X.Ve X.SH "Grammar Details" XPerl 5.6.0 is recommended for Inline::CPP, and is required to get all the Xnew features. If you are using Perl 5.005_03 the package will build and run, Xbut you will have problems in certain circumstances: X.Sh "Inline function definitions" XFor the purposes of this discussion, inline function definitions are best Xdescribed by this example: X.PP X.Vb 4 X\& class Foo { X\& public: X\& Foo() { /* Do something */ } X\& }; X.Ve XThis example shows a class with a constructor defined inline. Inline::\s-1CPP\s0 can Xparse this example with 5.005. But this example requires Perl 5.6.0: X.PP X.Vb 4 X\& class Foo { X\& public: X\& Foo() { if(1) { /* Do something */ } } X\& }; X.Ve XHere's what happened: Inline::\s-1CPP\s0 saw a class, saw the method, then noticed Xit was an inline method. So it grabbed this text: X.PP X.Vb 1 X\& "{ if(1) { /* Do something */ }" X.Ve XAnd then it tried to match another part of the class. But it failed because Xthe next part of the string is this (with newlines trimmed): X.PP X.Vb 1 X\& "} };" X.Ve XThe remaining text doesn't parse right. There are two solutions: X.Ip "a" 4 XUse Perl version 5.6.0 or better; or, X.Ip "b" 4 XMove the definition outside the class. X.Sh "Complex default parameters" XAgain, default parameters are best described by example: X.PP X.Vb 1 X\& int root(double number, int whatroot=2); X.Ve XThis function takes one or two arguments. If the second is missing, \*(C+ gives Xit the value 2. Inline::\s-1CPP\s0 can parse this simple example regardless of your Xperl version. But the following example requires 5.6.0: X.PP X.Vb 1 X\& int root(double number, int whatroot=((2))); X.Ve XThat's because if you're using 5.005, your arguments are parsed with a regular Xexpression that looks for only one closing parenthesis. Any more than that, Xand you get a parse error. X.PP XAgain, there are two solutions: X.Ip "a" 4 XUse Perl version 5.6.0 or better; or, X.Ip "b" 4 XMake the strange expression a constant or macro and use that. X.Sh "Rant: Perl 5.005 is for Dummies" XI'm going to take the opportunity to rant. Everything in the rest of this Xsection can be ignored if you don't want to hear it. X.PP XPerl 5.6.0 has been out for a long time. It's proven, stable, and people use Xit all the time. Perl 5.6.1 is the latest stable release. Unless you depend Xon one of the few modules which are only available for the ancient versions of XPerl, there is \fBabsolutely no reason\fR not to upgrade today! X.SH "SEE ALSO" XFor general information about how \f(CWInline\fR binds code to Perl, see Xthe \fIInline\fR manpage. X.PP XFor information on using C with Perl, see the \fIInline::C\fR manpage and Xthe \fIInline::C\-Cookbook\fR manpage. For \f(CWWMTYEWTK\fR, see the \fIperlxs\fR manpage, Xthe \fIperlxstut\fR manpage, the \fIperlapi\fR manpage, and the \fIperlguts\fR manpage. X.PP XFor information on using C and \*(C+ structs with Perl, see Xthe \fIInline::Struct\fR manpage. X.SH "BUGS AND DEFICIENCIES" XWhen reporting a bug, please do the following: X.PP X.Vb 4 X\& - Put "use Inline REPORTBUG;" at the top of your code, or X\& use the command line option "perl -MInline=REPORTBUG ...". X\& - Run your code. X\& - Follow the printed instructions. X.Ve XHere are some things to watch out for: X.Ip "1" 4 XThe grammar used for parsing \*(C+ is still quite simple, and does not allow Xseveral features of \*(C+: X.Ip "a" 8 Xtemplates X.Ip "b" 8 Xoperator overloading X.Ip "c" 8 Xfunction overloading X.Sp XOther grammar problems will probably be noticed quickly. X.Ip "2" 4 XIn order of relative importance, improvements planned in the near Xfuture are: X.Ip "a" 8 Xsupport for overloaded functions and methods X.Ip "b" 8 Xbinding to constants and constant #defines X.Ip "c" 8 Xbinding to unions X.Ip "d" 8 Xautogenerated get/set methods on public members X.SH "AUTHOR" XNeil Watkiss X.PP XBrian Ingerson is the author of \f(CWInline\fR, X\f(CWInline::C\fR and \f(CWInline::CPR\fR. He is known in the innermost Inline Xcircles as \*(L"Batman\*(R". ;) X.SH "COPYRIGHT" XCopyright (c) 2000 \- 2001, Neil Watkiss. X.PP XAll Rights Reserved. This module is free software. It may be used, Xredistributed and/or modified under the same terms as Perl itself. X.PP XSee http://www.perl.com/perl/misc/Artistic.html X X.rn }` '' X.IX Title "CPP 1" X.IX Name "Inline::CPP - Write Perl subroutines and classes in C++." X X.IX Header "NAME" X X.IX Header "SYNOPSIS" X X.IX Header "DESCRIPTION" X X.IX Header "Choosing a \*(C+ Compiler" X X.IX Header "Using Inline::CPP" X X.IX Header "\*(C+ Configuration Options" X X.IX Subsection "\s-1ALTLIBS\s0" X X.IX Subsection "\s-1AUTO_INCLUDE\s0" X X.IX Subsection "\s-1BOOT\s0" X X.IX Subsection "\s-1CC\s0" X X.IX Subsection "\s-1CCFLAGS\s0" X X.IX Subsection "\s-1FILTERS\s0" X X.IX Subsection "\s-1INC\s0" X X.IX Subsection "\s-1LD\s0" X X.IX Subsection "\s-1LDDLFLAGS\s0" X X.IX Subsection "\s-1LIBS\s0" X X.IX Subsection "\s-1MAKE\s0" X X.IX Subsection "\s-1MYEXTLIB\s0" X X.IX Subsection "\s-1PREFIX\s0" X X.IX Subsection "\s-1PRESERVE_ELLIPSIS\s0" X X.IX Subsection "\s-1STD_IOSTREAM\s0" X X.IX Subsection "\s-1STRUCTS\s0" X X.IX Subsection "\s-1TYPEMAPS\s0" X X.IX Header "\*(C+\-Perl Bindings" X X.IX Header "EXAMPLES" X X.IX Subsection "Example 1 \- Farmer Bob" X X.IX Subsection "Example 2 \- Plane and Simple" X X.IX Subsection "Example 3 \- The Ellipsis Abridged" X X.IX Subsection "Example 4 \- Stacks and Queues" X X.IX Header "Grammar Details" X X.IX Subsection "Inline function definitions" X X.IX Item "a" X X.IX Item "b" X X.IX Subsection "Complex default parameters" X X.IX Item "a" X X.IX Item "b" X X.IX Subsection "Rant: Perl 5.005 is for Dummies" X X.IX Header "SEE ALSO" X X.IX Header "BUGS AND DEFICIENCIES" X X.IX Item "1" X X.IX Item "a" X X.IX Item "b" X X.IX Item "c" X X.IX Item "2" X X.IX Item "a" X X.IX Item "b" X X.IX Item "c" X X.IX Item "d" X X.IX Header "AUTHOR" X X.IX Header "COPYRIGHT" X END-of-p5-Inline-CPP/work/Inline-CPP-0.23/blib/man3/Inline::CPP.3 echo x - p5-Inline-CPP/work/Inline-CPP-0.23/Makefile sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/Makefile << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/Makefile' X# This Makefile is for the Inline::CPP extension to perl. X# X# It was generated automatically by MakeMaker version X# 5.4302 (Revision: 1.222) from the contents of X# Makefile.PL. Don't edit this file, edit Makefile.PL instead. X# X# ANY CHANGES MADE HERE WILL BE LOST! X# X# MakeMaker ARGV: (q[CC=cc], q[CCFLAGS=-O -pipe ], q[PREFIX=/usr/local]) X# X# MakeMaker Parameters: X X# NAME => q[Inline::CPP] X# VERSION_FROM => q[CPP.pm] X# clean => { FILES=>q[_Inline/ grammar/_Inline] } X X# --- MakeMaker post_initialize section: X X X# --- MakeMaker const_config section: X X# These definitions are from config.sh (via /usr/libdata/perl/5.00503/mach/Config.pm) X X# They may have been overridden via Makefile.PL or on the command line XAR = ar XCC = cc XCCCDLFLAGS = -DPIC -fpic XCCDLFLAGS = -Wl,-R/usr/lib XDLEXT = so XDLSRC = dl_dlopen.xs XLD = cc XLDDLFLAGS = -Wl,-E -shared -lperl -lm XLDFLAGS = -Wl,-E -lperl -lm XLIBC = XLIB_EXT = .a XOBJ_EXT = .o XOSNAME = freebsd XOSVERS = 4.0-current XRANLIB = : XSO = so XEXE_EXT = X X X# --- MakeMaker constants section: XAR_STATIC_ARGS = cr XNAME = Inline::CPP XDISTNAME = Inline-CPP XNAME_SYM = Inline_CPP XVERSION = 0.23 XVERSION_SYM = 0_23 XXS_VERSION = 0.23 XINST_BIN = blib/bin XINST_EXE = blib/script XINST_LIB = blib/lib XINST_ARCHLIB = blib/arch XINST_SCRIPT = blib/script XPREFIX = /usr/local XINSTALLDIRS = site XINSTALLPRIVLIB = /usr/libdata/perl/5.00503 XINSTALLARCHLIB = /usr/libdata/perl/5.00503/mach XINSTALLSITELIB = /usr/local/lib/perl5/site_perl/5.005 XINSTALLSITEARCH = /usr/local/lib/perl5/site_perl/5.005/i386-freebsd XINSTALLBIN = $(PREFIX)/bin XINSTALLSCRIPT = $(PREFIX)/bin XPERL_LIB = /usr/libdata/perl/5.00503 XPERL_ARCHLIB = /usr/libdata/perl/5.00503/mach XSITELIBEXP = /usr/local/lib/perl5/site_perl/5.005 XSITEARCHEXP = /usr/local/lib/perl5/site_perl/5.005/i386-freebsd XLIBPERL_A = libperl.a XFIRST_MAKEFILE = Makefile XMAKE_APERL_FILE = Makefile.aperl XPERLMAINCC = $(CC) XPERL_INC = /usr/libdata/perl/5.00503/mach/CORE XPERL = /usr/bin/perl5.00503 XFULLPERL = /usr/bin/perl5.00503 X XVERSION_MACRO = VERSION XDEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\" XXS_VERSION_MACRO = XS_VERSION XXS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\" X XMAKEMAKER = /usr/libdata/perl/5.00503/ExtUtils/MakeMaker.pm XMM_VERSION = 5.4302 X X# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle). X# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle) X# ROOTEXT = Directory part of FULLEXT with leading slash (eg /DBD) !!! Deprecated from MM 5.32 !!! X# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar) X# DLBASE = Basename part of dynamic library. May be just equal BASEEXT. XFULLEXT = Inline/CPP XBASEEXT = CPP XPARENT_NAME = Inline XDLBASE = $(BASEEXT) XVERSION_FROM = CPP.pm XOBJECT = XLDFROM = $(OBJECT) XLINKTYPE = dynamic X X# Handy lists of source code files: XXS_FILES= XC_FILES = XO_FILES = XH_FILES = XMAN1PODS = XMAN3PODS = CPP.pod XINST_MAN1DIR = blib/man1 XINSTALLMAN1DIR = /usr/local/man/man1 XMAN1EXT = 1 XINST_MAN3DIR = blib/man3 XINSTALLMAN3DIR = /usr/local/lib/perl5/5.00503/man/man3 XMAN3EXT = 3 XPERM_RW = 644 XPERM_RWX = 755 X X# work around a famous dec-osf make(1) feature(?): Xmakemakerdflt: all X X.SUFFIXES: .xs .c .C .cpp .cxx .cc $(OBJ_EXT) X X# Nick wanted to get rid of .PRECIOUS. I don't remember why. I seem to recall, that X# some make implementations will delete the Makefile when we rebuild it. Because X# we call false(1) when we rebuild it. So make(1) is not completely wrong when it X# does so. Our milage may vary. X# .PRECIOUS: Makefile # seems to be not necessary anymore X X.PHONY: all config static dynamic test linkext manifest X X# Where is the Config information that we are using/depend on XCONFIGDEP = $(PERL_ARCHLIB)/Config.pm $(PERL_INC)/config.h X X# Where to put things: XINST_LIBDIR = $(INST_LIB)/Inline XINST_ARCHLIBDIR = $(INST_ARCHLIB)/Inline X XINST_AUTODIR = $(INST_LIB)/auto/$(FULLEXT) XINST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT) X XINST_STATIC = XINST_DYNAMIC = XINST_BOOT = X XEXPORT_LIST = X XPERL_ARCHIVE = X XTO_INST_PM = CPP.pm \ X CPP.pod X XPM_TO_BLIB = CPP.pod \ X $(INST_LIBDIR)/CPP.pod \ X CPP.pm \ X $(INST_LIBDIR)/CPP.pm X X X# --- MakeMaker tool_autosplit section: X X# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto XAUTOSPLITFILE = $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e 'use AutoSplit;autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1) ;' X X X# --- MakeMaker tool_xsubpp section: X X X# --- MakeMaker tools_other section: X XSHELL = /bin/sh XCHMOD = chmod XCP = cp XLD = cc XMV = mv XNOOP = $(SHELL) -c true XRM_F = rm -f XRM_RF = rm -rf XTEST_F = test -f XTOUCH = touch XUMASK_NULL = umask 0 XDEV_NULL = > /dev/null 2>&1 X X# The following is a portable way to say mkdir -p X# To see which directories are created, change the if 0 to if 1 XMKPATH = $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Command -e mkpath X X# This helps us to minimize the effect of the .exists files A yet X# better solution would be to have a stable file in the perl X# distribution with a timestamp of zero. But this solution doesn't X# need any changes to the core distribution and works with older perls XEQUALIZE_TIMESTAMP = $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Command -e eqtime X X# Here we warn users that an old packlist file was found somewhere, X# and that they should call some uninstall routine XWARN_IF_OLD_PACKLIST = $(PERL) -we 'exit unless -f $$ARGV[0];' \ X-e 'print "WARNING: I have found an old package in\n";' \ X-e 'print "\t$$ARGV[0].\n";' \ X-e 'print "Please make sure the two installations are not conflicting\n";' X XUNINST=0 XVERBINST=1 X XMOD_INSTALL = $(PERL) -I$(INST_LIB) -I$(PERL_LIB) -MExtUtils::Install \ X-e "install({@ARGV},'$(VERBINST)',0,'$(UNINST)');" X XDOC_INSTALL = $(PERL) -e '$$\="\n\n";' \ X-e 'print "=head2 ", scalar(localtime), ": C<", shift, ">", " L<", shift, ">";' \ X-e 'print "=over 4";' \ X-e 'while (defined($$key = shift) and defined($$val = shift)){print "=item *";print "C<$$key: $$val>";}' \ X-e 'print "=back";' X XUNINSTALL = $(PERL) -MExtUtils::Install \ X-e 'uninstall($$ARGV[0],1,1); print "\nUninstall is deprecated. Please check the";' \ X-e 'print " packlist above carefully.\n There may be errors. Remove the";' \ X-e 'print " appropriate files manually.\n Sorry for the inconveniences.\n"' X X X# --- MakeMaker dist section: X XDISTVNAME = $(DISTNAME)-$(VERSION) XTAR = tar XTARFLAGS = cvf XZIP = zip XZIPFLAGS = -r XCOMPRESS = gzip --best XSUFFIX = .gz XSHAR = shar XPREOP = @$(NOOP) XPOSTOP = @$(NOOP) XTO_UNIX = @$(NOOP) XCI = ci -u XRCS_LABEL = rcs -Nv$(VERSION_SYM): -q XDIST_CP = best XDIST_DEFAULT = tardist X X X# --- MakeMaker macro section: X X X# --- MakeMaker depend section: X X X# --- MakeMaker cflags section: X X X# --- MakeMaker const_loadlibs section: X X X# --- MakeMaker const_cccmd section: X X X# --- MakeMaker post_constants section: X X X# --- MakeMaker pasthru section: X XPASTHRU = LIB="$(LIB)"\ X LIBPERL_A="$(LIBPERL_A)"\ X LINKTYPE="$(LINKTYPE)"\ X PREFIX="$(PREFIX)"\ X OPTIMIZE="$(OPTIMIZE)" X X X# --- MakeMaker c_o section: X X X# --- MakeMaker xs_c section: X X X# --- MakeMaker xs_o section: X X X# --- MakeMaker top_targets section: X X#all :: config $(INST_PM) subdirs linkext manifypods X Xall :: pure_all manifypods X @$(NOOP) X Xpure_all :: config pm_to_blib subdirs linkext X @$(NOOP) X Xsubdirs :: $(MYEXTLIB) X @$(NOOP) X Xconfig :: Makefile $(INST_LIBDIR)/.exists X @$(NOOP) X Xconfig :: $(INST_ARCHAUTODIR)/.exists X @$(NOOP) X Xconfig :: $(INST_AUTODIR)/.exists X @$(NOOP) X Xconfig :: Version_check X @$(NOOP) X X X$(INST_AUTODIR)/.exists :: /usr/libdata/perl/5.00503/mach/CORE/perl.h X @$(MKPATH) $(INST_AUTODIR) X @$(EQUALIZE_TIMESTAMP) /usr/libdata/perl/5.00503/mach/CORE/perl.h $(INST_AUTODIR)/.exists X X -@$(CHMOD) $(PERM_RWX) $(INST_AUTODIR) X X$(INST_LIBDIR)/.exists :: /usr/libdata/perl/5.00503/mach/CORE/perl.h X @$(MKPATH) $(INST_LIBDIR) X @$(EQUALIZE_TIMESTAMP) /usr/libdata/perl/5.00503/mach/CORE/perl.h $(INST_LIBDIR)/.exists X X -@$(CHMOD) $(PERM_RWX) $(INST_LIBDIR) X X$(INST_ARCHAUTODIR)/.exists :: /usr/libdata/perl/5.00503/mach/CORE/perl.h X @$(MKPATH) $(INST_ARCHAUTODIR) X @$(EQUALIZE_TIMESTAMP) /usr/libdata/perl/5.00503/mach/CORE/perl.h $(INST_ARCHAUTODIR)/.exists X X -@$(CHMOD) $(PERM_RWX) $(INST_ARCHAUTODIR) X Xconfig :: $(INST_MAN3DIR)/.exists X @$(NOOP) X X X$(INST_MAN3DIR)/.exists :: /usr/libdata/perl/5.00503/mach/CORE/perl.h X @$(MKPATH) $(INST_MAN3DIR) X @$(EQUALIZE_TIMESTAMP) /usr/libdata/perl/5.00503/mach/CORE/perl.h $(INST_MAN3DIR)/.exists X X -@$(CHMOD) $(PERM_RWX) $(INST_MAN3DIR) X Xhelp: X perldoc ExtUtils::MakeMaker X XVersion_check: X @$(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) \ X -MExtUtils::MakeMaker=Version_check \ X -e "Version_check('$(MM_VERSION)')" X X X# --- MakeMaker linkext section: X Xlinkext :: $(LINKTYPE) X @$(NOOP) X X X# --- MakeMaker dlsyms section: X X X# --- MakeMaker dynamic section: X X## $(INST_PM) has been moved to the all: target. X## It remains here for awhile to allow for old usage: "make dynamic" X#dynamic :: Makefile $(INST_DYNAMIC) $(INST_BOOT) $(INST_PM) Xdynamic :: Makefile $(INST_DYNAMIC) $(INST_BOOT) X @$(NOOP) X X X# --- MakeMaker dynamic_bs section: X XBOOTSTRAP = X X X# --- MakeMaker dynamic_lib section: X X X# --- MakeMaker static section: X X## $(INST_PM) has been moved to the all: target. X## It remains here for awhile to allow for old usage: "make static" X#static :: Makefile $(INST_STATIC) $(INST_PM) Xstatic :: Makefile $(INST_STATIC) X @$(NOOP) X X X# --- MakeMaker static_lib section: X X X# --- MakeMaker manifypods section: XPOD2MAN_EXE = /usr/bin/pod2man XPOD2MAN = $(PERL) -we '%m=@ARGV;for (keys %m){' \ X-e 'next if -e $$m{$$_} && -M $$m{$$_} < -M $$_ && -M $$m{$$_} < -M "Makefile";' \ X-e 'print "Manifying $$m{$$_}\n";' \ X-e 'system(qq[$$^X ].q["-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" $(POD2MAN_EXE) ].qq[$$_>$$m{$$_}])==0 or warn "Couldn\047t install $$m{$$_}\n";' \ X-e 'chmod(oct($(PERM_RW))), $$m{$$_} or warn "chmod $(PERM_RW) $$m{$$_}: $$!\n";}' X Xmanifypods : pure_all CPP.pod X @$(POD2MAN) \ X CPP.pod \ X $(INST_MAN3DIR)/Inline::CPP.$(MAN3EXT) X X# --- MakeMaker processPL section: X X X# --- MakeMaker installbin section: X X X# --- MakeMaker subdirs section: X X# The default clean, realclean and test targets in this Makefile X# have automatically been given entries for each subdir. X X X Xsubdirs :: X @cd grammar && $(MAKE) all $(PASTHRU) X X X X# --- MakeMaker clean section: X X# Delete temporary files but do not touch installed files. We don't delete X# the Makefile here so a later make realclean still has a makefile to use. X Xclean :: X -cd grammar && $(TEST_F) Makefile && $(MAKE) clean X -rm -rf _Inline/ grammar/_Inline ./blib $(MAKE_APERL_FILE) $(INST_ARCHAUTODIR)/extralibs.all perlmain.c mon.out core so_locations pm_to_blib *~ */*~ */*/*~ *$(OBJ_EXT) *$(LIB_EXT) perl.exe $(BOOTSTRAP) $(BASEEXT).bso $(BASEEXT).def $(BASEEXT).exp X -mv Makefile Makefile.old $(DEV_NULL) X X X# --- MakeMaker realclean section: X X# Delete temporary files (via clean) and also delete installed files Xrealclean purge :: clean X -cd grammar && $(TEST_F) Makefile.old && $(MAKE) -f Makefile.old realclean X -cd grammar && $(TEST_F) Makefile && $(MAKE) realclean X rm -rf $(INST_AUTODIR) $(INST_ARCHAUTODIR) X rm -f $(INST_LIBDIR)/CPP.pod $(INST_LIBDIR)/CPP.pm X rm -rf Makefile Makefile.old X X X# --- MakeMaker dist_basics section: X Xdistclean :: realclean distcheck X Xdistcheck : X $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Manifest=fullcheck \ X -e fullcheck X Xskipcheck : X $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Manifest=skipcheck \ X -e skipcheck X Xmanifest : X $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Manifest=mkmanifest \ X -e mkmanifest X X X# --- MakeMaker dist_core section: X Xdist : $(DIST_DEFAULT) X @$(PERL) -le 'print "Warning: Makefile possibly out of date with $$vf" if ' \ X -e '-e ($$vf="$(VERSION_FROM)") and -M $$vf < -M "Makefile";' X Xtardist : $(DISTVNAME).tar$(SUFFIX) X Xzipdist : $(DISTVNAME).zip X X$(DISTVNAME).tar$(SUFFIX) : distdir X $(PREOP) X $(TO_UNIX) X $(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME) X $(RM_RF) $(DISTVNAME) X $(COMPRESS) $(DISTVNAME).tar X $(POSTOP) X X$(DISTVNAME).zip : distdir X $(PREOP) X $(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME) X $(RM_RF) $(DISTVNAME) X $(POSTOP) X Xuutardist : $(DISTVNAME).tar$(SUFFIX) X uuencode $(DISTVNAME).tar$(SUFFIX) \ X $(DISTVNAME).tar$(SUFFIX) > \ X $(DISTVNAME).tar$(SUFFIX)_uu X Xshdist : distdir X $(PREOP) X $(SHAR) $(DISTVNAME) > $(DISTVNAME).shar X $(RM_RF) $(DISTVNAME) X $(POSTOP) X X X# --- MakeMaker dist_dir section: X Xdistdir : X $(RM_RF) $(DISTVNAME) X $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Manifest=manicopy,maniread \ X -e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');" X X X# --- MakeMaker dist_test section: X Xdisttest : distdir X cd $(DISTVNAME) && $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) Makefile.PL X cd $(DISTVNAME) && $(MAKE) X cd $(DISTVNAME) && $(MAKE) test X X X# --- MakeMaker dist_ci section: X Xci : X $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Manifest=maniread \ X -e "@all = keys %{ maniread() };" \ X -e 'print("Executing $(CI) @all\n"); system("$(CI) @all");' \ X -e 'print("Executing $(RCS_LABEL) ...\n"); system("$(RCS_LABEL) @all");' X X X# --- MakeMaker install section: X Xinstall :: all pure_install doc_install X Xinstall_perl :: all pure_perl_install doc_perl_install X Xinstall_site :: all pure_site_install doc_site_install X Xinstall_ :: install_site X @echo INSTALLDIRS not defined, defaulting to INSTALLDIRS=site X Xpure_install :: pure_$(INSTALLDIRS)_install X Xdoc_install :: doc_$(INSTALLDIRS)_install X @echo Appending installation info to $(INSTALLARCHLIB)/perllocal.pod X Xpure__install : pure_site_install X @echo INSTALLDIRS not defined, defaulting to INSTALLDIRS=site X Xdoc__install : doc_site_install X @echo INSTALLDIRS not defined, defaulting to INSTALLDIRS=site X Xpure_perl_install :: X @$(MOD_INSTALL) \ X read $(PERL_ARCHLIB)/auto/$(FULLEXT)/.packlist \ X write $(INSTALLARCHLIB)/auto/$(FULLEXT)/.packlist \ X $(INST_LIB) $(INSTALLPRIVLIB) \ X $(INST_ARCHLIB) $(INSTALLARCHLIB) \ X $(INST_BIN) $(INSTALLBIN) \ X $(INST_SCRIPT) $(INSTALLSCRIPT) \ X $(INST_MAN1DIR) $(INSTALLMAN1DIR) \ X $(INST_MAN3DIR) $(INSTALLMAN3DIR) X @$(WARN_IF_OLD_PACKLIST) \ X $(SITEARCHEXP)/auto/$(FULLEXT) X X Xpure_site_install :: X @$(MOD_INSTALL) \ X read $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist \ X write $(INSTALLSITEARCH)/auto/$(FULLEXT)/.packlist \ X $(INST_LIB) $(INSTALLSITELIB) \ X $(INST_ARCHLIB) $(INSTALLSITEARCH) \ X $(INST_BIN) $(INSTALLBIN) \ X $(INST_SCRIPT) $(INSTALLSCRIPT) \ X $(INST_MAN1DIR) $(INSTALLMAN1DIR) \ X $(INST_MAN3DIR) $(INSTALLMAN3DIR) X @$(WARN_IF_OLD_PACKLIST) \ X $(PERL_ARCHLIB)/auto/$(FULLEXT) X Xdoc_perl_install :: X -@$(DOC_INSTALL) \ X "Module" "$(NAME)" \ X "installed into" "$(INSTALLPRIVLIB)" \ X LINKTYPE "$(LINKTYPE)" \ X VERSION "$(VERSION)" \ X EXE_FILES "$(EXE_FILES)" \ X >> $(INSTALLARCHLIB)/perllocal.pod X Xdoc_site_install :: X -@$(DOC_INSTALL) \ X "Module" "$(NAME)" \ X "installed into" "$(INSTALLSITELIB)" \ X LINKTYPE "$(LINKTYPE)" \ X VERSION "$(VERSION)" \ X EXE_FILES "$(EXE_FILES)" \ X >> $(INSTALLARCHLIB)/perllocal.pod X X Xuninstall :: uninstall_from_$(INSTALLDIRS)dirs X Xuninstall_from_perldirs :: X @$(UNINSTALL) $(PERL_ARCHLIB)/auto/$(FULLEXT)/.packlist X Xuninstall_from_sitedirs :: X @$(UNINSTALL) $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist X X X# --- MakeMaker force section: X# Phony target to force checking subdirectories. XFORCE: X @$(NOOP) X X X# --- MakeMaker perldepend section: X X X# --- MakeMaker makefile section: X X# We take a very conservative approach here, but it\'s worth it. X# We move Makefile to Makefile.old here to avoid gnu make looping. XMakefile : Makefile.PL $(CONFIGDEP) X @echo "Makefile out-of-date with respect to $?" X @echo "Cleaning current config before rebuilding Makefile..." X -@$(RM_F) Makefile.old X -@$(MV) Makefile Makefile.old X -$(MAKE) -f Makefile.old clean $(DEV_NULL) || $(NOOP) X $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL "CC=cc" "CCFLAGS=-O -pipe " "PREFIX=/usr/local" X @echo "==> Your Makefile has been rebuilt. <==" X @echo "==> Please rerun the make command. <==" X false X X# To change behavior to :: would be nice, but would break Tk b9.02 X# so you find such a warning below the dist target. X#Makefile :: $(VERSION_FROM) X# @echo "Warning: Makefile possibly out of date with $(VERSION_FROM)" X X X# --- MakeMaker staticmake section: X X# --- MakeMaker makeaperl section --- XMAP_TARGET = perl XFULLPERL = /usr/bin/perl5.00503 X X$(MAP_TARGET) :: static $(MAKE_APERL_FILE) X $(MAKE) -f $(MAKE_APERL_FILE) $@ X X$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) X @echo Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET) X @$(PERL) -I$(INST_ARCHLIB) -I$(INST_LIB) -I$(PERL_ARCHLIB) -I$(PERL_LIB) \ X Makefile.PL DIR=grammar \ X MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \ X MAKEAPERL=1 NORECURS=1 CCCDLFLAGS= \ X CC=cc \ X CCFLAGS='-O -pipe ' \ X PREFIX=/usr/local X X X# --- MakeMaker test section: X XTEST_VERBOSE=0 XTEST_TYPE=test_$(LINKTYPE) XTEST_FILE = test.pl XTEST_FILES = t/*.t XTESTDB_SW = -d X Xtestdb :: testdb_$(LINKTYPE) X Xtest :: $(TEST_TYPE) X @cd grammar && $(TEST_F) Makefile && $(MAKE) test $(PASTHRU) X Xtest_dynamic :: pure_all X PERL_DL_NONLAZY=1 $(FULLPERL) -I$(INST_ARCHLIB) -I$(INST_LIB) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -e 'use Test::Harness qw(&runtests $$verbose); $$verbose=$(TEST_VERBOSE); runtests @ARGV;' $(TEST_FILES) X Xtestdb_dynamic :: pure_all X PERL_DL_NONLAZY=1 $(FULLPERL) $(TESTDB_SW) -I$(INST_ARCHLIB) -I$(INST_LIB) -I$(PERL_ARCHLIB) -I$(PERL_LIB) $(TEST_FILE) X Xtest_ : test_dynamic X Xtest_static :: test_dynamic Xtestdb_static :: testdb_dynamic X X X# --- MakeMaker ppd section: X# Creates a PPD (Perl Package Description) for a binary distribution. Xppd: X @$(PERL) -e "print qq{\n}. qq{\tInline-CPP\n}. qq{\t\n}. qq{\t\n}. qq{\t\n}. qq{\t\t\n}. qq{\t\t\n}. qq{\t\t\n}. qq{\t\n}. qq{\n}" > Inline-CPP.ppd X X# --- MakeMaker pm_to_blib section: X Xpm_to_blib: $(TO_INST_PM) X @$(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" \ X "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -MExtUtils::Install \ X -e "pm_to_blib({qw{$(PM_TO_BLIB)}},'$(INST_LIB)/auto')" X @$(TOUCH) $@ X X X# --- MakeMaker selfdocument section: X X X# --- MakeMaker postamble section: X X X# End. END-of-p5-Inline-CPP/work/Inline-CPP-0.23/Makefile echo x - p5-Inline-CPP/work/Inline-CPP-0.23/pm_to_blib sed 's/^X//' >p5-Inline-CPP/work/Inline-CPP-0.23/pm_to_blib << 'END-of-p5-Inline-CPP/work/Inline-CPP-0.23/pm_to_blib' END-of-p5-Inline-CPP/work/Inline-CPP-0.23/pm_to_blib echo x - p5-Inline-CPP/work/.extract_done.p5-Inline-CPP-0.23 sed 's/^X//' >p5-Inline-CPP/work/.extract_done.p5-Inline-CPP-0.23 << 'END-of-p5-Inline-CPP/work/.extract_done.p5-Inline-CPP-0.23' END-of-p5-Inline-CPP/work/.extract_done.p5-Inline-CPP-0.23 echo x - p5-Inline-CPP/work/.patch_done.p5-Inline-CPP-0.23 sed 's/^X//' >p5-Inline-CPP/work/.patch_done.p5-Inline-CPP-0.23 << 'END-of-p5-Inline-CPP/work/.patch_done.p5-Inline-CPP-0.23' END-of-p5-Inline-CPP/work/.patch_done.p5-Inline-CPP-0.23 echo x - p5-Inline-CPP/work/.configure_done.p5-Inline-CPP-0.23 sed 's/^X//' >p5-Inline-CPP/work/.configure_done.p5-Inline-CPP-0.23 << 'END-of-p5-Inline-CPP/work/.configure_done.p5-Inline-CPP-0.23' END-of-p5-Inline-CPP/work/.configure_done.p5-Inline-CPP-0.23 echo x - p5-Inline-CPP/work/.build_done.p5-Inline-CPP-0.23 sed 's/^X//' >p5-Inline-CPP/work/.build_done.p5-Inline-CPP-0.23 << 'END-of-p5-Inline-CPP/work/.build_done.p5-Inline-CPP-0.23' END-of-p5-Inline-CPP/work/.build_done.p5-Inline-CPP-0.23 echo x - p5-Inline-CPP/Makefile sed 's/^X//' >p5-Inline-CPP/Makefile << 'END-of-p5-Inline-CPP/Makefile' X# New ports collection makefile for: Inline::CPP X# Date created: 14 Dec 2001 X# Whom: Sergey Skvortsov X# X# $FreeBSD$ X# X XPORTNAME= Inline-CPP XPORTVERSION= 0.23 XCATEGORIES= devel perl5 XMASTER_SITES= ${MASTER_SITE_PERL_CPAN} XMASTER_SITE_SUBDIR= Inline XPKGNAMEPREFIX= p5- X XMAINTAINER= skv@protey.ru X XBUILD_DEPENDS= ${LOCALBASE}/lib/perl5/site_perl/${PERL_VER}/Inline.pm:${PORTSDIR}/devel/p5-Inline XRUN_DEPENDS= ${BUILD_DEPENDS} X XPERL_CONFIGURE= yes XCONFIGURE_ARGS= END-of-p5-Inline-CPP/Makefile echo x - p5-Inline-CPP/pkg-comment sed 's/^X//' >p5-Inline-CPP/pkg-comment << 'END-of-p5-Inline-CPP/pkg-comment' XWrite Perl subroutines and classes in C++ END-of-p5-Inline-CPP/pkg-comment echo x - p5-Inline-CPP/pkg-descr sed 's/^X//' >p5-Inline-CPP/pkg-descr << 'END-of-p5-Inline-CPP/pkg-descr' XThe Inline::CPP module allows you to put C++ source code directly X"inline" in a Perl script or module. You code classes or functions in XC++, and you can use them as if they were written in Perl. X XWWW: http://search.cpan.org/search?dist=Inline-CPP X X-- Sergey Skvortsov Xskv@protey.ru END-of-p5-Inline-CPP/pkg-descr echo x - p5-Inline-CPP/pkg-plist sed 's/^X//' >p5-Inline-CPP/pkg-plist << 'END-of-p5-Inline-CPP/pkg-plist' Xlib/perl5/site_perl/%%PERL_VER%%/%%PERL_ARCH%%/auto/Inline/CPP/.packlist Xlib/perl5/site_perl/%%PERL_VER%%/Inline/CPP.pm Xlib/perl5/site_perl/%%PERL_VER%%/Inline/CPP.pod Xlib/perl5/site_perl/%%PERL_VER%%/Inline/CPP/grammar.pm X@dirrm lib/perl5/site_perl/%%PERL_VER%%/Inline/CPP X@dirrm lib/perl5/site_perl/%%PERL_VER%%/%%PERL_ARCH%%/auto/Inline/CPP X@unexec rmdir %D/lib/perl5/site_perl/%%PERL_VER%%/Inline 2>/dev/null || true X@unexec rmdir %D/lib/perl5/site_perl/%%PERL_VER%%/%%PERL_ARCH%%/auto/Inline 2>/dev/null || true END-of-p5-Inline-CPP/pkg-plist exit >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-ports" in the body of the message