|
|
![]() |
|
|
RPG Programs for Qshell by Ted Holt [The code for this article is available for download.]
To accomplish some feat in Qshell, look for a utility or sequence of utilities that will serve your purpose. If no utility is available, write a Qshell script. If the Qshell language cannot do what you need, write a program in a high-level language. In C, this is easy. But if you hate C as much as I do, and love RPG as much as I do, you'll want to write your program in RPG. This article tells you how. Requirements For a program to run under Qshell, it must be able to do four things:
That doesn't seem like a lot to ask for, does it? The C language is built for this sort of work. C has plenty of library functions that do these tasks; scanf, printf, gets, puts, perror, and exit are some of them. RPG has none of that stuff, but it can link to the C library functions. I have played with this method, and it works. I also wrote some RPG programs that used the QtmhRdStin and QtmhWrStout APIs, which are stored in the QTMHCGI library and are used for CGI programming. That also works. But then I stumbled upon a short RPG program that was written by Scott Klement, and I knew I'd found what I'd been looking for. Scott used the Unix-type APIs. (Click here to see Scott's code.) It did my heart good to see those APIs in his code. They are old friends to me, since I started using them to access the IFS from RPG in late 1997. My Solution The APIs are slightly messy. Some of the parameters require pointers, which I know how to use but avoid whenever possible. I developed a service program to simplify the programming interface to the APIs. I call my service program stdio. It is built from three source members:
I have written four subprocedures to handle the I/O and define the exit function. I call my subprocedures stdin, stdout, stderr, and exit. They are easier to use than the APIs. The I/O subprocedures require one variable-length character parameter. I consider that an improvement over the read and write APIs, which require three parameters, one of which is a pointer. Subprocedure stdin is a function subprocedure; it returns the number of bytes read from the stdin device. The other three subprocedures do not return values. Here's the service program source code. This is the procedure prototype. Here is the binder language. Place the service program source code in member STDIO of file QRPGLESRC. Place the prototype source code in a source physical file member of your choosing. I use member STDIO of file PROTOTYPES. Place the binder language in member STDIO of file QSRVSRC. The library, of course, is up to you. An Example Now you need a program that you can play with, and I have just the thing. This program, which I call EKOR4 (don't ask me why), reads stdin and writes to stdout, reversing the order of words in the process. If, for example, you feed it the sentence "I like cheese," it produces "cheese. like I". If you include a -b option when you call the program, it leaves in all the blanks. If you don't include the -b option, the program leaves only one blank between each word pair. Running the Example Once you've compiled everything, you'll want to run the EKOR4 example. First, make sure you have some test data. I suggest you create an IFS file with text data in it. Anything will do, as long as it has spaces here and there. For this example, I assume your file is mydata.txt. Here's my mydata.txt file: Reading List ============================================ Title Author ============================================ Anna Karenina Leo Tolstoy Moby Dick Herman Melville 1984 George Orwell Breakfast of Champions Kurt Vonnegut, Jr. The Republic Plato Next, use the qsh command to crank up Qshell. Use the cd command to change to the directory from which you intend to work. Then call the program. Qshell doesn't use the call command to start a program. Instead, you can type the program's name, in IFS style. If your program object is stored in library MYLIB, type the following: /qsys.lib/mylib.lib/ekor4.pgm < /home/mydir/mydata.txt If all goes well, Qshell lists your file, with the words reversed, on the display: List Reading ============================================ Author Title ============================================ Tolstoy Leo Karenina Anna Melville Herman Dick Moby Orwell George 1984 Jr. Vonnegut, Kurt Champions of Breakfast Plato Republic The Once that is working, run the command with the -b option. /qsys.lib/mylib.lib/ekor4.pgm -b < /home/mydir/mydata.txt Qshell should respond with something like this: List Reading ============================================ Author Title ============================================ Tolstoy Leo Karenina Anna Melville Herman Dick Moby Orwell George 1984 Jr. Vonnegut, Kurt Champions of Breakfast Plato Republic The A Better Way to Run the Example You shouldn't have to type all that /qsys.lib garbage every time you want to run this program. To avoid that, create a symbolic link in the IFS to point to the program object. You can create the link in either of two ways. You can use CL's Add Link (ADDLNK) command or Qshell's ln command. Let's say you want to refer to the program as reverse. Here's the CL command to create the link:
ADDLNK OBJ('/qsys.lib/tholts.lib/ekor4.pgm') +
NEWLNK('/home/tholt/reverse') +
LNKTYPE(*SYMBOLIC)
Here's the Qshell command: ln -s /qsys.lib/tholts.lib/ekor4.pgm reverse Now use the symbolic link to run the program within Qshell: reverse < /home/mydir/mydata Empowered Now you are empowered to write RPG programs to enhance Qshell. I use a good bit of PC software, and I often feel frustrated because I can't modify the way the program works or add a nifty feature. I like to write programs to make the computer do what I want it to do, rather than "make do" with what someone else has decided I needed. So I was glad to find a way to write programs to overcome Qshell's limitations. I hope that the ability to write RPG programs to run in Qshell excites you as much as it does me. I am just getting started. I will continue to work on the stdio service program, and I have several more projects in mind to tackle as soon as I can find the time. Be aware that these programs are new and I haven't used them in production yet. Use them at your own risk. If you find bugs or have suggestions for improvement, please email me at tholt@itjungle.com.
|
Editors
Contact the Editors |
|
Last Updated: 11/21/02 Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved. |