Chapter 2
Developing a PL/I Program
This chapter describes how to create, compile, link, and run a Endless PL/I for POSIX Systems program.
2.1. Creating Source Files
A PL/I source file is a UNIX file that contains PL/I code, as defined in the Endless PL/I for POSIX Systems Reference Manual.
To create a source file, use the text editor of your preference, such as the vi editor. You can also
use any of the UNIX file management tools available on your system to generate source files. For example:
2.2. Compiling and Linking a PL/I Program
The following sections discuss the pl1 command and the command options.
A program called a driver invokes the major components of the compiler system. The components are:
The PL/I front-end (fpli)
The assembler (as)
The link editor (
ld)
The pl1 command runs the driver that compiles, optimizes, assembles, and link edits your programs.
The command may be followed immediately by one or more options, by one or more filenames, or both.
Format
pl1 [option] ...filename.suffix[filename.suffix...]
optionA driver option. Driver options specify instructions to all the processing phases. You can specify either the long or short version of the options, as shown in Table 2.1, “Alphabetic List of PL/I Driver Options”.
filename.suffixAn input source file containing the program or module to be compiled. You must specify a file suffix. Valid suffixes are:
PL/I:
.plior.pl1Object code:
.o
You can include more than one file specification on the same command line by separating the file specifications with a space as follows:
pl1 file1.pl1 file2.pl1
2.2.1.1. Compilation with pl1
The driver command, pl1, invokes the following processing phases to compile and optionally link edit the source
file:
PL/I compiler: The front-end processes the source file, producing an internal language called ucode. PL/I then converts the optimized ucode to assembly language.
Assembly: Converts the assembly-language code to an object file.
Link edit: Merges object files and libraries producing an executable binary.
By default, the pl1 command both compiles and link edits a source module. If you specify the
-c driver option, processing stops after the assembler phase, producing a linkable object file. You can
then use the pl1 or ld command to link edit the linkable object(s) into one
executable binary. By default, the linkable object file has the same name as the source file, but with the suffix
.o.
For example:
pl1 file.pli -c
This produces the linkable object file.o.
The default name of the executable binary is a.out. For example:
pl1 file.pl1This command line produces the executable binary a.out.
You can specify a different name for the executable binary by using the driver option -o and
supplying the desired file name. For example:
pl1 file.pl1 -o file
This command line compiles and link edits the source module file.pli and produces an executable
binary, file.
If you have previously compiled the source module and used the -c option to produce the linkable
object file.o, the following command line links edit the object module:
pl1 file.o -o file
This command link edits the object module file.o and produces the executable binary file. You can
link edit several object modules together to produce a single executable binary, as follows:
pl1 file1.o file2.o -o file
This command link edits the object modules file1.o and file2.o and produces
the executable binary file.
When specifying a name for your executable binary or object module, note that the full file name (file name and
extension) must differ from the name of the source file(s). In other words, when compiling file.pli,
do not supply file.pli as the full file name of your executable binary or object module.
2.2.1.2. Compiling Multi-Language Programs
When your application has two or more source programs written in different languages, including C, Pascal,
and Fortran, compile each program module separately with the appropriate driver and then link them in a separate step. To
create the linkable objects, use the pl1 command option -c. The following example
compiles a PL/I program and a C program:
pl1 -c plifile.pli cc -c cfile.c
When you compile the routines, the drivers produce the linkable object files plifile.o and
cfile.o. Use the pl1 command to perform the link edit, which loads and initializes
the appropriate run-time libraries for PL/I.
2.2.1.3. Driver Options
Table 2.1, “Alphabetic List of PL/I Driver Options” lists the options for the pl1 command
line. The UNIX manpage pl1(1) also describes the pl1 command options if the manual
pages are installed on the system.
| Option | Long Option | Meaning |
|---|---|---|
-a | --align | Specifies natural alignment. On Alpha processors, -a is equivalent to -a8
|
-a | --align= | Aligns to the specified byte boundary. n must be a power of two. The default value is -a1,
which causes the compiler to align so there are no pad bytes in structures. Note: Some programs rely on structures
not being padded for alignment. |
-c | --compile_only | Suppresses the loading phase of the compilation. Produces an object file even when you compile only one program. |
-D dialect | --dialect= | Defines the dialect of the compiler, where dialect is one of the following: ibm, dec, ansi. The default dialect is ansi. See the Endless PL/I for POSIX Systems Reference Manual for information on the differences in dialects. |
-g | --debug | Produces debugger symbol table information. This option implies the -N option. |
-I | --include_dir= | Defines an additional directory for the PL/I preprocessor to search when looking for %INCLUDE modules You can specify this option multiple times to define several directories. |
-k | --check | Enables range and subscript checking. Turns on signalling of the STRINGRANGE and SUBSCRIPTRANGE conditions. Use this option to generate code to dynamically check the values of array, character, and bit string indexes. See the Endless PL/I for POSIX Systems Reference Manual for more information on the STRINGRANGE and SUBSCRIPTRANGE conditions. |
-l | --library= | When linking, search an object library named libname.a, where name is a string. |
-L | --library_dir | Changes the algorithm of searching for libx.a or libx.b so the default directories are
not searched. Use this option when you only want to search the directories specified by the
ld(1) option -L. |
-L | --library_dir= | Changes the algorithm of searching for libx.a or libx.b so that ld
searches the specified directory before the default library directories. |
-m lower[a] | --case lower | Specifies that all identifiers are case insensitive and externals are converted to lower case. This is the default. |
-m mix | --case mix | Specifies that all identifiers are case sensitive. Allows mixed case identifiers |
-m upper | --case upper | Specifies that all identifiers are case insensitive and externals are converted to upper case. |
|
|
| Specifies the case of the include file names in a preprocessor %INCLUDE statement. The specified case is
applied when the module name is built by the preprocessor. -M lower is the default, specifying
that all file names are converted to lowercase. -M mix specifies case sensitivity, allowing mixed
case file names. -M upper converts filenames to upper-case. |
-N | --non_shared | Links the image without shared libraries. By default, images are linked with shared libraries. You must link
without shared libraries to use the dbg debugger. Thus the -N option is
implied by the -g option. |
-o file | --output file | Generates an executable binary with the specified file name. If you do not use this option, the compiler
names the executable binary a.out. |
-O | --optimize |
Performs all optimizations, including global register allocation. Use this option to create ucode object
files for all PL/I source files. The newly created ucode object files, ucode object files specified on the
command line, the run-time start-up routine, and all the run-time libraries are ucode linked. The compiler
optimizes the resulting ucode linked file, then links it as usual, producing an executable binary. The ucode
linking does not produce an Restrictions: The |
-p or -p1 | --profile or --profile=1 | Generate information for profiling. Use this option to prepare for profiling by periodically sampling the
program counter value. The option affects run-time loading. When loading occurs, the standard run-time start-up is
replaced by the profiling run-time start-up routine. The level 1 profiling library libprof1.a
is searched. |
-p0 | --profile=0 | Do not generate information for profiling. This is the default. |
-P or -P1 | --preprocessor or --preprocessor=1 | Turns on the preprocessor phase of compilation. This is the default for the -D dec dialect.
See the Endless PL/I for POSIX Systems Reference Manual for more information on the preprocessor. |
-P0 | --preprocessor=0 | Turns off the preprocessor phase of compilation. This is the default for the -D ibm and
-D ansi dialects. |
-s | --list | Generates a compiler listing file with corresponding filename and a suffix of .l. The
listing file includes source program lines with all the included files expanded, and a datamap of the
program. |
-T variant | --variant variant | Defines the compilation variant used by the VARIANT preprocessor built-in function. Ignored if you compile without using the preprocessor. See the Endless PL/I for POSIX Systems Reference Manual for more information. |
-u suffixname | --suffix suffixname | Defines the file suffix for include files. Supplied for compatibility with Digital and valid for the
-D dec dialect only. |
-v | --verbose | Displays the compiler passes, with their arguments, input, and output files, as they execute. Also displays resource usage in the C shell time format. |
-w | --nowarn | Suppresses compiler warning messages. |
-x | --xref | Includes cross reference information in the listing file. Implies -s; you need not use
-s if you use -x. |
[a] If you do not specify | ||
2.2.2. Linking Objects using the pl1 Command
Use the pl1 command to link edit separate objects into one
executable binary when the main program is written in PL/I. The driver recognizes the .o suffix as the
name of a file containing object code suitable for link editing and immediately invokes the link editor. For example:
pl1 -o file mainfile1.o file2.o
Write the main program in PL/I and use the pl1 command to link edit the program to insure correct
initialization of the PL/I run-time library. This statement produces the executable binary file.
The pl1 command implicitly calls the ld link editor (unless you specify the
-c compile-only option). The link editor combines object modules to produce an executable binary. These
object modules include:
Object modules previously produced during the operation of
pl1Object modules in
.ofiles that you name on thepl1command lineThe PL/I run-time library
Object modules from specified libraries
A pl1 command where all the parameters are object files does only a link edit. For example, such a
command might appear in a file for make(1) that specifies a build procedure. This file separates the compile operations from
the link edit so that make can omit operations on source files that have not been modified.
If possible, use the pl1 command instead of ld to link edit PL/I object files.
This automatically selects the correct run-time libraries and the correct version of ld. However, if you
need to specify options to ld, you must invoke ld directly. Refer to the manpage on
ld(1) for more information on specifying ld options, including specifying the run-time
libraries.
2.2.2.1. Run-Time Libraries
The object code for the PL/I built-in routines is in an archive library. The distinctive suffix .a identifies a
file as an archive library. The link editor gets your program code from your object file or files, and then gets the
built-in routine code from object libraries called run-time libraries. It merges them and resolves references.
Endless PL/I for POSIX Systems includes the following run-time libraries:
libpli.a
The default run-time library for the pl1 command. It contains support for all PL/I language
features except indexed file support (files declared or opened using the ENVIRONMENT(INDEXED) option). Programs using
indexed files that are linked to this library generate fatal run-time errors.
libplit.a
Contains the same features as libpli.a with the addition of indexed file support (see
libpli.a). Because the library increases the size of executable binaries, slows the link editing
process, and requires additional memory during execution, use it only when indexed file support is required.
Note
Indexed file support is an add-on option to Endless PL/I for POSIX Systems.
libpliisam.a
Contains additional support functions required by libplit.a.
To specify other libraries when invoking the link editor, use the -l option. Library names start with
lib and have extensions .so (shared object), .a (archive) or .b (ucode). For
example, if you have written a PL/I program that calls routines from the run-time library libx11.a,
then specify:
pl1 . . . -lx11
2.2.2.2. Library Search Path
The link editor (ld) searches for any libraries you specify using the default search path listed in
the manpage for ld. However, the system administrator or installer determines the actual location
of the PL/I run-time libraries, so you might need to add directories to the default search path.
The -L option to the link editor, when followed by a directory name, adds the
specified directory to the search path for run-time libraries. Do not type any separators between -L and
the name of the directory. You can use this option several times; the link editor searches the directories in the order
that you specify on the command line. Your definition of the search path must precede your specification of libraries
(using the -l option described in Section 2.2.2.1, “Run-Time Libraries”) on the command line.
The link editor searches the directories you specify with -L, in the order you specify them on the
command line, before it searches the standard directories (which were specified during installation). This lets you
specify files that supersede the usual run-time library.
If you use the -L option and do not follow it with a directory name, the link editor does not search
its standard directories.
When you use the -L option, the link editor uses the following search path:
1st directory specified by
-L2nd directory specified by
-LLast directory specified by
-LThe default search directories, as listed in the manpage for
ldon your system, unless you specified the-Loption without a path
2.2.3. PL/I Preprocessor
The PL/I preprocessor lets you change a source program at compile time. You can mix preprocessor statements with nonpreprocessor statements in the source program, but the preprocessor statements only execute at compile time. The resulting source program is then used for further compilation.
Note
By default, the preprocessor is turned on if you specify the -D dec command line option, and off if
you specify either the -D ibm or -D ansi command line option, since the preprocessor
provides compatibility with Digital implementations of PL/I.
The preprocessor does two types of preprocessing:
It interprets preprocessor statements and evaluates preprocessor expressions.
It replaces the values of preprocessor variables and procedures.
Preprocessor statements let you include text from other sources (%INCLUDE statements), control the course of compilation (%DO, %GOTO, %VARIANT, %PROCEDURE, and %IF), issue user-generated diagnostic messages, and selectively control listings and formats. The preprocessor statements are described in full in the Endless PL/I for POSIX Systems Reference Manual.
2.2.3.1. Preprocessor Compilation Control
At compile time, preprocessor variables, procedures, and variable expressions are evaluated in the order in which they appear in the source text, and the new values are substituted in the source program in the same order. Thus, the course of compilation becomes conditional, and the resulting executable binary may exhibit a variety of unique features. Note that preprocessor variables and procedures must be declared and activated before replacement occurs.
For example:
%DECLARE HOUR FIXED; %HOUR = SUBSTR(TIME(),1,2); %IF HOUR > 7 & HOUR < 18 %THEN %FATAL 'Please compile this outside of prime time'; %DECLARE T CHARACTER; %ACTIVATE T NORESCAN; %T = '''Compiled on '||DATE()||''''; DECLARE INIT_MESSAGE CHARACTER(60) VARYING INITIAL(T); %IF VARIANT() = ''| VARIANT() = 'NORMAL' %THEN %INFORM 'NORMAL'; %ELSE %DO; %IF VARIANT() = 'SPECIAL'; %THEN %INFORM 'SPECIAL'; %ELSE %IF VARIANT() = 'NONE'; %THEN %; %ELSE %DO; %T = '''unknown variant '||variant()||''''; %WARN t; INIT_MESSAGE=INIT_MESSAGE||' with '||T; %END; %END; PUT SKIP LIST (INIT_MESSAGE);
This example illustrates several aspects of the preprocessor. First, you must compile this program outside of prime time. Second, depending upon the value of VARIANT, the program is compiled with a different variant.
Notice the number of single quote marks around the string constant assigned to T. Single quotes are sufficient if you only use the value of T in a preprocessor user-generated diagnostic message. That is, the value of T is concatenated with nonpreprocessor text and assigned to INIT_MESSAGE because during preprocessing, single quotes are stripped off of string constants. To ensure that the run-time program also has quotes around the string, you must supply additional quotes, as shown.
2.2.3.2. Preprocessor Procedures
The %PROCEDURE statement defines the beginning of a preprocessor procedure block and specifies the parameters, if any, of the procedure. A preprocessor procedure executes only at compile time. Invocation is similar to a function reference and occurs in two ways:
Preprocessor statements can invoke preprocessor procedures. In addition, preprocessor statements from within preprocessor procedures can invoke other preprocessor procedures.
Statements from the source program can invoke preprocessor procedures.
A preprocessor procedure is invoked by the appearance of its entry name and list of arguments. If the reference occurs in a nonpreprocessor statement, the entry name must be active before the preprocessor procedure is invoked. If the entry name is activated with the RESCAN option, the value of the preprocessor procedure is rescanned for further possible preprocessor variable replacement and procedure invocation. Preprocessor procedures can be invoked recursively.
Since the preprocessor procedure is always invoked as a function, the %PROCEDURE statement must also specify (using the RETURNS option) the data type attributes of the value that is returned to the point of invocation.
The return value replaces the preprocessor procedure reference in the invoking source code. Preprocessor procedures cannot return values using their parameter list. The return value must be capable of being converted to one of the data types CHARACTER, FIXED, or BIT. The maximum precision of the value returned by the %RETURNS statement is BIT(31), CHARACTER(32500), and FIXED(10).
You can use either of the following two types of argument lists in preprocessor procedures:
Positional argument lists end with a right parenthesis. They use parameters sequentially, as in a parenthesized list. Positional argument lists can be used in any preprocessor procedure.
Keyword argument lists end with a semicolon. They use parameters in any order, as long as each keyword matches the name of a parameter. Therefore, the order in which you list them does not affect the correct matching of parameters and arguments. You can only use keyword argument lists when the preprocessor procedure contains the STATEMENT option and is invoked from a nonpreprocessor statement.
Since a keyword argument list ends with a semicolon rather than a right parenthesis, the STATEMENT option lets you use a preprocessor procedure that has a keyword argument list as if it were a statement. Consequently, preprocessor procedures using the STATEMENT option let you extend the PL/I language by simulating otherwise unavailable features.
Preprocessor Statements and Procedures
All preprocessor statements are preceded by a percent sign (%) and are terminated by a semicolon (;). All text that appears within these delimiters is considered part of the preprocessor statement and is executed at compile time. For example:
%DECLARE HOUR FIXED; /* declaration of a preprocessor single variable */ %DECLARE (A,B) CHARACTER; /* a factored preprocessor declaration */ %HOUR = SUBSTR(TIME(),1,2); /* preprocessor assignment statement using two built-in functions */
Notice that a percent sign (%) is required only at the beginning of the statement, and must be the first item, other than white space (spaces or tabs) on the line. Preprocessor built-in functions are contained within preprocessor statements and consequently do not require a percent sign.
You can label preprocessor statements. Like other PL/I labels, you can use labels on preprocessor statements as the targets of program control statements. A preprocessor label must be an unsubscripted label constant preceded by a percent sign. The format for a preprocessor label is:
%label: preprocessor-statement;As with other preprocessor statements, the percent sign alerts the compiler that all text until the semicolon line terminator is preprocessor text. Therefore, you do not need to enter another percent sign on that line.
The compiler treats all statements within a preprocessor procedure as preprocessor statements. You must label preprocessor procedures to invoke them, and you must use a percent sign before the procedure label. However, statements within the procedure do not require leading percent signs.
For a table summarizing the preprocessor statements and for individual descriptions of the statements, see the Endless PL/I for POSIX Systems Reference Manual.
Preprocessor Built-In Functions
A number of PL/I preprocessor built-in functions are available for use at compile time. With few exceptions, they have the same effect as run-time PL/I built-in functions with the same name. For a table summarizing the preprocessor built-in functions and for individual descriptions of the functions, see the Endless PL/I for POSIX Systems Reference Manual.
2.2.4. Compiler Listing Files
If you specify either the -s or -x compiler option, the PL/I compiler produces a
listing file. The listing file contains the following information:
Source program lines
Expansions of all included files
A datamap
(with the
-xoption) A cross reference listingerror messages
The following example shows portions of a listing file:
source file: /lang/tmp/real_progAAAaagzEa.pl ❶
compiled on: 950923 at: 17:24:54 by: ANSI/IBM PL/I, rev 1.04in: /local/home/louise/test
Listing File is in: /local/home/louise/test/
0-1 0 0 Test: procedure options (main); ❷
0-2 1 0
0-3 1 0 declare x character (8) initial ('foo'),
0-4 1 0 input_x character (8) initial ('');
0-5 1 0 declare y fixed bin (15) initial (42),
0-6 1 0 input_y fixed bin (15) initial (0);
0-7 1 0 declare valid bit(1) initial ('0'B);
0-8 1 0
0-9 1 0 put skip list ('What is the answer?: ');
0-10 1 0 get list (input_y);
0-11 1 0 put skip list ('Type the most common file name: ');
0-12 1 0 get list (input_x);
0-13 1 0
0-14 1 0 if (x = input_x) & (y = input_y)
0-15 1 0 then
0-16 1 0 valid=real_programmer();
0-17 1 0 else begin;
0-18 2 0 put skip list ('You''re not a real programmer!');
0-19 2 0 goto exit;
0-20 2 0 end;
0-21 1 0
0-22 1 0 real_programmer: procedure() returns(bit(1));
0-23 2 0
0-24 2 0 /* this exists to show another subroutine level */
0-25 * 2 0 /* in the listing file */
0-26 2 0
0-27 2 0 declare real_prog bit(1);
0-28 2 0
0-29 2 0 put skip list ('You''re a Real Programmer!!!');
0-30 2 0 real_prog = '1'B;
0-31 2 0
0-32 2 0 end; /* real_programmer */
0-33 1 0
0-34 1 0 exit:
0-35 1 0
0-36 1 0 end Test;
<FF>
***** EXTERNAL ENTRY POINTS ***** ❸
name class size loc attributes
TEST constant ENTRY EXTERNAL
procedure TEST on line 1
name class size loc attributes
EXIT constant LABEL
def ref set
34
19
INPUT_X automatic 8c 84 CHAR(8) UNALIGNED INITIAL
def ref set
4
12
14
INPUT_Y automatic 1 96 FIXED BIN(15,0) ALIGNED PRECISION INITIAL
def ref set
6
10
14
REAL_PROGRAMMER
constant ENTRY RETURNS INTERNAL
def ref set
22
16
SYSIN constant FILE EXTERNAL
def ref set
1
10
12
SYSPRINT constant FILE EXTERNAL
def ref set
1
9
11
18
29
VALID automatic 1b 112 BIT(1) UNALIGNED INITIAL
def ref set
7
16
X automatic 8c 92 CHAR(8) UNALIGNED INITIAL
def ref set
3
14
Y automatic 1 128 FIXED BIN(15,0) ALIGNED PRECISION INITIAL
def ref set
5
14
begin block on line 17
no declared names
procedure REAL_PROGRAMMER on line 22
name class size loc attributes
REAL_PROG automatic 1b 96 BIT(1) UNALIGNED
def ref set
27
30
***** ENTRY POINTS AND ARRAY OF LABELS *****
name class size loc attributes
TEST constant ENTRY EXTERNAL
REAL_PROGRAMMER
constant ENTRY RETURNS INTERNAL
def ref set
22
16
<FF>
*****ERROR 179 SEVERITY 1 on line 1 in file ❹ /lang/tmp/real_progAAAaagzEa.pl.*****
The undeclared name "SYSIN" has been contextually declared
in this block. It will acquire default attributes.
*****ERROR 179 SEVERITY 1 on line 1 in file /lang/tmp/real_progAAAaagzEa.pl.*****
The undeclared name "SYSPRINT" has been contextually
declared in this block. It will acquire default attributes.The following list describes the callouts in the preceding listing file example:
- ❶
Header information—contains information about the source file you compiled, such as when you compiled it, the compiler variant used (dec, ansi, ibm), and the directory specification of the listing file.
- ❷
The source program listing—contains line numbers generated by the compiler, an optional asterisk (*) if the line is continued from a previous line, a level number, specifying the level of procedural nesting, a second level number, specifying the block level within a procedure, and the source text.
- ❸
Cross reference listing tables—includes tables listing external entry points, then a block-by-block listing of each procedure or internal block in the program, describing each variable declared in the block.
- ❹
Compilation error messages—the text of any error messages generated during compilation.
2.2.5. Compiler Error Messages
The PL/I compiler identifies syntax errors and violations of language rules in the source program. If the compiler
locates any errors, it writes messages to standard output. If you enter the
pl1 command interactively, the messages are displayed on your screen.
If the compiler creates a listing file it also writes these messages to the listing, as shown in the previous section.
When it appears on the screen, a message from the compiler has the following format:
*****ERRORnnSEVERITYson lineline-noin filefilename*****message-text
The nn specifies the error number.
The s specifies the severity of the error. The following letters represent possible severities:
4—Fatal. The compiler stops executing, does not continue the compilation, and does not produce an object module. You must correct the error before you can compile the program.
3—Error. The compiler continues, but does not produce an object module. You must correct the error before you can successfully compile the program.
2—Warning. The compiler produces an object module. It attempts to correct the error in the statement, but you should verify that the compiler's action is acceptable. Otherwise, your program may produce unexpected results.
The compiler produces messages with warning severity if it encounters the following:
Syntax errors (such as a missing END statement) that the compiler attempts to fix.
Language elements (such as undeclared variables) that are not part of the PL/I General-Purpose subset but do belong to full PL/I.
Legal PL/I General-Purpose Subset usage (such as assignment of a bit-string value to a fixed-point binary variable) that nonetheless may represent a programming error or produce unexpected results.
1—Informational. This message usually appears with other messages to inform you of specific actions taken by the compiler. Informational messages also indicate nonstandard constructs and items that are syntactically correct, but that may contain programming errors. No action is necessary on your part. You may, however, want to check that your code performs as expected, and possibly modify the specified line.
The filename indicates the file specification.
The line number n specifies the source file line number of the statement that caused the error. This is the line number assigned to a statement by the compiler. The error message also appears in the listing file (if listing is requested) with the listing line number.
The message-text is the message. In many cases, the message text consists of more than one
line of output. The messages generally provide enough information for you to determine the cause of an error and correct
it.
For a message of severity 1, the first word is WARNING instead of ERROR. Appendix C, Compiler Messages lists the messages by number, with an explanation of each and the action to take.
2.3. Running a PL/I Program
To run a PL/I program, enter the name of the executable binary produced by the pl1 command. If you
did not use the -o option in the pl1 command, the default name of the executable binary is
a.out. Enter a.out to run your PL/I program. If you used the -o
option and specified a filename, enter the filename to run your program.
2.3.1. Run-Time Errors
If an error occurs at run-time and the program does not handle it, the run-time library writes a report of it on standard error and ends the program. See Appendix B, Run-Time Messages for the format of the report and a description of the messages.
2.3.2. Passing Command Line Parameters to a PL/I Program
You can pass command line parameters to your PL/I program, and access the parameters in your program. The following sections show how to write your code to access command line parameters, and how to run a program and specify command line parameters.
2.3.2.1. Accessing Command Line Parameters in PL/I Programs
Endless PL/I for POSIX Systems provides two methods to access command line parameters:
Through procedure parameters in the main program.
In your main program, you can declare up to ten parameters to be passed from the command line when users run your program. You must declare these parameters CHARACTER VARYING, giving the actual length of the string as the maximum length.
For example:
PARAM: PROCEDURE (name,address,city,state,zip) OPTIONS(MAIN); DECLARE (name,address,city,state,zip) CHAR(100) VARYING;
Your program can access these parameters only if the parameters are actually passed upon program invocation. To check
the number of specified parameters, reference the external variable ARGC (argument count), included in the global
definitions file pl1std.in, as shown in the example below.
Through array of pointers to parameters.
You can access the command line parameters using the global variable ARGV (argument pointer), a pointer to an array of pointers to the actual parameters passed to the program. Again you can reference only as many parameters as were actually passed on the command line.
Both ARGC and ARGV are included in the global declarations include file, plistd.in, supplied with Endless PL/I for POSIX Systems.
The following example shows both methods of accessing command line parameters:
%INCLUDE pl1std; PARAM_TEST: PROCEDURE (name, address, city, state, zip) OPTIONS(MAIN); DECLARE (name, address, city, state, zip) CHARACTER(100) VARYING; DECLARE i FIXED BIN; IF ARGC >= 1 THEN PUT SKIP EDIT ('Name: ',Name) (a,a); ELSE PUT SKIP EDIT ('Name is missing') (a); IF ARGC >= 2 THEN PUT SKIP EDIT ('Address: ',Address) (a,a); ELSE PUT SKIP EDIT ('Address is missing') (a); IF ARGC >= 3 THEN PUT SKIP EDIT ('City: ',City) (a,a); ELSE PUT SKIP EDIT ('City is missing') (a); IF ARGC >= 4 THEN PUT SKIP EDIT ('State: ',State) (a,a); ELSE PUT SKIP EDIT ('State is missing') (a); IF ARGC >= 5 THEN PUT SKIP EDIT ('Zip: ',Zip) (a,a); ELSE PUT SKIP EDIT ('Zip is missing') (a); DO I = 1 TO ARGC; PUT SKIP EDIT ('Parameter ',i, 'is ',ARGS(i)->ARG_CV) (a,f(2),a,a); END; /* of do loop */ END; /* of program */
2.3.2.2. Specifying Command Line Parameters
To specify command line parameters, type them after the command that runs your PL/I program. For example, if you
compile the preceding example using the -o command line option, and call your program param_test, run it
as follows:
% param_test "Jocelyn Wood" "92 Forest Path" "Groveland" "New Hampshire" "01110"
Note
Command line format varies in different UNIX shells. If this format does not work, see the manual pages for your shell for the correct format.