Last week I wrote about a new way in debug of changing the value returned from a procedure in a RPG program. Having had some time to look around I have found some other of these special debug features. These others have been around for several releases, therefore, if you are not on IBM i 7.4 or 7.3 with the latest Technology Refreshes you might be able to use some or all of them.
These "special names for debugging" are:
- _QRNU_NULL_name: See or change null indicator for a variable
- _QRNU_TABI_name: See or change the index of a RPG table
- _QRNU_DSI_name: See or change index of multiple occurrence data structures
- _QRNU_RETVAL_name: See change value returned from a procedure
- _QRNU_XMLSAX: View names of the associated with the events for the XML-SAX operation code
_QRNU_NULL_name: See or change null indicator for a variable
It has always bugged me that I cannot see the value of a null indicator for a variable or field when I am in debug. This special values allows me to do that, and to change it if I want too.
Example program:
01 **free 02 ctl-opt alwnull(*usrctl) ; 03 dcl-s wkVar char(3) inz('A') nullind ; 04 %nullind(wkVar) = *on ; 05 %nullind(wkVar) = *off ; 06 *inlr = *on ; |
Line 1: My RPG is always free!
Line 2: As I am going to be playing with nulls I need this control option.
Line 3: My variable definition, I have defined it with its own null indicator using the NULLIND keyword.
Line 4: To make a variable null I turn on the null indicator.
Line 5: To change the variable to not be null I turn off the null indicator.
As I mentioned above these "special names" can only be used in debug. When I started debug with this program I added breakpoints at:
- Line 5
- Line 6
At line 5 even though the variable is null it contains the value I initialized it with:
ev wkvar WKVAR = 'A ' |
The only way I can tell that the variable is null is by using _QRNU_NULL + the variable's name. For example:
ev _qrnu_null_wkvar _QRNU_NULL_WKVAR = '1' |
Onto the next breakpoint. Having made the variable not null it is no surprise that the "special value" tells me the variable is not null.
ev _qrnu_null_wkvar _QRNU_NULL_WKVAR = '0' |
I can even change the null indicator using the following:
ev _qrnu_null_wkvar = '1' _QRNU_NULL_WKVAR = '1' = '1' |
What happens if I want to do this with a data structure:
01 **free 02 ctl-opt alwnull(*usrctl) ; 03 dcl-ds wkDS qualified ; 04 sf1 char(1) inz('1') nullind ; 05 sf2 char(1) inz('2') nullind ; 06 end-ds ; 07 %nullind(wkDS.sf1) = *on ; 08 *inlr = *on ; |
Line 3 – 6: My data structure definition. Notice that both the subfields have been defined with null indicators.
Line 7: Turn on the null indicator for the first subfield.
I add the break point at line 8. I can see the null indicators for the subfields in the data structure that have null indicators:
ev qrnu_null_wkds EVAL _qrnu_null_wkds _QRNU_NULL_WKDS.SF1 = '1' _QRNU_NULL_WKDS.SF2 = '0' |
Let me turn on the indicator for the second subfield:
ev qrnu_null_wkds.sf2 = '1' EVAL _qrnu_null_wkds.sf2 = '1' _QRNU_NULL_WKDS.SF2 = '1' = '1' |
Now I can both the indicators are null:
ev qrnu_null_wkds EVAL _qrnu_null_wkds _QRNU_NULL_WKDS.SF1 = '1' _QRNU_NULL_WKDS.SF2 = '1' |
This is very useful, I will be using this a lot.
_QRNU_TABI_name: See or change the index of a RPG table
Another thing that is hard to find out in a RPG program what is the current index of a table, not a SQL table... you know the ones at the bottom of your RPG programs.
01 **free 02 dcl-s Table1 char(2) dim(5) ctdata ; 03 *inlr = *on ; 04 ** 05 1 06 2 07 3 08 4 09 5 |
Line 2: Definition of my table.
Lines 4 – 9: The table.
The debug break point is at line 3.
If I do the following debug statement I am looking at the first table element as that is the default:
ev table1 EVAL table1 TABLE1 = '1 ' |
If I want to see what is in all of the table I would do this:
ev table1(1..5) EVAL table1(1..5) TABLE1(1) = '1 ' TABLE1(2) = '2 ' TABLE1(3) = '3 ' TABLE1(4) = '4 ' TABLE1(5) = '5 ' |
If I only wanted to see what was in the third element of the table I would:
ev table(3) EVAL table1(3) TABLE1(3) = '3 ' |
The table's index is still set to the first table element. If want to change the index I would:
ev table1 = %index(3) EVAL TABLE1 = %index(3) TABLE1 = %INDEX(3) = 3 ev table1 TABLE1 = '3 ' |
I can also see which table element the index is pointing at using:
ev _qrnu_tabi_table1 EVAL _qrnu_tabi_table1 _QRNU_TABI_TABLE1 = 3 |
I could also change the index's position using:
ev _qrnu_tabi_table1 = 5 EVAL _qrnu_tabi_table1 = 5 _QRNU_TABI_TABLE1 = 5 = 5 ev table1 EVAL table1 TABLE1 = '5 ' |
Another useful trick I will be using.
_QRNU_DSI_name: See or change index of multiple occurrence data structures
Let me start by saying that you cannot code multiple occurrence data structures in free format RPG definitions. They have been superseded by data structure arrays. Therefore my example has to use fixed format definitions:
01 D wkMODS DS occurs(10) 02 %occur(wkMODS) = 5 ; 03 *inlr = *on ; |
Line 1: Definition for the MODS, Multiple Occurrence Data Structure.
Line 2: Set the data structure to the fifth occurrence.
The breakpoint is at line 3. I can see which occurrence the data structure is positioned to using:
ev _qrnu_dsi_wkmods _QRNU_DSI_WKMODS = 5 |
I can also change the occurrence:
ev _qrnu_dsi_wkmods = 3 EVAL _qrnu_dsi_wkmods = 3 _QRNU_DSI_WKMODS = 3 ev _qrnu_dsi_wkmods _QRNU_DSI_WKMODS = 3 |
Fortunately I do not encounter MODS that often so I might use this occasionally.
_QRNU_XMLSAX: View names of the associated with the events for the XML-SAX operation code
As I have not written about the XML-SAX I do not want to turn this post into that article.
When I do write about it I will try to remember to include this.
You can learn more about this from the IBM website:
This article was written for IBM i 7.4, and should work for some earlier releases too.
Thank you for
ReplyDeletethanks a lot
ReplyDeleteThanks very much! This is helpful.
ReplyDeleteJust I was searching an error with an array and this timely article helped me. Thanks Simon
ReplyDelete