Determining the usage of a module on your system can be a difficult task. There are opportunities to use a module object in any number of programs or service programs. This means you should keep track of where those modules are used. Unfortunately, no command--not even DSPPGMREF--provides this kind of information.
But before I get into that, I need to make a couple of corrections.
In the last issue, I inadvertently mixed up the CRTxxxMOD and CRTBNDxxx commands in the article entitled "The ILE Program Model from the Compiler Perspective."
The CRTBNDxxx commands are used when PDM option 14 is selected to compile a source member. The CRTxxxMOD commands are used when PDM option 15 is selected to compile a source member.
The CRTBNDxxx commands are the commands that provide a single-step, source-to-*PGM feature. They compile the source, generate a *MODULE object in QTEMP, and then bind that module into a *PGM object. Afterward, they delete the *MODULE from QTEMP.
Now, let's get back to determining where you used your modules. Once a program is created, there are two methods for viewing the names of the modules that were used to create the program. The first method is DSPPGM. DSPPGM has several screens of information you may page through. One of these screens contains the names of the modules that were used to create the program. In addition, you may display the module's object information by selecting option 5 from the same screen. The second method to access the list of modules used to create a program or service program is by using either the QBNLPGMI API or the QBNLSPGM API. QBNLPGMI lists the modules used to create a *PGM object, and QBNLSPGM lists the modules used to create a *SRVPGM (service program) object.
These APIs return their information into a user space object that may be retrieved into any RPG program. Once the information is retrieved into RPG, you may of course do anything you want with it, including write it out to a database file.
The parameters are similar for both of these APIs. In fact, why there are two different APIs is mysterious. IBM could have accomplished the same effect with one, by adding an object-type parameter. The table in Figure 1 illustrates the parameter list for both the QBNLPGMI API and the QBNLSPGM API.
Parameter | Data Type (Length) | Description |
User Space | Char(20) | This is the name of the user space that will receive the program information. The first 10 positions contain the user space name. The second 10 positions contain the library name. |
Format | Char(8) | This is thee API format ID. For QBNLPGMI, generate a list of module names used by the program PGML0100. For a list of service programs used by this program, use format PGML0200. For QBNLSPGM use SPGL0100 for a list of module names and SPGL0200 for a list of service program names. |
Program Name | Char(20) | This is the name of the program whose module list is generated. The first 10 positions must contain the program name. The second 10 positions must contain the library name. The program name may be generic, full, or *ALL. The library name may be a full library name or any of the traditional special library values, such as *ALL, *LIBL, *CURLIB, *ALLUSR, or *USRLIBL. |
API Error DS | Char(16) | This is the API error data structure. It contains feedback information on any errors that occurred during the API call. The first 4 bytes of this data structure should be a binary field that contains the length of the data structure. The second 4 bytes indicate how much data is returned by the API (if any). Typically, you can declare a 16-position data structure and initialize it to *ALLX'00' and ignore the error data structure. |
Figure 1: Both the QBNLPGMI API and the QBNLSPGM API use these parameters.
And the Results Are...
When these APIs are called, they produce a lot of useful information. Figure 2 shows the information about each module that the PGML0100 and SPGL0100 format produce.
Data Type (Length) | Description |
CHAR(10) | Program/service program name |
CHAR(10) | Program/service program library name |
CHAR(10) | Bound module name |
CHAR(10) | Bound module library name |
CHAR(10) | Source file name |
CHAR(10) | Source file library name |
CHAR(10) | Source file member name |
CHAR(10) | Module attribute |
CHAR(13) | Module creation date and time |
CHAR(13) | Source file updated date and time |
Figure 2: PGML0100 and SPGL0100 generate this information.
The APIs also return a lot of other program/service program attribute information in these formats. That information, however, has little to do with the module "where-used" information you want.
By calling either of these APIs, you can retrieve the module information and then write that information out to a database file. Once the database file has been created, you can use anything from Query/400 to SQL to extract a where-used list. See if you can get this working yourself. In the next issue, I'll provide the code to do just that: create a module-where-used database. But my solution will take advantage of the RPG ToolKit, which masks the complexities of the APIs with easy-to-use RPG IV subprocedure calls.
LATEST COMMENTS
MC Press Online