Easy Printing from CL, Take Two
August 30, 2016 Hey, Ted:
When I read your statement that CL cannot write to printer files, I immediately thought, “It can’t? Then what have I been doing for the last couple of decades?” I looked through the article and saw that it didn’t mention my most used method, and I wondered how it was missed.
Tom takes advantage of one of the best features of ILE, namely the ability to bind routines written in different languages to form one program. The non-CL procedure that he included is the printf function, which is well-known to C programmers. Even though printf produces stream output, IBM i can make it write record output as well.
Here’s Tom’s program to list disabled user profiles.
/* + CRTCLMOD MODULE( mylib/LSTUSRDSE ) + SRCFILE( mylib/QCLTSRC ) + SRCMBR( LSTUSRDSE ) + LOG( *NO ) + + CRTPGM PGM( mylib/LSTUSRDSE ) + BNDDIR( QC2LE ) + ACTGRP( *NEW ) + USRPRF( *OWNER ) + */ pgm ( + ) dcl &msgdta *char 128 dcl &NL *char 1 value( x'15' ) dcl &x00 *char 1 value( x'00' ) dcl &rc *int dcl &eofUSRDSE *lgl value( '0' ) /* Compile over the IBM-supplied model file... */ dclf QADSPUPB /* List user profiles to a temporary file... */ dspusrprf *ALL output( *OUTFILE ) outfile( QTEMP/LSTUSRDSE ) /* ...and point the compiled file to our temporary one... */ ovrdbf QADSPUPB tofile( QTEMP/LSTUSRDSE ) /* Set a trivial page heading... */ chgvar &msgdta ( + 'List Disabled Profiles' *cat + &NL *cat + &NL *cat + &x00 + ) /* Assign our printed output to QPRINT... */ ovrdbf STDOUT + tofile( QPRINT ) + ovrscope( *JOB ) + share( *YES ) /* Print our trivial heading... */ callprc 'printf' ( + &msgdta + ) + rtnval(&rc ) /* Now loop through our temporary file until EOF... */ dountil (&eofUSRDSE ) rcvf monmsg ( cpf0864 ) exec( do ) chgvar &eofUSRDSE '1' iterate enddo /* If this one is '*DISABLED', print a line... */ if ( &UPSTAT *eq '*DISABLED' ) do chgvar &msgdta ( + &UPUPRF *cat + ' ' *cat + &UPTEXT *cat + &NL *cat + &x00 + ) callprc 'printf' ( + &msgdta + ) + rtnval(&rc ) enddo enddo /* Clear away our override... */ dltovr STDOUT lvl( *JOB ) /* ...and get out of here... */ return endpgm
Let’s look at the second printf in more detail.
chgvar &msgdta ( + &UPUPRF *cat + ' ' *cat + &UPTEXT *cat + &NL *cat + &x00 + ) callprc 'printf' ( + &msgdta + ) + rtnval(&rc )
The text to print begins with the contents of two variables with an intervening space. The &NL (new line) variable marks the end of a print line. The &X00 variable signals the end of the string.
The report looks like this:
List Disabled Profiles JNAZIUM Jim Nazium PWOGG Polly Wogg SMANDER Sally Mander
My thanks to Tom for showing us how to use a tool that I suspect lies dormant on most IBM i systems.
Ted Holt welcomes your comments and questions. Email him through the IT Jungle Contacts page.