Mailing List Archive

perlapi -> perlxs patch
First:

mv perlapi.pod perlxs.pod

Then apply the patch. You should apply it over the perlapi that is in
5.001m, ignoring the patch I sent last week.

I think the section "Creating A New Extension" should be thrown out now that
the "Getting Started" section exists. Put it together, let me know what you
think.

perlapi is referenced in the following pod/ files:

Makefile
perl.pod
perlcall.pod
perlguts.pod
perlmod.pod

Should we point all of them to perlxs?

Dean


*** pod/perlxs.pod Wed May 31 16:08:11 1995
--- ../patches/perlxs.pod Thu Oct 12 23:03:24 1995
***************
*** 1,6 ****
=head1 NAME

! perlapi - Perl 5 application programming interface for C extensions

=head1 DESCRIPTION

--- 1,6 ----
=head1 NAME

! perlxs - XS language reference manual

=head1 DESCRIPTION

***************
*** 23,30 ****
to handle special structures and types for the library being
linked.

Many of the examples which follow will concentrate on creating an
! interface between Perl and the ONC+RPC bind library functions.
Specifically, the rpcb_gettime() function will be used to demonstrate many
features of the XS language. This function has two parameters; the first
is an input parameter and the second is an output parameter. The function
--- 23,65 ----
to handle special structures and types for the library being
linked.

+ =head2 Getting Started
+
+ A new extension should begin with the B<h2xs> tool. This will generate
+ templates for the new Perl module (PM), the XS source file (XS), the MANIFEST
+ file, and the Makefile.PL (PL) files. The Makefile.PL file is a Perl script
+ which will generate a Makefile. This makefile knows how to find and run
+ xsubpp for your extension. When you type "make" your XS file will be run
+ through xsubpp and a C file will be produced. Then the C file will be
+ compiled. A simple example looks like this for an example module named
+ B<Foo>:
+
+ $ h2xs -Afn Foo
+ $ cd ext/Foo
+ $ ls
+ Foo.pm Foo.xs MANIFEST Makefile.PL
+ $ perl5 Makefile.PL
+ $ ls
+ Foo.pm Foo.xs MANIFEST Makefile.PL Makefile
+ $ <edit Foo.pm and Foo.xs to add your stuff>
+ $ make
+ <you will see xsubpp run on Foo.xs and you'll see the C compiler
+ <run on Foo.c, and a bunch of other less-interesting things
+ <will happen.
+
+ If your Perl was built with dynamic loading then the makefile will build a
+ dynamically loadable extension. If you don't have dynamic loading then the
+ makefile will build a static extension and should create a new Perl binary.
+ The default behavior depends on what is available.
+
+ For more information about h2xs consult its manpage, embedded in the
+ source. For information about the Makefile.PL and Makefile consult the
+ MakeMaker manpage.
+
+ =head2 On The Road
+
Many of the examples which follow will concentrate on creating an
! interface between Perl and the ONC+ RPC bind library functions.
Specifically, the rpcb_gettime() function will be used to demonstrate many
features of the XS language. This function has two parameters; the first
is an input parameter and the second is an output parameter. The function
***************
*** 66,73 ****

bool_t
rpcb_gettime(host,timep)
! char * host
! time_t &timep
OUTPUT:
timep

--- 101,108 ----

bool_t
rpcb_gettime(host,timep)
! char *host
! time_t &timep
OUTPUT:
timep

***************
*** 100,136 ****
allow the programmer to create a more Perl-like interface to the C
function.

- It is recommended that the B<h2xs> tool be used when creating new
- extensions. This tool will generate template source files and Makefiles.
- This is discussed in more detail in the section titled "Creating A New
- Extension" and in the B<h2xs> manpage.
-
=head2 The Anatomy of an XSUB

! The following XSUB allows a Perl program to access a C library function called sin(). The XSUB will imitate the C
! function which takes a single argument and returns a single
! value.

double
sin(x)
! double<tab>x

! The compiler expects a tab between the parameter name and its type, and
! any or no whitespace before the type. When using C pointers the
! indirection operator C<*> should be considered part of the type and the
! address operator C<&> should be considered part of the variable, as is
! demonstrated in the rpcb_gettime() function above. See the section on
! typemaps for more about handling qualifiers and unary operators in C
! types.

