![]() |
Iron Spring PL/I compilerProgramming Guide
|
| This is alpha software. The compiler is capable of compiling itself, but no guarantee of completeness or correctness should be inferred. Many PL/I features, or parts of features, that were not necessary for the compiler have been omitted from the initial version. A partial list is provided under restrictions below. |
PL/I is widely used on mainframes and midrange systems today, but since the demise of Digital Research, Inc. has not been easily available on personal computers.
This as an alpha version of Iron Spring PL/I. Version 0.5e is missing many features and parts of features of full PL/I. The section Restrictions lists many of the missing features.
Trademarks
eComStation is a trademark of Serenity Systems International.
EMX is a trademark of Eberhard Mattes.
Gnu is a trademark of the Free Software Foundation.
IBM is a trademark of IBM, Inc.
Intel is a trademark of Intel Corporation.
Iron Spring is a trademark of Iron Spring Software.
Linux is a registered trademark of Linus Torvalds.
WATCOM is a trademark of Sybase, Inc. and its subsidiaries.
| Compiler Limits | |
|---|---|
| Maximum number of dimensions | 15 |
| Maximum number of levels in a structure | 15 |
| Maximum level number in a structure | 255 |
| Maximum number of picture characters in a picture (after expanding all repetition factors) | 511 |
| Maximum length of a CHAR or BIT string (after expanding all repetition factors) | ~32000 |
| Maximum nesting depth of %include files | 4 |
| Maximum precision of FIXED DECIMAL data | 18 |
| Default precision of FIXED DECIMAL data | 5 |
| Maximum precision of FIXED BINARY data | 31 |
| Default precision of FIXED BINARY data | 15 |
| Maximum precision of FLOAT DECIMAL data | 20 |
| Default precision of FLOAT DECIMAL data | 6 |
| Maximum precision of FLOAT BINARY data | 64 |
| Default precision of FLOAT BINARY data | 52 |
| Minimum/maximum scale factor | -128 / 128 |
| Maximum length of an internal or external label | 31 |
See Restrictions for information on major language features that are not currently implemented.
| ALLOCATE | ALLOCATE(n) allocates n bytes of storage and returns a pointer to the first byte. |
| BYTE | BYTE returns a character string of length one. Byte(n) is equivalent to the
following: SUBSTR( COLLATE(), MOD(n,256)+1, 1 ) |
| COLLATE | COLLATE Returns a character string of length 256 containing all 256 possible character values. |
| COMPARE | COMPARE(x,y,z) compares "z" bytes from locations pointed to by "x" and "y". |
| COPY | COPY(x,y) returns a string consisting of "y" concatenated copies of string "x". |
| PLIFILL | PLIFILL moves requested number of copies of a single byte to a specified location with no conversion, padding, or truncation. |
| PLIFREE | PLIFREE frees storage allocated by the ALLOCATE builtin. |
| PLIMOVE | PLIMOVE(x,y,z) moves "z" bytes to the location pointed to by "x" from the location pointed to by "y". |
| RANK | RANK returns a FIXED BINARY(15) result. The argument for RANK is a
character string of length one. RANK(c) is equivalent to the following: INDEX( COLLATE(), c ) - 1 |
EXTERNAL data (not EXTERNAL ENTRY) is not shared between executable and DLL code, nor among procedures in different DLLs. For example, data declared DECLARE a EXTERNAL POINTER; will identify different "a"s in procedures linked into in the executable, in DLL "1", and DLL "2". Within the executable or any one of the DLLs all occurrences of that declaration will identify the same "a".
The OPTIONS keyword on an ENTRY or PROCEDURE statement or an ENTRY declaration provides information regarding the linkage convention to be used.
OPTIONS( LINKAGE(SYSTEM) ) indicates that the entry uses
a C-type linkage convention, where arguments are passed by value without descriptors.
This can be used to call OS/2 functions which use this convention, but is also a valid
convention among PL/I procedures, with some restrictions.
For source compatibility with IBM PL/I for OS/2, specify
'OPTIONS( BYVALUE LINKAGE(SYSTEM) )'.
BYVALUE is assumed by this compiler and the keyword is ignored, but IBM PL/I defaults
to BYADDR unless otherwise specified.
OPTIONS( LINKAGE(OPTLINK) ) will be implemented in a future version to specify the "Optlink" calling convention that uses registers for some arguments.
OPTIONS( ASM ) indicates that the called entry point is a non-PL/I entry. If OPTIONS(ASM) is not specified for these entries, the program may not function correctly
If OPTIONS is not specified, a standard PL/I calling convention is used where arguments are passed by reference and descriptors are passed for arguments other than computational element-variables.
An example of an entry declaration using these features and the equivalent C-language definition is:
DECLARE Create_MUTEX ENTRY( PTR, PTR, FIXED BIN(31), FIXED BIN(31) )
RETURNS( FIXED BIN(31) )
OPTIONS( ASM BYVALUE LINKAGE(SYSTEM) )
EXTERNAL( 'DosCreateMutexSem' );
ULONG DosCreateMutexSem (PCSZ pszName, PHMTX phmtx, ULONG ulAttr, BOOL32 fState);
The syntax of the PLIC command is shown. The case of the option switches is significant. Lower-case options have parameters, upper-case do not.
PLIC [<options>] <input files> [-o <output file>]
<options> = <output option> [<include options>] [<listing options>]
[<source margins>] [<character substitutions>] [<version info>]
[<error option>] [<misc options>]
(options may be entered in any order).
<output option> = -S | -C | -L
-S = generate assembler (symbolic) output.
This is the only output option currently supported.
-C = generate compiled (object) output.
-L = generated linked (EXE or DLL) output.
<include options> = -i<directory>
where <directory> is the absolute or relative path
to a directory to be searched for %INCLUDE files.
This option may be used more than once on the command line,
and directories will be searched in the order listed.
<listing options> = -l[siaxg]
one or more of [siaxg] may be entered, in any order.
-ls = list source
-li = list insource
-la = list attributes
-lx = list cross-reference
-lg = list aggregates
None of these options are currently implemented, the source
and attribute listings are always generated,
the insource, aggregate, and cross-reference are not.
<source margins> = -m(start[,end])
This option defines the first and last positions of each
input line that contain input for the compiler. If this
option is omitted the source is assumed to be the entire line.
This is included for compatibility with mainframe compilers
which would use, for example, -m(2,72).
<character substitutions> = -cn(<list>) and/or
-co(<list>)
This option defines up to four characters each to be used as
substitutions for the NOT(¬) [-cn()] and/or OR(|) [-co()]
operator IN ADDITION TO the defaults. The caret (^) is
a metacharacter for the OS/2 command processor; if the
caret is to be used, code two consecutive carets,
for example -cn(^^).
<version info> = -V
The compiler prints version and copyright information on stderr.
<error option> = -e<option>
This option sets the errorlevel returned by the compiler for warning
and error messages. Normally compiler returns 4 if only warnings were
issued, and 8 for any errors.
-ew tells the compiler to return 0 if only warning messages were issued.
-es tells the compiler to return 0 if any errors or warnings were issued.
This option is useful when the compiler is run from a script or makefile.
<misc options> = -d<option>
<option> is a character string, with or without enclosing quotes.
Currently the only miscellaneous option is -dLIB to tell the compiler it
is compiling a standard run-time library procedure.
<input files> and <output files> are absolute or relative path names. Ony one input and one
one output file are currently allowed. If the output file is omitted the name
is generated. For example, PLIC -S abc.pli will create a file named abc.asm.
declare two_line_constant char(24) static initial( ('Line one' || '0D0A'x || 'Line two.') );
This type of expression is resolved at compile-time and does not generate any additional code.
The default representations for the OR and NOT characters are '|' and '¬' (U+004F and U+00AA respectively. 'AA'x is ALT-1-7-0 on the numeric keypad.) As indicated above under Running the compiler, the options -cn and -co can be used to indicate additional encodings used to represent these characters.
String data can be delimited by either the single (') or double (") quote characters. The same character must be used to begin and and the string. The character not used as a delimiter may be part of the string. If portability is a concern, use only the single-quote to delimit strings. The character used as a delimiter can be included in the string by specifying it twice in succession, for example, 'Let''s dance' will be compiled as Let's dance, """Fine"", he said" as "Fine", he said.
Source lines are logically continued from the right margin of one line to the left margin of the next, with no whitespace assumed between the two character positions. (see the -m compiler option). Any characters outside the margins, as well as any characters less than space in the collating sequence, are ignored. For example:
Left Margin Right Margin Line End
| | |
"This is a continued charsome stuff outside the margin
extra stuff acter string"
will be compiled as This is a continued character string.
INCLUDE files are identical in format to the source file. Currently INCLUDE files must have the extension ".inc" or ".cpy". The compiler option -i, which can be repeated multiple times, provides a list of directories to be searched, in the order written, to locate an INCLUDE file. The current working directory is always searched last if the file is not found sooner. INCLUDE files use the same list of alternate characters as the source, and must use the same margins, although a future release will allow these to be overridden for each individual file.
| Internal Data Representations | |
|---|---|
| FIXED BIN, precision 7 or less | BYTE |
| FIXED BIN, precision 15 or less | WORD |
| FIXED BIN, precision 31 or less | DWORD |
| FIXED DEC, any precision Intel x87 BCD format | TBYTE |
| FLOAT BIN, precision 23 or less Intel x87 short floating-point | REAL4 |
| FLOAT BIN, precision 52 or less Intel x87 long floating-point | REAL8 |
| FLOAT BIN, precision>52 Intel x87 extended floating-point | REAL10 |
| FLOAT DEC, precision 5 or less | REAL4 |
| FLOAT DEC, precision 14 or less | REAL8 |
| FLOAT DEC, precision>14 | REAL10 |
| CHARACTER(n) | n bytes |
| BIT(n) ALIGNED | (n+7)/8 bytes |
| BIT(n) UNALIGNED | n bits |
| PTR, OFFSET | NEAR PTR |
Work file:
The compiler creates a temporary work file named PLI-xxxxxxxx-yyyyyyyy-zzzzzzzz.tmp
in the current working directory. Normally this file is deleted at the end
of compliation. Errors in the alpha version of the compiler causing
certain traps may prevent deletion of this file. If it not automatically removed
it may be deleted manually.
Iron Spring PL/I can read and write:
File Declarations
The general form of a file declaration is shown below. As usual, keywords can be specified in any order. Many
keywords may be specified either in the declaration or in the OPEN statement for the file. If they are
specified in both, they must not conflict. For example, a file declared INPUT cannot be opened as OUTPUT.
>>-DECLARE-name-+------+-+--------+-+--------+-+----------------------------------+-+------------------+-><
| | | | | | | | | |
+-FILE-+ +-RECORD-+ +-INPUT -+ +-ENVIRONMENT(environment options)-+ +-other attributes-+
| | | |
+-STREAM-+ +-OUTPUT-+
| |
+-UPDATE-+
RECORD and STREAM Files
INPUT, OUTPUT, and UPDATE
| SYSIN | ENV(V CRLF RECSIZE(120)) LINESIZE(120) |
| SYSPRINT | ENV(V CRLF RECSIZE(120)) LINESIZE(120) PAGESIZE(60) |
| If stdin and stdout are the current VIO window, these files default to ENV( BLKSIZE(0) ). | |
STREAM files default to ENV(V CRLF) unless other attributes are specified. All other ENV(V) files default to ENV(V VARLS). Specifying PAGESIZE(0) on the OPEN statement will suppress page breaks for PRINT files.
Data Specification
SKIP[(expr)]
PAGE
LINE(expr)
For OS/2 system exceptions, "hhhhhhhh" and "tttttttt" are the hexadecimal value
and the description of the exception respectively.
The sample program 'numwrd.pli' is an example of a program that uses the command-line.
PL/I programs use the stack for activation records for procedures and BEGIN-blocks, including
all AUTOMATIC storage. The heap is used for all allocated BASED and CONTROLLED storage, for
control information for error-handling, and for file information and buffers.
The stack size is taken
from the value stored with the executable, either by the linker, by EXEHDR, or a default minimal
value of 16K bytes. Stack storage is allocated when the program is loaded, but is not committed
until actually used. Stack probes are employed to prevent traps when more than 4K is requested
at one time.
The heap size is currently fixed at 1MB (1024K), although a future release will allow this value
to be respecified at run time. In the interim, if a larger heap is required, the library procedure
INIT can be re-assembled specifying a larger value for the data item 'def_heap_size'.
The layout of the stack frame for one procedure or Begin-block is illustrated below.
For both conventions, the called program is responsible for saving registers EBP, and
EBX, ESI, and EDI. It is the caller's responsibility to save any other registers necessary.
If the called entry is specified with OPTIONS(ASM), the caller saves and restores the 80x87
FPU control register. The calling program passes the size of the argument list in DWORDs
in AL.
The standard PL/I calling sequence passes all arguments by reference, that is by
passing their addresses and, optionally, their descriptors. This means that changes
to the values of parameters in the called procedure are reflected back to the caller.
Descriptors are passed
for structure, array, and string arguments. Normally descriptors are not passed for arithmetic
arguments, although many PL/I runtime procedures require a descriptor. The library include
file 'desc.inc' shows the layout of descriptors for various types of data [subject to change
in future releases]. When the argument is a constant, an expression, or
the data type doesn't match the corresponding parameter, a dummy argument is created
and stored on the stack, and the called procedure is passed the address of the dummy. In this case,
changes to the values of parameters change the dummy argument and don't modify the actual argument.
Descriptors are normally stored in STATIC storage, or in the current stack frame for adjustable
data.
Two other pieces of information are also passed to a called PL/I procedure. The static backchain
is passed in ESI, and the address of the Program Global Table (PGT) is passed in EDI.
These are passed for both "system" and PL/I linkage unless the called entry is specified with OPTIONS(ASM).
The PGT is a vector table containing the addresses of some required runtime routines. The static
backchain is the EBP value of the block which lexically contains the called procedure.
This allows the called procedure to reference automatic data belonging to containing blocks. This is
not necessarily the same as the EBP value of the caller. For example, consider the following:
The stack layout for a standard PL/I call is illustrated below.
The "system" calling sequence passes arguments by value. All arguments, normally limited
to arithmetic data, pointers, and nonvarying strings, are evaluated and the values are
passed to the called procedure. Changes to the values of parameters do not cause changes in
the values of the corresponding arguments.
tempnam generates a unique name for a temporary file.
The following steps are not required, but will simplify debugging.
To get the debugger to stop at the beginning of the PL/I program,
make the following modifications to "setup.dbg", normally found
in the <WATCOM>\binw directory.
The IBM "ASDT" debugger is also usable.
Sometimes it may be desirable to compile-in a breakpoint
to be activated when a specific location is reached or
condition occurs. The following statement inserted in your
source will activate a breakpoint when it is reached when running
under control of a debugger:
Future versions will be extended to dump PL/I STATIC storage ('H'), and information
about opened files ('F').
Options may be combined and may appear in
any order, for example "TCB" means: print trace, continue after snap, and dump
all automatic storage.
The stack is dumped from the current procedure (_pli_Dump) [lowest address] to
the PL/I startup code (_pli_Init) [highest address]. Storage for each procedure is
dumped in three sections (see sample segment of PLIDUMP output below):
Temporaries (argument lists
and storage used during expression evaluation),
Data (AUTOMATIC variables and other non-temporary user data in
the stack frame),
and DSA (system data in stack frame). The layout of the DSA is
given in lib\include\dsa.inc. This is subject to change in future releases.
Each data line includes the
actual address of the first byte, the offset (±EBP for DSA and data, +ESP
for temporaries), up to sixteen bytes of data in hex as actually stored in memory
(no byte-swapping), and the ASCII representation of the same data.
The DSA display provides additional formatted information regarding the ON-conditions
enabled for this block and identifies runtime-library procedure.
Input/Output Statements
OPEN and CLOSE apply to both STREAM and RECORD files. The GET and PUT
statements operate on STREAM files. The READ, WRITE, REWRITE, and LOCATE
statements operate on RECORD files. The assumption is made that the reader is familiar with, or has access
to a reference for, the I/O statements of IBM PL/I for MVS and VM. Only the syntax accepted by Iron Spring
PL/I is shown here, no explanation is provided.
+----------------------- , -------------------------------------+
v |
>>-OPEN--.---FILE(file_ref)-+------------------+----+---------------+----+---- ; ----><
| | | |
+-|stream-options|-+ +-TITLE(string)-+
| |
+-|record-options|-+
|stream-options|
+-INPUT ---------------------------+
| |
|----STREAM---+----------------------------------+-+-------------+-----|
| | | |
+OUTPUT ---+-----------------------+ +-LINESIZE(m)-+
| |
+-PRINT-+-------------+-+
| |
+-PAGESIZE(n)-+
|record-options|
+-INPUT -+
| |
|---RECORD----+--------+-+------------+-+-------+------|
| | | | | |
+-OUTPUT-+ +-BUFFERED---+ +-KEYED-+
| | | |
+-UPDATE-+ +-UNBUFFERED-+
STREAM Input/Output
>>-GET-FILE(file_ref)-+-----------------+-+----------------------+- ; --><
| | | |
+-SKIP----------+-+ +-|data_specification|-+
| |
+-(expr)-+
>>-PUT-FILE(file_ref)-+---------------------+-+----------------------+- ; --><
| | | |
+-PAGE-+------------+-+ +-|data_specification|-+
| | | |
| +-LINE(expr)-+ |
| |
+-SKIP-+--------+-----+
| | | |
| +-(expr)-+ |
| |
+-LINE(expr)----------+
|--+------+---( |data-list| )---------------------+----|
| | |
+-LIST-+ |
| |
+-DATA---+-----------------+-------------------+
| | | |
| +-( |data-list| )-+ |
| |
| +-----------------------------------+ |
| v | |
+-EDIT---.-( |data-list| )-( |format-list| }-+-+
The SKIP option causes a new line to be started
in the data stream prior to transmitting any data from the current or subsequent GET or PUT statement.
The (expr) is converted to an integer n. On output, n newlines (linefeed or
carriage-return/linefeed) are inserted. On input the remainder of the current line and the n-1 following
lines are skipped.
If (expr) is omitted or not greater than zero, 1 is used for the value of n.
For PRINT files, the ENDPAGE condition may be raised if PAGESIZE is exceeded.
The PAGE option is valid only for PRINT files. It causes a page eject (ASCII '0C'x)
to be inserted in the output stream prior to transmitting any data from the current or subsequent
PUT statement. If both PAGE and LINE are present, the PAGE option is
applied first.
The LINE option is valid only for PRINT files. It causes a new line to be started
in the output stream prior to transmitting any data from the current or subsequent PUT statement.
The (expr) is converted to an integer n. If n or more lines have been written on the
current page, or if n exceeds PAGESIZE, a new page is started. newlines are inserted in
the output strean to position the next data written at line n.
If (expr) is less than or equal to zero, 1 is used for the value of n.
RECORD Input/Output
>>-READ-FILE(file_ref)-+-----------------------------------+----------- ; --><
| |
+-INTO(ref)-+-------------+---------+
| | | |
| +-KEY(expr)---+ |
| | | |
| +-KEYTO(ref)--+ |
| |
+-SET(pointer-ref)-+-------------+--+
| | | |
| +-KEY(expr)---+ |
| | | |
| +-KEYTO(ref)--+ |
| |
+-IGNORE(expr)----------------------+
>>-WRITE-FILE(file_ref)--FROM(ref)--+-------------------------+----------- ; --><
| |
+-KEYFROM(expr)-----------+
| |
+-KEYTO(ref)--------------+
>>-LOCATE--based-variable--FILE(file-ref)--+------------------+-------------------+---- ; --><
| | | |
+-SET(pointer-ref)-+ +-KEYFROM(expr)--+
>>-REWRITE-FILE(file_ref)--+-----------+--+-----------+----------- ; --><
| | | |
+-FROM(ref)-+ +-KEY(expr)-+
Run-time considerations
Run-time messages
All run-time messages are written to stderr:
Issued by: _pli_IIC
Cause: is either a compiler error or a mismatch between
the compiled program and the version of the runtime library used.
and no OTHERWISE clause present.
Issued by: _pli_OTH
Cause: User error. None of the conditions specified in a
SELECT-statement were satisfied and the statement did not include an OTHERWISE.
in procedure with entry eeee
[condition=xxxx]
[ONFILE=ffff]
[System Code=hhhhhhhh tttttttt]
Issued by: _pli_SIG
Cause: Condition "cccc" was raised, either by a SIGNAL statement or by
the occurrence of an error. "aaaa" is the address where the error occurred,
"eeee" is the name of the entry point called in the procedure in which
the error occurred. If the condition was CONDITION(name), xxxx is the
name of the user-defined condition. If the error is associated with an
input-output statement, "ffff" is the name of the file.Parameter of MAIN Procedure
The MAIN procedure is called with one parameter: A CHARACTER(*) VARYING string containing
the possibly edited image of the command line that invoked the program. A future release
will allow programs to permit run-time options such as heap size to be specified on the
command line. These options will be edited out of the text pased to the program.
Memory utilization
Generated PL/I code does not modify STATIC storage except during program initialization.
All code is reentrant unless the user program modifies STATIC storage in such
a way as to invalidate this.
^
| | |
+08 | Parameters (see program linkage below) | Higher addresses
+------------------------------------------+ |
+04 | Calling program's EIP | |
+------------------------------------------+ |
EBP+00 | Calling program's EBP | |
+------------------------------------------+ |
| PL/I control information | |
| [see library include file 'dsa.inc' | |
| for layout (subject to change)] | |
| ... | v
+------------------------------------------+ Lower addreses
| AUTOMATIC non-adjustable data |
| for this block |
| ... |
+------------------------------------------+
| AUTOMATIC adjustable data |
| ... |
+------------------------------------------+
| Temporaries, argument lists |
...
Program Linkage
PL/I supports a standard PL/I linkage, and an optional "system" linkage used to link to
C programs, including system APIs. The two conventions are similar: all arguments are pushed
on the stack right to left (leftmost arguments in lower addresses). Returned values from
function procedures may be returned on the stack or in EAX or ST(0).
A: PROC;
CALL B;
B: PROC;
CALL B;
C: BEGIN;
END;
END B;
END A;
A is always the 'containing' block of B, regardless of whether B is called from A or from itself recursively.
B is the containing block of block C. Using the static backchain, C can address AUTOMATIC data from
B and A, and so on.
+--------------//--------------------------+
| Space for returned value if on stack |
+------------------------------------------+
(optional, locator/ +------------------------------------------+
descriptor pair | Address of descriptor | --->
for returned value) +------------------------------------------+
| Address of data |
+------------------------------------------+
(optional) +-------------//---------------------------+
| Dummy arguments |
| ... |
+------------------------------------------+
(optional, locator/ +------------------------------------------+
descriptor pair | Address of descriptor | --->
for arguments +------------------------------------------+
requiring a | Address of data | --->
descriptor - +------------------------------------------+ <------+
one per argument) |
|
(optional) +-------------//---------------------------+ |
| Saved values of 'live' registers | |
| not saved by the called procedure | |
| ... | |
+------------------------------------------+ |
|
+------------------------------------------+ |
| Argument list, one DWORD per argument. | |
| This address points to either the data | |
| or the address of the locator/ | -------+
| descriptor pair for the data. |
| The last (highest addressed) argument | -or-
| identifies the returned value. | -------> argument
ESP -----> +------------------------------------------+
Oncodes
Oncode
Condition Value
finish 4
error 9
name 10
record 20
transmit 40
key 50
endfile 70
undefinedfile 80
endpage 90
pending 100
stringsize 150
overflow 300
fixedoverflow 310
zerodivide 320
underflow 330
size 340
stringrange 350
area 360
attention 400
condition 500
check 510
subscriptrange 520
conversion 600
Efficient Programming
PUT LIST(a);
PUT LIST(b);
use:
PUT LIST(a,b);
User-callable PL/I Library Procedures
Most of the procedures in the PL/I runtime library (prf.lib) are for use by the compiler
and are not user-callable. The following, however, may be useful:
osdelete deletes a file by name.
DECLARE osdelete ENTRY( CHAR(*) VAR )
RETURNS( FIXED BIN(31) )
EXT( '_pli_OSDelete' );
DECLARE rc FIXED BIN(31);
RC = osdelete( filename );
0 indicates no error.
2 indicates that the file was not found.
for other errors see the OS/2 Operating System Control Program
Guide and Reference.
DECLARE tempnam ENTRY( CHAR(*) VAR, CHAR(*) VAR, CHAR(*) VAR )
RETURNS( CHAR(260) VARYING)
EXT( '_pli_Tempnam' );
DECLARE temp_filename CHAR(260) VARYING;
temp_filename = tempnam( sDir, sPfx, sSfx );
'sPfxpppppppp-tttttttt-uuuuuuuusSfx'
where 'pppppppp' is the hex value of the current process id (pid),
'tttttttt' is the hex value of the current thread id (tid), and 'uuuuuuuu'
is a unique number within this process. If another file with this name
already exists, the unique number is incremented until the generated name
does not confilct with an existing file.
Debugging PL/I programs
Debuggers
The WATCOM® debugger may be used to debug PL/I programs.
Source-level debugging is not yet available, but since the
compiler can generate assembly-language output, debugging
at the assembly level is straightforward.
After this, you will also need to link your program with a module definition file
to export the symbol "_PLI_Main" so that it is visible to the debugger.
The "samples" directory contains an example .def file and linker command
to do this.
elseif _dbg@dbg$os == 12 && ?@main { Following this go/until/noflip @main } elseif ?@@_PLI_MAIN { Insert these three lines go/until/noflip @@_PLI_MAIN } *PROCESS DBG(INT3);
If the resulting executable is not run under a debugger, the
interrupt will be ignored. Nevertheless, INT3 traps should not be
left in a production program.
SNAP traceback
The PL/I statement "ON CONDITION(xxx) SNAP..." will generate a traceback
on stderr when the specified condition is raised. Beginning with the procedure
generating the traceback (_pli_Trace) and working backwards, the trace
lists the address of the active entry point of the procedure, the address
of the statement in the calling procedure that called that entry, and
the name of the entry point if available.
PLIDUMP
The PL/I statement "CALL PLIDUMP( "<options>", "<title>" );
will generate debugging output on stderr when executed.
"title" is a character string used as the title of the dump.
"options" provide one or more dump options:
'S' = terminate after dump
'C' = continue after dump
'T' = print traceback
'B' = dump automatic storage.sample PLIDUMP output
***error dump***
Address Caller Entry name
... omitted from the example ...
0001868A 00027402 FTPRO
Temporaries at 003C80C4
003C80C4 ( 000000) 74823C00 5C863C00 98823C00 3C813C00 |t.<.\.<...<.<.<.|
003C80D4 ( 000010) 53003C00 F4803C00 5C863C00 A8A2021C |S.<...<.\.<.....|
... omitted from the example ...
003C83B4 ( 0002F0) 3C843C00 00000000 3C843C00 C4833C00 |<.<.....<.<...<.|
003C83C4 ( 000300) 64140500 |d...|
Data at 003C83C8
003C83C8 (-000074) 786D0500 00843C00 3E350400 E4C34300 |xm....<.>5....C.|
003C83D8 (-000064) 00000000 30823C00 0083E180 B8813C00 |....0.<.......<.|
003C83E8 (-000054) 0000E181 E4C34300 00000000 B5570400 |......C......W..|
003C83F8 (-000044) 31000000 10843C00 786D0500 80853C00 |1.....<.xm....<.|
003C8408 (-000034) 12720200 600F3C00 01001500 00001B00 |.r..`.<.........|
003C8418 (-000024) E0320500 |.2..|
DSA at 003C841C
Enabled: CONV FOFL OFL UFL ZDIV
003C841C (-000020) C8833C00 0000E180 E4C34300 00000000 |..<.......C.....|
003C842C (-000010) 8A860100 31000000 48843C00 786D0500 |....1...H.<.xm..|
003C843C ( 000000) 80853C00 02740200 |..<..t..|
00026C79 00010123 PH10
Temporaries at 003C8444
003C8444 ( 000000) 48843C00 11000000 42000000 |H.<.....B...|
... omitted from the example ...
version 0.5e, 25 Apr, 2008
http://www.iron-spring.com