At first glance, adding line commands may not seem useful. But think about how often you need to do any of the following when you are editing a program: print just a selected block of code, change the code from uppercase to lowercase, actually copy in /COPY code because you can't remember the field names, clear out the first five columns of the source lines, clear out the comment area of C specs, etc. All of these things can be done with user-defined line commands.
IBM's documentation of how to create these user-defined line commands is fairly detailed and easy to follow. You can find the PDF version of the SEU documentation at the IBM iSeries Information Web site. I have included here a simple exit program that will process line commands to change the text from uppercase to lowercase (LC or LCC) or lowercase to uppercase (UC or UCC). This is a handy tool for when you are converting from "old" RPG to "new" RPG (I have given up trying to determine if it's RPG III, RPG IV, or RPG ILE, but I'm sure you get the idea).
The program I have included at the end of this tip is based on a C program that was written by one of my cohorts, Philip Read. The C version is longer and more tedious because string handling is not as easy in C as it is in RPG.
The parameters passed to the exit program by SEU are pointers to a user space in QTEMP called QSUSPC. The first parameter points to the beginning of the user space and the header information. The second points to the return/output information section of the user space. The last points to the beginning of the source code lines. For specific information about fields in the user space, check out the SEU documentation.
The first pointer is really the only pointer you need because all the other fields and source code lines can be accessed by using offsets from this pointer. The offset to the return/output information is not necessary because it lies just after the header information. That being the case, I have included the return/output data in the data structure defined for the header. The offset to the source code lines is calculated using the pointer to the first source code line that is passed from SEU. From that first line (which can also be calculated as an offset from the header pointer), you can calculate the pointer to all the other source lines by using the length of the source records (hdRecLen) and the length of the source code header information as shown in the pseudo-code below:
Pointer to rec. = pointer to 1st rec. + ((source rec. length + source header length)*(source rec.# - 1))
Once you get the hang of stepping through the user space using pointers, the rest of the program is very simple.
There are some oddities to watch out for or at least be aware of. First, SEU will load into the user space all source lines--from the first "unidentified line command" to the last. This means that if you are using LC on line 1 and LC on line 18, then all the lines from 1 to 18 will be placed in the user space. Not a big deal because only the two lines that have the LC in the line command area should be updated (if you write your program correctly). But SEU does not recognize that the other lines have not been updated. So what you will see is that all the lines between 1 and 18 will have their SEU sequence number and last update date updated (say that three times fast). This can be a problem if you use the last updated date for change tracking.
Also, even when you use a line command on only a single line, SEU will load the user space with that line and the next line. So you will always have at least two lines of source code in the user space. This can be a problem when you are setting the number of lines to be output (hdRecsOut). My first inclination was to simply "Z-ADD" the number of lines input to the number of lines output. This was not a good, idea but you should try it just to see the results. Unless you are adding lines to your source member, then the output lines should be the number of input lines minus one.
Adding lines to your source code is a little tricky. You add the lines to the user space again using offsets. Don't forget to include the source line "header" information for each added line. If you are adding many lines, you may need to extend the user space (use the QUSCUSAT API). You will also need to track how many lines you are adding and adjust the number of lines to output accordingly.
Once your program is written, you must let SEU know that it should use that program to process line commands. This can be done two ways. One way is to start editing a source member and use F13 to get to the Change Session Defaults display. From there, page down and enter your exit program name and library at the User Exit Program prompt. This will change your exit program for the current session and all future sessions. However, if you want to have the exit program available to everyone, you will need to use the other way--the Work with Registration Information (WRKREGINF) command. When the WRKREGINF display appears, scroll through the entries until you find the QIBM_QSU_LCMD exit point. Use option 8 to add, remove, or display user-defined line command programs.
I have found the user-defined line commands to be very useful, and they have saved me a lot of time. I mentioned several possible applications for line commands. If you have others or think of others, please share them on the forums. I'm always interested in better ways to do things.
Jeff Olen is a member of the AS/400 development team at Gauss Interprise, a content management software company located in Irvine, California. He can be reached by email at
|
LATEST COMMENTS
MC Press Online