Writing Sample:
Club Tech Programming TIps Newsletter
*********** Club Tech iSeries Programming Tips Newsletter ***********
An AS400 Network Publication http://www.as400network.com
Home of NEWS/400 Magazine
Issue 41 March 29, 2001
Sponsored by Generic Software
ARCHIVE YOUR AS/400 REPORTS WITH SOQ FOR ONLY $599.
SAVE OUTPUT QUEUE (SOQ) not only archives spool files to any AS/400
tape device, but it can also manage (move, copy, delete, convert)
spool files by user name, job name, creation date, etc. For a 30-day
FREE trial, Contact Generic Software, Inc., at (800) 698-5669 or visit
http://www.genericsoftware.com/html/save_output_queue.htm .
******************************************************************
THIS WEEK:
> APIs by Example: Read/Write an IFS File Line in RPG IV
> APIs by Example: Read an IFS File Line in Cobol
> Data Area Editor Utility
> Poor Man's Cross-Reference
> Maximum Libraries in *LIBL to Change from 25 to 250
Featured Tip:
APIs BY EXAMPLE: READ/WRITE AN IFS FILE LINE IN RPG IV
This installment of "APIs by Example" offers sample RPG code showing
how to read a text line from an IFS file until a line terminator is
encountered, and also how to write a line to an IFS file.
The sample code consists of three RPG IV programs that create and read
three text files in QOpenSys to show how the APIs work. Here are the
programs:
CBX002A
Creates stream files /QOpenSys/access001.log and
/QOpenSys/access002.log.
CBX002B
Creates file /QOpenSys/access00x.log, reads the access001.log and
access002.log files, and appends them to access00x.log.
CBX002C
Reads access00x.log, then deletes the example stream files.
The sample RPG IV programs use seven C library functions, listed
below:
Open stream file (fopen)
Opens or creates the specified stream file. The access level required
is defined by the mode parameter and is followed by an optional
keyword parameter specifying various file attributes.
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.2.48
Read stream (fgets)
Reads characters from current stream position for the number of bytes
specified by the second parameter or until new-line character or end-
of-stream is encountered. The new-line character (x'25') is included
in the retrieved string.
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.2.42
Write stream (fputs)
Appends the string parameter to the current stream position. The
number of bytes written is returned.
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.2.51
Close stream (fclose)
Closes the stream pointed to by the FILE structure.
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.2.35
Delete stream file (remove)
Deletes the specified stream file.
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.2.136
Get error number (errno)
Retrieves the current value of the C runtime error number variable.
The errno function simply returns a pointer to a 4-byte integer.
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at702/9.1.2
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.3.1
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.3.2
Map error number (strerror)
Converts the error number variable to an error message string.
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.2.184
Below is the sample RPG IV code.
** Program: CBX002A
** Description: Create files used by IFS file API example.
** Compile: CRTBNDRPG ... DBGVIEW(*LIST)
**
**-- Control spec: -----------------------------------------------**
H Option( *SrcStmt ) DftActGrp( *No ) BndDir( 'QC2LE' )
**-- Global variables: -------------------------------------------**
D FILE_o s *
D String s 512a
D rc s 10i 0
D Idx s 5u 0
**-- Global constants: -------------------------------------------**
D FilNam_1 c '/QOpenSys/access001.log'
D FilNam_2 c '/QOpenSys/access002.log'
D LF c x'25'
**-- IFS stream file functions: ----------------------------------**
Dopen Pr * ExtProc( '_C_IFS_fopen' )
D * Value Options( *String )
D * Value Options( *String )
**
Dfgets Pr * ExtProc( '_C_IFS_fgets' )
D * Value
D 10i 0 Value
D * Value
**
Dfputs Pr 10i 0 ExtProc( '_C_IFS_fputs' )
D * Value Options( *String )
D * Value
**
Dclose Pr 10i 0 ExtProc( '_C_IFS_fclose' )
D * Value
**
**-- Mainline: ------------------------------------------------------
---**
**
**-- create file, set codepage (pc):
C Eval FILE_o = open( %TrimR( FilNam_1 )
C : 'w, codepage=850'
C )
**
C Eval rc = close( FILE_o )
**
C Eval FILE_o = open( %TrimR( FilNam_2 )
C : 'w, codepage=850'
C )
**
C Eval rc = close( FILE_o )
**
**-- open files, implicit conversion to job codepage:
C Eval FILE_o = open( %TrimR( FilNam_1 )
C : 'w'
C )
**
C If FILE_o <> *Null
**
C For Idx = 1 to 10
C Eval rc = fputs( 'Stream 1 line: ' +
C %Char( Idx ) +
C LF
C : FILE_o
C )
C EndFor
**
C Eval rc = close( FILE_o )
C EndIf
**
**-- open files, implicit conversion to job codepage:
C Eval FILE_o = open( %TrimR( FilNam_2 )
C : 'w'
C )
**
C If FILE_o <> *Null
**
C For Idx = 1 to 10
C Eval rc = fputs( 'Stream 2 line: ' +
C %Char( Idx ) +
C LF
C : FILE_o
C )
C EndFor
**
C Eval rc = close( FILE_o )
C EndIf
**
C Eval *InLr = *On
C Return
** Program: CBX002B
** Description: Read two files, and append them to a third new file.
** Compile: CRTBNDRPG ... DBGVIEW(*LIST)
**
**
**-- Control spec: ------------------------------------------------**
H Option( *SrcStmt ) DftActGrp( *No ) BndDir( 'QC2LE' )
**-- Global variables: --------------------------------------------**
D FILE_i s *
D FILE_o s *
D ErrTxt s 128a
D String s 512a
D rc s 10i 0
**-- Global constants: --------------------------------------------**
D FilNam_1 c '/QOpenSys/access001.log'
D FilNam_2 c '/QOpenSys/access002.log'
D FilNam_o c '/QOpenSys/access00x.log'
**-- Error identification: ----------------------------------------**
D errno Pr 10i 0
**
D strerror Pr 128a Varying
**-- IFS stream file functions: -----------------------------------**
Dopen Pr * ExtProc( '_C_IFS_fopen' )
D * Value Options( *String )
D * Value Options( *String )
**
Dfgets Pr * ExtProc( '_C_IFS_fgets' )
D * Value
D 10i 0 Value
D * Value
**
Dfputs Pr 10i 0 ExtProc( '_C_IFS_fputs' )
D * Value Options( *String )
D * Value
**
Dclose Pr 10i 0 ExtProc( '_C_IFS_fclose' )
D * Value
**
**-- Mainline: ----------------------------------------------------**
**
**-- create file, set codepage (pc):
C Eval FILE_o = open( %TrimR( FilNam_o )
C : 'w, codepage=850'
C )
**
C Eval rc = close( FILE_o )
**
**-- open files, implicit conversion to job codepage:
C Eval FILE_o = open( %TrimR( FilNam_o )
C : 'w'
C )
**
C Eval FILE_i = open( %TrimR( FilNam_1 )
C : 'r'
C )
**
C If FILE_i = *Null
C Eval ErrTxt = %Char( Errno ) + ': ' +
C Strerror
C Else
**
C Dow fgets( %Addr( String )
C : %Size( String )
C : FILE_i
C ) <> *Null
**-- copy file 1 to new file...
C Eval rc = fputs( %Str( %Addr( String
))
C : FILE_o
C )
C EndDo
**
C Eval rc = close( FILE_i )
C EndIf
**
C Eval FILE_i = open( %TrimR( FilNam_2 )
C : 'r'
C )
**
C If FILE_i = *Null
C Eval ErrTxt = %Char( Errno ) + ': ' +
C Strerror
C Else
**
C Dow fgets( %Addr( String )
C : %Size( String )
C : FILE_i
C ) <> *Null
**-- copy file 2 to new file...
C Eval rc = fputs( %Str( %Addr( String
))
C : FILE_o
C )
C EndDo
**
C Eval rc = close( FILE_i )
C EndIf
C Eval rc = close( FILE_o )
**
C Eval *InLr = *On
C Return
**
**-- Get runtime error number: ------------------------------------**
P Errno B
D Pi 10i 0
D sys_errno Pr * ExtProc( '__errno' )
**
D Error s 10i 0 Based( pError ) NoOpt
**
C Eval pError = sys_errno
C Return Error
**
P Errno E
**-- Get runtime error text: --------------------------------------**
P Strerror B
D Pi 128a Varying
D sys_strerror Pr * ExtProc( 'strerror' )
D 10i 0 Value
**
C Return %Str( sys_strerror( Errno ))
**
P Strerror E
** Program: CBX002C
** Description: Read merged file and clean up IFS example files.
** Compile: CRTBNDRPG ... DBGVIEW(*LIST)
**
**-- Control spec: ------------------------------------------------**
H Option( *SrcStmt ) DftActGrp( *No ) BndDir( 'QC2LE' )
**-- Global variables: --------------------------------------------**
D FILE_i s *
D String s 512a
D rc s 10i 0
D Idx s 5u 0
**-- Global constants: --------------------------------------------**
D FilNam_o c '/QOpenSys/access00x.log'
D FilNam_1 c '/QOpenSys/access001.log'
D FilNam_2 c '/QOpenSys/access002.log'
**-- IFS stream file functions: -----------------------------------**
Dopen Pr * ExtProc( '_C_IFS_fopen' )
D * Value Options( *String )
D * Value Options( *String )
**
Dfgets Pr * ExtProc( '_C_IFS_fgets' )
D * Value
D 10i 0 Value
D * Value
**
Dfputs Pr 10i 0 ExtProc( '_C_IFS_fputs' )
D * Value Options( *String )
D * Value
**
Dclose Pr 10i 0 ExtProc( '_C_IFS_fclose' )
D * Value
**
Dremove Pr 10i 0 ExtProc( '_C_IFS_remove' )
D * Value Options( *String )
**
**-- Mainline: ----------------------------------------------------**
**
C Eval FILE_i = open( %TrimR( FilNam_o )
C : 'r'
C )
**
C Dow fgets( %Addr( String )
C : %Size( String )
C : FILE_i
C ) <> *Null
C EndDo
**
C Eval rc = close( FILE_i )
**
C Eval rc = remove( %TrimR( FilNam_o
))
C Eval rc = remove( %TrimR( FilNam_1
))
C Eval rc = remove( %TrimR( FilNam_2
))
**
C Eval *InLr = *On
C Return
The above tip was written by Carsten Flensburg. For questions
regarding this tip, contact Carsten at mailto:flensburg@novasol.dk.
Short Takes:
1. APIs BY EXAMPLE: READ AN IFS FILE LINE IN COBOL
Simon Coulter offers a Cobol example showing how to read lines from an
IFS file at http://archive.midrange.com/cobol400-l/200010/msg00006.html .
2. DATA AREA EDITOR UTILITY
Lynne Noll has made available a utility to easily edit data areas. The
utility determines the attributes of the specified data area, then
loads the contents into the screen. You can then type over the
contents and press Enter to make the changes permanent.
The utility can edit character, logical, and decimal data areas. It
can't update character data areas containing embedded packed numbers
or other unprintable characters, or numeric data areas with more than
15 positions to the left of the decimal. If there are decimal
positions to the right of the decimal, it can support up to 10
positions to the left and 5 to the right of the decimal.
The utility consists of a CL program, ITUDTAC, an RPG IV program, a
DSPF file, and a help file. You can download the utility from
http://www.as400network.com/noderesources/code/clubtechcode/DataAreaEdit.zip .
3. POOR MAN'S CROSS-REFERENCE
In the February 28 issue, I suggested the use of commercial utilities
to show a list of programs used by a particular file. Many readers
suggested a quick-and-dirty method of providing that information. Most
importantly, the method is free.
While there is no single command that gives you a list of all programs
used by a file, you can query the outfile from the Display Program
References (DSPPGMREF) command to give you this information. Here are
the steps:
a. Run the DSPPGMREF command specifying the name of your library, *ALL
for the program name, and a file name to receive the output:
DSPPGMREF PGM(YourLib/*ALL) OUTPUT(*OUTFILE) OBJTYPE(*ALL)
OUTFILE(YourOutLib/YourOutFile)
If you have multiple libraries, run the command again and change the
output member parameter from *REPLACE to *ADD.
b. Use Query/400 to select records where the WHFNAM field is equal to
your file name:
SELECT DISTINCT WHLIB, WHPNAM, WHTEXT FROM
YourOutLib/YourOutFile
WHERE WHFNAM='YourFileName'
ORDER BY WHLIB, WHPNAM
The above technique works, but it has its limitations. It won't list
files overridden with OVRDBF, it will show logicals but not the
physical file used by the logical, and it misses join OPNQRYs and DFUs
and programs hidden in library lists. That's why many programmers
recommend using a commercial documentation package, because they tend
to have far fewer limitations. Still, though, you can't beat the
price!
Thanks to all who sent in this suggestion: Bob Abbott, Paul J.
Crowley, Susan Deem, Ray Gernon, Nizar S. Hajjaj, Patrick Holthuizen,
Julie Hills, Michael Lynch, and Ron Wolford. Whew!
4. MAXIMUM LIBRARIES IN *LIBL TO CHANGE FROM 25 TO 250
The V5 release of OS/400, due out in May, changes the maximum number
of libraries in the user part of a library list (*LIBL) from 25 to
250. This will alleviate some problems that arose from the previous
limitations, but it may cause other problems with your existing code.
The new versions of the RTVJOBA (Retrieve Job Attribute) command and
the QUSRJOBI (Retrieve Job Information), QWCRTVCA (Retrieve Current
Attributes), QUSRSPLA (Retrieve Spool File Attributes), and QWDRJOBD
(Retrieve Job Description) APIs can now return more data than in
previous releases. Be sure that any applications you have that use one
of these interfaces provides enough room for 250 libraries in the
return value.
When you increase the size of a return variable, you can still safely
call V4R5 and earlier releases of these interfaces because there is no
harm in providing more space than needed. Just be sure that your own
application logic correctly handles however many library entries are
returned.
For more information, see:
http://www.ibm.com/eserver/iseries/developer/os400/lib_list.html
Thanks to Paul Conte for the above item
************************** ADVERTISING **************************:
NEW DOMINO GUIDE GOES BEYOND THEORY ON THE AS/400!
Domino R5 and the AS/400 is your concise guide to the multi-faceted
world of Domino. From electronic mail to workflow-based computing,
from database replication to document management, Domino R5 can do it
all -- if you know how to harness its power. Domino R5 and the AS/400
untangles the intricacies of Domino R5 with extensive information
about Domino's mail server capabilities, its dial-up connectivity
features, and Operations Navigator. To order this essential guide, go
to http://as400network.com/str/books/uniquebook2.cfm?NextBook=181 .
**************** ABOUT AS400 NETWORK NEWSLETTERS ****************:
Club Tech iSeries Programming Tips Newsletter and Club Tech iSeries
DB2 UDB & SQL/400 Newsletter are published on alternate Thursdays.
Club Tech Networking Tips Newsletter and Club Tech iSeries Systems
Management Newsletter are published on alternate Wednesdays.
NEWSWire/400 brings you daily AS/400 industry news, tech tips, product
news, and IBM announcements. Tech Observatory Newsletter is published
every other Tuesday and pinpoints Internet resources for iSeries 400
professionals. ChannelWire and Hot Blasts, published on alternate
Fridays, contain the latest news for IBM software developers and
resellers. All are *FREE OF CHARGE*!
|