The %INFORM statement specifies a user-written diagnostic informational message to be displayed during program compilation.
The format of the %INFORM statement is:
preprocessor-expressionThe text of the informational message displayed. The text is a character string of up to 64 characters. The string is truncated if necessary.
The format of the message to be displayed by %INFORM is:
The %INFORM statement increments the informational diagnostic count
displayed in the compilation summary.
The %LIST_xxx statement (where xxx is either ALL, DICTIONARY, INCLUDE, MACHINE, or SOURCE) enables the selective listing display of INCLUDE file contents, extracted Common Data Dictionary (CDD) record descriptions, machine code, and source code. The %LIST_xxx statement has a number of forms, each of which enables listing control for specific portions of the source text.
The format of the %LIST_xxx statements are:
You must compile the program with the appropriate value specified for the /SHOW qualifier before the above statements can be effective.
The %LIST_xxx form of each statement enables the appearance of the specified information starting with the listing line following the %LIST_xxx statement. If you previously specified %NOLIST_xxx, the %LIST_xxx statement has the effect of reenabling the display.
The text displayed with each form of the %LIST_xxx statement is summarized as follows:
To disable a %LIST_xxx statement, specify %NOLIST_xxx at the appropriate line in the source text.
%LIST_xxx statements cannot be nested.
The %NOLIST_xxx statement (where xxx is either ALL, DICTIONARY, INCLUDE, MACHINE, or SOURCE) disables the selective listing display of INCLUDE file contents, extracted Common Data Dictionary (CDD) record descriptions, machine code, and source code. The %NOLIST_xxx statement has a number of forms; each disables listing control for specific portions of the source text.
The format of the %NOLIST_xxx statements are:
You must compile the program with the /SHOW qualifier before any of these statements can be effective.
The %NOLIST_xxx form of each statement disables the appearance of the specified information starting with the listing line following the %NOLIST_xxx statement. If you previously specified %LIST_xxx, the %NOLIST_xxx statement has the effect of disabling the display.
The following summarizes the text suppressed with each form of the %NOLIST_xxx statement:
To cancel the effect of any of the %NOLIST_xxx statements, specify
%LIST_xxx (see Section 10.2.15) at the appropriate line in the source
The %PAGE statement provides listing pagination without inserting form-feed characters into the source text.
The format of the %PAGE statement is:
The first source record following the record that contains the %PAGE
statement is printed on the first line of the next page of the source
A preprocessor procedure is a sequence of preprocessor statements headed by a %PROCEDURE statement and terminated by a %END statement. A preprocessor procedure executes only at compile time. Invocation is similar to a function reference and occurs in two ways:
The format of the %PROCEDURE statement is:
labelAn unsubscripted label constant. A preprocessor procedure is invoked by the appearance of the label name on the %PROCEDURE statement and terminated by the corresponding %END statement. The label name must be active if invoked from a nonpreprocessor statement.
Preprocessor label names can be activated and deactivated, but cannot be specified in a %DECLARE statement.
parameter-identifierThe name of a preprocessor identifier. Each identifier is a parameter of the procedure.
STATEMENTA preprocessor procedure option. The STATEMENT option permits the use of a keyword argument list followed by an optional positional argument list in the preprocessor procedure invocation. The STATEMENT option returns strings that can be used as PL/I statements at run time.
RETURNSA preprocessor procedure attribute. The RETURNS attribute defines the data type to be returned to the point of invocation in the source code. If you specify a data type that is inconsistent with the returned value, a conversion error may result.
preprocessor-expressionValue to be returned to the invoking source code. The preprocessor expression must be specified. The preprocessor expression is converted to the data type specified in the RETURNS option and is returned to the point of invocation. Therefore, the expression must be capable of being converted to CHARACTER(32500), FIXED(10), or BIT(31).
The %PROCEDURE statement defines the beginning of a preprocessor procedure block and specifies the parameters, if any, of the procedure. Because the preprocessor procedure is always invoked as a function, the %PROCEDURE statement must also specify (via the RETURNS option) the data type attributes of the value that is returned to the point of invocation.
%A_VAR = A_PROC();
In this statement, the preprocessor procedure A_PROC is invoked and evaluated, and the result is returned and assigned to the preprocessor variable A_VAR.
As with other PL/I procedures, a parenthesized parameter list specifies the parameters that the preprocessor procedure expects when it is invoked. Each preprocessor parameter specifies the name of a variable declared in the preprocessor procedure. The preprocessor parameters must correspond one-to-one with arguments specified for the preprocessor procedure when it is invoked, except when the STATEMENT option is used.
The value to be returned to the invoking source code is converted to the data type specified in the RETURNS option. The return value replaces the preprocessor procedure reference in the invoking source code. Preprocessor procedures cannot return values through 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), or FIXED(10).
Preprocessor procedures cannot be nested. The scope of a preprocessor procedure is the procedure itself; that is, variables, labels, and any %GOTO statements used inside of the procedure must be local.
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. You can invoke preprocessor procedures recursively.
When a preprocessor procedure (with or without the STATEMENT option) is invoked from a preprocessor statement, each argument is treated as an expression and the result of executing the preprocessor procedure is returned to the statement containing the invocation.
When a preprocessor procedure is invoked from nonpreprocessor source text, the arguments are interpreted as character strings and are delimited by the appearance of a comma or a right parenthesis occuring outside of balanced parentheses. For example, the positional argument list (Q(E,D), XYZ) has two arguments; the strings 'Q(E,D)' and 'XYZ'.
%A1: PROCEDURE RETURNS(FIXED); DECLARE (A,B,C) FIXED; A = 2; B = 10; C = A + B; RETURN(C); END;
This example declares the preprocessor procedure A1 and specifies that the procedure return a fixed decimal result after the preprocessor statements within the procedure have been executed.
The procedure returns the value 12 to the point of invocation. Note that the leading percent signs, normally associated with preprocessor statements, are not required within a preprocessor procedure.
PPFIB: PROCEDURE OPTIONS (MAIN); DECLARE Y CHAR(14) INITIAL('Fibonacci Test'); (1) %DECLARE Y FIXED; (2) %F: PROCEDURE(X) RETURNS (FIXED); (3) DECLARE X FIXED; IF (X <= 1) THEN RETURN(1); ELSE RETURN(F(X-1)+F(X-2)); END; /* End preprocessor procedure */ %Y = F(10); (4) PUT SKIP LIST(Y); %Y = F(11); (5) PUT SKIP LIST(Y); %Y = F(12); (6) PUT SKIP LIST(Y); %DEACTIVATE Y; (7) PUT SKIP LIST(Y); (8) END; /* End run-time procedure */
This example uses a preprocessor procedure to return a Fibonacci number. The recursive preprocessor procedure labeled %F is invoked to return a single value, a Fibonacci number, to the point of invocation. The following notes correspond to the example:
The output from this program is:
89 144 233 Fibonacci Test
Using the STATEMENT Option
All preprocessor procedures (with or without the STATEMENT option) return a value to the invoking source code; that is, they are function procedures. Through the use of the STATEMENT option, the argument list to a preprocessor procedure can be a keyword argument list. Keyword argument lists are unique to preprocessor procedures and provide a powerful tool for manipulating PL/I.
A keyword argument list ends with a semicolon rather than the right parenthesis. In this way, the STATEMENT option permits you to use a preprocessor procedure as if it were a statement. Consequently, preprocessor procedures using the STATEMENT option permit you to extend the PL/I language by simulating features that may not otherwise be available.
Preprocessor procedures can have one of two distinctly different types of argument lists: positional or keyword. Positional argument lists (ending with a right parenthesis) use parameters sequentially, as in a parenthesized list. You can use positional argument lists in any preprocessor procedure. Keyword argument lists (ending with a semicolon) use parameters in any order, as long as each keyword matches the name of a parameter. This permits the option of specifying the order in which parameters are passed. You can use keyword argument lists only when the preprocessor procedure contains the STATEMENT option and is invoked from a nonpreprocessor statement.
When a preprocessor procedure is invoked from a nonpreprocessor statement, the STATEMENT option permits the use of a keyword argument list that follows the optional positional argument list in a preprocessor procedure invocation.
When you use keyword arguments in nonpreprocessor statements, the keywords can be used in any order. The following reference examples would produce a variety of results with positional arguments, because values would be used sequentially. Keyword arguments produce consistent results because keyword parameters are matched with keyword arguments.
%B: PROCEDURE (ALPHA, BETA, GAMMA) STATEMENT...; DECLARE (ALPHA, BETA, GAMMA) FIXED; . . . END; B(1,2,3); B ALPHA(1) GAMMA(3) BETA(2); B(1) GAMMA(3) BETA(2); B (,2,3) ALPHA(1);
The next example shows a more common use of the STATEMENT option; to generate PL/I source statements that define a unique run time feature. The preprocessor procedure APPEND returns a string, which is incorporated into the source program at compile time. At run time, the returned string is used as a PL/I function.
This preprocessor procedure permits a varying string to accumulate text up to its maximum size without danger of undetected truncation. Normally, strings that exceed their maximum size are truncated. The text returned by the preprocessor procedure provides the run-time program with a way to handle truncation. If the string would be truncated, a message is printed and the FINISH condition is signaled.
%APPEND: PROCEDURE (string,to) STATEMENT RETURNS(CHARACTER); (1) %DECLARE (string,to) CHARACTER; (2) %RETURN ( 'DO;'|| (3) 'IF LENGTH('||string||')+LENGTH('||to||') > SIZE('||to||')-2'|| ' THEN DO;'|| 'PUT SKIP LIST (''Buffer overflowed appending to '||to||''');'|| 'SIGNAL FINISH;'|| (4) 'END;'|| 'ELSE '||to||' = '||to||'||'||string||';'|| 'END;' ); %END;
The following notes are keyed to this example:
APPEND STRING('New String') TO (My_string); APPEND TO(My_string) STRING('New String'); APPEND('New String') TO(My_string);
Notice that if you have a preprocessor procedure (A) with a label that
is the same as the name of a keyword argument in another preprocessor
procedure (B) with the STATEMENT option, then when B is invoked the
keyword argument is treated as a call to procedure A, and not as a
keyword parameter in B.
10.2.19 %REPLACE Statement
The preprocessor %REPLACE statement specifies that an identifier is a constant of a given value. It can be used anywhere within a procedure or anywhere in a PL/I source file.
Beginning at the point at which a %REPLACE statement is encountered, PL/I replaces all occurrences of the specified identifier with the specified constant value, until the end of compilation.
The format of the %REPLACE statement is:
%REPLACE identifier BY constant-value;
identifierAny valid PL/I identifier. PL/I keywords are not valid identifiers in a %REPLACE statement. The identifier must not be the name of a declared preprocessor or program variable. PL/I permits multiple %REPLACE statements and %REPLACE statements that redefine the %REPLACE identifier.
constant-valueAny valid character-string, bit-string, or arithmetic constant.
Integer constants that are given values by %REPLACE statements are valid in constant expressions. For example:
%REPLACE PREFIX BY 8; DECLARE BUFFER CHARACTER( 80 + PREFIX);
When the program containing these lines is compiled, the variable
BUFFER is declared with a length of 88 characters.
10.2.20 %RETURN Statement
The %RETURN statement terminates execution of the current preprocessor procedure.
The format of the %RETURN statement is:
preprocessor-expressionValue to be returned to the invoking procedure. The preprocessor expression must be specified. The preprocessor expression is converted to the data type specified in the RETURNS option, and the value of the expression is returned to the point of invocation. Therefore, the expression must be capable of being converted to CHARACTER (32500) VARYING, FIXED (10), or BIT (31).
The value returned by a preprocessor procedure cannot contain preprocessor statements.
When the value of the evaluated preprocessor expression is passed back to the point of invocation, control returns to the evaluation of the statement that contained the reference to the preprocessor procedure.
Within a preprocessor procedure, the leading percent sign (%) is optional.
Multiple %RETURN statements are permitted in preprocessor procedures.
See Section 10.2.18 for examples of %RETURN.
The %SBTTL statement allows specification of an arbitrary compile-time string for the listing subtitle line. PL/I uses the procedure IDENT, or 01 if no IDENT was specified. If %SBTTL is used, the specified subtitle appears to the right of IDENT or 01. Subtitles do not appear on the first page of the listing file.
The format of the %SBTTL statement is:
preprocessor-expressionA character string with a maximum length of 30 characters. It is truncated if necessary.
The %TITLE statement allows specification of an arbitrary compile-time string for the listing title line. If %TITLE is used, the specified title appears to the right of the customary title. (If no TITLE option is specified, PL/I uses the name of the first level-1 procedure in the source program as the title.)
The format of the %TITLE statement is:
preprocessor-expressionA character string with a maximum length of 30 characters. It will be truncated if necessary.
The %WARN statement provides a diagnostic warning message during program compilation.
The format of the %WARN statement is:
preprocessor-expressionThe text of the warning message to be displayed. The text is a character string with a maximum length of 60 characters. It is truncated if necessary.
The message displayed by %WARN is:
The %WARN statement increments the warning diagnostic count displayed in the compilation summary.