Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Dec 2001 16:48:28 +0300
From:      skv@protey.ru
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   ports/32869: New port: p5-Inline-CPP-0.23 
Message-ID:  <E16FFAy-000Jxs-00@3wgraphics.com>

next in thread | raw e-mail | index | archive | help

>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:
<Organization of PR author (multiple lines)>
>Environment:

	<Relevant environment information (multiple lines)>

>Description:

New port: p5-Inline-CPP-0.23

Write Perl subroutines and classes in C++

>How-To-Repeat:

	<Code/input/activities to reproduce the problem (multiple lines)>

>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" <NEILW@cpan.org>
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<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
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<gcc>, use C<g++>.
XIf you're on a Sun or an IRIX box and the system C compiler C<cc> built perl,
Xthen use the system C++ compiler, C<CC>. 
X
XSome compilers actually compile both C and C++ with the same compiler. 
XMicrosoft's C<cl.exe> 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<Inline>. 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<ExtUtils::MakeMaker> and
XL<perlxs>.
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<perlxs> 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<iostream.h> at the top of your code. This 
Xoption makes it include C<iostream> 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<Inline::Struct> for more details about how C<Inline::Struct>
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<Perl> variables get mapped to C<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<Inline::CPP> uses a much simpler approach. It parses the system's
Xtypemap files and only binds to functions with supported types. You 
Xcan tell C<Inline::CPP> 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<Inline::Struct> 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<Farmer>) 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<Object> are bound to Perl, but there is no constructor or 
Xdestructor, meaning you cannot instantiate an C<Object>. 
X
XThe C<Airplane> 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<Inline_Stack_Items; i++) {
X         avg *= i;
X         avg += SvNV(Inline_Stack_Item(i));
X         avg /= i + 1;
X      }
X      return avg;
X   }
X
XHere's a benchmark program that tests which is faster:
X
X   use Inline CPP;
X   my @numbers = map { rand } (1 .. 10000);
X   my ($a, $stop);
X   $stop = 200;
X   if (@ARGV) {
X      $a = avg(@numbers) while $stop--;
X   }
X   else {
X      $a = average(@numbers) while $stop--;
X   }
X   print "The average of 10000 random numbers is: ", $a, "\n";
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
X   __END__
X   __CPP__
X
X   double avg(...) {
X       Inline_Stack_Vars;
X       double avg = 0.0;
X       for (int i=0; i<items; i++) {
X           avg *= i;
X           avg += SvNV(ST(i));
X           avg /= i + 1;
X       }
X       return avg;
X   }
X
XThe perl sub runs in 14.18 seconds, an average of 0.0709s per call.
XThe C function runs in 1.52 seconds, an average of 0.0076s per call.
XMind you, those both include the time taken to initialize the array with
Xrandom numbers. And by varying the number of elements in the array and the
Xnumber of repetitions of the function, we can change this number a lot.
X
XWhat's the point? Of B<course> 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<absolutely no reason> not to upgrade today!
X
X=head1 SEE ALSO
X
XFor general information about how C<Inline> binds code to Perl, see
XL<Inline>.
X
XFor information on using C with Perl, see L<Inline::C> and
XL<Inline::C-Cookbook>. For C<WMTYEWTK>, see L<perlxs>,
XL<perlxstut>, L<perlapi>, and L<perlguts>.
X
XFor information on using C and C++ structs with Perl, see 
XL<Inline::Struct>.
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 <NEILW@cpan.org>
X
XBrian Ingerson <INGY@cpan.org> is the author of C<Inline>,
XC<Inline::C> and C<Inline::CPR>. 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; i<items; i++) {
X	int tmp = SvIV(Inline_Stack_Item(i));
X	s += tmp;
X    }
X    return s;
X}
END-of-p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/13vararg.t
echo x - p5-Inline-CPP/work/Inline-CPP-0.23/grammar/t/12retlst.t
sed 's/^X//' >p5-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 ':' <leftop: inherit ',' inherit> '{' 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 '(' <leftop: arg ',' arg>(s?) ')' ';'
X              {
X                {rtype => $item[1], name => $item[2], args => $item[4]}
X              }
X            | rtype IDENTIFIER '(' <leftop: arg ',' arg>(s?) ')' code_block
X              {
X                {rtype => $item[1], name => $item[2], args => $item[4]}
X              }
X
Xmethod_def: IDENTIFIER '(' <leftop: arg ',' arg>(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 '(' <leftop: arg ',' arg>(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: ':' <leftop: subexpr ',' subexpr>
X
Xmember_def: anytype <leftop: var ',' var> ';'
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: <leftop: subexpr OP subexpr> { 
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 = <<END;
X    if (sv_isobject(\$arg) && (SvTYPE(SvRV(\$arg)) == SVt_PVMG)) {
X        \$var = (\$type)SvIV((SV*)SvRV( \$arg ));
X    }
X    else {
X        warn ( \\"\${Package}::\$func_name() -- \$var is not a blessed reference\\" );
X        XSRETURN_UNDEF;
X    }
XEND
X    $OUTPUT = <<END;
X    sv_setref_pv( \$arg, CLASS, (void*)\$var );
XEND
X
X    my $ctypename = $typename . " *";
X    $parser->{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{<SOFTPKG NAME=\"Inline-CPP-grammar\" VERSION=\"0,23,0,0\">\n}. qq{\t<TITLE>Inline-CPP-grammar</TITLE>\n}. qq{\t<ABSTRACT></ABSTRACT>\n}. qq{\t<AUTHOR></AUTHOR>\n}. qq{\t<IMPLEMENTATION>\n}. qq{\t\t<OS NAME=\"$(OSNAME)\" />\n}. qq{\t\t<ARCHITECTURE NAME=\"i386-freebsd\" />\n}. qq{\t\t<CODEBASE HREF=\"\" />\n}. qq{\t</IMPLEMENTATION>\n}. qq{</SOFTPKG>\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} ||= <<END;
X#ifndef bool
X#include <%iostream%>
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 .= <<END;
XMODULE = $module     	PACKAGE = $proper_pkg
X
XPROTOTYPES: DISABLE
X
XEND
X
X	my ($ctor, $dtor, $abstract) = (0, 0, 0);
X	for my $thing (@{$data->{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} .= <<END;
X{
X#ifndef get_av
X    AV *isa = perl_get_av("$ISA_name", 1);
X#else
X    AV *isa = get_av("$ISA_name", 1);
X#endif
X    av_push(isa, newSVpv("$parent", 0));
X}
XEND
X	    }
X
X	    # Get/set methods will go here:
X
X	    # Cases we skip:
X            $abstract ||= ($type eq 'method' and $thing->{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 .= <<END unless ($ctor or $abstract);
X$class *
X${class}::new()
X
XEND
X	$XS .= <<END unless ($dtor or $abstract);
Xvoid
X${class}::DESTROY()
X
XEND
X    }
X
X    my $prefix = (($o->{ILSM}{XS}{PREFIX}) ?
X		  "PREFIX = $o->{ILSM}{XS}{PREFIX}" :
X		  '');
X    $XS .= <<END;
XMODULE = $module     	PACKAGE = $pkg	$prefix
X
XPROTOTYPES: DISABLE
X
XEND
X
X    for my $function (@{$data->{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 <<END;
XTYPEMAP
X$typemap
XOUTPUT
X$TYPEMAP_KIND
X$o->{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 = <CPP>;
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++' => <<END;
X
Xclass Soldier {
X public:
X  Soldier(char *name, char *rank, int serial);
X
X  char *get_name();
X  char *get_rank();
X  int get_serial();
X
X private:
X  char *name;
X  char *rank;
X  int serial;
X};
X
XSoldier::Soldier(char *name, char *rank, int serial) {
X   this->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<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
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<gcc>, use C<g++>.
XIf you're on a Sun or an IRIX box and the system C compiler C<cc> built perl,
Xthen use the system C++ compiler, C<CC>. 
X
XSome compilers actually compile both C and C++ with the same compiler. 
XMicrosoft's C<cl.exe> 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<Inline>. 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<ExtUtils::MakeMaker> and
XL<perlxs>.
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<perlxs> 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<iostream.h> at the top of your code. This 
Xoption makes it include C<iostream> 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<Inline::Struct> for more details about how C<Inline::Struct>
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<Perl> variables get mapped to C<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<Inline::CPP> uses a much simpler approach. It parses the system's
Xtypemap files and only binds to functions with supported types. You 
Xcan tell C<Inline::CPP> 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<Inline::Struct> 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<Farmer>) 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<Object> are bound to Perl, but there is no constructor or 
Xdestructor, meaning you cannot instantiate an C<Object>. 
X
XThe C<Airplane> 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<Inline_Stack_Items; i++) {
X         avg *= i;
X         avg += SvNV(Inline_Stack_Item(i));
X         avg /= i + 1;
X      }
X      return avg;
X   }
X
XHere's a benchmark program that tests which is faster:
X
X   use Inline CPP;
X   my @numbers = map { rand } (1 .. 10000);
X   my ($a, $stop);
X   $stop = 200;
X   if (@ARGV) {
X      $a = avg(@numbers) while $stop--;
X   }
X   else {
X      $a = average(@numbers) while $stop--;
X   }
X   print "The average of 10000 random numbers is: ", $a, "\n";
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
X   __END__
X   __CPP__
X
X   double avg(...) {
X       Inline_Stack_Vars;
X       double avg = 0.0;
X       for (int i=0; i<items; i++) {
X           avg *= i;
X           avg += SvNV(ST(i));
X           avg /= i + 1;
X       }
X       return avg;
X   }
X
XThe perl sub runs in 14.18 seconds, an average of 0.0709s per call.
XThe C function runs in 1.52 seconds, an average of 0.0076s per call.
XMind you, those both include the time taken to initialize the array with
Xrandom numbers. And by varying the number of elements in the array and the
Xnumber of repetitions of the function, we can change this number a lot.
X
XWhat's the point? Of B<course> 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<absolutely no reason> not to upgrade today!
X
X=head1 SEE ALSO
X
XFor general information about how C<Inline> binds code to Perl, see
XL<Inline>.
X
XFor information on using C with Perl, see L<Inline::C> and
XL<Inline::C-Cookbook>. For C<WMTYEWTK>, see L<perlxs>,
XL<perlxstut>, L<perlapi>, and L<perlguts>.
X
XFor information on using C and C++ structs with Perl, see 
XL<Inline::Struct>.
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 <NEILW@cpan.org>
X
XBrian Ingerson <INGY@cpan.org> is the author of C<Inline>,
XC<Inline::C> and C<Inline::CPR>. 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} ||= <<END;
X#ifndef bool
X#include <%iostream%>
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 .= <<END;
XMODULE = $module     	PACKAGE = $proper_pkg
X
XPROTOTYPES: DISABLE
X
XEND
X
X	my ($ctor, $dtor, $abstract) = (0, 0, 0);
X	for my $thing (@{$data->{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} .= <<END;
X{
X#ifndef get_av
X    AV *isa = perl_get_av("$ISA_name", 1);
X#else
X    AV *isa = get_av("$ISA_name", 1);
X#endif
X    av_push(isa, newSVpv("$parent", 0));
X}
XEND
X	    }
X
X	    # Get/set methods will go here:
X
X	    # Cases we skip:
X            $abstract ||= ($type eq 'method' and $thing->{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 .= <<END unless ($ctor or $abstract);
X$class *
X${class}::new()
X
XEND
X	$XS .= <<END unless ($dtor or $abstract);
Xvoid
X${class}::DESTROY()
X
XEND
X    }
X
X    my $prefix = (($o->{ILSM}{XS}{PREFIX}) ?
X		  "PREFIX = $o->{ILSM}{XS}{PREFIX}" :
X		  '');
X    $XS .= <<END;
XMODULE = $module     	PACKAGE = $pkg	$prefix
X
XPROTOTYPES: DISABLE
X
XEND
X
X    for my $function (@{$data->{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 <<END;
XTYPEMAP
X$typemap
XOUTPUT
X$TYPEMAP_KIND
X$o->{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 ':' <leftop: inherit ',' inherit> '{' 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 '(' <leftop: arg ',' arg>(s?) ')' ';'
X              {
X                {rtype => $item[1], name => $item[2], args => $item[4]}
X              }
X            | rtype IDENTIFIER '(' <leftop: arg ',' arg>(s?) ')' code_block
X              {
X                {rtype => $item[1], name => $item[2], args => $item[4]}
X              }
X
Xmethod_def: IDENTIFIER '(' <leftop: arg ',' arg>(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 '(' <leftop: arg ',' arg>(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: ':' <leftop: subexpr ',' subexpr>
X
Xmember_def: anytype <leftop: var ',' var> ';'
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: <leftop: subexpr OP subexpr> { 
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 = <<END;
X    if (sv_isobject(\$arg) && (SvTYPE(SvRV(\$arg)) == SVt_PVMG)) {
X        \$var = (\$type)SvIV((SV*)SvRV( \$arg ));
X    }
X    else {
X        warn ( \\"\${Package}::\$func_name() -- \$var is not a blessed reference\\" );
X        XSRETURN_UNDEF;
X    }
XEND
X    $OUTPUT = <<END;
X    sv_setref_pv( \$arg, CLASS, (void*)\$var );
XEND
X
X    my $ctypename = $typename . " *";
X    $parser->{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; i<Inline_Stack_Items; i++) {
X\&         avg *= i;
X\&         avg += SvNV(Inline_Stack_Item(i));
X\&         avg /= i + 1;
X\&      }
X\&      return avg;
X\&   }
X.Ve
XHere's a benchmark program that tests which is faster:
X.PP
X.Vb 11
X\&   use Inline CPP;
X\&   my @numbers = map { rand } (1 .. 10000);
X\&   my ($a, $stop);
X\&   $stop = 200;
X\&   if (@ARGV) {
X\&      $a = avg(@numbers) while $stop--;
X\&   }
X\&   else {
X\&      $a = average(@numbers) while $stop--;
X\&   }
X\&   print "The average of 10000 random numbers is: ", $a, "\en";
X.Ve
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
X.Vb 2
X\&   __END__
X\&   __CPP__
X.Ve
X.Vb 10
X\&   double avg(...) {
X\&       Inline_Stack_Vars;
X\&       double avg = 0.0;
X\&       for (int i=0; i<items; i++) {
X\&           avg *= i;
X\&           avg += SvNV(ST(i));
X\&           avg /= i + 1;
X\&       }
X\&       return avg;
X\&   }
X.Ve
XThe perl sub runs in 14.18 seconds, an average of 0.0709s per call.
XThe C function runs in 1.52 seconds, an average of 0.0076s per call.
XMind you, those both include the time taken to initialize the array with
Xrandom numbers. And by varying the number of elements in the array and the
Xnumber of repetitions of the function, we can change this number a lot.
X.PP
XWhat's the point? Of \fBcourse\fR 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.PP
X.Vb 1
X\&   double avg(...)
X.Ve
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.PP
X.Vb 1
X\&   double avg(   )
X.Ve
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.PP
X.Vb 1
X\&   void myprintf(char *format, ...);
X.Ve
Xthen you'd better be reading things from the Perl stack. If you aren't, then
Xspecify the \s-1PRESERVE_ELLIPSIS\s0 option in your script. That will leave the 
Xellipsis in the code for the compiler to whine about. :)
X.Sh "Example 4 \- Stacks and Queues"
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.PP
XThis example implements a Queue and a Stack class, and shows off just 
Xa few more new features of Inline::\s-1CPP\s0: default values to arguments,
X.PP
X.Vb 1
X\&   use Inline CPP;
X.Ve
X.Vb 9
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\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 <NEILW@cpan.org>
X.PP
XBrian Ingerson <INGY@cpan.org> 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{<SOFTPKG NAME=\"Inline-CPP\" VERSION=\"0,23,0,0\">\n}. qq{\t<TITLE>Inline-CPP</TITLE>\n}. qq{\t<ABSTRACT></ABSTRACT>\n}. qq{\t<AUTHOR></AUTHOR>\n}. qq{\t<IMPLEMENTATION>\n}. qq{\t\t<OS NAME=\"$(OSNAME)\" />\n}. qq{\t\t<ARCHITECTURE NAME=\"i386-freebsd\" />\n}. qq{\t\t<CODEBASE HREF=\"\" />\n}. qq{\t</IMPLEMENTATION>\n}. qq{</SOFTPKG>\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 <skv@protey.ru>
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= </dev/null
X
XMANPREFIX=	${PREFIX}/lib/perl5/${PERL_VERSION}
XMAN3=		Inline::CPP.3
X
X.include <bsd.port.mk>
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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?E16FFAy-000Jxs-00>