How To Print a Pointer Value
November 3, 2010 Ted Holt
|
Over the past few months I’ve been working on more articles dealing with the use of pointers in RPG programs. While I was working on my demo programs, I ran into a little snag while verifying that everything was working correctly. Let me tell you what I ran into and how I got around it. I wanted to double-check the value of all the pointer variables. In the interactive green-screen debugger, which I was using, seeing the value of a pointer is no problem. Place the cursor on the pointer variable name and press F11, or use the EVAL command. The debugger displays the pointer’s value in hexadecimal. But I don’t always want to step through a program pressing F11. Another favorite technique I use is to write miscellaneous information to a spool file, which I can then read to track the behavior of a program (or module). So how do you print the hex representation of a pointer? You can’t put the pointer in printer file DDS or O specs. (DDS has no pointer type. Put a pointer in O specs and you’ll get error RNF7601.) I ended up writing a function subprocedure that, given a pointer, builds a string of hex digits, the same string you see when you press F11 in the debugger. I call it PtrToHex (Pointer to Hexadecimal), and that’s what I want to share with you today. First, here’s the command to create a printer file for the debugging trail. CRTPRTF FILE(xxx/DEBUGPRTF) Of course, you can use QSYSPRT or some other program-described printer file if you prefer. Here’s a short program that reads QIWS/QCUSTCDT, allocating memory for each record and printing the pointer value in hex for each allocation.
/define debugging
H dftactgrp(*no) actgrp(*new)
H option(*srcstmt: *nodebugio)
FQCustCdt if e disk
/if defined(debugging)
FDebugPrtf o f 132 printer
/endif
D gPtr s *
/if defined(debugging)
D DbgPrtLine ds 132
/endif
D PtrToHex pr 16a varying
D inPtr *
D inSize 5u 0 value options(*nopass)
/free
*inlr = *on;
dow '1';
read qcustcdt;
if %eof();
leave;
endif;
gPtr = %alloc(20);
/if defined(debugging)
DbgPrtLine = LstNam + ' ' + PtrToHex (gPtr);
write DebugPrtf DbgPrtLine;
/endif
// do other stuff
dealloc gPtr;
enddo;
return;
/end-free
P PtrToHex b
D pi 16a varying
D inPtr *
D inSize 5u 0 value options(*nopass)
D** locals
D DS ds
D Ptr
D Num 20u 0 overlay(DS: 9)
D Size s like(inSize)
D MaxSize s like(inSize)
D MaxPtrAddrSize c const(16)
D HexString s 16a varying
D Digits s 16a inz('0123456789ABCDEF')
D Number s 20u 0
D Rem s 5u 0
D Base c const(16)
/free
Ptr = inPtr;
Number = Num;
if Number = *zero;
return '*NULL';
endif;
select;
when %parms()< 2;
MaxSize = MaxPtrAddrSize;
when inSize = *zero or inSize > MaxPtrAddrSize;
MaxSize = MaxPtrAddrSize;
other;
MaxSize = inSize;
endsl;
dow Size < MaxSize;
Rem = %rem(Number: Base);
HexString = %subst(Digits:Rem+1:1) + HexString;
Number = %div(Number: Base);
Size += 1;
enddo;
return HexString;
/end-free
P e
Here’s the report. Henning E1D840C14A002000 Jones E1D840C14A002030 Vine E1D840C14A002060 Johnson E1D840C14A002090 Tyron E1D840C14A0020C0 Stevens E1D840C14A0020F0 Alison E1D840C14A002120 Doe E1D840C14A002150 Thomas E1D840C14A002180 Williams E1D840C14A0021B0 Lee E1D840C14A0021E0 Abraham E1D840C14A002210 PtrToHex has a second, optional parameter that I didn’t use in this example. When working on the demo programs, I realized that I only needed to see the last four or five hex digits of each pointer value. The second parameter tells the number of low-order digits to print. The default is 16. Notice that all the debug code is conditioned to the debugging compiler condition. If this were a real program, I would change the /DEFINE to /UNDEFINE before putting this code into production. If you use pointers in your programming, I hope you find the PtrToHex routine beneficial. If you don’t use pointers, you’re in for some fun! In the near future I will show you what I mean.
|

