REXX Can Talk to Other Languages
October 5, 2005 Bruce Guetzkow
The code and figures for this article are available for download.
One of the most confusing aspects of using REXX can be how to pass data between a REXX procedure and a procedure that has been written in another programming language. What follows is an explanation of the many ways to pass data into a procedure and then extract it back out.
Calling a REXX procedure
Before you can pass data to a REXX procedure you need to know how to execute a REXX procedure. The first way is to use CL’s Start REXX Procedure (STRREXPRC) command.
STRREXPRC SRCMBR(member) SRCFILE(library/file) PARM(parm-data) CMDENV(command-environment) EXITPGM((exit-pgm1) (exit-pgm2) … )
Another way is to call the QREXX API. Further information on this program can be found in REXX Reference Manual. The parameters for this API are the same as for the STRREXPRC command:
- Source member: 10 bytes character (source member containing REXX procedure script)
- Source file: 20 bytes character (positions 1-10 contain the file name, 11-20 contain the library name)
- Argument string: up to 32,767 bytes character (positions 1-2 contain the length in binary of the argument string; the balance of the field is data being passed into the REXX procedure)
- Command environment: 20 bytes character (*COMMAND, *CPICOMM, *EXECSQL or positions 1-10 contain the program name, 11-20 contain the library name)
- System exits: up to eight repetitions of 22 bytes character (positions 1-10 contain the exit program name, 11-20 contain the exit program library name, 21-22 contain the binary exit code which triggers this exit program)
A third way is to specify the REXX procedure as the command processing program (CPP) for a user-defined command using the Create Command (CRTCMD) command. The command passes values directly to the QREXX program, combining all command parameter values into the argument string in the order that the parameters are defined.
The final way is by using option 16 from the Work with PDM Members (WRKPDMMBR) panel. This is really just a shortcut to the STRREXPRC command with the SRCMBR and SRCFILE parameters filled in with the source member and source file selected with the PDM option.
Four Ways to Receive Data
Now we move on to the business of passing data. The first method that REXX can use to receive data is the ARG or PARSE ARG instruction. These instructions accept data passed via the PARM parameter on the STRREXPRC command or the argument string of the QREXX program. Up to 3,000 bytes of data can be passed via the PARM parameter and up to 32,765 bytes of data can be passed via the argument string. This method (see Figure 1 in the code file) is much like calling any other high level language (HLL) program.
The second method (see Figure 2 in the code file) uses the PARSE LINEIN instruction to receive data from the standard input file, STDIN. For procedures executed interactively, STDIN defaults to keyboard input. In this case an interactive session is presented with an input-capable line where data can be directly entered. Upon pressing the Enter key the keyed data is passed to the REXX procedure.
When a REXX procedure is executed in batch, STDIN defaults to file QINLINE. Each execution of the PARSE LINEIN statement reads another record from file QINLINE or another input string from the keyboard. What makes this option particularly valuable is that you can issue an Override Database File (OVRDBF FILE(STDIN) TOFILE(library/anyfile)) command to redirect input to any file. Reading database files in this manner is restricted to sequential access only.
Using the PULL or PARSE PULL instructions receives data from the REXX external data queue. This queue functions much the way a permanent data queue does but is unique to each iSeries job. Programs and procedures may place data on the external data queue and other programs and procedures in the same job may remove that data. HLL programs access the external data queue by using the QREXQ program. Further information on this program can be found in REXX Reference Manual. This program has the following parameters:
- Function Code: 1 byte character (indicates whether lines are added or removed from the queue along with other functions
- Data Buffer Target: variable-length bytes character (indicates the field containing data to be added or the target field into which is removed)
- Numeric Value: 10 byte integer (value varies based on function code)
- Operation Flag: 5 byte integer (used only for add and remove functions)
- Return Code: 5 byte integer (contains result of call)
When a PULL or PARSE PULL instruction is executed (see Figure 3 in the code file) and there are no entries on the external data queue, data is instead read from standard input, as is done with ARG or PARSE ARG.
The final method (see Figure 4 in the code file) is to use the PARSE SOURCE instruction. This retrieves information about the source member being executed. The five pieces of information that can be returned (in this order) are: the text string “OS/400”, how the procedure was called (“COMMAND”, “FUNCTION” or “SUBROUTINE”), the member name, the source file, and the library. This information can be used for self-documentation of a procedure.
Now that your REXX procedure has received data and acted upon it, it is time to return results to your calling program. The first way is again using the external data queue (see Figure 5 in the code file). You can PUSH data to the top of the queue or QUEUE it to the bottom of the queue. This allows you to control the order that data is placed on the queue and how it is processed. Languages other than REXX can use the QREXQ program to retrieve data from the external data queue.
A second method (see Figure 6 in the code file) is to use the SAY instruction to write to standard output. Standard output (STDOUT) defaults to the 5250 screen display for interactive sessions, and to file QPRINT for batch sessions. Like standard input, you can override standard output to any file. This is another powerful feature as you can easily write data to any existing file.
The third REXX output method (see Figure 7 in the code file) is to use the EXIT instruction and specify a return code (0-9). An exit code other than 0 (zero) also causes error message CPF7CFF to be sent with the value of the return code in the message text. This can be valuable to indicate errors back to the calling program.
Like standard input and standard output, REXX also employs a standard error output file. Like standard output, standard error (STDERR) defaults to the 5250 screen display for interactive sessions, and to file QPRINT for batch sessions. You can override this file as you would the other standard files. Standard error is where REXX error information is sent if there is no logic in the REXX procedure to handle the error.
Putting REXX to work
Now you’ve seen several methods to pass data into and out of a REXX procedure. Your next step is to take advantage of the features of REXX and put them to use for your programming benefit.