*********************************************************************** * Perl for GUARDIAN * *********************************************************************** FORWARD ------- Welcome to Perl (Version 5.004) for Guardian. This is version 2 of the Guardian Port. This file contains information you will need to: * Run Perl on your Guardian NSK system * Compile Perl on your Guardian NSK system (should that be necessary) * Install Perl on your Guardian NSK system (jump to end of document) Take a look at the file whatsnew.txt for a description of the changes since the last upload. This port has only been running on a D35 version of Guardian and has been tested on G06 (using the D44 C compiler & the G06 NMC compiler). If the executable file doesn't run on your system, try recompiling (using the supplied instructions). If it still doesn't run, give me a call and maybe I can help you figure out what to do next. This document contains the following sections: * INTRODUCTION Some remarks on why I tried to do this port (_why_ indeed?) * FILE ORGANIZATION How the Perl subdirectories got mapped into Guardian file names * LIBRARIES How libraries work under Guardian * HOW TO USE PERL ON GUARDIAN An explanation of the command line * STUFF THAT APPEARS TO WORK A discussion of what works * STUFF THAT WON'T WORK A discussion of what doesn't (or can't ever) work. * PERFORMANCE A brief remark on performance. * EXTENDING PERL FOR GUARDIAN WITH C ROUTINES A pointer to another text file to read * TEST SUITE RESULTS A discussion of what happened when I ran the validation suite * COMPILATION INSTRUCTIONS Some tools for recompiling and re-binding Perl for Guardian * TACL SUPPORT An explanation of the TACL macros * LICENSING This describes the LICENSE (it points you at the LICENSE file). * INSTALLATION INSTRUCTIONS How to install this beast. * README DOCUMENT CHANGE HISTORY A list of changes made to this document and the software over time. If you make any changes to the software please update this document to reflect them. First, a caveat: I'm not a UNIX person and only a moderately experienced C programmer (most of my work has been in TAL). So the choices I made about what to get working and the approach I took for getting it working may seem odd or idiosyncratic or even just plain wrong. So, I am very open to suggestions about how to improve this port. Please feel free to call or write with any ideas or thoughts you might have. Enjoy! Carl Adler IDX, Systems Corp. Seattle, Washington (206) 689-1479 carl_adler@idx.com (206) 542-6291 carla@universalmediation.com INTRODUCTION ------------ This first bit of verbiage is a discussion of why we are trying to do this port and some of the peculiarities associated with implementing Perl on Guardian. Perl was built to help people do interesting work on UNIX platforms, primarily related to system managment. It has been successfully ported to a number of other platforms which resemble UNIX in several important aspects: * The file system is tree structured * Process creation is not a capital crime * Most of the UNIX utilities or something like them have already been ported. Gurdian does not resemble UNIX in any of these aspects. So what did we hope to gain by trying to do this port? * TACL doesn't do regular expressions; Perl does. * Many people know Perl; not many know TACL. * There are books you can buy to help you learn Perl. There are no books on TACL that I'm aware of. * For people who know C, Perl is probably easier to learn than TACL. * With a little luck, any Perl scripts generated for our use on Guardian, will be useful on other platforms. It's a cinch that our TACL macros won't be useful. * There are a ton of Perl scripts available in the world that might be usable to people on a Tandem (obviously, those that are used to help manage UNIX systems won't be). FILE ORGANIZATION ----------------- On tree structured file systems, Perl is usually in something like: /usr/perl/... and there is a tree under this with "bin", "lib", etc. Here's what we did: PERL is currently installed on volume $SYS2 and resides in a set of subvols, each of whose names is prefixed with "PERL": PERL PERLO executeable, TACL library, PERLLOCL (config & init) PERL bootstrap macro and this file. PERLMNT Perl Maintanence macros PERLSRC Source code (program and header files) PERLOBJ Object code (one per source compile) PERLL01 - PERLL09 Library directories (see the AAREADME file in each subvol for it's original UNIX name). PERLT01 - PERLT07 /t directories (see the README file in each subvol for it's orignal UNIX name). PERLLIB - Libraries added by implementer and site PERLEXT - This is where we've stashed code to implement our extensions (at the time of this writing there are two). PERLEXTT - PERL scripts we used to test our extensions LIBRARIES --------- Starting with the 10Sep1998 version of this port, the way we handle libraries has changed. You no longer need to specifically have a define for each library file. You only need defines for sub-volumes. In particular: =PERL_LIBRARY, CLASS SEARCH, SUBVOL0(...) =PERL_LIBRARY_FILE, CLASS SEARCH, SUBVOL1(...) =PERL_LIBRARY_TEXT, CLASS SEARCH, SUBVOL2(...) =PERL_LIBRARY_MATH, CLASS SEARCH, SUBVOL3(...) =PERL_LIBRARY_GETOPT, CLASS SEARCH, SUBVOL4(...) =PERL_LIBRARY_SYS, CLASS SEARCH, SUBVOL5(...) =PERL_LIBRARY_SEARCH, CLASS SEARCH, SUBVOL6(...) =PERL_LIBRARY_TIME, CLASS SEARCH, SUBVOL7(...) =PERL_LIBRARY_TIE, CLASS SEARCH, SUBVOL8(...) =PERL_LIBRARY_LOCAL, CLASS SEARCH, SUBVOL9(...) =PERL_LIBRARY_CSTM, CLASS SEARCH, SUBVOL10(...) =PERL_LIBRARY_EXT, CLASS SEARCH, SUBVOL11(...) where "..." is a list of subvols that hold the library files. ** Library Sub-volumes. In the distribution, there are 9 sub-volumes: PERLL01 thru PERLL09 which map to various library sub-directories in the original CPAN distribution. The PERLL01 sub-volume maps to the top level "LIB" dictory. The rest map to lower level directies. We have added a sub-volume called PERLLIB for IDX or Guardian specific libraries. =PERL_LIBRARY_LOCAL always maps to PERLLIB. ** Search DEFINES. Each one of these defines maps to one of these sub-volumes (via the contents of the "...". You can put home-grown libraries that you want to make available to everyone on the system in PERLLIB (and map that subvol to "..._LOCAL". Individual user libraries can be mapped to any subvolume desired via the "..._CSTM" define (these work more or less like TACLLOCL and TACLCSTM). ** How it Works. In your PERL script you could say: use strict; and internally, PERL for Guardian will use the =PERL_LIBRARY search define to find the file: $vol.PERLL01.STRICT. For portability reasons, we have to be able to support, for example: use File::Find; In the UNIX world: "File::Find" maps to "./File/Find.pm" which is a relative path from the current directory (note that through the @INC mechanism, UNIX and DOS versions of perl accomplish what we're doing here via SEARCH defines. When PERL for Guardian sees this usage, it will strip the "file" and append it to the main LIBRARY define, creating the define: =PERL_LIBRARY_FILE PERL for Guardian then uses the =PERL_LIBRARY_FILE search define to locate $vol.PERLL02.FIND. ONLY two levels are supported in PERL for Guardian. That is: use foo::bar::zot; is equivalent to: use bar::zot; Internally, PERL converts: "strict" and "File::Find" to: "strict%" and "File/Find%" which acts as a trigger for invoking these mechansims. In the stock PERL for Guardian distribution the define =PERL_LIBRARY lists every library subvol as search subvols. Thus You never have to qualifify a library name unless it is duplicated in which case you will want to qualify it. For example, suppose you wanted to create an alternate version of "find" for use at your site. You would put in in the PERLLIB sub-volume and in your script you would say: use local::find and PERL for Guardian would use the library $vol.PERLLIB.FIND instead of $vol.PERLL01.FIND. NOTE: The Perl error message: "Can't locate in @INC" has been changed to: "Unable to resolve to a file". When you get this error it typically means the DEFINE that was selected by PERL (based on ) does not reference as sub-volume that contains the file you are trying to USE. ANOTHER NOTE: The Perl error message (or something like it): Undefined subroutine &main::find called at foo line 6 occurs when you have a "use" statement that references a library file that did exist but references package names that don't. Notice in the previous example where we did (first letter of each is in caps): use File::Find; This is because the package name associated with File Finder Library is: package File::Find; While Guardian file names are not case sensitive, package names are. That is: use file::find; will compile and execute correctly, but the subroutine call find (...); will not. ** When do the DEFINES get created? When you execute the PERL macro in PERLMAC, the first thing that happens is that a macro called PERL.PERLLOCL is executed. This macro contains all of the defines for the standard PERL library directories (or at least many of them). PERLMAC maintains a timestamp which tells it not run the PERLLOCL macro again unless it has been modified. The PERL macro will also execute a macro called PERLCSTM if it finds it in your default sub-volume. This PERLCSTM is a macro which should contain, among other things: ADD DEFINE =PERL_LIBRARY_, CLASS SEARCH SUBVOL10 where: is a subvolume name where you want to put your own personal library files. To access your own library files you would say: use :: where: is some string you invent for the higher level directory and: is the name of a file in the subvolume HOW TO USE PERL ON GUARDIAN --------------------------- 1. Use normal PERL run line syntax. For example: PERL -w PSCRIPT ARG1 ARG2 Assuming .PERL has been added to your PMSEARCHLIST, "PERL" in this case is really a macro that will execute the PERL interpreter. The first time you execute PERL in any particular TACL session, the PERL macro will initialize your TACL session by creating a bunch of variables and defines that make PERL work correctly on GUARDIAN. Other macros are available for debugging PERL. Look inside .PERL.PERLMAC for details. STUFF THAT APPEARS TO WORK -------------------------- In general anything that operates on variables and does no I/O or system calls appears to work. Some I/O and system calls work: 1. Basic "line oriented" file I/O AND ENSCRIBE I/O works. Line oriented files are EDIT files and UNSTRUCTURED files. You must include the "\n" character to terminate a line oriented record. ENSCRIBE is different. See 1.3 below for details. 1.1 Perl can read and write UNSTRUCTURED files. This means for example, that, a file of binary data that has been FTP'd to the Tandem can be processed. PAY ATTENTION TO THIS: UNSTRUCTURED files must have ODDUNSTR flag set in order for Perl to be able to write to them. Otherwise you will get the following error: "Not a C file" You can use either <> or "read" to read UNSTRUCTURED files. However, suppose $D1.FOO.BAR is a an UNSTRUCTURED file containing binary (i.e. non-displayable) information. The following script: $foo = "\$D1.FOO.BAR"; open F,$foo; $d = ; will read all of the information from the file $D1.FOO.BAR into the variable $d until either EOF or until a "\n" character is found. That is, for "line oriented" files the will read one line and a line is alway terminated with the "\n" character. NOTE: the "\n" character will be included in the information in $d. If there is no "\n" character in a file, will read the entire file into memory. So far we have not seen a limit on how large the file can be in this case. 1.2 Perl scripts can know what kind of file you are using. The following script demonstrates this: stat($ARGV[0]); # get "status" of file if (!defined -e _) { # does not exist if undefinded print "$ARGV[0] doesn't exist\n"; exit 0; } print "Directory\n" if -d _; # if file was