! The parameter list of a function must not have whitespace
! after the open-parenthesis or before the close-parenthesis.

INCORRECT CORRECT

double double
sin( x ) sin(x)
! double x double x

The function name and the return type must be placed on
separate lines.
--- 135,165 ----
allow the programmer to create a more Perl-like interface to the C
function.

=head2 The Anatomy of an XSUB

! The following XSUB allows a Perl program to access a C library function
! called sin(). The XSUB will imitate the C function which takes a single
! argument and returns a single value.

double
sin(x)
! double x

! When using C pointers the indirection operator C<*> should be considered
! part of the type and the address operator C<&> should be considered part of
! the variable, as is demonstrated in the rpcb_gettime() function above. See
! the section on typemaps for more about handling qualifiers and unary
! operators in C types.

! The parameter list of a function must not have whitespace after the
! open-parenthesis or before the close-parenthesis. (This restriction will be
! relaxed in later versions of B<xsubpp>.)

INCORRECT CORRECT

double double
sin( x ) sin(x)
! double x double x

The function name and the return type must be placed on
separate lines.
***************
*** 138,145 ****
INCORRECT CORRECT

double sin(x) double
! double x sin(x)
! double x

=head2 The Argument Stack

--- 167,174 ----
INCORRECT CORRECT

double sin(x) double
! double x sin(x)
! double x

=head2 The Argument Stack

***************
*** 151,158 ****
first position on that stack which belongs to the active
function will be referred to as position 0 for that function.

! XSUBs refer to their stack arguments with the macro B<ST(x)>, where I<x> refers
! to a position in this XSUB's part of the stack. Position 0 for that
function would be known to the XSUB as ST(0). The XSUB's incoming
parameters and outgoing return values always begin at ST(0). For many
simple cases the B<xsubpp> compiler will generate the code necessary to
--- 180,187 ----
first position on that stack which belongs to the active
function will be referred to as position 0 for that function.

! XSUBs refer to their stack arguments with the macro B<ST(x)>, where I<x>
! refers to a position in this XSUB's part of the stack. Position 0 for that
function would be known to the XSUB as ST(0). The XSUB's incoming
parameters and outgoing return values always begin at ST(0). For many
simple cases the B<xsubpp> compiler will generate the code necessary to
***************
*** 246,259 ****
The OUTPUT: keyword can also be used to indicate that function parameters
are output variables. This may be necessary when a parameter has been
modified within the function and the programmer would like the update to
! be seen by Perl. If function parameters are listed under OUTPUT: along
! with the RETVAL variable then the RETVAL variable must be the last one
! listed.

bool_t
rpcb_gettime(host,timep)
! char * host
! time_t &timep
OUTPUT:
timep

--- 275,286 ----
The OUTPUT: keyword can also be used to indicate that function parameters
are output variables. This may be necessary when a parameter has been
modified within the function and the programmer would like the update to
! be seen by Perl.

bool_t
rpcb_gettime(host,timep)
! char *host
! time_t &timep
OUTPUT:
timep

***************
*** 263,272 ****

bool_t
rpcb_gettime(host,timep)
! char * host
! time_t &timep
OUTPUT:
! timep<tab>sv_setnv(ST(1), (double)timep);

=head2 The CODE: Keyword

--- 290,299 ----

bool_t
rpcb_gettime(host,timep)
! char *host
! time_t &timep
OUTPUT:
! timep sv_setnv(ST(1), (double)timep);

=head2 The CODE: Keyword

***************
*** 284,291 ****

bool_t
rpcb_gettime(host,timep)
! char * host
! time_t timep
CODE:
RETVAL = rpcb_gettime( host, &timep );
OUTPUT:
--- 311,318 ----

bool_t
rpcb_gettime(host,timep)
! char *host
! time_t timep
CODE:
RETVAL = rpcb_gettime( host, &timep );
OUTPUT:
***************
*** 314,321 ****

bool_t
rpcb_gettime(host,timep)
! char * host
! time_t &timep = NO_INIT
OUTPUT:
timep

--- 341,348 ----

bool_t
rpcb_gettime(host,timep)
! char *host
! time_t &timep = NO_INIT
OUTPUT:
timep

