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. 
 
  | 

							 
								
					