Free-Form Syntax | {CALLP{(EMR)}} name( {parm1{:parm2...}} ) |
Code | Factor 1 | Extended Factor 2 | ||||
---|---|---|---|---|---|---|
CALLP (E M/R) | name{ (parm1 {:parm2…}) } |
The CALLP operation is used to call prototyped procedures or programs.
Unlike the other call operations, CALLP uses a free-form syntax. You use the name operand to specify the name of the prototype of the called program or procedure, as well as any parameters to be passed. (This is similar to calling a built-in function.) A maximum of 255 parameters are allowed for a program call, and a maximum of 399 for a procedure call.
On a free-form calculation specification, the operation code name may be omitted if no extenders are needed, and if the prototype does not have the same name as an operation code.
The compiler then uses the prototype name to obtain an external name, if required, for the call. If the keyword EXTPGM is specified on the prototype, the call will be a dynamic external call; otherwise it will be a bound procedure call.
If the called program or procedure is defined in a different module, a prototype for the program or procedure being called must be included in the definition specifications preceding the CALLP. If the called program or procedure is defined in the same module as the call, an explicit prototype is not required; the prototype can be implicitly defined from the procedure interface of the called program or procedure.
Note that if CALLP is used to call a procedure which returns a value, that value will not be available to the caller. If the value is required, call the prototyped procedure from within an expression.
CALLP(E) PROGNAME(FileRecs(Fld) + 1)
For more information on call operations, see Call Operations. For more information on defining prototypes, see Prototypes and Parameters. For information on how operation extenders M and R are used, see Precision Rules for Numeric Operations.
*..1....+....2....+....3....+....4....+....5....+....6....+....7...+....
*-------------------------------------------------------------
* This prototype for QCMDEXC defines two parameters:
* 1- a character field that may be shorter in length
* than expected
* 2- any numeric field
*-------------------------------------------------------------
D qcmdexc PR extpgm('QCMDEXC')
D cmd 200A options(*varsize) const
D cmdlen 15P 5 const
/FREE
qcmdexc ('WRKSPLF' : %size ('WRKSPLF'));
/END-FREE
* The prototype for the procedure has an array parameter.
D proc pr
D parm 10a dim(5)
* An array to pass to the procedure
D array s 10a dim(5)
* Call the procedure, passing the array
C callp proc (array)
The following example of CALLP is from the service program example in Rational Development Studio for i: ILE RPG Programmer's Guide. CvtToHex is a procedure in a service program created to hold conversion routines. CvtToHex converts an input string to its hexadecimal form. The prototyped calls are to the ILE CEE API, CEEDOD (Retrieve Operational Descriptor). It is used to determine the length of the input string.
*..1....+....2....+....3....+....4....+....5....+....6....+....7...+....
*=================================================================*
* CvtToHex - convert input string to hex output string *
*=================================================================*
D/COPY MYLIB/QRPGLESRC,CVTHEXPR
*-----------------------------------------------------------------*
* Main entry parameters *
* 1. Input: string character(n) *
* 2. Output: hex string character(2 * n) *
*-----------------------------------------------------------------*
D CvtToHex PI OPDESC
D InString 16383 CONST OPTIONS(*VARSIZE)
D HexString 32766 OPTIONS(*VARSIZE)
*-----------------------------------------------------------------*
* Prototype for CEEDOD (Retrieve operational descriptor) *
*-----------------------------------------------------------------*
D CEEDOD PR
D 10I 0 CONST
D 10I 0
D 10I 0
D 10I 0
D 10I 0
D 10I 0
D 12A OPTIONS(*OMIT)
* Parameters passed to CEEDOD
D ParmNum S 10I 0
D DescType S 10I 0
D DataType S 10I 0
D DescInfo1 S 10I 0
D DescInfo2 S 10I 0
D InLen S 10I 0
D HexLen S 10I 0
*-----------------------------------------------------------------*
* Other fields used by the program *
*-----------------------------------------------------------------*
D HexDigits C CONST('0123456789ABCDEF')
D IntDs DS
D IntNum 5I 0 INZ(0)
D IntChar 1 OVERLAY(IntNum:2)
D HexDs DS
D HexC1 1
D HexC2 1
D InChar S 1
D Pos S 5P 0
D HexPos S 5P 0
/FREE
//-------------------------------------------------------------//
// Use the operational descriptors to determine the lengths of //
// the parameters that were passed. //
//-------------------------------------------------------------//
CEEDOD (1 : DescType : DataType :
DescInfo1 : DescInfo2 : Inlen : *OMIT);
CEEDOD (2 : DescType : DataType :
DescInfo1 : DescInfo2 : HexLen : *OMIT);
//-------------------------------------------------------------//
// Determine the length to handle (minimum of the input length //
// and half of the hex length) //
//-------------------------------------------------------------//
if InLen > HexLen / 2;
InLen = HexLen / 2;
endif;
//-------------------------------------------------------------//
// For each character in the input string, convert to a 2-byte //
// hexadecimal representation (for example, '5' --> 'F5') //
//-------------------------------------------------------------//
HexPos = 1;
for Pos = 1 to InLen;
InChar = %SUBST(InString : Pos :1);
exsr GetHex;
%subst (HexString: HexPos: 2) = HexDs;
HexPos = HexPos + 2;
endfor;
return;
//================================================================//
// GetHex - subroutine to convert 'InChar' to 'HexDs' //
// Use division by 16 to separate the two hexadecimal digits. //
// The quotient is the first digit, the remainder is the second. //
//================================================================//
begsr GetHex;
IntChar = InChar;
//-----------------------------------------------------//
// Use the hexadecimal digit (plus 1) to substring the //
// list of hexadecimal characters '012...CDEF'. //
//-----------------------------------------------------//
HexC1 = %subst (HexDigits: %div(IntNum:16) + 1: 1);
HexC2 = %subst (HexDigits: %rem(IntNum:16) + 1: 1);
endsr; // GetHex