DSPLY Sucks. QUILNGTX Rocks.

IBM i

Feb 27

AKA – writing a new DSPLY opcode that shows more than 52 characters

Using the DSPLY opcode to quickly debug a program has long been a staple of us RPG keyboard whackers. The DSPLY operation lets us “display the data in a variable” onto the screen. Everyone uses this quick and dirty technique and everyone (and I mean everyone) swears at the ridiculous 52 character field limit on the DSPLY operation code.

What kind of idiot adds a neat little debugging tool to make RPG programmers happy… and then decides to limit it to the first 52 characters of the debugging data?

#someDisgruntledFiftyTwoYearOldIbmProgrammerProbably

I dont think that hashtag will ever go viral.

A few months ago, I knocked up a little blog waffling about the “QUILNGTX” API that lets us quickly display any old program field in a nice dynamic window on the screen.

So, why dont we just use this same technique for a displaying debug data on the screen?

The QUILNGTX API lets us popup windows with no DSPF coding

You can add an RPG ILE procedure to your program (or preferably a commonly used service program) that looks like this:

// +---------------------------------------------------------------+
// | Display String of Data in Popup IBM i Window +
// +---------------------------------------------------------------+
// The Display Long Text (QUILNGTX) API displays a pop-up window containing
// the string of text that is passed to it.
// This API may not be used to display text that is bidirectional right2left. 
//
// Required Parameter Group
// Text string
// INPUT; CHAR(*)
// The text string that is to be displayed in a pop-up window.
// Length of text string
// INPUT; BINARY(4)
// The length of the text string, in bytes. The value must be greater
// than zero and less than or equal to 15 728 640.
// Message ID
// INPUT; CHAR(7)
// The specified message ID of the panel title text that will be retrieved.
// If the message ID is not found in the specified message file, the message
// ID will be displayed at the top of the panel as the title. If the message
// ID is blank, the title for the panel is blank.
// Qualified message file name
// INPUT; CHAR(20)
// Error code
// I/O; CHAR(*)
//
// Error Messages
// Message ID Error Message Text
// CPF3C90 E Literal value cannot be changed
// CPF6A4C E At least one parameter value is not correct. Reason code is &1
// CPF9871 E Error occurred while processing 
RPG Code Snippetdcl-proc dspWindow export;
 dcl-pi dspWindow;
 p_Text varchar(8192) const;
 p_MsgId char(7) Options(*nopass:*omit);
 p_MsgFile char(21) Options(*nopass:*omit);
end-pi;

dcl-ds myApiError likeds(apierror);

dcl-pr QUILNGTX extpgm('QUILNGTX');
 *n char(8192) const; // MsgText
 *n int(10) const; // MsgLength
 *n char(7) const; // MessageId
 *n char(21) const; // MessageFile
 *n options( *omit: *varsize ) like( apierror ); // ErrorDS
 end-pr;

dcl-s MsgId like(p_MsgId);
dcl-s MsgFile like(p_MsgFile);

If %Parms = 1;
 MsgId = 'CPF9999';
 MsgFile = 'QCPFMSG';
Elseif %Parms = 2;
 MsgId = p_MsgId;
 MsgFile = 'QCPFMSG';
Elseif %Parms = 3; 
 MsgId = p_MsgId;
 MsgFile = p_MsgFile;
Endif ;

QUILNGTX ( p_Text
         : %Len(p_Text)
         : MsgId
         : MsgFile
         : myApiError
         );
 
end-proc;

So, that little procedure simply display a window on the screen showing the contents of a big long field that you send it.

How can we use this instead of the DSPLY opcode?

When I’m writing RPG I tend to build in a variable called $debug that can be turned *ON or *OFF at program init:

dcl-s $debug ind inz(*off); // run in debug mode

This works great for webservices because you can simply pass in the ?debug=1 to change this value to on.

It also works well for native #IBMi batch or screen IO programs which can updated to set the variable ($debug) to *ON which will then load extra data and do extra stuff.

You can simply turn it on using STRDBG or perhaps pull the debug value from a data area or perhaps recompile with a compile directive:

/if defined(DEBUGME)
   $debug = *on;
/endif

fresher_note: you would recompile your program using something like ‘CRTRPGMOD MODULE(RPGTHING) SRCFILE(QRPGLESRC) DEFINE(DEBUGME)’

shopping cart push it to the limits worst bad tattoos ugliest. 198x200 - DSPLY Sucks. QUILNGTX Rocks.Now that we have a variable called ‘$debug’ that defaults to *OFF we can simply have blocks of code that does extra stuff if $debug is ever *on:

A web-service RPG program might want to return the job details or SQL statement that is being processed:

if $debug;
  yajl_addChar('Job Name':psds.job);
  yajl_addChar('Job User':psds.jobuser);
  yajl_addChar('Job Number':psds.jobnumber);
  yajl_addChar('debug-SQLSTM':%trim(sqlstm));
  yajl_addChar('debug-fetchStartNumeric':%char(fetchStartNumeric));
  yajl_addChar('debug-fetchCountNumeric':%char(fetchCountNumeric));
 endif;

Or to get back on track and stop waffling… we might want to show some variables in a nice little window

if $debug;
  dspWindow ( %char(The_Variable_we_want_to_debug) );
 endif;

fresher_note: of we could construct a big variable containing lots of fields and show it.

Lets imagine we want to see the values of fields called alpha_name, numeric_age and date_of_birth.

We could create a field called $window_text like this:

dcl-s $windows_text varchar(8192); // field to be populated each time we display the window

Then we could so something like this:

if $debug;
   $window_text = 'alpha_name(' + %trim(alpha_name) + '),';
   // now add some more data to this field (just to show other technique)
   $window_text = $window_text + ' numeric_age(' + %char(numeric_age) + '),' +
                 'dateofbirth(' + %char(date_of_birth) ').';
   dspWindow ( $window_text );
 endif;

Now each time we hit that debug statement, if the value $debug=*on a window will be displayed showing you the data values and let you press ENTER to continue.

All the size of the data… not the just the bloody annoying first 52 characters of it.

Who decided we only want to see the first 52 characters anyway?

Numpties….