home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-03-02 | 55.9 KB | 1,057 lines |
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- NNNNAAAAMMMMEEEE
- perlXStut - Tutorial for XSUB's
-
- DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
- This tutorial will educate the reader on the steps
- involved in creating a Perl extension. The reader is
- assumed to have access to the _p_e_r_l_g_u_t_s manpage and the
- _p_e_r_l_x_s manpage.
-
- This tutorial starts with very simple examples and becomes
- more complex, with each new example adding new features.
- Certain concepts may not be completely explained until
- later in the tutorial in order to slowly ease the reader
- into building extensions.
-
- VVVVEEEERRRRSSSSIIIIOOOONNNN CCCCAAAAVVVVEEEEAAAATTTT
-
- This tutorial tries hard to keep up with the latest
- development versions of Perl. This often means that it is
- sometimes in advance of the latest released version of
- Perl, and that certain features described here might not
- work on earlier versions. This section will keep track of
- when various features were added to Perl 5.
-
- +o In versions of 5.002 prior to version beta 3, then the
- line in the .xs file about "PROTOTYPES: DISABLE" will
- cause a compiler error. Simply remove that line from
- the file.
-
- +o In versions of 5.002 prior to version 5.002b1h, the
- test.pl file was not automatically created by h2xs.
- This means that you cannot say "make test" to run the
- test script. You will need to add the following line
- before the "use extension" statement:
-
- uuuusssseeee lllliiiibbbb ''''....////bbbblllliiiibbbb'''';;;;
-
-
- +o In versions 5.000 and 5.001, instead of using the
- above line, you will need to use the following line:
-
- BBBBEEEEGGGGIIIINNNN {{{{ uuuunnnnsssshhhhiiiifffftttt((((@@@@IIIINNNNCCCC,,,, """"....////bbbblllliiiibbbb"""")))) }}}}
-
-
- +o This document assumes that the executable named "perl"
- is Perl version 5. Some systems may have installed
- Perl version 5 as "perl5".
-
- DDDDYYYYNNNNAAAAMMMMIIIICCCC VVVVEEEERRRRSSSSUUUUSSSS SSSSTTTTAAAATTTTIIIICCCC
-
- It is commonly thought that if a system does not have the
- capability to dynamically load a library, you cannot build
- XSUB's. This is incorrect. You _c_a_n build them, but you
- must link the XSUB's subroutines with the rest of Perl,
-
-
-
- 12/Feb/96 perl 5.002 with 1
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- creating a new executable. This situation is similar to
- Perl 4.
-
- This tutorial can still be used on such a system. The
- XSUB build mechanism will check the system and build a
- dynamically-loadable library if possible, or else a static
- library and then, optionally, a new statically-linked
- executable with that static library linked in.
-
- Should you wish to build a statically-linked executable on
- a system which can dynamically load libraries, you may, in
- all the following examples, where the command "make" with
- no arguments is executed, run the command "make perl"
- instead.
-
- If you have generated such a statically-linked executable
- by choice, then instead of saying "make test", you should
- say "make test_static". On systems that cannot build
- dynamically-loadable libraries at all, simply saying "make
- test" is sufficient.
-
- EEEEXXXXAAAAMMMMPPPPLLLLEEEE 1111
-
- Our first extension will be very simple. When we call the
- routine in the extension, it will print out a well-known
- message and return.
-
- Run "h2xs -A -n Mytest". This creates a directory named
- Mytest, possibly under ext/ if that directory exists in
- the current working directory. Several files will be
- created in the Mytest dir, including MANIFEST,
- Makefile.PL, Mytest.pm, Mytest.xs, test.pl, and Changes.
-
- The MANIFEST file contains the names of all the files
- created.
-
- The file Makefile.PL should look something like this:
-
- uuuusssseeee EEEExxxxttttUUUUttttiiiillllssss::::::::MMMMaaaakkkkeeeeMMMMaaaakkkkeeeerrrr;;;;
- #### SSSSeeeeeeee lllliiiibbbb////EEEExxxxttttUUUUttttiiiillllssss////MMMMaaaakkkkeeeeMMMMaaaakkkkeeeerrrr....ppppmmmm ffffoooorrrr ddddeeeettttaaaaiiiillllssss ooooffff hhhhoooowwww ttttoooo iiiinnnnfffflllluuuueeeennnncccceeee
- #### tttthhhheeee ccccoooonnnntttteeeennnnttttssss ooooffff tttthhhheeee MMMMaaaakkkkeeeeffffiiiilllleeee tttthhhhaaaatttt iiiissss wwwwrrrriiiitttttttteeeennnn....
- WWWWrrrriiiitttteeeeMMMMaaaakkkkeeeeffffiiiilllleeee((((
- ''''NNNNAAAAMMMMEEEE'''' ====>>>> ''''MMMMyyyytttteeeesssstttt'''',,,,
- ''''VVVVEEEERRRRSSSSIIIIOOOONNNN____FFFFRRRROOOOMMMM'''' ====>>>> ''''MMMMyyyytttteeeesssstttt....ppppmmmm'''',,,, #### ffffiiiinnnnddddssss $$$$VVVVEEEERRRRSSSSIIIIOOOONNNN
- ''''LLLLIIIIBBBBSSSS'''' ====>>>> [[[['''''''']]]],,,, #### eeee....gggg....,,,, ''''----llllmmmm''''
- ''''DDDDEEEEFFFFIIIINNNNEEEE'''' ====>>>> '''''''',,,, #### eeee....gggg....,,,, ''''----DDDDHHHHAAAAVVVVEEEE____SSSSOOOOMMMMEEEETTTTHHHHIIIINNNNGGGG''''
- ''''IIIINNNNCCCC'''' ====>>>> '''''''',,,, #### eeee....gggg....,,,, ''''----IIII////uuuussssrrrr////iiiinnnncccclllluuuuddddeeee////ooootttthhhheeeerrrr''''
- ))));;;;
-
- The file Mytest.pm should start with something like this:
-
- ppppaaaacccckkkkaaaaggggeeee MMMMyyyytttteeeesssstttt;;;;
-
-
-
-
-
- 12/Feb/96 perl 5.002 with 2
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- rrrreeeeqqqquuuuiiiirrrreeee EEEExxxxppppoooorrrrtttteeeerrrr;;;;
- rrrreeeeqqqquuuuiiiirrrreeee DDDDyyyynnnnaaaaLLLLooooaaaaddddeeeerrrr;;;;
-
- @@@@IIIISSSSAAAA ==== qqqqwwww((((EEEExxxxppppoooorrrrtttteeeerrrr DDDDyyyynnnnaaaaLLLLooooaaaaddddeeeerrrr))));;;;
- #### IIIItttteeeemmmmssss ttttoooo eeeexxxxppppoooorrrrtttt iiiinnnnttttoooo ccccaaaalllllllleeeerrrrssss nnnnaaaammmmeeeessssppppaaaacccceeee bbbbyyyy ddddeeeeffffaaaauuuulllltttt.... NNNNooootttteeee:::: ddddoooo nnnnooootttt eeeexxxxppppoooorrrrtttt
- #### nnnnaaaammmmeeeessss bbbbyyyy ddddeeeeffffaaaauuuulllltttt wwwwiiiitttthhhhoooouuuutttt aaaa vvvveeeerrrryyyy ggggoooooooodddd rrrreeeeaaaassssoooonnnn.... UUUUsssseeee EEEEXXXXPPPPOOOORRRRTTTT____OOOOKKKK iiiinnnnsssstttteeeeaaaadddd....
- #### DDDDoooo nnnnooootttt ssssiiiimmmmppppllllyyyy eeeexxxxppppoooorrrrtttt aaaallllllll yyyyoooouuuurrrr ppppuuuubbbblllliiiicccc ffffuuuunnnnccccttttiiiioooonnnnssss////mmmmeeeetttthhhhooooddddssss////ccccoooonnnnssssttttaaaannnnttttssss....
- @@@@EEEEXXXXPPPPOOOORRRRTTTT ==== qqqqwwww((((
-
- ))));;;;
- $$$$VVVVEEEERRRRSSSSIIIIOOOONNNN ==== ''''0000....00001111'''';;;;
-
- bbbboooooooottttssssttttrrrraaaapppp MMMMyyyytttteeeesssstttt $$$$VVVVEEEERRRRSSSSIIIIOOOONNNN;;;;
-
- #### PPPPrrrreeeellllooooaaaaddddeeeedddd mmmmeeeetttthhhhooooddddssss ggggoooo hhhheeeerrrreeee....
-
- #### AAAAuuuuttttoooollllooooaaaadddd mmmmeeeetttthhhhooooddddssss ggggoooo aaaafffftttteeeerrrr ________EEEENNNNDDDD________,,,, aaaannnndddd aaaarrrreeee pppprrrroooocccceeeesssssssseeeedddd bbbbyyyy tttthhhheeee aaaauuuuttttoooosssspppplllliiiitttt pppprrrrooooggggrrrraaaammmm....
-
- 1111;;;;
- ________EEEENNNNDDDD________
- #### BBBBeeeelllloooowwww iiiissss tttthhhheeee ssssttttuuuubbbb ooooffff ddddooooccccuuuummmmeeeennnnttttaaaattttiiiioooonnnn ffffoooorrrr yyyyoooouuuurrrr mmmmoooodddduuuulllleeee.... YYYYoooouuuu bbbbeeeetttttttteeeerrrr eeeeddddiiiitttt iiiitttt!!!!
-
- And the Mytest.xs file should look something like this:
-
- ####iiiiffffddddeeeeffff ________ccccpppplllluuuusssspppplllluuuussss
- eeeexxxxtttteeeerrrrnnnn """"CCCC"""" {{{{
- ####eeeennnnddddiiiiffff
- ####iiiinnnncccclllluuuuddddeeee """"EEEEXXXXTTTTEEEERRRRNNNN....hhhh""""
- ####iiiinnnncccclllluuuuddddeeee """"ppppeeeerrrrllll....hhhh""""
- ####iiiinnnncccclllluuuuddddeeee """"XXXXSSSSUUUUBBBB....hhhh""""
- ####iiiiffffddddeeeeffff ________ccccpppplllluuuusssspppplllluuuussss
- }}}}
- ####eeeennnnddddiiiiffff
-
- PPPPRRRROOOOTTTTOOOOTTTTYYYYPPPPEEEESSSS:::: DDDDIIIISSSSAAAABBBBLLLLEEEE
-
- MMMMOOOODDDDUUUULLLLEEEE ==== MMMMyyyytttteeeesssstttt PPPPAAAACCCCKKKKAAAAGGGGEEEE ==== MMMMyyyytttteeeesssstttt
-
- Let's edit the .xs file by adding this to the end of the
- file:
-
- vvvvooooiiiidddd
- hhhheeeelllllllloooo(((())))
- CCCCOOOODDDDEEEE::::
- pppprrrriiiinnnnttttffff((((""""HHHHeeeelllllllloooo,,,, wwwwoooorrrrlllldddd!!!!\\\\nnnn""""))));;;;
-
- Now we'll run "perl Makefile.PL". This will create a real
- Makefile, which make needs. It's output looks something
- like:
-
-
-
-
-
-
-
-
- 12/Feb/96 perl 5.002 with 3
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- %%%% ppppeeeerrrrllll MMMMaaaakkkkeeeeffffiiiilllleeee....PPPPLLLL
- CCCChhhheeeecccckkkkiiiinnnngggg iiiiffff yyyyoooouuuurrrr kkkkiiiitttt iiiissss ccccoooommmmpppplllleeeetttteeee............
- LLLLooooooookkkkssss ggggoooooooodddd
- WWWWrrrriiiittttiiiinnnngggg MMMMaaaakkkkeeeeffffiiiilllleeee ffffoooorrrr MMMMyyyytttteeeesssstttt
- %%%%
-
- Now, running make will produce output that looks something
- like this (some long lines shortened for clarity):
-
- %%%% mmmmaaaakkkkeeee
- uuuummmmaaaasssskkkk 0000 &&&&&&&& ccccpppp MMMMyyyytttteeeesssstttt....ppppmmmm ....////bbbblllliiiibbbb////MMMMyyyytttteeeesssstttt....ppppmmmm
- ppppeeeerrrrllll xxxxssssuuuubbbbpppppppp ----ttttyyyyppppeeeemmmmaaaapppp ttttyyyyppppeeeemmmmaaaapppp MMMMyyyytttteeeesssstttt....xxxxssss >>>>MMMMyyyytttteeeesssstttt....ttttcccc &&&&&&&& mmmmvvvv MMMMyyyytttteeeesssstttt....ttttcccc MMMMyyyytttteeeesssstttt....cccc
- cccccccc ----cccc MMMMyyyytttteeeesssstttt....cccc
- RRRRuuuunnnnnnnniiiinnnngggg MMMMkkkkbbbboooooooottttssssttttrrrraaaapppp ffffoooorrrr MMMMyyyytttteeeesssstttt (((())))
- cccchhhhmmmmoooodddd 666644444444 MMMMyyyytttteeeesssstttt....bbbbssss
- LLLLDDDD____RRRRUUUUNNNN____PPPPAAAATTTTHHHH===="""""""" lllldddd ----oooo ....////bbbblllliiiibbbb////PPPPAAAA----RRRRIIIISSSSCCCC1111....1111////aaaauuuuttttoooo////MMMMyyyytttteeeesssstttt////MMMMyyyytttteeeesssstttt....ssssllll ----bbbb MMMMyyyytttteeeesssstttt....oooo
- cccchhhhmmmmoooodddd 777755555555 ....////bbbblllliiiibbbb////PPPPAAAA----RRRRIIIISSSSCCCC1111....1111////aaaauuuuttttoooo////MMMMyyyytttteeeesssstttt////MMMMyyyytttteeeesssstttt....ssssllll
- ccccpppp MMMMyyyytttteeeesssstttt....bbbbssss ....////bbbblllliiiibbbb////PPPPAAAA----RRRRIIIISSSSCCCC1111....1111////aaaauuuuttttoooo////MMMMyyyytttteeeesssstttt////MMMMyyyytttteeeesssstttt....bbbbssss
- cccchhhhmmmmoooodddd 666644444444 ....////bbbblllliiiibbbb////PPPPAAAA----RRRRIIIISSSSCCCC1111....1111////aaaauuuuttttoooo////MMMMyyyytttteeeesssstttt////MMMMyyyytttteeeesssstttt....bbbbssss
-
- Now, although there is already a test.pl template ready
- for us, for this example only, we'll create a special test
- script. Create a file called hello that looks like this:
-
- ####!!!! ////oooopppptttt////ppppeeeerrrrllll5555////bbbbiiiinnnn////ppppeeeerrrrllll
-
- uuuusssseeee lllliiiibbbb ''''....////bbbblllliiiibbbb'''';;;;
-
- uuuusssseeee MMMMyyyytttteeeesssstttt;;;;
-
- MMMMyyyytttteeeesssstttt::::::::hhhheeeelllllllloooo(((())));;;;
-
- Now we run the script and we should see the following
- output:
-
- %%%% ppppeeeerrrrllll hhhheeeelllllllloooo
- HHHHeeeelllllllloooo,,,, wwwwoooorrrrlllldddd!!!!
- %%%%
-
-
- EEEEXXXXAAAAMMMMPPPPLLLLEEEE 2222
-
- Now let's add to our extension a subroutine that will take
- a single argument and return 0 if the argument is even, 1
- if the argument is odd.
-
- Add the following to the end of Mytest.xs:
-
-
-
-
-
-
-
-
-
-
- 12/Feb/96 perl 5.002 with 4
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- iiiinnnntttt
- iiiissss____eeeevvvveeeennnn((((iiiinnnnppppuuuutttt))))
- iiiinnnntttt iiiinnnnppppuuuutttt
- CCCCOOOODDDDEEEE::::
- RRRREEEETTTTVVVVAAAALLLL ==== ((((iiiinnnnppppuuuutttt %%%% 2222 ======== 0000))));;;;
- OOOOUUUUTTTTPPPPUUUUTTTT::::
- RRRREEEETTTTVVVVAAAALLLL
-
- There does not need to be white space at the start of the
- "int input" line, but it is useful for improving
- readability. The semi-colon at the end of that line is
- also optional.
-
- Any white space may be between the "int" and "input". It
- is also okay for the four lines starting at the "CODE:"
- line to not be indented. However, for readability
- purposes, it is suggested that you indent them 8 spaces
- (or one normal tab stop).
-
- Now re-run make to rebuild our new shared library.
-
- Now perform the same steps as before, generating a
- Makefile from the Makefile.PL file, and running make.
-
- In order to test that our extension works, we now need to
- look at the file test.pl. This file is set up to imitate
- the same kind of testing structure that Perl itself has.
- Within the test script, you perform a number of tests to
- confirm the behavior of the extension, printing "ok" when
- the test is correct, "not ok" when it is not.
-
- Remove the line that starts with "use lib", change the
- print statement in the BEGIN block to print "1..4", and
- add the following code to the end of the file:
-
- pppprrrriiiinnnntttt &&&&MMMMyyyytttteeeesssstttt::::::::iiiissss____eeeevvvveeeennnn((((0000)))) ======== 1111 ???? """"ooookkkk 2222"""" :::: """"nnnnooootttt ooookkkk 2222"""",,,, """"\\\\nnnn"""";;;;
- pppprrrriiiinnnntttt &&&&MMMMyyyytttteeeesssstttt::::::::iiiissss____eeeevvvveeeennnn((((1111)))) ======== 0000 ???? """"ooookkkk 3333"""" :::: """"nnnnooootttt ooookkkk 3333"""",,,, """"\\\\nnnn"""";;;;
- pppprrrriiiinnnntttt &&&&MMMMyyyytttteeeesssstttt::::::::iiiissss____eeeevvvveeeennnn((((2222)))) ======== 1111 ???? """"ooookkkk 4444"""" :::: """"nnnnooootttt ooookkkk 4444"""",,,, """"\\\\nnnn"""";;;;
-
- We will be calling the test script through the command
- "make test". You should see output that looks something
- like this:
-
- %%%% mmmmaaaakkkkeeee tttteeeesssstttt
- PPPPEEEERRRRLLLL____DDDDLLLL____NNNNOOOONNNNLLLLAAAAZZZZYYYY====1111 ////oooopppptttt////ppppeeeerrrrllll5555....000000002222bbbb2222////bbbbiiiinnnn////ppppeeeerrrrllll ((((lllloooottttssss ooooffff ----IIII aaaarrrrgggguuuummmmeeeennnnttttssss)))) tttteeeesssstttt....ppppllll
- 1111........4444
- ooookkkk 1111
- ooookkkk 2222
- ooookkkk 3333
- ooookkkk 4444
- %%%%
-
-
-
-
-
-
- 12/Feb/96 perl 5.002 with 5
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- WWWWHHHHAAAATTTT HHHHAAAASSSS GGGGOOOONNNNEEEE OOOONNNN????
-
- The program h2xs is the starting point for creating
- extensions. In later examples we'll see how we can use
- h2xs to read header files and generate templates to
- connect to C routines.
-
- h2xs creates a number of files in the extension directory.
- The file Makefile.PL is a perl script which will generate
- a true Makefile to build the extension. We'll take a
- closer look at it later.
-
- The files <extension>.pm and <extension>.xs contain the
- meat of the extension. The .xs file holds the C routines
- that make up the extension. The .pm file contains
- routines that tell Perl how to load your extension.
-
- Generating and invoking the Makefile created a directory
- blib (which stands for "build library") in the current
- working directory. This directory will contain the shared
- library that we will build. Once we have tested it, we
- can install it into its final location.
-
- Invoking the test script via "make test" did something
- very important. It invoked perl with all those -I
- arguments so that it could find the various files that are
- part of the extension.
-
- It is _v_e_r_y important that while you are still testing
- extensions that you use "make test". If you try to run
- the test script all by itself, you will get a fatal error.
-
- Another reason it is important to use "make test" to run
- your test script is that if you are testing an upgrade to
- an already-existing version, using "make test" insures
- that you use your new extension, not the already-existing
- version.
-
- When Perl sees a uuuusssseeee eeeexxxxtttteeeennnnssssiiiioooonnnn;;;;, it searches for a file
- with the same name as the use'd extension that has a .pm
- suffix. If that file cannot be found, Perl dies with a
- fatal error. The default search path is contained in the
- @@@@IIIINNNNCCCC array.
-
- In our case, Mytest.pm tells perl that it will need the
- Exporter and Dynamic Loader extensions. It then sets the
- @@@@IIIISSSSAAAA and @@@@EEEEXXXXPPPPOOOORRRRTTTT arrays and the $$$$VVVVEEEERRRRSSSSIIIIOOOONNNN scalar; finally
- it tells perl to bootstrap the module. Perl will call its
- dynamic loader routine (if there is one) and load the
- shared library.
-
- The two arrays that are set in the .pm file are very
- important. The @@@@IIIISSSSAAAA array contains a list of other
- packages in which to search for methods (or subroutines)
-
-
-
- 12/Feb/96 perl 5.002 with 6
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- that do not exist in the current package. The @@@@EEEEXXXXPPPPOOOORRRRTTTT
- array tells Perl which of the extension's routines should
- be placed into the calling package's namespace.
-
- It's important to select what to export carefully. Do NOT
- export method names and do NOT export anything else _b_y
- _d_e_f_a_u_l_t without a good reason.
-
- As a general rule, if the module is trying to be object-
- oriented then don't export anything. If it's just a
- collection of functions then you can export any of the
- functions via another array, called @@@@EEEEXXXXPPPPOOOORRRRTTTT____OOOOKKKK.
-
- See the _p_e_r_l_m_o_d manpage for more information.
-
- The $$$$VVVVEEEERRRRSSSSIIIIOOOONNNN variable is used to ensure that the .pm file
- and the shared library are "in sync" with each other. Any
- time you make changes to the .pm or .xs files, you should
- increment the value of this variable.
-
- WWWWRRRRIIIITTTTIIIINNNNGGGG GGGGOOOOOOOODDDD TTTTEEEESSSSTTTT SSSSCCCCRRRRIIIIPPPPTTTTSSSS
-
- The importance of writing good test scripts cannot be
- overemphasized. You should closely follow the "ok/not ok"
- style that Perl itself uses, so that it is very easy and
- unambiguous to determine the outcome of each test case.
- When you find and fix a bug, make sure you add a test case
- for it.
-
- By running "make test", you ensure that your test.pl
- script runs and uses the correct version of your
- extension. If you have many test cases, you might want to
- copy Perl's test style. Create a directory named "t", and
- ensure all your test files end with the suffix ".t". The
- Makefile will properly run all these test files.
-
- EEEEXXXXAAAAMMMMPPPPLLLLEEEE 3333
-
- Our third extension will take one argument as its input,
- round off that value, and set the _a_r_g_u_m_e_n_t to the rounded
- value.
-
- Add the following to the end of Mytest.xs:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 12/Feb/96 perl 5.002 with 7
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- vvvvooooiiiidddd
- rrrroooouuuunnnndddd((((aaaarrrrgggg))))
- ddddoooouuuubbbblllleeee aaaarrrrgggg
- CCCCOOOODDDDEEEE::::
- iiiiffff ((((aaaarrrrgggg >>>> 0000....0000)))) {{{{
- aaaarrrrgggg ==== fffflllloooooooorrrr((((aaaarrrrgggg ++++ 0000....5555))));;;;
- }}}} eeeellllsssseeee iiiiffff ((((aaaarrrrgggg <<<< 0000....0000)))) {{{{
- aaaarrrrgggg ==== cccceeeeiiiillll((((aaaarrrrgggg ---- 0000....5555))));;;;
- }}}} eeeellllsssseeee {{{{
- aaaarrrrgggg ==== 0000....0000;;;;
- }}}}
- OOOOUUUUTTTTPPPPUUUUTTTT::::
- aaaarrrrgggg
-
- Edit the Makefile.PL file so that the corresponding line
- looks like this:
-
- ''''LLLLIIIIBBBBSSSS'''' ====>>>> [[[[''''----llllmmmm'''']]]],,,, #### eeee....gggg....,,,, ''''----llllmmmm''''
-
- Generate the Makefile and run make. Change the BEGIN
- block to print out "1..9" and add the following to
- test.pl:
-
- $$$$iiii ==== ----1111....5555;;;; &&&&MMMMyyyytttteeeesssstttt::::::::rrrroooouuuunnnndddd(((($$$$iiii))));;;; pppprrrriiiinnnntttt $$$$iiii ======== ----2222....0000 ???? """"ooookkkk 5555"""" :::: """"nnnnooootttt ooookkkk 5555"""",,,, """"\\\\nnnn"""";;;;
- $$$$iiii ==== ----1111....1111;;;; &&&&MMMMyyyytttteeeesssstttt::::::::rrrroooouuuunnnndddd(((($$$$iiii))));;;; pppprrrriiiinnnntttt $$$$iiii ======== ----1111....0000 ???? """"ooookkkk 6666"""" :::: """"nnnnooootttt ooookkkk 6666"""",,,, """"\\\\nnnn"""";;;;
- $$$$iiii ==== 0000....0000;;;; &&&&MMMMyyyytttteeeesssstttt::::::::rrrroooouuuunnnndddd(((($$$$iiii))));;;; pppprrrriiiinnnntttt $$$$iiii ======== 0000....0000 ???? """"ooookkkk 7777"""" :::: """"nnnnooootttt ooookkkk 7777"""",,,, """"\\\\nnnn"""";;;;
- $$$$iiii ==== 0000....5555;;;; &&&&MMMMyyyytttteeeesssstttt::::::::rrrroooouuuunnnndddd(((($$$$iiii))));;;; pppprrrriiiinnnntttt $$$$iiii ======== 1111....0000 ???? """"ooookkkk 8888"""" :::: """"nnnnooootttt ooookkkk 8888"""",,,, """"\\\\nnnn"""";;;;
- $$$$iiii ==== 1111....2222;;;; &&&&MMMMyyyytttteeeesssstttt::::::::rrrroooouuuunnnndddd(((($$$$iiii))));;;; pppprrrriiiinnnntttt $$$$iiii ======== 1111....0000 ???? """"ooookkkk 9999"""" :::: """"nnnnooootttt ooookkkk 9999"""",,,, """"\\\\nnnn"""";;;;
-
- Running "make test" should now print out that all nine
- tests are okay.
-
- You might be wondering if you can round a constant. To
- see what happens, add the following line to test.pl
- temporarily:
-
- &&&&MMMMyyyytttteeeesssstttt::::::::rrrroooouuuunnnndddd((((3333))));;;;
-
- Run "make test" and notice that Perl dies with a fatal
- error. Perl won't let you change the value of constants!
-
- WWWWHHHHAAAATTTT''''SSSS NNNNEEEEWWWW HHHHEEEERRRREEEE????
-
- Two things are new here. First, we've made some changes
- to Makefile.PL. In this case, we've specified an extra
- library to link in, in this case the math library, libm.
- We'll talk later about how to write XSUBs that can call
- every routine in a library.
-
- Second, the value of the function is being passed back not
- as the function's return value, but through the same
- variable that was passed into the function.
-
-
-
-
-
- 12/Feb/96 perl 5.002 with 8
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- IIIINNNNPPPPUUUUTTTT AAAANNNNDDDD OOOOUUUUTTTTPPPPUUUUTTTT PPPPAAAARRRRAAAAMMMMEEEETTTTEEEERRRRSSSS
-
- You specify the parameters that will be passed into the
- XSUB just after you declare the function return value and
- name. Each parameter line starts with optional white
- space, and may have an optional terminating semicolon.
-
- The list of output parameters occurs after the OUTPUT:
- directive. The use of RETVAL tells Perl that you wish to
- send this value back as the return value of the XSUB
- function. In Example 3, the value we wanted returned was
- contained in the same variable we passed in, so we listed
- it (and not RETVAL) in the OUTPUT: section.
-
- TTTTHHHHEEEE XXXXSSSSUUUUBBBBPPPPPPPP CCCCOOOOMMMMPPPPIIIILLLLEEEERRRR
-
- The compiler xsubpp takes the XS code in the .xs file and
- converts it into C code, placing it in a file whose suffix
- is .c. The C code created makes heavy use of the C
- functions within Perl.
-
- TTTTHHHHEEEE TTTTYYYYPPPPEEEEMMMMAAAAPPPP FFFFIIIILLLLEEEE
-
- The xsubpp compiler uses rules to convert from Perl's data
- types (scalar, array, etc.) to C's data types (int, char
- *, etc.). These rules are stored in the typemap file
- ($PERLLIB/ExtUtils/typemap). This file is split into
- three parts.
-
- The first part attempts to map various C data types to a
- coded flag, which has some correspondence with the various
- Perl types. The second part contains C code which xsubpp
- uses for input parameters. The third part contains C code
- which xsubpp uses for output parameters. We'll talk more
- about the C code later.
-
- Let's now take a look at a portion of the .c file created
- for our extension.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 12/Feb/96 perl 5.002 with 9
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- XXXXSSSS((((XXXXSSSS____MMMMyyyytttteeeesssstttt____rrrroooouuuunnnndddd))))
- {{{{
- ddddXXXXSSSSAAAARRRRGGGGSSSS;;;;
- iiiiffff ((((iiiitttteeeemmmmssss !!!!==== 1111))))
- ccccrrrrooooaaaakkkk((((""""UUUUssssaaaaggggeeee:::: MMMMyyyytttteeeesssstttt::::::::rrrroooouuuunnnndddd((((aaaarrrrgggg))))""""))));;;;
- {{{{
- ddddoooouuuubbbblllleeee aaaarrrrgggg ==== ((((ddddoooouuuubbbblllleeee))))SSSSvvvvNNNNVVVV((((SSSSTTTT((((0000))))))));;;; ////**** XXXXXXXXXXXXXXXXXXXX ****////
- iiiiffff ((((aaaarrrrgggg >>>> 0000....0000)))) {{{{
- aaaarrrrgggg ==== fffflllloooooooorrrr((((aaaarrrrgggg ++++ 0000....5555))));;;;
- }}}} eeeellllsssseeee iiiiffff ((((aaaarrrrgggg <<<< 0000....0000)))) {{{{
- aaaarrrrgggg ==== cccceeeeiiiillll((((aaaarrrrgggg ---- 0000....5555))));;;;
- }}}} eeeellllsssseeee {{{{
- aaaarrrrgggg ==== 0000....0000;;;;
- }}}}
- ssssvvvv____sssseeeettttnnnnvvvv((((SSSSTTTT((((0000)))),,,, ((((ddddoooouuuubbbblllleeee))))aaaarrrrgggg))));;;; ////**** XXXXXXXXXXXXXXXXXXXX ****////
- }}}}
- XXXXSSSSRRRREEEETTTTUUUURRRRNNNN((((1111))));;;;
- }}}}
-
- Notice the two lines marked with "XXXXX". If you check
- the first section of the typemap file, you'll see that
- doubles are of type T_DOUBLE. In the INPUT section, an
- argument that is T_DOUBLE is assigned to the variable arg
- by calling the routine SvNV on something, then casting it
- to double, then assigned to the variable arg. Similarly,
- in the OUTPUT section, once arg has its final value, it is
- passed to the sv_setnv function to be passed back to the
- calling subroutine. These two functions are explained in
- the _p_e_r_l_g_u_t_s manpage; we'll talk more later about what
- that "_S_T(0)" means in the section on the argument stack.
-
- WWWWAAAARRRRNNNNIIIINNNNGGGG
-
- In general, it's not a good idea to write extensions that
- modify their input parameters, as in Example 3. However,
- in order to better accomodate calling pre-existing C
- routines, which often do modify their input parameters,
- this behavior is tolerated.
-
- EEEEXXXXAAAAMMMMPPPPLLLLEEEE 4444
-
- In this example, we'll now begin to write XSUB's that will
- interact with pre-defined C libraries. To begin with, we
- will build a small library of our own, then let h2xs write
- our .pm and .xs files for us.
-
- Create a new directory called Mytest2 at the same level as
- the directory Mytest. In the Mytest2 directory, create
- another directory called mylib, and cd into that
- directory.
-
- Here we'll create some files that will generate a test
- library. These will include a C source file and a header
- file. We'll also create a Makefile.PL in this directory.
-
-
-
- 12/Feb/96 perl 5.002 with 10
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- Then we'll make sure that running make at the Mytest2
- level will automatically run this Makefile.PL file and the
- resulting Makefile.
-
- In the testlib directory, create a file mylib.h that looks
- like this:
-
- ####ddddeeeeffffiiiinnnneeee TTTTEEEESSSSTTTTVVVVAAAALLLL 4444
-
- eeeexxxxtttteeeerrrrnnnn ddddoooouuuubbbblllleeee ffffoooooooo((((iiiinnnntttt,,,, lllloooonnnngggg,,,, ccccoooonnnnsssstttt cccchhhhaaaarrrr****))));;;;
-
- Also create a file mylib.c that looks like this:
-
- ####iiiinnnncccclllluuuuddddeeee <<<<ssssttttddddlllliiiibbbb....hhhh>>>>
- ####iiiinnnncccclllluuuuddddeeee """"....////mmmmyyyylllliiiibbbb....hhhh""""
-
- ddddoooouuuubbbblllleeee
- ffffoooooooo((((aaaa,,,, bbbb,,,, cccc))))
- iiiinnnntttt aaaa;;;;
- lllloooonnnngggg bbbb;;;;
- ccccoooonnnnsssstttt cccchhhhaaaarrrr **** cccc;;;;
- {{{{
- rrrreeeettttuuuurrrrnnnn ((((aaaa ++++ bbbb ++++ aaaattttooooffff((((cccc)))) ++++ TTTTEEEESSSSTTTTVVVVAAAALLLL))));;;;
- }}}}
-
- And finally create a file Makefile.PL that looks like
- this:
-
- uuuusssseeee EEEExxxxttttUUUUttttiiiillllssss::::::::MMMMaaaakkkkeeeeMMMMaaaakkkkeeeerrrr;;;;
- $$$$VVVVeeeerrrrbbbboooosssseeee ==== 1111;;;;
- WWWWrrrriiiitttteeeeMMMMaaaakkkkeeeeffffiiiilllleeee((((
- ''''NNNNAAAAMMMMEEEE'''' ====>>>> ''''MMMMyyyytttteeeesssstttt2222::::::::mmmmyyyylllliiiibbbb'''',,,,
- ''''cccclllleeeeaaaannnn'''' ====>>>> {{{{''''FFFFIIIILLLLEEEESSSS'''' ====>>>> ''''lllliiiibbbbmmmmyyyylllliiiibbbb....aaaa''''}}}},,,,
- ))));;;;
-
- ssssuuuubbbb MMMMYYYY::::::::ppppoooossssttttaaaammmmbbbblllleeee {{{{
- ''''
- aaaallllllll :::::::: ssssttttaaaattttiiiicccc
-
- ssssttttaaaattttiiiicccc :::::::: lllliiiibbbbmmmmyyyylllliiiibbbb$$$$((((LLLLIIIIBBBB____EEEEXXXXTTTT))))
-
- lllliiiibbbbmmmmyyyylllliiiibbbb$$$$((((LLLLIIIIBBBB____EEEEXXXXTTTT)))):::: $$$$((((OOOO____FFFFIIIILLLLEEEESSSS))))
- $$$$((((AAAARRRR)))) ccccrrrr lllliiiibbbbmmmmyyyylllliiiibbbb$$$$((((LLLLIIIIBBBB____EEEEXXXXTTTT)))) $$$$((((OOOO____FFFFIIIILLLLEEEESSSS))))
- $$$$((((RRRRAAAANNNNLLLLIIIIBBBB)))) lllliiiibbbbmmmmyyyylllliiiibbbb$$$$((((LLLLIIIIBBBB____EEEEXXXXTTTT))))
-
- '''';;;;
- }}}}
-
- We will now create the main top-level Mytest2 files.
- Change to the directory above Mytest2 and run the
- following command:
-
- %%%% hhhh2222xxxxssss ----OOOO ----nnnn MMMMyyyytttteeeesssstttt2222 <<<< ....////MMMMyyyytttteeeesssstttt2222////mmmmyyyylllliiiibbbb////mmmmyyyylllliiiibbbb....hhhh
-
-
-
-
- 12/Feb/96 perl 5.002 with 11
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- This will print out a warning about overwriting Mytest2,
- but that's okay. Our files are stored in Mytest2/mylib,
- and will be untouched.
-
- The normal Makefile.PL that h2xs generates doesn't know
- about the mylib directory. We need to tell it that there
- is a subdirectory and that we will be generating a library
- in it. Let's add the following key-value pair to the
- WriteMakefile call:
-
- ''''MMMMYYYYEEEEXXXXTTTTLLLLIIIIBBBB'''' ====>>>> ''''mmmmyyyylllliiiibbbb////lllliiiibbbbmmmmyyyylllliiiibbbb$$$$((((LLLLIIIIBBBB____EEEEXXXXTTTT))))'''',,,,
-
- and a new replacement subroutine too:
-
- ssssuuuubbbb MMMMYYYY::::::::ppppoooossssttttaaaammmmbbbblllleeee {{{{
- ''''
- $$$$((((MMMMYYYYEEEEXXXXTTTTLLLLIIIIBBBB)))):::: mmmmyyyylllliiiibbbb////MMMMaaaakkkkeeeeffffiiiilllleeee
- ccccdddd mmmmyyyylllliiiibbbb &&&&&&&& $$$$((((MMMMAAAAKKKKEEEE))))
- '''';;;;
- }}}}
-
- (Note: Most makes will require that there be a tab
- character that indents the line "cd mylib && $(MAKE)".)
-
- Let's also fix the MANIFEST file so that it accurately
- reflects the contents of our extension. The single line
- that says "mylib" should be replaced by the following
- three lines:
-
- mmmmyyyylllliiiibbbb////MMMMaaaakkkkeeeeffffiiiilllleeee....PPPPLLLL
- mmmmyyyylllliiiibbbb////mmmmyyyylllliiiibbbb....cccc
- mmmmyyyylllliiiibbbb////mmmmyyyylllliiiibbbb....hhhh
-
- To keep our namespace nice and unpolluted, edit the .pm
- file and change the line setting @@@@EEEEXXXXPPPPOOOORRRRTTTT to @@@@EEEEXXXXPPPPOOOORRRRTTTT____OOOOKKKK.
- And finally, in the .xs file, edit the #include line to
- read:
-
- ####iiiinnnncccclllluuuuddddeeee """"mmmmyyyylllliiiibbbb////mmmmyyyylllliiiibbbb....hhhh""""
-
- And also add the following function definition to the end
- of the .xs file:
-
- ddddoooouuuubbbblllleeee
- ffffoooooooo((((aaaa,,,,bbbb,,,,cccc))))
- iiiinnnntttt aaaa
- lllloooonnnngggg bbbb
- ccccoooonnnnsssstttt cccchhhhaaaarrrr **** cccc
- OOOOUUUUTTTTPPPPUUUUTTTT::::
- RRRREEEETTTTVVVVAAAALLLL
-
- Now we also need to create a typemap file because the
- default Perl doesn't currently support the const char *
- type. Create a file called typemap and place the
-
-
-
- 12/Feb/96 perl 5.002 with 12
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- following in it:
-
- ccccoooonnnnsssstttt cccchhhhaaaarrrr **** TTTT____PPPPVVVV
-
- Now run perl on the top-level Makefile.PL. Notice that it
- also created a Makefile in the mylib directory. Run make
- and see that it does cd into the mylib directory and run
- make in there as well.
-
- Now edit the test.pl script and change the BEGIN block to
- print "1..4", and add the following lines to the end of
- the script:
-
- pppprrrriiiinnnntttt &&&&MMMMyyyytttteeeesssstttt2222::::::::ffffoooooooo((((1111,,,, 2222,,,, """"HHHHeeeelllllllloooo,,,, wwwwoooorrrrlllldddd!!!!"""")))) ======== 7777 ???? """"ooookkkk 2222\\\\nnnn"""" :::: """"nnnnooootttt ooookkkk 2222\\\\nnnn"""";;;;
- pppprrrriiiinnnntttt &&&&MMMMyyyytttteeeesssstttt2222::::::::ffffoooooooo((((1111,,,, 2222,,,, """"0000....0000"""")))) ======== 7777 ???? """"ooookkkk 3333\\\\nnnn"""" :::: """"nnnnooootttt ooookkkk 3333\\\\nnnn"""";;;;
- pppprrrriiiinnnntttt aaaabbbbssss((((&&&&MMMMyyyytttteeeesssstttt2222::::::::ffffoooooooo((((0000,,,, 0000,,,, """"----3333....4444"""")))) ---- 0000....6666)))) <<<<==== 0000....00001111 ???? """"ooookkkk 4444\\\\nnnn"""" :::: """"nnnnooootttt ooookkkk 4444\\\\nnnn"""";;;;
-
- (When dealing with floating-point comparisons, it is often
- useful to not check for equality, but rather the
- difference being below a certain epsilon factor, 0.01 in
- this case)
-
- Run "make test" and all should be well. Unlike previous
- examples, we've now run h2xs on a real include file. This
- has caused some extra goodies to appear in both the .pm
- and .xs files.
-
- +o
- In the .xs file, there's now a #include declaration with
- the full path to the mylib.h header file.
-
- +o
- There's now some new C code that's been added to the .xs
- file. The purpose of the ccccoooonnnnssssttttaaaannnntttt routine is to make the
- values that are #define'd in the header file available to
- the Perl script (in this case, by calling &&&&mmmmaaaaiiiinnnn::::::::TTTTEEEESSSSTTTTVVVVAAAALLLL).
- There's also some XS code to allow calls to the ccccoooonnnnssssttttaaaannnntttt
- routine.
-
- +o
- The .pm file has exported the name TESTVAL in the @@@@EEEEXXXXPPPPOOOORRRRTTTT
- array. This could lead to name clashes. A good rule of
- thumb is that if the #define is only going to be used by
- the C routines themselves, and not by the user, they
- should be removed from the @@@@EEEEXXXXPPPPOOOORRRRTTTT array. Alternately, if
- you don't mind using the "fully qualified name" of a
- variable, you could remove most or all of the items in the
- @@@@EEEEXXXXPPPPOOOORRRRTTTT array.
-
- We've also told Perl about the library that we built in
- the mylib subdirectory. That required only the addition
- of the MYEXTLIB variable to the WriteMakefile call and the
- replacement of the postamble subroutine to cd into the
- subdirectory and run make. The Makefile.PL for the
-
-
-
- 12/Feb/96 perl 5.002 with 13
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- library is a bit more complicated, but not excessively so.
- Again we replaced the postamble subroutine to insert our
- own code. This code simply specified that the library to
- be created here was a static archive (as opposed to a
- dynamically loadable library) and provided the commands to
- build it.
-
- SSSSPPPPEEEECCCCIIIIFFFFYYYYIIIINNNNGGGG AAAARRRRGGGGUUUUMMMMEEEENNNNTTTTSSSS TTTTOOOO XXXXSSSSUUUUBBBBPPPPPPPP
-
- With the completion of Example 4, we now have an easy way
- to simulate some real-life libraries whose interfaces may
- not be the cleanest in the world. We shall now continue
- with a discussion of the arguments passed to the xsubpp
- compiler.
-
- When you specify arguments in the .xs file, you are really
- passing three pieces of information for each one listed.
- The first piece is the order of that argument relative to
- the others (first, second, etc). The second is the type
- of argument, and consists of the type declaration of the
- argument (e.g., int, char*, etc). The third piece is the
- exact way in which the argument should be used in the call
- to the library function from this XSUB. This would mean
- whether or not to place a "&" before the argument or not,
- meaning the argument expects to be passed the address of
- the specified data type.
-
- There is a difference between the two arguments in this
- hypothetical function:
-
- iiiinnnntttt
- ffffoooooooo((((aaaa,,,,bbbb))))
- cccchhhhaaaarrrr &&&&aaaa
- cccchhhhaaaarrrr **** bbbb
-
- The first argument to this function would be treated as a
- char and assigned to the variable a, and its address would
- be passed into the function foo. The second argument
- would be treated as a string pointer and assigned to the
- variable b. The _v_a_l_u_e of b would be passed into the
- function foo. The actual call to the function foo that
- xsubpp generates would look like this:
-
- ffffoooooooo((((&&&&aaaa,,,, bbbb))));;;;
-
- Xsubpp will identically parse the following function
- argument lists:
-
- cccchhhhaaaarrrr &&&&aaaa
- cccchhhhaaaarrrr&&&&aaaa
- cccchhhhaaaarrrr &&&& aaaa
-
- However, to help ease understanding, it is suggested that
- you place a "&" next to the variable name and away from
-
-
-
- 12/Feb/96 perl 5.002 with 14
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- the variable type), and place a "*" near the variable
- type, but away from the variable name (as in the complete
- example above). By doing so, it is easy to understand
- exactly what will be passed to the C function -- it will
- be whatever is in the "last column".
-
- You should take great pains to try to pass the function
- the type of variable it wants, when possible. It will
- save you a lot of trouble in the long run.
-
- TTTTHHHHEEEE AAAARRRRGGGGUUUUMMMMEEEENNNNTTTT SSSSTTTTAAAACCCCKKKK
-
- If we look at any of the C code generated by any of the
- examples except example 1, you will notice a number of
- references to _S_T(n), where n is usually 0. The "ST" is
- actually a macro that points to the n'th argument on the
- argument stack. _S_T(0) is thus the first argument passed
- to the XSUB, _S_T(1) is the second argument, and so on.
-
- When you list the arguments to the XSUB in the .xs file,
- that tell xsubpp which argument corresponds to which of
- the argument stack (i.e., the first one listed is the
- first argument, and so on). You invite disaster if you do
- not list them in the same order as the function expects
- them.
-
- EEEEXXXXTTTTEEEENNNNDDDDIIIINNNNGGGG YYYYOOOOUUUURRRR EEEEXXXXTTTTEEEENNNNSSSSIIIIOOOONNNN
-
- Sometimes you might want to provide some extra methods or
- subroutines to assist in making the interface between Perl
- and your extension simpler or easier to understand. These
- routines should live in the .pm file. Whether they are
- automatically loaded when the extension itself is loaded
- or only loaded when called depends on where in the .pm
- file the subroutine definition is placed.
-
- DDDDOOOOCCCCUUUUMMMMEEEENNNNTTTTIIIINNNNGGGG YYYYOOOOUUUURRRR EEEEXXXXTTTTEEEENNNNSSSSIIIIOOOONNNN
-
- There is absolutely no excuse for not documenting your
- extension. Documentation belongs in the .pm file. This
- file will be fed to pod2man, and the embedded
- documentation will be converted to the man page format,
- then placed in the blib directory. It will be copied to
- Perl's man page directory when the extension is installed.
-
- You may intersperse documentation and Perl code within the
- .pm file. In fact, if you want to use method autoloading,
- you must do this, as the comment inside the .pm file
- explains.
-
- See the _p_e_r_l_p_o_d manpage for more information about the pod
- format.
-
-
-
-
-
- 12/Feb/96 perl 5.002 with 15
-
-
-
-
-
- PERLXSTUT(1) User Contributed Perl Documentation PERLXSTUT(1)
-
-
- IIIINNNNSSSSTTTTAAAALLLLLLLLIIIINNNNGGGG YYYYOOOOUUUURRRR EEEEXXXXTTTTEEEENNNNSSSSIIIIOOOONNNN
-
- Once your extension is complete and passes all its tests,
- installing it is quite simple: you simply run "make
- install". You will either need to have write permission
- into the directories where Perl is installed, or ask your
- system administrator to run the make for you.
-
- SSSSEEEEEEEE AAAALLLLSSSSOOOO
-
- For more information, consult the _p_e_r_l_g_u_t_s manpage, the
- _p_e_r_l_x_s manpage, the _p_e_r_l_m_o_d manpage, and the _p_e_r_l_p_o_d
- manpage.
-
- AAAAuuuutttthhhhoooorrrr
-
- Jeff Okamoto <okamoto@corp.hp.com>
-
- Reviewed and assisted by Dean Roehrich, Ilya Zakharevich,
- Andreas Koenig, and Tim Bunce.
-
- LLLLaaaasssstttt CCCChhhhaaaannnnggggeeeedddd
-
- 1996/2/9
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 12/Feb/96 perl 5.002 with 16
-
-
-