With Version 1, Release 3 of OS/400, IBM provides and documents many openness application program interfaces (API). Some of the APIs allow you to access system information from within a program -- an improvement over prior methods such as reading information from system-defined OUTFILEs or copying spool files to database files, and then writing special programs to interpret those files.
Although the new version of OS/400 reportedly contains many additional APIs, we will consider the creation of parameter lists using externally described data structures that can be used with several of the List APIs. How to use these APIs is discussed in the program that accompanies this article.
If you have not already done so, you should read the companion article, "The Anatomy of a User Space," which begins on the facing page. As you will see in this program, the APIs use the user space to contain information, rather than database files. Also, you should obtain and apply PTF SF06260, which contains changes to the List Objects (QUSLOBJ) API. You will also want to print the cover letter that comes with the PTF. If this PTF is not applied you will be missing some of the formats of the QUSLOBJ API.
Organization
There are three sections to the code that accompanies this article: the parameter lists used to call the APIs and the data returned from an API; the List API Processor program; and a program to test the List API Processor. You will need all of the code on your system to compile and test the programs, so you should either key it in, download it through the Midrange Computing BBS, or get it from the ResourceLibrary.
Parameter Lists
There are five parameter lists that we'll use, shown in Figures 1 - 5. Each of these lists is used with a different API call.
These lists, and the information formats shown in Figures 6 - 10, are in the form of physical file definitions. I enter all of my parameter lists this way, then use the CRTPF command with the MBR parameter value of *NONE to create the physical file. These files are not meant to store any data, but by keeping the definition on the system as a file, we can reference it in our programs as an external definition.
In RPG programs, we can reference these parameter lists as externally described data structures; other languages use INCLUDE statements to bring the definition into the program. The advantages of using this technique are: 1) each program that uses the parameter lists is assured of using the same definition, in terms of the field attributes and lengths (also, the field names are the same in each program using the definitions); and 2) when a parameter list changes, the change is only required in one place (the definition); you then recreate the physical file and recompile the programs that use the definition. I strongly advise you to adopt this technique in your own programming.
The first parameter list is used to call the Create User Space API. Of special note here, and common to Figures 2 - 5, is the qualified space name field. This is a single field, 20 bytes long. The first 10 bytes must contain the name of the user space, left justified. Bytes 11 through 20 must contain the name of the library, starting in byte 11. This, of course, is the opposite of the way you are used to using qualified object names. Do not enter the "/" library qualifier in this field. Also, since the APIs call for a single field, don't try to call an API with two 10-character fields. The other fields for this parameter list are covered in the companion article, "The Anatomy of a User Space."
List Fields
Using the QUSLFLD parameter list when calling the List Fields API lets the API generate a list of fields in a specific record format in a file. The first field is LFQLSN, the user space that will contain the generated list. LFFMTN is the format that you want the API to use to generate information. For the List Fields API, there is only one format, FLDL0100. The information contained in format FLDL0100 is shown in 7. For each listed field in the file, the List Fields API fills in information as shown in 7.
Using the QUSLFLD parameter list when calling the List Fields API lets the API generate a list of fields in a specific record format in a file. The first field is LFQLSN, the user space that will contain the generated list. LFFMTN is the format that you want the API to use to generate information. For the List Fields API, there is only one format, FLDL0100. The information contained in format FLDL0100 is shown in Figure 7. For each listed field in the file, the List Fields API fills in information as shown in Figure 7.
Field LFOBLI is the qualified file name that you want to list. This follows the same rule as the user space name: a single field, 20 bytes long, with the file name left-justified in the first 10 positions, and the library name left- justified in the second 10 positions. Field LFRFMT is the name of the record format in the file that you want to list. Specify the name, even if the file has only one record format in it.
Use field LFOVRP to indicate if overrides are to be processed. This field has a value of 0 (no overrides) or 1 (process overrides). This controls whether or not an OVRDBF, for example, changes the information that you retrieve. If you select no overrides, then the file that you specify in LFOBLI is used. If you allow overrides, then the system will use an override if one is in effect for the file named in LFOBLI. A similar field is used on other List APIs.
List Members
The List Members parameter list, QUSLMBR, is similar to the List Fields list. The first field, LMQLSN, is the qualified user space.
In this API, there are two formats of member list data that may be requested. In the example, we call for format MBRL0200, shown in 8, so when the List Members API is called, we can put MBRL0200 into the LMFMTN field. If format MBRL0100 is requested, the only information returned in the format is the member name (only the first field, as shown in 8). The example program always asks for the format that returns the maximum information.
In this API, there are two formats of member list data that may be requested. In the example, we call for format MBRL0200, shown in Figure 8, so when the List Members API is called, we can put MBRL0200 into the LMFMTN field. If format MBRL0100 is requested, the only information returned in the format is the member name (only the first field, as shown in Figure 8). The example program always asks for the format that returns the maximum information.
Field LMOBLI is used to name the file and library that you want to list. Field LMMBRN contains a generic member name or *ALL. LMOVRP, override processing, is the same as described above.
List Objects
The List Objects parameter list, QUSLOBJ, is used to generate a list of objects in a library. The qualified space name (LOQLSN) is the first field.
You have many choices for the format to list (shown in 9). The example program always uses format OBJL0700, maximum information. Supposedly, there is a performance benefit to be gained by requesting less information. If performance is a consideration, study 9 to determine if your needs can be met with a less-extensive format. If this is possible, then substitute the name of that format for OBJL0700.
You have many choices for the format to list (shown in Figure 9). The example program always uses format OBJL0700, maximum information. Supposedly, there is a performance benefit to be gained by requesting less information. If performance is a consideration, study Figure 9 to determine if your needs can be met with a less-extensive format. If this is possible, then substitute the name of that format for OBJL0700.
LOOBLI, the qualified object name, is similar to what you would specify on the WRKOBJ or DSPOBJD commands. The object name can be a specific name, a generic name or *ALL. The library name can be a name, *LIBL, *USRLIBL, *CURLIB, *ALLUSR, or *ALL.
The object type, LOOTYP, can be a specific type (such as *PGM or *FILE), or *ALL.
As with the WRKOBJ or DSPOBJD commands, specifying *ALL for the library or object type causes the API to run much longer.
List Record Formats
The final API parameter list is QUSLRCD, used with the List Record Formats API. You will probably use this API as an intermediary, when you want to generate a field list. Recall that the List Fields API requires that you specify a record format name for the file that you are listing. By using APIs, first generate a list of files with the List Objects API, then for each file, generate the list of record formats. Work through the record format list, and call the List Fields API for each record format.
This parameter list contains standard fields: qualified user space name, format to use for the listing (see 10). Format RCDL0100 lists only the record format name, and the name of the file to list (LROBLI). This must be an exact file name, although you can use *LIBL or *CURLIB for the library name.
This parameter list contains standard fields: qualified user space name, format to use for the listing (see Figure 10). Format RCDL0100 lists only the record format name, and the name of the file to list (LROBLI). This must be an exact file name, although you can use *LIBL or *CURLIB for the library name.
Formats Returned From the APIs
Figures 6 - 10 show the formats returned from the APIs. Think of these as record formats, since the information returned from an API is in a certain order, in clearly defined fields. These formats are used as templates to get the information from the user space that the lists were generated into. The purpose of this program is to show you how to use the list APIs to generate the lists, and the Retrieve User Space API to get information back through these formats. This takes the place of using OUTFILES with their record formats.
The Retrieve User Space format, QUSRTVUS, is described in "The Anatomy of a User Space." This format is a listing of information that the List APIs generate into the user space as a header. As you will learn in the program, you must refer to the header when you are processing a user space generated by a List API. When the APIs change, as they may in future releases, you can simply change the parameter lists and formats, and recompile the programs; the logic for accessing the user space will remain the same. This is in contrast to the direct method of accessing the user space based upon an absolute position within the space. If you go to the trouble of determining specific from and through positions within a user space, there is no guarantee that those positions will be valid in subsequent releases.
The other formats are self-explanatory. They enumerate the information that you can expect to get back from the List APIs. For the multiple format lists, I have adopted a convention of using the second character of the field name as the format number. So, for example, if I were to create format OBJL0300 for the QUSLOBJ (List Objects API), I would rename fields O7ONAM through O7RS02 as O3ONAM through O3RS02.
If you take a few minutes to study the information provided with the List APIs, you will see that you get the same information as you would from the OUTFILES, printed listings or displays that are provided with commands.
The List API Processor
The List API Processor program shown in 11 performs the following tasks: 1) It creates a user space with a unique name in QTEMP, and fills it with information for the type of list requested; 2) It returns the next entry to your calling program from the requested list; and, 3) It allows you to delete the user space when no longer needed.
The List API Processor program shown in Figure 11 performs the following tasks: 1) It creates a user space with a unique name in QTEMP, and fills it with information for the type of list requested; 2) It returns the next entry to your calling program from the requested list; and, 3) It allows you to delete the user space when no longer needed.
Four types of lists may be requested: objects, members, record formats and fields. As previously mentioned, some of the list requests imply that you already have information. For example, to get a record format list, supply the name of the file. To get a field list, supply the name of the file and the record format. Depending upon the type of application created, you may need to call the List API Processor several times in succession. This does not cause a problem, since you specify when you want a new user space and list created, and the type of list to create. Several user spaces, filled with lists, may be active simultaneously.
Component Overview
To understand the List API Processor, you should be familiar with the parameter lists and formats described above. These are referenced as externally described data structures in the program; you can locate them in the I-specs. Notice that there are no file specifications used in the program; all of the processing is done through calls to the APIs, which return information to the data structures.
The main routine starts with the parameters passed to this program. The first parameters are the Requested Operation, Return Code and Requested List. The Requested Operation is C to create and fill a new user space, N to return the next entry from a user space and D to delete a user space. This parameter is used in conjunction with the Requested List parameter. The Requested List is F for a list of fields, M for a list of members, O for an objects list and R for a record format list. The Return Code is used to process a return next entry request. It is set to 0 if there are no more entries and 1 if an entry was found and returned.
Since we are processing four types of lists, the parameter list appears rather lengthy. The remaining eight parameters are the request parameters for each type of list and the format returned from each list. These parameters are associated with the externally described data structures.
The main routine examines the Requested Operation and passes control to a subroutine to perform the work.
When you create a new user space, the program formats a user space name as USHHMMSS, where US is the prefix and HHMMSS is the system time. This should be unique. If you are running an extremely fast AS/400 and calling the List API Processor faster than the system clock changes, then you may not generate a unique name with this scheme. After creating the name, the program deletes this user space in library QTEMP, if it is already there. It then creates the user space in QTEMP, initialized as 100,000 blanks. This size is extended as needed, up to 16 MB. Finally, the routine calls for the new user space to be filled with the requested list.
Listing Into the User Space
Four subroutines list into your user space; each calls a different List API. These subroutines are similar, so understanding any one of them will help you understand the others.
For example, the List Fields subroutine (#LSFLD) starts by assigning the user space name to a save field. The save field is used when you issue a delete user space request. This way, the program knows which of the user spaces you want to delete. The subroutine then formats the qualified user space name, as described above in the parameter discussion. Next, the format for listing information is given. You can change the format to any other valid format (valid for the particular API). At this point, the List Fields API is called.
Now if you examine the subroutine, a question should arise. We have formatted the qualified space name (LFQLSN) and the format name (LFFMTN), but what about the other parameters (LFOBLI, LFRFMT and LFOVRP -- the object/library, record format and override processing)? The answer is, those parameters are formatted in the calling program. The caller should know (in this case) which file you want to list fields from, and the name of the record format, and whether or not to allow overrides. The caller does not really need to know the name of the user space or the format used in the user space, so that is why those two parameters are set in the List API Processor program, rather than in the caller. Even though the caller does not set those fields (LFQLSN and LFFMTN), they are passed back to the caller, so you can use those values if you need to.
Before returning to the caller, the user space header is examined and some very important fields are set. Those fields are the list count, the size of each list entry and the offset to the start of the list. The list count is used to determine when all entries in the list have been processed. The size of each entry is needed when you call the Retrieve User Space API; this is the length of the format (shown in the compiled version as the end position of the externally described data structure). The offset to the start of the list is used with the Retrieve User Space API which instructs the API where in the user space to begin processing the list.
Finally, each list subroutine sets the current entry count for its list to zero.
Retrieving the Next Entry From the User Space
After creating and listing into a user space, your calling program will usually want to start retrieving list entries. Do this by setting the Requested Operation to N, Retrieve Next Entry, and the Requested List to F, M, O or R, to determine the type of list to retrieve. When the List API Processor is called, the program directs you to subroutine #NXTEN to return the next entry.
Understanding how any one of the returns works helps you understand the others. The first thing #NXTEN does is assume that you're not going to be successful; it sets the return code to 0. The calling program should check the return code (PMRTCD). Assume that when you get a 0, you are done with the list.
If processing a List Fields entry, the program increments the current List Fields counter, and compares that to the number of entries in the most recent List Fields user space. If under or at the limit, you can call the Retrieve User Space API to return information from the user space. Each call to QUSRTVUS passes four parameters.
The first parameter names the user space to retrieve from. In the List Fields case, the name is taken from the List Fields parameter list. If you don't change the field, it remains set to the most recent List Fields user space.
The second parameter is the starting position in the user space. Each list API puts a header into the user space, so don't start retrieving list information from position 1. The starting offset was set when the list was generated. If you are keeping several user spaces for the same API active simultaneously, maintain the starting offset values in the calling program.
The third parameter specifies the length of the data retrieved. The length must equal the length of the variable that you are receiving information into. In our program, this is the length of the associated externally described data structure. The receiver itself is the fourth parameter, which is the name of the externally described data structure.
After the call to the Retrieve User Space API, the list information for one entry is placed into the data structure, which is then available to the caller (since it is a parameter). The next starting position is set, and the return code is set to 1 to indicate that an entry was retrieved.
Deleting a User Space
When a list is completely processed and no longer needed, call the List API Processor to delete the user space. Set the Requested Operation to D and set the Requested List parameter to F, M, O or R, for the type of list to delete. When calling the List API Processor, control passes directly to subroutine #DLTSP, which deletes the user space from QTEMP.
Calling the List API Processor
The sample program shown in 12, Test List API Processor (TSTAPIR) shows how to call the List API Processor. This program calls the List API Processor to print a list of all objects in library QGPL.
The sample program shown in Figure 12, Test List API Processor (TSTAPIR) shows how to call the List API Processor. This program calls the List API Processor to print a list of all objects in library QGPL.
First, format the Requested Operation (PMRQOP) and the List Request (PMRQLS) parameters. These are set to create and fill a list -- the list being an object list. Next, fill in the object/library to list parameter, and then the type of objects to list. A call to the List API Processor gets things rolling. Run this program in debug mode and stop it after the call to the List API Processor, if desired. You can then examine library QTEMP, and see if you have a user space object there. Examine the contents of the user space with the DMPOBJ command.
Back in the program, the next step is to get each entry in the list. This is done with a simple DOUEQ loop, which retrieves each list entry. Before calling the List API Processor, set the Requested Operation to N, to retrieve the next entry, and the List Request to O, to work with the object list. After calling the List API Processor, check the return code (PMRTCD). If the return code is not 0 assume that the entry is empty, and print it.
Finally, format the parameters and call the List API Processor to delete the user space.
Uses of the List API Processor
Use the List API Processor wherever you now use system commands that list information into OUTFILES. As mentioned in "Real Life APIs" (Midrange Computing, June 1991), you will probably not notice any significant performance improvement with RPG APIs, as compared to using the OUTFILE technique. The benefit of using the List API Processor, though, is that you can call it from your programs without a great deal of preliminary steps. You can make adaptations of the List API Processor; for example, you may create four separate processors, one for each type of List API, rather than combine all four into one program.
A List API Processor
Figure 1 Create User Space parameters
A***************************************************************** A* QUSCRTUS: create user space request parms A***************************************************************** A R CRTUS TEXT('Create User Space rqst parms') A CSQLSN 20 TEXT('Qualified Space name ') A CSEXTA 10 TEXT('Extended attribute ') A CSINSZ 9B 0 TEXT('Initial size ') A CSINVL 1 TEXT('Initial value ') A CSPAUT 10 TEXT('Public authority ') A CSTEXT 50 TEXT('Text description ')
A List API Processor
Figure 10 Format for List Record Formats
A***************************************************************** A* QUSLRCD: format RCDL0200 A***************************************************************** A R RL0200 TEXT('QUSLRCD, format RCDL0200 ') A R2RFMT 10 TEXT('Record format name ') A R2FMID 13 TEXT('Format ID ') A R2RSV1 1 TEXT('Reserved ') A R2RECL 9B 0 TEXT('Record length ') A R2NBFL 9B 0 TEXT('Number of fields ') A R2TEXT 50 TEXT('Text ')
A List API Processor
Figure 11 List API processor RPG program
**************************************************************** * List API Processor **************************************************************** I 'DLTUSRSPC QTEMP/' C DLTSPC ICRTUS E DS##0003PF IRTVUS E DS##0010PF ILFLD E DS##0006PF ILMBR E DS##0007PF ILOBJ E DS##0008PF ILRCD E DS##0009PF IFL0100 E DS##0011PF IML0200 E DS##0012PF IOL0700 E DS##0013PF IRL0200 E DS##0014PF I DS I**************************************************************** I* Parms for Retrieve User Space (QUSRTVUS) I* I* RTQLSN - qualified User Space name I* RTSTRT - starting position I* RTLEN - length of receiver variable I* I* Other fields are for binary definition of I* Size of each entry, Offset of entry I**************************************************************** I 1 20 RTQLSN I B 21 240RTSTRT I B 25 280RTLEN I* I B 31 340LFSZEN I B 35 380LMSZEN I B 39 420LOSZEN I B 43 460LRSZEN I* I B 51 540LFOFLS I B 55 580LMOFLS I B 59 620LOOFLS I B 63 660LROFLS C *ENTRY PLIST C PARM PMRQOP 1 *RequestedOp C PARM PMRTCD 1 *ReturnCode C PARM PMRQLS 1 *RequestedList C PARM LFLD *Rqst:FldList C PARM LMBR *Rqst:MbrList C PARM LOBJ *Rqst:ObjList C PARM LRCD *Rqst:RcdList C PARM FL0100 *Data:FldList C PARM ML0200 *Data:MbrList C PARM OL0700 *Data:ObjList C PARM RL0200 *Data:RcdList C* C *LIKE DEFN RSCTLS LFCTLS *FldListCount C *LIKE DEFN RSCTLS LMCTLS *MbrListCount C *LIKE DEFN RSCTLS LOCTLS *ObjListCount C *LIKE DEFN RSCTLS LRCTLS *RcdListCount C* C PMRQOP CASEQ'C' #CRTNS *CreateNewSpace C PMRQOP CASEQ'N' #NXTEN *RtnNextEntry C PMRQOP CASEQ'D' #DLTSP *DeleteSpace C END C* C RETRN C/EJECT C**************************************************************** C* Create and fill a new User Space C**************************************************************** C* C #CRTNS BEGSR C* *************** C* C* ..format unique User Space name C* C TIME W06N0 60 C MOVELW06N0 W06 6 *WorkField C MOVEL*BLANKS USNAME 10 *UserSpaceName C 'US' CAT W06 USNAME C* C* ..delete user space, if existing C* C MOVEL'1' NEWFLG 1 *NEW flag C EXSR #DLTSP C MOVEL*BLANKS NEWFLG C* C* ..create user space C* C MOVEL*BLANKS CSQLSN *QualSpaceName C MOVEL*BLANKS CSEXTA *ExtendedAttr C MOVEL*BLANKS CSINVL *InitialValue C MOVEL*BLANKS CSPAUT *PublicAuth C MOVEL*BLANKS CSTEXT *Text C* C USNAME CAT 'QTEMP':2 CSQLSN *QualSpaceName C MOVEL'USRSPC' CSEXTA *ExtendedAttr C MOVEL'*ALL' CSPAUT *PublicAuth C Z-ADD100000 CSINSZ *InitialSize C* C CALL 'QUSCRTUS' 99 *99 on - error C PARM CSQLSN *QualSpaceName C PARM CSEXTA *ExtendedAttr C PARM CSINSZ *InitialSize C PARM CSINVL *InitialValue C PARM CSPAUT *PublicAuth C PARM CSTEXT *Text C* C* ..fill User Space for selected list C* C PMRQLS CASEQ'F' #LSFLD *List Fields C PMRQLS CASEQ'M' #LSMBR *List Members C PMRQLS CASEQ'O' #LSOBJ *List Objects C PMRQLS CASEQ'R' #LSRCD *List RcdFormat C END C* C ENDSR C/EJECT C**************************************************************** C* Delete User Space C**************************************************************** C* C #DLTSP BEGSR C* *************** C* C* ..if not NEW space, get space name from List Request C* C NEWFLG IFEQ *BLANKS *Not NEW C PMRQLS IFEQ 'F' *List Fields C MOVELUSFLD USNAME C END C* C PMRQLS IFEQ 'M' *List Members C MOVELUSMBR USNAME C END C* C PMRQLS IFEQ 'O' *List Objects C MOVELUSOBJ USNAME C END C* C PMRQLS IFEQ 'R' *List RcdFmt C MOVELUSRCD USNAME C END C END C* C* ..format command for DLTUSRSPC C* C Z-ADD26 W15N5 155 *WorkField C MOVEL*BLANKS W26 26 *WorkField C DLTSPC CAT USNAME W26 *DLTUSRSPC cmd C* C CALL 'QCMDEXC' 99 *99 on - error C PARM W26 *Command C PARM W15N5 *CommandLength C* C ENDSR C/EJECT C**************************************************************** C* Return next entry from User Space C**************************************************************** C* C #NXTEN BEGSR C* *************** C* C MOVEL'0' PMRTCD *ReturnCode C* C* ..retrieve User Space: List Fields entry C* C PMRQLS IFEQ 'F' C ADD 1 LFCUR *CurrentEntry C* C LFCUR IFLE LFCTLS C CALL 'QUSRTVUS' 99 *99 on - error C PARM LFQLSN *QualSpaceName C PARM LFOFLS *StartingPosn C PARM LFSZEN *ReceiverLength C PARM FL0100 *Receiver C* C ADD LFSZEN LFOFLS *Next StartPosn C MOVEL'1' PMRTCD *ReturnCode C END C END C* C* ..retrieve User Space: List Members entry C* C PMRQLS IFEQ 'M' C ADD 1 LMCUR *CurrentEntry C* C LMCUR IFLE LMCTLS C CALL 'QUSRTVUS' 99 *99 on - error C PARM LMQLSN *QualSpaceName C PARM LMOFLS *StartingPosn C PARM LMSZEN *ReceiverLength C PARM ML0200 *Receiver C* C ADD LMSZEN LMOFLS *Next StartPosn C MOVEL'1' PMRTCD *ReturnCode C END C END C* C* ..retrieve User Space: List Objects entry C* C PMRQLS IFEQ 'O' C ADD 1 LOCUR *CurrentEntry C* C LOCUR IFLE LOCTLS C CALL 'QUSRTVUS' 99 *99 on - error C PARM LOQLSN *QualSpaceName C PARM LOOFLS *StartingPosn C PARM LOSZEN *ReceiverLength C PARM OL0700 *Receiver C* C ADD LOSZEN LOOFLS *Next StartPosn C MOVEL'1' PMRTCD *ReturnCode C END C END C* C* ..retrieve User Space: List Record Formats entry C* C PMRQLS IFEQ 'R' C ADD 1 LRCUR *CurrentEntry C* C LRCUR IFLE LRCTLS C CALL 'QUSRTVUS' 99 *99 on - error C PARM LRQLSN *QualSpaceName C PARM LROFLS *StartingPosn C PARM LRSZEN *ReceiverLength C PARM RL0200 *Receiver C* C ADD LRSZEN LROFLS *Next StartPosn C MOVEL'1' PMRTCD *ReturnCode C END C END C* C ENDSR C/EJECT C**************************************************************** C* List Fields into User Space C**************************************************************** C* C #LSFLD BEGSR C* *************** C* C MOVELUSNAME USFLD 10 *Space: Fields C* C MOVEL*BLANKS LFQLSN *QualSpaceName C USFLD CAT 'QTEMP':2 LFQLSN *QualSpaceName C* C MOVEL*BLANKS LFFMTN *ListFormat C MOVEL'FLDL0100'LFFMTN C* C CALL 'QUSLFLD' 99 *99 on - error C PARM LFQLSN *QualSpaceName C PARM LFFMTN *ListFormat C PARM LFOBLI *Obj/Lib C PARM LFRFMT *RcdFormat C PARM LFOVRP *OverrideProc C* C* ..get count of User Space entries C* C MOVELLFQLSN RTQLSN *QualSpaceName C EXSR #RTVHD C* C Z-ADDRSCTLS LFCTLS *FldListCount C Z-ADDRSSZEN LFSZEN *FldListEntSize C Z-ADDRSOFLS LFOFLS *FldListOffset C Z-ADD0 LFCUR 50 *CurrentEntry C* C ENDSR C/EJECT C**************************************************************** C* List Members into User Space C**************************************************************** C* C #LSMBR BEGSR C* *************** C* C MOVELUSNAME USMBR 10 *Space: Members C* C MOVEL*BLANKS LMQLSN *QualSpaceName C USMBR CAT 'QTEMP':2 LMQLSN *QualSpaceName C* C MOVEL*BLANKS LMFMTN *ListFormat C MOVEL'MBRL0200'LMFMTN C* C CALL 'QUSLMBR' 99 *99 on - error C PARM LMQLSN *QualSpaceName C PARM LMFMTN *ListFormat C PARM LMOBLI *Obj/Lib C PARM LMMBRN *MbrName C PARM LMOVRP *OverrideProc C* C* ..get count of User Space entries C* C MOVELLMQLSN RTQLSN *QualSpaceName C EXSR #RTVHD C* C Z-ADDRSCTLS LMCTLS *MbrListCount C Z-ADDRSSZEN LMSZEN *MbrListEntSize C Z-ADDRSOFLS LMOFLS *MbrListOffset C Z-ADD0 LMCUR 50 *CurrentEntry C* C ENDSR C/EJECT C**************************************************************** C* List Objects into User Space C**************************************************************** C* C #LSOBJ BEGSR C* *************** C* C MOVELUSNAME USOBJ 10 *Space: Objects C* C MOVEL*BLANKS LOQLSN *QualSpaceName C USOBJ CAT 'QTEMP':2 LOQLSN *QualSpaceName C* C MOVEL*BLANKS LOFMTN *ListFormat C MOVEL'OBJL0700'LOFMTN C* C CALL 'QUSLOBJ' 99 *99 on - error C PARM LOQLSN *QualSpaceName C PARM LOFMTN *ListFormat C PARM LOOBLI *Obj/Lib C PARM LOOTYP *ObjType C* C* ..get count of User Space entries C* C MOVELLOQLSN RTQLSN *QualSpaceName C EXSR #RTVHD C* C Z-ADDRSCTLS LOCTLS *ObjListCount C Z-ADDRSSZEN LOSZEN *ObjListEntSize C Z-ADDRSOFLS LOOFLS *ObjListOffset C Z-ADD0 LOCUR 50 *CurrentEntry C* C ENDSR C/EJECT C**************************************************************** C* List Record Formats into User Space C**************************************************************** C* C #LSRCD BEGSR C* *************** C* C MOVELUSNAME USRCD 10 *Space: RcdFmts C* C MOVEL*BLANKS LRQLSN *QualSpaceName C USRCD CAT 'QTEMP':2 LRQLSN *QualSpaceName C* C MOVEL*BLANKS LOFMTN *ListFormat C MOVEL'OBJL0700'LOFMTN C* C CALL 'QUSLRCD' 99 *99 on - error C PARM LRQLSN *QualSpaceName C PARM LRFMTN *ListFormat C PARM LROBLI *Obj/Lib C PARM LROVRP *OverrideProc C* C* ..get count of User Space entries C* C MOVELLRQLSN RTQLSN *QualSpaceName C EXSR #RTVHD C* C Z-ADDRSCTLS LRCTLS *RcdListCount C Z-ADDRSSZEN LRSZEN *RcdListEntSize C Z-ADDRSOFLS LROFLS *RcdListOffset C Z-ADD0 LRCUR 50 *CurrentEntry C* C ENDSR C/EJECT C**************************************************************** C* Retrieve User Space header C**************************************************************** C* C #RTVHD BEGSR C* *************** C* C Z-ADD1 RTSTRT *StartingPosn C Z-ADD140 RTLEN *ReceiverLength C* C CALL 'QUSRTVUS' 99 *99 on - error C PARM RTQLSN *QualSpaceName C PARM RTSTRT *StartingPosn C PARM RTLEN *ReceiverLength C PARM RTVUS *Receiver C* C ENDSR
A List API Processor
Figure 12 Example RPG program using List Processor
**************************************************************** * Test List API Processor **************************************************************** FQSYSPRT O F 132 OF PRINTER ILFLD E DS##0006PF ILMBR E DS##0007PF ILOBJ E DS##0008PF ILRCD E DS##0009PF IFL0100 E DS##0011PF IML0200 E DS##0012PF IOL0700 E DS##0013PF IRL0200 E DS##0014PF C SETON LR C* C* ..get list of objects in a library C* C MOVEL'C' PMRQOP *RequestedOp C MOVEL'O' PMRQLS *ListRequest C '*ALL' CAT 'QGPL':6 LOOBLI *Obj/Lib C MOVEL'*ALL' LOOTYP *ObjType C* C EXSR #LSTAP C* C* ..print object list C* C EXCPTEXHDR C* C PMRTCD DOUEQ'0' *ReturnCode C MOVEL'N' PMRQOP *RequestedOp C MOVEL'O' PMRQLS *ListRequest C EXSR #LSTAP C* C PMRTCD IFNE '0' *Entry returned C ADD 1 COUNT 50 C EXCPTEXDTL C OF EXCPTEXHDR C END C END C* C EXCPTEXTOT C* C* ..delete User Space C* C MOVEL'D' PMRQOP *RequestedOp C MOVEL'O' PMRQLS *ListRequest C EXSR #LSTAP C/EJECT C**************************************************************** C* Call List API Processor C**************************************************************** C* C #LSTAP BEGSR C* *************** C* C CALL '##0004RG' 99 *99 on - error C PARM PMRQOP 1 *RequestedOp C PARM PMRTCD 1 *ReturnCode C PARM PMRQLS 1 *RequestedList C PARM LFLD *Rqst:FldList C PARM LMBR *Rqst:MbrList C PARM LOBJ *Rqst:ObjList C PARM LRCD *Rqst:RcdList C PARM FL0100 *Data:FldList C PARM ML0200 *Data:MbrList C PARM OL0700 *Data:ObjList C PARM RL0200 *Data:RcdList C* C ENDSR OQSYSPRT E 0103 EXHDR O 25 'List Objects using API' OQSYSPRT E 1 EXDTL O O7ONAM O O7LNAM + 2 O O7OTYP + 2 O O7EXAT + 2 O O7TEXT + 2 OQSYSPRT E 2 EXTOT O COUNT Z 5 O + 2 'ENTRIES'
A List API Processor
Figure 2 List Fields parameters
A***************************************************************** A* QUSLFLD: List fields request parms A***************************************************************** A R LFLD TEXT('List fields request parms ') A LFQLSN 20 TEXT('Qualified Space name ') A LFFMTN 8 TEXT('Format name ') A LFOBLI 20 TEXT('Object/library to list ') A LFRFMT 10 TEXT('Record format to list ') A LFOVRP 1 TEXT('Override processing ')
A List API Processor
Figure 3 List Members parameters
A***************************************************************** A* QUSLMBR: List DB file members request parms A***************************************************************** A R LMBR TEXT('List DB file mbr request ') A LMQLSN 20 TEXT('Qualified Space name ') A LMFMTN 8 TEXT('Format name ') A LMOBLI 20 TEXT('Object/library to list ') A LMMBRN 10 TEXT('Member name to list ') A LMOVRP 1 TEXT('Override processing ')
A List API Processor
Figure 4 List Objects parameters
A***************************************************************** A* QUSLOBJ: List Objects request parms A***************************************************************** A R LOBJ TEXT('List Objects parms ') A LOQLSN 20 TEXT('Qualified Space Name ') A LOFMTN 8 TEXT('Format name ') A LOOBLI 20 TEXT('Object/Library to list ') A LOOTYP 10 TEXT('Object type to list ')
A List API Processor
Figure 5 List Formats parameters
A***************************************************************** A* QUSLRCD: List record formats request parms A***************************************************************** A R LRCD TEXT('List record formats request ') A LRQLSN 20 TEXT('Qualified Space name ') A LRFMTN 8 TEXT('Format name ') A LROBLI 20 TEXT('Object/library to list ') A LROVRP 1 TEXT('Override processing ')
A List API Processor
Figure 6 Retrieve User Space parameters
A***************************************************************** A* QUSRTVUS: RETRIEVE USER SPACE GENERIC LAYOUT A***************************************************************** A R RTVUS TEXT('Retrieve User Space layout ') A RSRSCL 64 TEXT('Reserved for caller ') A RSHDSZ 9B 0 TEXT('Size of generic header ') A RSSTLV 4 TEXT('Structure level ') A RSFMTN 8 TEXT('Format name ') A RSPGM 10 TEXT('Pgm/API generating list ') A RSLSDT 13 TEXT('List written date/time ') A RSINST 1 TEXT('Information status ') A RSUSSZ 9B 0 TEXT('Total size of space used ') A RSOFIP 9B 0 TEXT('Offset - input parms ') A RSSZIP 9B 0 TEXT('Size - input parms ') A RSOFHD 9B 0 TEXT('Offset - header ') A RSSZHD 9B 0 TEXT('Size - header ') A RSOFLS 9B 0 TEXT('Offset - list data ') A RSSZLS 9B 0 TEXT('Size - list data ') A RSCTLS 9B 0 TEXT('Count - list data ') A RSSZEN 9B 0 TEXT('Size - each entry ')
A List API Processor
Figure 7 Format for List Data section
A***************************************************************** A* QUSLFLD: format FLDL0100 A***************************************************************** A R FL0100 TEXT('QUSLFLD, format FLD0100 ') A F1FLDN 10 TEXT('Field name ') A F1DTYP 1 TEXT('Data type ') A F1USAG 1 TEXT('Field usage ') A F1OBUF 9B 0 TEXT('Output buffer position ') A F1IBUF 9B 0 TEXT('Input buffer position ') A F1FLEN 9B 0 TEXT('Field length ') A F1DGTS 9B 0 TEXT('Number of digits ') A F1DEC 9B 0 TEXT('Number of decimals ') A F1TEXT 50 TEXT('Field text ') A F1EDTC 2 TEXT('Edit code ') A F1EDWL 9B 0 TEXT('Edit word length ') A F1EDWD 64 TEXT('Edit word ') A F1CHD1 20 TEXT('Column heading 1 ') A F1CHD2 20 TEXT('Column heading 2 ') A F1CHD3 20 TEXT('Column heading 3 ')
A List API Processor
Figure 8 Format for Retrieve Member Description
A***************************************************************** A* QUSLMBR: format MBRL0200 A***************************************************************** A R ML0200 TEXT('QUSLMBR, format MBRL0200 ') A M2MBRN 10 TEXT('Member name ') A M2STYP 10 TEXT('Source type ') A M2CRDT 13 TEXT('Creation date/time ') A M2LCDT 13 TEXT('Last source change date/time') A M2TEXT 50 TEXT('Member text ')
A List API Processor
Figure 9 Format for Retrieve Object Decsription
A***************************************************************** A* QUSLOBJ: FORMAT OBJL0700 A***************************************************************** A R OL0700 TEXT('QUSLOBJ, FORMAT OBJL0700 ') A***************************************************************** A* ..format OBJL0100: name information A***************************************************************** A O7ONAM 10 TEXT('Object name ') A O7LNAM 10 TEXT('Library name ') A O7OTYP 10 TEXT('Object type ') A***************************************************************** A* ..format OBJL0200: name, extended atr, text A***************************************************************** A O7OSTS 1 TEXT('Object status ') A O7EXAT 10 TEXT('Extended attribute ') A O7TEXT 50 TEXT('Text description ') A O7RS01 17 TEXT('Reserved ') A***************************************************************** A* ..format OBJL0300: basic object information A***************************************************************** A O7AUXP 9B 0 TEXT('Auxiliary storage pool ') A O7OWNR 10 TEXT('Owner ') A O7DOMN 2 TEXT('Domain - *S=System, *U=User ') A O7DTCR 8 TEXT('Date, creation ') A O7DTCG 8 TEXT('Date, change ') A O7STOR 10 TEXT('Storage ') A O7RS02 22 TEXT('Reserved ') A***************************************************************** A* ..format OBJL0400: creation information A***************************************************************** A O7SRCF 10 TEXT('Source file name ') A O7SRCL 10 TEXT('Source file library ') A O7SRCM 10 TEXT('Source file member ') A O7SRCU 13 TEXT('Source file update date/time') A O7CRET 10 TEXT('Creator ') A O7SYSC 8 TEXT('System created on ') A O7SYSL 9 TEXT('System level ') A O7COMP 16 TEXT('Compiler ') A O7OBLV 8 TEXT('Object level ') A O7USCG 1 TEXT('User changed ') A O7LCPG 16 TEXT('Licensed program ') A O7PTF 10 TEXT('PTF ') A O7APAR 10 TEXT('APAR ') A O7RS03 21 TEXT('Reserved ') A***************************************************************** A* ..format OBJL0500: save/restore information A***************************************************************** A O7DTSV 8 TEXT('Date, save ') A O7DTRS 8 TEXT('Date, restore ') A O7SVSZ 9B 0 TEXT('Save size ') A O7SVMU 9B 0 TEXT('Save size multiplier ') A O7SVSQ 9B 0 TEXT('Save sequence number ') A O7SVCM 10 TEXT('Save command ') A O7SVVL 71 TEXT('Save volume IDs ') A O7SVDV 10 TEXT('Save device ') A O7SVFI 10 TEXT('Save file ') A O7SVFL 10 TEXT('Save file library ') A O7SVLB 17 TEXT('Save label ') A O7RS04 52 TEXT('Reserved ') A***************************************************************** A* ..format OBJL0600: usage information A***************************************************************** A O7DTLU 8 TEXT('Date, last used ') A O7DTRE 8 TEXT('Date, reset ') A O7USCT 9B 0 TEXT('Usage count ') A O7USUP 1 TEXT('Usage updated ') A O7RS05 23 TEXT('Reserved ') A***************************************************************** A* ..format OBJL0700: size information A***************************************************************** A O7OSIZ 9B 0 TEXT('Object size ') A O7OSMU 9B 0 TEXT('Object size multiplier ')
LATEST COMMENTS
MC Press Online