DocumentationEndless PL/I for POSIX SystemsUser's Manual  ·  ESS-PFUUM-001

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:

  • You can obtain and incorporate any source files to which you have access from other file systems, or processors.

  • Programs and shell scripts can generate PL/I code and write a source file for later compilation.

2.2. Compiling and Linking a PL/I Program

The following sections discuss the pl1 command and the command options.

2.2.1. The pl1 Command

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 ...]
option

A 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.suffix

An input source file containing the program or module to be compiled. You must specify a file suffix. Valid suffixes are:

  • PL/I: .pli or .pl1

  • Object 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.pl1

This 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.

Table 2.1. Alphabetic List of PL/I Driver Options
OptionLong OptionMeaning
-a--alignSpecifies natural alignment. On Alpha processors, -a is equivalent to -a8
-an--align=nAligns 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_onlySuppresses the loading phase of the compilation. Produces an object file even when you compile only one program.
-D dialect--dialect=dialectDefines 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--debugProduces debugger symbol table information. This option implies the -N option.
-Idir--include_dir=dirDefines 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--checkEnables 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.
-lname--library=nameWhen linking, search an object library named libname.a, where name is a string.
-L--library_dirChanges 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 -Ldir.
-Ldir--library_dir=dirChanges 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 lowerSpecifies that all identifiers are case insensitive and externals are converted to lower case. This is the default.
-m mix--case mixSpecifies that all identifiers are case sensitive. Allows mixed case identifiers
-m upper--case upperSpecifies that all identifiers are case insensitive and externals are converted to upper case.

-M lower

-M mix

-M upper

--include_case lower

--include_case mix

--include_case upper

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_sharedLinks 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 fileGenerates 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 .o file.

Restrictions: The -c option cannot be specified with the -O option. The -O option must precede all source file arguments.

-p or -p1--profile or --profile=1Generate 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=0Do not generate information for profiling. This is the default.
-P or -P1--preprocessor or --preprocessor=1Turns 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=0Turns off the preprocessor phase of compilation. This is the default for the -D ibm and -D ansi dialects.
-s--listGenerates 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 variantDefines 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 suffixnameDefines the file suffix for include files. Supplied for compatibility with Digital and valid for the -D dec dialect only.
-v--verboseDisplays the compiler passes, with their arguments, input, and output files, as they execute. Also displays resource usage in the C shell time format.
-w--nowarnSuppresses compiler warning messages.
-x--xrefIncludes cross reference information in the listing file. Implies -s; you need not use -s if you use -x.

[a] If you do not specify --case upper, do not declare an external symbol that will map to "main" (lowercase). This will conflict with the library function "main" supplied in the Endless PL/I for POSIX Systems run-time library. In addition, the file symbols "SYSPRINT", "SYSIN", and "SYSOUT" are always case insensitive regardless of the specified compiler option. In other words, whether you specify "sysprint", "Sysprint", or "SYSPRINT", you will always refer to the pre-declared PL/I files.


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 pl1

  • Object modules in .o files that you name on the pl1 command line

  • The 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:

  1. 1st directory specified by -L

  2. 2nd directory specified by -L

  3. Last directory specified by -L

  4. The default search directories, as listed in the manpage for ld on your system, unless you specified the -L option 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 -x option) A cross reference listing

  • error 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:

*****ERROR nn SEVERITY s on line line-no in file filename *****
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:

  1. 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.

  1. 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.