Odds and Ends
May 1, 2013 Ted Holt
It’s been awhile since we had an issue of odds and ends. Today seems like a good day for it. I hope you find something of benefit here.
I tried to use the sed command in a CL program to replace [ with [n (newline). I tried many ways to get it to work. I finally gave up and used tr to translate from [ to n. I was really hoping to keep the bracket.
When running Qshell commands in a CL procedure, how can you force a continuation line for a sed command? How can you insert a newline character in CL Qshell commands?
When using the tr command, can you translate from one character to two (i.e. [ to [n)?
The tr command translates one for one, so no, it won’t replace one character with two.
In an interactive Qshell session, you can press the Enter key to place a new line character into a sed command. Here’s how to replace the right bracket with a right bracket and new line character in an interactive session.
sed -e 's:]:] :g' wyatt.txt
In a CL procedure, embed a hexadecimal 25 character in the string.
dcl &QshellCmd *char 80 dcl &EndOfLine *char 1 value(x'25') dcl &Quote *char 1 value('''') chgvar &QshellCmd value(+ 'sed -e' *bcat &Quote *cat 's:]:]' *cat + &EndOfLine *cat ':g' *cat &Quote *bcat + 'wyatt.txt >output.txt') qsh cmd(&QshellCmd)
At least, X’25’ works on my system. I don’t know whether that character works for all CCSIDs or not.
If your input is:
line 1]line 2]line 3]
Your output will be:
line 1] line 2] line 3]
I totally agree with the concept of naming constants/literals. I have a minor nit to pick on your example. A good programming rule is to use multiplication instead of division whenever possible. Instead of dividing by 2.2046, multiply by 0.453592.
Thanks, David. I agree, and I typically do use multiplication instead of division. I’ve heard for years that the computer can multiply a lot faster than it can divide.
I asked Barbara Morris, of the RPG compiler team, if she had any more information, and she was kind enough to respond. You can see what she had to say about the matter by visiting the RPG Café.
I know how to retrieve an RPG program’s name from the program status data structure and how to make a CL program retrieve its own name. I’ve changed jobs, and now I need to make a COBOL program retrieve its own name. Can you tell me how?
COBOL also has a program status data structure, but the system only loads it when something goes wrong.
I suggest you begin by creating a copybook for the PSDS. Here’s the one I use.
01 PSDS. 02 PSDS-Program-name pic x(10). 02 PSDS-Program-library pic x(10). 02 PSDS-Module-name pic x(10). 02 PSDS-Statement-number pic x(10). 02 PSDS-Optimization-level pic x(06). 02 PSDS-Exception-msg-ID pic x(07). 02 PSDS-Job-name pic x(10). 02 PSDS-Job-number pic x(06). 02 PSDS-Job-type pic x(01). 02 PSDS-User-profile pic x(10). 02 PSDS-Timestamp pic x(14).
Tell the COBOL program to use the structure.
Environment division. Configuration section. Special-names. Program status is PSDS.
When your program begins to run, force an exception in order to load the structure. I do so by calling a program that doesn’t exist.
Call 'DUMMY$PGM$' on exception continue end-call
I am trying to write a REXX procedure (a new experience for me), and I want to make it run a Retrieve Job Attributes (RTVJOBA) command. According to the message CPD0001, which I can see if I type RTVJOBA on a command line and press F4 to prompt, RTVJOBA is allowed in REXX procedures. How do I load return values into REXX variables?
You must add an ampersand to the beginning of each variable name in the CL command, like this:
'RTVJOBA JOB(&xJOB) USER(&xUSER) NBR(&xNbr)' say xJob xUser xNbr
Notice that the REXX code itself does not include the ampersands.
I much prefer the iSeries System Debugger to the green-screen version, but the locals window is hard to use in a large program with a lot of structures and variables. I miss the eval command.
You can still use the eval command. Open the Console pane, which is one of the tabs in the same group with the Locals tab. (See Figure 1.) The command line there supports commands such as break, eval, and qual. See the help text for the console pane for more information.
Figure 1. (Click graphic to enlarge.)
In response to your article, When Who Did What, a little nugget you might find useful is knowing which program performed the I/O. There’s a function called “GuiltyPgm” in the Inuendo open source that looks upward in the job stack from a specified starting point (in this case, your trigger program name) until it finds a reasonably named program object that should represent the application program responsible for the I/O.
It’s in the service program WHODUNNIT. There’s an RPG, a CPY and a SRV source component. I’ve recently made the source available in zip file as well. Visit http://inuendo.us for more information.
Let’s end this edition of Four Hundred Guru with a few miscellaneous tips and comments.
Here’s a tip for those (like me) whose typing still has room for improvement. I created proxy commands for CL commands that I commonly misspell. For instance, while I should type STRPDM, Enter, and 3, in that order, I have a habit of typing STRPDM, 3, and Enter, so I created a proxy command call STRPDM3.
CRTPRXCMD CMD(QGPL/STRPDM3) TGTCMD(STRPDM)
It takes me to the PDM menu. I still have to type option 3 again, of course, but at least I don’t have to deal with the error and redo the STRPDM command.
If you’re looking for old IBM manuals, you might try trailing-edge.com, a site I stumbled upon recently.
Finally, you can toggle a numeric variable between two values by subtracting it from the sum of those values.
To toggle variable SWITCH between zero and one, do this:
SWITCH = 1 - SWITCH
To toggle between one and negative one:
SWITCH = 0 - SWITCH
To toggle between two and three:
SWITCH = 5 - SWITCH
You get the idea. Does anybody have a use for this technique?