V5R3 CL Programming Enhancements, Part 2
March 24, 2004 Ted Holt
Last week I wrote about the integer data types, the select structure, and the looping commands that will be available in V5R3. This week I’ll finish my tour of new V5R3 CL programming features by telling you what’s new with input/output operations, parameter passing, and the generation of CL command documentation.
DECLARE MORE FILES!
One limitation that System/38, AS/400, and iSeries programmers have complained about is that only one Declare File (DCLF) command was allowed in a CL procedure (i.e., a compiled program or module). Using a database file automatically eliminated the possibility of using a display file, and vice versa. As of V5R3, you will be allowed a maximum of five DCLF commands. Now you’ll be able to have both a database file and a display file in a CL procedure. You’ll be able to process more than one database file in a single procedure, and you’ll be able to process the same file more than once by declaring it multiple times.
IBM has added a new parameter, OPNID, which you use to distinguish the files. You must specify an identifying name of no more than 10 characters for the file. This name will be prepended, along with an underscore, to the field names of the file. As an example, suppose you specify OPNID(WORKF) when declaring file WORKFILE, which has fields MBRNAME, MBRTYPE, and MBRSIZE.
DCLF FILE(WORKFILE) OPNID(WORKF)
The CL compiler will generate variables named &WORKF_MBRNAME, &WORKF_MBRTYPE, and &WORKF_MBRSIZE. Since the open ID may be 10 characters long and database field names may be 10 characters long, the variables that are associated with a file may be up to 22 characters long when the ampersand (&) and underscore ( _ ) are added. Regular CL variables, declared with the DCL command, are still limited to 11 characters, the first of which is an ampersand.
If you declare more than one file, you must use the OPNID parameter on all input-output commands: Declare File (DCLF), End Receive (ENDRCV), Receive File (RCVF), Send File (SNDF), Send/Receive File (SNDRCVF), and WAIT (Wait for input operation).
You’ve just seen an example of OPNID within DCLF. Here’s an example that reads from the declared file.
RCVF OPNID(WORKF) MONMSG CPF0864 EXEC(GOTO FINISHED) /* End of file */
IBM has made some changes to the Program (PGM), CALL, Call Procedure (CALLPRC), and Transfer Control (TFRCTL) commands. In V5R2, you are allowed to list up to 40 positional parameters in the PARM parameter of the PGM command. However, in V5R3, you may list up to 255 parameters. CALL and TFRCTL accept up to 255 parameters, up from the V5R2 limits of 99 and 40 respectively.
CALLPRC has been enhanced to allow passing parameters by value. Parameters have been redefined as two-element lists. The first element is the passed parameter value. The second element may be either *BYREF (by reference) or *BYVAL (by value). To preserve compatibility with code written for earlier releases, the default value of the second element is *BYREF.
Assume you have an RPG subprocedure that returns a month name given a month number. Here’s the prototype.
D GetMonthName pr n D MonthNbr 2p 0 value D MonthName 9a
The first parameter is passed by value, and the second parameter is passed by reference, since the procedure modifies it. The return value indicates whether the procedure failed, which would happen only if the first parameter had a value less than 1 or greater than 12. You cannot link to this procedure from CL modules in V5R2 and prior releases, but you can use the following CALLPRC command in V5R3.
DCL VAR(&OK) TYPE(*LGL) DCL VAR(&MONTH) TYPE(*DEC) LEN(2 0) DCL VAR(&MONTHNAME) TYPE(*CHAR) LEN(9) CALLPRC PRC(GETMONTHNAME) + PARM((&MONTH *BYVAL) (&MONTHNAME *BYREF)) + RTNVAL(&OK)
One reason pass-by-value is so exciting is that it opens CL to the world of APIs. Think about it: IBM may some day modify the SNDF command to let you write to database files. Then again, IBM may never do that. But if you can link to the stream I/O APIs, you can write to database files and Integrated File System (IFS) files. By allowing you to pass parameters by value, IBM has added thousands of new operations to the CL language.
The ability to pass parameters by value also makes it easier for CL to use subprocedures you write in other languages. V5R3 will obsolete the remarks I made about calling RPG subprocedures from CL in the January 10, 2003, edition of Midrange Guru.
V5R3 begins a new era in OS/400 documentation. Before V5R3, IBM maintained two code bases of documentation. One set of code was used to produce online help (the text you see when you press the Help key or the F1 key in an interactive session). The other set of code built the reference manuals, including what you see on the Web on the iSeries Information Center. IBM has eliminated this double effort by developing a tool that creates documentation from command objects and panel group objects.
The tool is a Java class named CommandHelpRetriever. It uses two APIs: Retrieve Command Definition (QCDRCMDD) and Retrieve Help Text (QUHRHLPT). You will be able to run the class from Qshell or with the Run Java (RUNJVA) command, of course, but you may find it easier to use the new Generate Command Documentation (GENCMDDOC) CL command instead.
GENCMDDOC can produce documentation in HTML or UIM. If you specify GENOPT(*UIM), GENCMDDOC generates a skeleton UIM member from a command object. You can add explanatory text with your favorite text editor and create a help panel group for the command. If you specify GENOPT(*HTML), GENCMDDOC creates an HTML file from the command object and the help text in the panel group object.
You can write the generated source code to an IFS or a database file, but you must use the IFS syntax in either case.
In the following example, a skeletal help text member of UIM source is generated in member CPYTOTST of source physical file QPNLSRC in library UTILITY from the CPYTOTST command object in library UTILITY.
GENCMDDOC CMD(UTILITY/CPYTOTST) + TODIR('/QSYS.LIB/UTILITY.LIB/QPNLSRC.FILE') + TOSTMF('CPYTOTST.MBR') REPLACE(*NO) GENOPT(*UIM)
At this point, you may want to run GENCMDDOC again, but this time specify GENOPT(*HTML) to generate a full HTML file from the command definition and the panel group. The following example places the HTML in file cpytotst.html in directory /home/jsmith of the IFS.
GENCMDDOC CMD(UTILITY/CPYTOTST) + TODIR('/home/jsmith') + TOSTMF('cpytotst.html') + GENOPT(*HTML)
IBM is using this new tool to generate all of the V5R3 CL command documentation in the iSeries Information Center. This means that (1) one form of documentation will not contradict the other, as happens in the present case in a few places and (2) IBM will be able to provide documentation for all CL commands in all program products on the Information Center, which is not the present case.
One thing you will notice is that “railroad track” command-syntax diagrams have been replaced by parameter syntax tables. Here’s the syntax table for GENCMDDOC:
|CMD||Command||Qualified object name||Required, Positional 1|
|Qualifier 1: Command||Generic name, name, *ALL|
|Qualifier 2: Library||Name, *LIBL, *CURLIB|
|TODIR||To directory||Path name, .||Optional|
|TOSTMF||To stream file||Character value, *CMD||Optional|
|REPLACE||Replace file||*YES, *NO||Optional|
|GENOPT||Generation options||Values (up to 3 repetitions): *HTML, *UIM, *NOSHOWCHOICEPGMVAL, *SHOWCHOICEPGMVAL, *NOSERVICE, *SERVICE||Optional|
Expect to see these new, tabular syntax tables when you install V5R3.
LONG OVERDUE AND VERY WELCOME
To say that I am glad to see CL programming take a giant leap forward is a vast understatement. I like CL, especially its use of keyword parameters and the way it allows me to be prompted for parameter values. My contact at IBM told me that they are not finished beefing up the CL compilers. They are kicking around some good ideas for future releases of OS/400.
The bottom line is productivity. I strive to write effective programs–programs that do what they’re supposed to do, programs that are easy to understand and modify. I believe that the enhancements I’ve written about in this article and in its predecessor will help me achieve those goals, and I am looking forward to getting my hands on V5R3.