For years, I have been an advocate of taking advantage of what's available in a programming language. For example, the C language includes a number of functions that RPG IV programmers can and should consider extensions to RPG IV. In most cases, they are as easy to use as the %CHAR and %LEN built-in functions.
Because RPG IV is used to create ILE objects, any function or procedure (for purposes of this article, the terms function, procedure, and subprocedure are being used interchangeably) that has been exported by any of the ILE languages can be called from any of the other ILE languages.
In order to satisfy certain C language syntax requirements, IBM exported the entire library of C language runtime functions. This means that the entire C language runtime library is available to RPG IV programmers to use as they see fit.
Learning which C language functions have wide application isn't always easy, but it certainly isn't impossible. To determine which C language runtime functions are useful to an RPG IV programmer, you can look at shortcomings in RPG IV and then search the C language for solutions to those shortcomings.
Converting Character to Numeric
One of RPG IV's shortcoming is its inability to convert character fields to numeric. The RPG ToolKit includes an MI routine named CharToNum(). This routine converts a character string to a numeric value, including decimal positions. It is very efficient and works with up to 30-digit decimal values with 9 decimal places--that is, 21 digits to the left of the decimal and 9 to the right.
The C language has a few routines that also may be used to convert character strings into numeric, including those listed below.
- int4 = atoi()--ASCII to integer (an integer is a 4-byte binary value)
- int4 = atol()--ASCII to long integer (a long integer is the same as an integer to the OS/400 C compiler, or a 10i0 value in RPG IV)
- int8 = atoll()--ASCII to long long integer (a "long long" integer is an 8-byte binary field, or a 20i0 value in RPG IV)
To use these functions in RPG IV, the RPG IV source member must include the prototypes for the functions. As usual, IBM does not provide the prototypes for these functions in RPG IV syntax. So, I've provided them for you; see Figure 1.
|
Figure 1: These C prototypes convert character to numeric.
To use any C language runtime function, you must use the binding directory named QC2LE. The easiest way to use this binding directory is to include it on a Header specification at the beginning of each source member, as illustrated below:
The BNDDIR keyword can be used on the Header specification as well as on the CRTBNDRPG, CRTPGM, and CRTSRVPGM commands. Multiple binding directory names may be specified on the Header specification keyword or on the compiler parameter.
To specify multiple binding directories on the BNDDIR keyword on a Header specification, enclose each binding directory name in single quotes and separate each binding directory name with a colon, as shown below. Note that a qualified name is fully supported for any of the binding directory names.
Be sure to specify the binding directory names in all uppercase; otherwise, the compiler will not locate the procedure stored in its entries.
To use the atoi() or atoll() function, include the prototypes I showed you above, and then specify them on the Calculation specifications (regular or free-format) just as you would with an RPG IV built-in function. That's all there is to it.
A couple of comments on these three functions: The atoi() and atol() functions are identical functions and can return up to a 10-digit value. However, this value is not 9,999,999,999. Rather, 2,147,483,647 is the maximum integer value that these two functions can return. The other function, atoll() can return up to a 19-digit value, again not all 9's but rather 9,223,372,036,854,775,807 as the maximum.
The RPG compiler developers tell me there is no performance issue with using atoll() vs. atoi() vs. atoll(), so I tend to use atoll() exclusively simply because I don't have to worry about the length of the return value as much as I do with the other two functions. Since I convert phone numbers from/to numeric frequently, atol() will blow up whenever the area code is 215 or higher because that puts the value over the 2,147,483,647 limit.
Replacing QCMDEXC
The C language doesn't stop with a few conversion functions; it also has hundreds of other functions, including one that is of particular interest to RPG programmers: system ().
The system() function runs an OS/400 CL command, just like QCMDEXC does. The difference between this function and calling QCMDEXC is that (a) QCMDEXC is a program call whereas system() is a procedure call and (b) QCMDEXC requires that you pass the length of the command string as the second parameter; system() has no such requirement.
This means you can run any CL command that you would normally run with QCMDEXC by using the simplified syntax of the system() function, as illustrated in Figure 2.
|
Figure 2: Use this prototype for the system() function.
On lines 1 and 2 of Figure 2, I have included the prototype for the system() function. Then, on line 3, I declare a field named CPFMSGID. This is a seven-position character field that is imported. The import symbol name is _EXCP_MSGID. This is a field in the C runtime library that contains the CPF message ID resulting from the call to the command passed to the system() function. You can check this field for the CPF message ID.
On line 4, the call to the system() function is performed, adding the library named TOOLKIT to the library list. If the library name is not added, CPF2103 is generated.
The system() function is much easier to use in RPG IV than QCMDEXC, and it is easier to check for the final CPF error message.
Taking a Nap
The last C language runtime function I want to mention today is the sleep() function. Sleep() performs a function similar to the DLYJOB CL command. It goes to sleep for the specified number of milliseconds.
D seconds 10U 0 value
To use the sleep() function, simply call it using the CALLP operation code and pass it the number of milliseconds to sleep, as follows:
In this example, the sleep() function "goes to sleep" for 10 seconds.
Remember to look into what's available to the RPG IV programmer in other languages. We currently have APIs, C language functions, Java, and REXX stuff to leverage. It's a great new world of programming, and RPG IV is the center of the universe!
Bob Cozzi has been programming in RPG since 1978. Since then, he has written many articles and several books, including The Modern RPG Language --the most widely used RPG reference manual in the world. Bob is also a very popular speaker at industry events such as COMMON and RPG World and is the author of his own Web site, www.rpgiv.com, and of the RPG ToolKit, an add-on library for RPG IV programmers.
LATEST COMMENTS
MC Press Online