***************
*** 335,342 ****

bool_t
rpcb_gettime(host,timep)
! char * host = (char *)SvPV(ST(0),na);
! time_t &timep = 0;
OUTPUT:
timep

--- 362,369 ----

bool_t
rpcb_gettime(host,timep)
! char *host = (char *)SvPV(ST(0),na);
! time_t &timep = 0;
OUTPUT:
timep

***************
*** 368,375 ****

bool_t
rpcb_gettime(timep,host="localhost")
! char * host
! time_t timep = NO_INIT
CODE:
RETVAL = rpcb_gettime( host, &timep );
OUTPUT:
--- 395,402 ----

bool_t
rpcb_gettime(timep,host="localhost")
! char *host
! time_t timep = NO_INIT
CODE:
RETVAL = rpcb_gettime( host, &timep );
OUTPUT:
***************
*** 398,404 ****

bool_t
rpcb_gettime(timep, ...)
! time_t timep = NO_INIT
CODE:
{
char *host = "localhost";
--- 425,431 ----

bool_t
rpcb_gettime(timep, ...)
! time_t timep = NO_INIT
CODE:
{
char *host = "localhost";
***************
*** 427,433 ****

void
rpcb_gettime(host)
! char * host
PPCODE:
{
time_t timep;
--- 454,460 ----

void
rpcb_gettime(host)
! char *host
PPCODE:
{
time_t timep;
***************
*** 513,519 ****

void
rpcb_gettime(host)
! char * host
PPCODE:
{
time_t timep;
--- 540,546 ----

void
rpcb_gettime(host)
! char *host
PPCODE:
{
time_t timep;
***************
*** 728,734 ****
is of the expected type.

The following XS code shows the getnetconfigent() function which is used
! with ONC TIRPC. The getnetconfigent() function will return a pointer to a
C structure and has the C prototype shown below. The example will
demonstrate how the C pointer will become a Perl reference. Perl will
consider this reference to be a pointer to a blessed object and will
--- 755,761 ----
is of the expected type.

The following XS code shows the getnetconfigent() function which is used
! with ONC+ TIRPC. The getnetconfigent() function will return a pointer to a
C structure and has the C prototype shown below. The example will
demonstrate how the C pointer will become a Perl reference. Perl will
consider this reference to be a pointer to a blessed object and will
***************
*** 754,766 ****

Netconfig *
getnetconfigent(netid)
! char * netid

MODULE = RPC PACKAGE = NetconfigPtr PREFIX = rpcb_

void
rpcb_DESTROY(netconf)
! Netconfig * netconf
CODE:
printf("Now in NetconfigPtr::DESTROY\n");
free( netconf );
--- 781,793 ----

Netconfig *
getnetconfigent(netid)
! char *netid

MODULE = RPC PACKAGE = NetconfigPtr PREFIX = rpcb_

void
rpcb_DESTROY(netconf)
! Netconfig *netconf
CODE:
printf("Now in NetconfigPtr::DESTROY\n");
free( netconf );
***************
*** 899,905 ****

void
rpcb_gettime(host="localhost")
! char * host
CODE:
{
time_t timep;
--- 926,932 ----

void
rpcb_gettime(host="localhost")
! char *host
CODE:
{
time_t timep;
***************
*** 910,922 ****

Netconfig *
getnetconfigent(netid="udp")
! char * netid

MODULE = RPC PACKAGE = NetconfigPtr PREFIX = rpcb_

void
rpcb_DESTROY(netconf)
! Netconfig * netconf
CODE:
printf("NetconfigPtr::DESTROY\n");
free( netconf );
--- 937,949 ----

Netconfig *
getnetconfigent(netid="udp")
! char *netid

MODULE = RPC PACKAGE = NetconfigPtr PREFIX = rpcb_

void
rpcb_DESTROY(netconf)
! Netconfig *netconf
CODE:
printf("NetconfigPtr::DESTROY\n");
free( netconf );
***************
*** 956,959 ****
=head1 AUTHOR

Dean Roehrich F<E<lt>roehrich@cray.comE<gt>>
! May 3, 1995
--- 983,986 ----
=head1 AUTHOR

Dean Roehrich F<E<lt>roehrich@cray.comE<gt>>
! Oct 12, 1995
Re: perlapi -> perlxs patch [ In reply to ]
Dean Roehrich writes:
> + A new extension should begin with the B<h2xs> tool. This will generate
> + templates for the new Perl module (PM), the XS source file (XS), the MANIFEST
> + file, and the Makefile.PL (PL) files. The Makefile.PL file is a Perl script
> + which will generate a Makefile. This makefile knows how to find and run
> + xsubpp for your extension. When you type "make" your XS file will be run
> + through xsubpp and a C file will be produced. Then the C file will be
> + compiled. A simple example looks like this for an example module named
> + B<Foo>:
> +

This looks a little bit obscure for me. I would (and did) start with a
section "Creating empty extension", will put

echo "use Foo;" > test.pl

after 'ls' below, and after the sequence below will explain what happens
"inside make" and inside `make test'.


Aha: why not have default test.pl made by h2xs?

> + $ h2xs -Afn Foo
> + $ cd ext/Foo
> + $ ls
> + Foo.pm Foo.xs MANIFEST Makefile.PL
> + $ perl5 Makefile.PL
> + $ ls
> + Foo.pm Foo.xs MANIFEST Makefile.PL Makefile
> + $ <edit Foo.pm and Foo.xs to add your stuff>
> + $ make
> + <you will see xsubpp run on Foo.xs and you'll see the C compiler
> + <run on Foo.c, and a bunch of other less-interesting things
> + <will happen.
> +
> + If your Perl was built with dynamic loading then the makefile will build a
> + dynamically loadable extension. If you don't have dynamic loading then the
> + makefile will build a static extension and should create a new Perl binary.
> + The default behavior depends on what is available.
> +


I think static build looks like
make static
make perl
if default is dynamic. Do not know what happens if default is "no
dynamic".

After this section I would explain that editing Foo.pm and Foo.xs will
give you something usable.

Ilya
Re: perlapi -> perlxs patch [ In reply to ]
> Then apply the patch. You should apply it over the perlapi that is in
> 5.001m, ignoring the patch I sent last week.

Which I already applied and checked in, of course...

Larry
Re: perlapi -> perlxs patch [ In reply to ]
> From: Ilya Zakharevich <ilya@math.ohio-state.edu>
>
> Dean Roehrich writes:
> > + A new extension should begin with the B<h2xs> tool. This will generate
> > + templates for the new Perl module (PM), the XS source file (XS), the MANIFEST
> > + file, and the Makefile.PL (PL) files. The Makefile.PL file is a Perl script
> > + which will generate a Makefile. This makefile knows how to find and run
> > + xsubpp for your extension. When you type "make" your XS file will be run
> > + through xsubpp and a C file will be produced. Then the C file will be
> > + compiled. A simple example looks like this for an example module named
> > + B<Foo>:
> > +
>
> This looks a little bit obscure for me. I would (and did) start with a
> section "Creating empty extension", will put
>
> echo "use Foo;" > test.pl
>
> after 'ls' below, and after the sequence below will explain what happens
> "inside make" and inside `make test'.
>
> Aha: why not have default test.pl made by h2xs?
>
Good idea. h2xs should also add a $VERSION = "0.01"; to Foo.pm.

> > + $ h2xs -Afn Foo
> > + $ cd ext/Foo
> > + $ ls
> > + Foo.pm Foo.xs MANIFEST Makefile.PL
> > + $ perl5 Makefile.PL
> > + $ ls
> > + Foo.pm Foo.xs MANIFEST Makefile.PL Makefile
> > + $ <edit Foo.pm and Foo.xs to add your stuff>
> > + $ make
> > + <you will see xsubpp run on Foo.xs and you'll see the C compiler
> > + <run on Foo.c, and a bunch of other less-interesting things
> > + <will happen.
> > +
> > + If your Perl was built with dynamic loading then the makefile will build a
> > + dynamically loadable extension. If you don't have dynamic loading then the
> > + makefile will build a static extension and should create a new Perl binary.
> > + The default behavior depends on what is available.
>
> I think static build looks like
> make static
> make perl
> if default is dynamic. Do not know what happens if default is "no
> dynamic".

To be exact:

if (!$att{LINKTYPE}) {
$att{LINKTYPE} = grep(/dynamic/,@{$att{SKIP} || []})
? 'static'
: ($Config{'usedl'} ? 'dynamic' : 'static');
};


> After this section I would explain that editing Foo.pm and Foo.xs will
> give you something usable.

:-) Yes. And explaining the h2xs does not translate function prototypes
into XS functions will reduce the dissapointment I remember feeling
when I discovered that it hadn't.

> Ilya
>
Tim.
Re: perlapi -> perlxs patch [ In reply to ]
> From: Tim Bunce <Tim.Bunce@ig.co.uk>


> Good idea. h2xs should also add a $VERSION = "0.01"; to Foo.pm.

If Foo.pm is going to have a version it must come from Makefile.PL, not h2xs.


Dean
Re: perlapi -> perlxs patch [ In reply to ]
: :-) Yes. And explaining the h2xs does not translate function prototypes
: into XS functions will reduce the dissapointment I remember feeling
: when I discovered that it hadn't.

Alternately, you could just make h2xs translate the function prototypes. :-)

Larry
Re: perlapi -> perlxs patch [ In reply to ]
On Fri, 13 Oct 1995, Dean Roehrich wrote:

> > From: Tim Bunce <Tim.Bunce@ig.co.uk>
>
>
> > Good idea. h2xs should also add a $VERSION = "0.01"; to Foo.pm.
>
> If Foo.pm is going to have a version it must come from Makefile.PL, not h2xs.

This means MakeMaker would have to touch your files -- a probable no-no.
Look at it this way: h2xs would add a statement of '$VERSION = "0.01"' to all
of Makefile.PL, README, Foo.pm, and Foo.xs. Yes, you would be charged with
keeping them up-to-date, but at least they would all be there.

However, there is a different way of doing this, if you specifically want a
run-time version: have MakeMaker pass the version off as a -Define when it
compiles the .xs, so the extension can create $VERSION with the correct value
when it is loaded.

> Dean

--
Kenneth Albanowski (kjahds@kjahds.com, CIS: 70705,126)
Re: perlapi -> perlxs patch [ In reply to ]
> From: Dean Roehrich <roehrich@cray.com>
>
> > From: Tim Bunce <Tim.Bunce@ig.co.uk>
>
> > Good idea. h2xs should also add a $VERSION = "0.01"; to Foo.pm.
>
> If Foo.pm is going to have a version it must come from Makefile.PL, not h2xs.
>
True but I think MakeMaker's version propogation scheme is still experimental.

Meanwhile just having $VERSION = "0.01"; be present will encourage the
developer to maintain it. Once MakeMaker's version propogation scheme
is stable we can switch to that.

Tim.
Re: perlapi -> perlxs patch [ In reply to ]
> From: Kenneth Albanowski <kjahds@kjahds.com>
> >
> > If Foo.pm is going to have a version it must come from Makefile.PL, not h2xs.
>
> This means MakeMaker would have to touch your files -- a probable no-no.
> Look at it this way: h2xs would add a statement of '$VERSION = "0.01"' to all
> of Makefile.PL, README, Foo.pm, and Foo.xs. Yes, you would be charged with
> keeping them up-to-date, but at least they would all be there.

I'm not really happy with this idea. The tool's job is to automate things,
not to create more manual, and unnecessary, work.

Dean
Re: perlapi -> perlxs patch [ In reply to ]
On Fri, 13 Oct 1995, Dean Roehrich wrote:

> > From: Kenneth Albanowski <kjahds@kjahds.com>
> > >
> > > If Foo.pm is going to have a version it must come from Makefile.PL, not h2xs.
> >
> > This means MakeMaker would have to touch your files -- a probable no-no.
> > Look at it this way: h2xs would add a statement of '$VERSION = "0.01"' to all
> > of Makefile.PL, README, Foo.pm, and Foo.xs. Yes, you would be charged with
> > keeping them up-to-date, but at least they would all be there.
>
> I'm not really happy with this idea. The tool's job is to automate things,
> not to create more manual, and unnecessary, work.

What's the goal? If the goal is to have version numbers in each of the
files, then -- baring RCS -- there isn't any choice.

If the goal is to have an accessible $VERSION variable after the module is
loaded, then my other comment about MakeMake passing it to the XS file
stands.

> Dean

--
Kenneth Albanowski (kjahds@kjahds.com, CIS: 70705,126)
Re: perlapi -> perlxs patch [ In reply to ]
>>>>> "Kenneth" == Kenneth Albanowski <kjahds@kjahds.com> writes:

Kenneth> On Fri, 13 Oct 1995, Dean Roehrich wrote:
>> > From: Tim Bunce <Tim.Bunce@ig.co.uk>
>>
>>
>> > Good idea. h2xs should also add a $VERSION = "0.01"; to Foo.pm.
>>
>> If Foo.pm is going to have a version it must come from Makefile.PL, not h2xs.

Kenneth> This means MakeMaker would have to touch your files -- a probable no-no.

Agreed.

Kenneth> Look at it this way: h2xs would add a statement of '$VERSION = "0.01"' to all
Kenneth> of Makefile.PL, README, Foo.pm, and Foo.xs. Yes, you would be charged with
Kenneth> keeping them up-to-date, but at least they would all be there.

Kenneth> However, there is a different way of doing this, if you specifically want a
Kenneth> run-time version: have MakeMaker pass the version off as a -Define when it

This goes immediately on my ToDo list. (And yes, I *will* work off my ToDo list :)

Kenneth> compiles the .xs, so the extension can create $VERSION with the correct value
Kenneth> when it is loaded.

>> Dean

Kenneth> --
Kenneth> Kenneth Albanowski (kjahds@kjahds.com, CIS: 70705,126)



andreas
Re: perlapi -> perlxs patch [ In reply to ]
In <Pine.LNX.3.91.951013121016.1950N-100000@kjahds.com>
On Fri, 13 Oct 1995 12:13:47 -0400 (EDT)
Kenneth Albanowski <kjahds@kjahds.com> writes:
>
>However, there is a different way of doing this, if you specifically want a
>run-time version: have MakeMaker pass the version off as a -Define when it
>compiles the .xs, so the extension can create $VERSION with the correct value
>when it is loaded.
>
This is how Tk does it - Version is pulled from Makefile.PL -> Makefile
and passed in as a -D to C compile.
Re: perlapi -> perlxs patch [ In reply to ]
FYI, Tim, I just got all your email from Friday, 13th. Also the other
one, where you talk about the scanning for Prerequisites :-( Must have
been a true Friday, the 13th ;-)


>>>>> "tim" == Tim Bunce <Tim.Bunce@ig.co.uk> writes:

>> From: Dean Roehrich <roehrich@cray.com>
>>
>> > From: Tim Bunce <Tim.Bunce@ig.co.uk>
>>
>> > Good idea. h2xs should also add a $VERSION = "0.01"; to Foo.pm.
>>
>> If Foo.pm is going to have a version it must come from Makefile.PL, not h2xs.
>>
tim> True but I think MakeMaker's version propogation scheme is still experimental.

There is a misunderstanding. I do not even experiment with a version
propagation from Makefile.PL.

As Kenneth has pointed out, we do not want to write anything into
Foo.pm, because that is souvereign territory. What we can do is write
a -DVERSION=$(VERSION) to propagate the version into the compiler
call, so a Foo.c may use that.

But how the author optimizes version management is at his discretion.

I myself keep it in Msql.pm, MakeMaker.pm, and Symdump.pm. As Msql.pm
is an XS extension, I cannot run 'use Msql' in the Makefile.PL for
obvious reasons. I parse the first few lines of Msql.pm instead, and
pass the result to Makefile.PL. This is really efficient and I would
recommend that, but your mileage may vary.

Additionally I add the MakeMaker.pm to the dependencies like so:

'macro' => {CONFIGDEP => '$(PERL_ARCHLIB)/Config.pm $(PERL_INC)/config.h lib/ExtUtils/MakeMaker.pm'}

This rebuilds my Makefile every time I change a byte, which is
annoing, but an excellent way to be reminded of version management.

I get the feeling, we should collect opinions and write a paragraph in
the pods.

andreas


tim> Meanwhile just having $VERSION = "0.01"; be present will encourage the
tim> developer to maintain it.

I agree.

tim> Once MakeMaker's version propogation scheme
tim> is stable we can switch to that.



tim> Tim.