04
Mon, Nov
5 New Articles

Treating Library Lists As Objects

General
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

A Way to take the pain out of library list management

by Ernie Malaga

One of the drawbacks of library list management is that you cannot assign a name to a library list and store it as another object. If this were possible, you could create library lists for different tasks, giving them different names and placing them in libraries just like other objects. These library list objects could then be referenced by CL programs when it becomes necessary to change your library list.

As it is now, you can only use the Change Library List command (CHGLIBL); your library list comes from your job description object (*JOBD) every time you sign on. It is likely that your job description simply references system value QUSRLIBL (user library list) as the source for your library list.

The four commands I wrote take the pain out of managing library lists. The commands CRTLIBLOBJ, CHGLIBLOBJ, and DLTLIBLOBJ let you create, change, and delete library list objects, while the Set Library List command (SETLIBL) changes your job description by retrieving a given library list object.

In January, 1991, we published Ted Holt's article titled, "Using AS/400 Library Lists in Parallel Environments." If you have not done so already, you should read that article in order to understand the concept of the library list, and why it is so important.

What Do You Mean, Library List Objects?

Picture the following scenario. Your MIS department is understaffed, so each programmer is working on three separate projects. Because the projects are of diverse nature, each requires a different library list to compile, test, and debug the programs. Take note that during sign-on the system obtains the user's initial library list from the job description, and that the user cannot change the job description using the CHGJOB command. What is left? Using CHGLIBL each time the programmer goes from one project to another. The trouble with CHGLIBL is that it is an error-prone command; the user has to think too much and has to type too much.

The alternative is to create a separate library list object containing all the libraries needed for each project, giving them names. After this set-up process has been done once, the programmer must only run the SETLIBL command to change from one library list to another - quick, convenient, and less prone to error than CHGLIBL.

Or consider this other case. After changing the library list a dozen times (CHGLIBL, ADDLIBLE, RMVLIBLE, EDTLIBL), your library list will no longer be as it was when you signed on. How do you restore your library list? Is this possible? Yes it is, if you have created a library list object, named after yourself, using the CRTLIBLOBJ command. Anytime at all you can then use the SETLIBL command to reset the library list as it was when you signed on.

As a final example, if you find the same CHGLIBL statement in several CL programs (with the same set of libraries), you may wish to create a library list object and then change all occurrences of CHGLIBL with SETLIBL. You gain modularity in your programming, since the list of library names is stored in only one object (the library list object created with CRTLIBLOBJ). Should you need to add yet another library to the same group of libraries, you would not have to change all CL programs, then recompile them. All that would be necessary is to change the library list object with CHGLIBLOBJ.

The Library Object Commands

The Create Library List Object (CRTLIBLOBJ) command accepts a list of up to twenty-five libraries and assigns it a name and a fifty-character text. The library list "object" so created is actually a data area object. See the sample command prompt on 1.

The Create Library List Object (CRTLIBLOBJ) command accepts a list of up to twenty-five libraries and assigns it a name and a fifty-character text. The library list "object" so created is actually a data area object. See the sample command prompt on Figure 1.

The Change Library List Object (CHGLIBLOBJ) command changes the list of library names or the text assigned to the object, or both.

The Delete Library List Object (DLTLIBLOBJ) command deletes an existing library list object.

The Set Library List (SETLIBL) command actually changes your job's library list, matching the library list object that was referenced.

The xxxLIBLOBJ commands have the following parameters:

LIBL: Qualified name of the library list object being updated. The name is required, but the library defaults to LIBLLIB.

LIBS: List of libraries to make up the library list object. This list can contain a maximum of twenty-five library names. Not applicable to DLTLIBLOBJ.

TEXT: Text for the library list object, fifty characters maximum. Not applicable to DLTLIBLOBJ.

All commands use data area objects as library list objects. These objects can be in any library you wish, but the default library name is LIBLLIB (Library List Library), which should be created before running these commands. Optionally, you may change this default value and use one of your libraries for that purpose.

For a listing of the command sources, see2a, 2b, and 2c. 3a shows program LIBL001CL, the command's CPP. This program assumes the existence of command CVTBINDEC in your system. If it does not exist, you must create it from the source provided in Chapter 9 of the CL Programmer's Guide.

For a listing of the command sources, see Figures 2a, 2b, and 2c. Figure 3a shows program LIBL001CL, the command's CPP. This program assumes the existence of command CVTBINDEC in your system. If it does not exist, you must create it from the source provided in Chapter 9 of the CL Programmer's Guide.

Further, the CHGLIBLOBJ command takes advantage of a new feature of Release 3.0 (the prompt override program, or POP), which retrieves the current values of the library names when the command prompter is invoked. This program, LIBL003CL, is listed in 3b.

Further, the CHGLIBLOBJ command takes advantage of a new feature of Release 3.0 (the prompt override program, or POP), which retrieves the current values of the library names when the command prompter is invoked. This program, LIBL003CL, is listed in Figure 3b.

AS/400 shops still running under releases below 3.0 can use the CHGLIBLOBJ without the prompt override program. When executed, the CHGLIBLOBJ command will not show the names of the libraries contained in the library list object; it will be the responsibility of the user to type them all over.

The SETLIBL Command

The SETLIBL command has only one parameter: the qualified name of the library list object. The command source is listed in 4, while 5 shows program LIBL002CL, the CPP for this command.

The SETLIBL command has only one parameter: the qualified name of the library list object. The command source is listed in Figure 4, while Figure 5 shows program LIBL002CL, the CPP for this command.

Compiling the Commands

Compile CRTLIBLOBJ, DLTLIBLOBJ, and SETLIBL as follows:

CRTCMD CMD(xxx/CRTLIBLOBJ) + PGM(xxx/LIBL001CL) + SRCFILE(xxx/QCMDSRC)

CRTCMD CMD(xxx/DLTLIBLOBJ) + PGM(xxx/LIBL001CL) + SRCFILE(xxx/QCMDSRC)

CRTCMD CMD(xxx/SETLIBL) + PGM(xxx/LIBL002CL) + SRCFILE(xxx/QCMDSRC)

To create CHGLIBLOBJ, execute one of the following, depending on your OS/400 release level:

Releases 1.0, 1.2, and 2.0:

CRTCMD CMD(xxx/CHGLIBLOBJ) + PGM(xxx/LIBL001CL) + SRCFILE(xxx/QCMDSRC)

Release 3.0:

CRTCMD CMD(xxx/CHGLIBLOBJ) + PGM(xxx/LIBL001CL) + SRCFILE(xxx/QCMDSRC) + PMTOVRPGM(xxx/LIBL003CL)

What's Your Excuse?

Ted Holt showed you two months ago how to take advantage of the library list to run parallel or test environments on the AS/400. If you have put off using the technique because the library list baffled you, you must now come up with a better excuse: with the help of the four commands presented here, managing the library list is as simple as the proverbial piece of cake. ------------------------------------------------------------------------------- SIDEBAR

Our Library List Object utility uses new features of Release 3.0 of OS/400 that have brought a long-overdue improvement to the command prompter: the Prompt Override Program (POP). The POP is a program, written in any language, which can retrieve information and present it on the command prompter. This feature is now used in most CHGxxx commands, so that when the command prompter is invoked, it will show the current values, rather than *SAME, by default. Setting up POP for your favorite commands is a three-step process. First, you must determine what parameters are considered key parameters: this is not unlike determining which fields make up the key of a file -- you simply pick up the parameters that uniquely identify the item whose current values you want to bring up. Second, you must write the POP. Third, you must create the command indicating the name of the POP in the PMTOVRPGM parameter. Let's review this process step by step, using the CHGLIBLOBJ command presented in this article as an example.

1) Determine the key parameters. Which parameters uniquely identify the library list objects? Only one parameter: the qualified name of the library list object. Therefore, the CHGLIBLOBJ command indicates KEYPARM(*YES) for the LIBL parameter.

2) Write the POP. This is by far the hardest part; please refer to 3b as you read this sidebar. The POP receives, in its first parameter, the qualified name of the command that invoked it. In our case, this is CHGLIBLOBJ. This information is passed to the POP in case the same POP is invoked by several commands. Then the POP receives one parameter per key parameter from the command. Since the CHGLIBLOBJ command has one key parameter only, the POP receives only one parameter. Finally, the POP returns to the command prompter, in its last parameter, a selective prompt string.

2) Write the POP. This is by far the hardest part; please refer to Figure 3b as you read this sidebar. The POP receives, in its first parameter, the qualified name of the command that invoked it. In our case, this is CHGLIBLOBJ. This information is passed to the POP in case the same POP is invoked by several commands. Then the POP receives one parameter per key parameter from the command. Since the CHGLIBLOBJ command has one key parameter only, the POP receives only one parameter. Finally, the POP returns to the command prompter, in its last parameter, a selective prompt string.

This selective prompt string must include, in its first two bytes, the hexadecimal representation of the length of the string. The actual string follows. This hexadecimal representation can be built from a decimal variable or literal with the Convert Decimal to Binary (CVTDECBIN) command which, although not part of OS/400, is completely listed in page 6-37 of the CL Programmer's Guide. The string we need to pass back to the command prompter is:

??LIBS(all the library names) ??TEXT(text for library list object)

Since we must retrieve the component library names from the library list object (which is actually a data area object), and we have to perform many concatenations, CL is the language of choice for this POP. Also, RPG is ruled out since the last parameter of the POP must be a 5700-byte character string, and such long strings are not supported in RPG, unless extra steps are taken in the RPG program to process this string as a data structure. Building this return string is not complicated. The values are retrieved from the library list object with the Retrieve Data Area (RTVDTAARA) command, then concatenated together and placed in the last parameter. Before we do so, however, we use the CVTDECBIN to build the two-byte length indicator at the beginning of the return string; we can expect the return string to be less than four hundred bytes long, so that is the value we convert to hexadecimal.

3) Create the command. This is the easiest step, involving the execution of the CRTCMD with PMT OVRPGM (LIBL003CL).

For more information about POPs, please refer to the CL Programmer's Guide, pages 9-35 to 9-42. If you need help with selective prompt strings, see pages 6-14 to 6-16 of the same manual.


Treating Library Lists As Objects

Figure 1 Sample Command Prompt

 Create Library List Object (CRTLIBLOBJ) Type choices, press Enter. Name of library list . . . . . . > WAYNE Name Library . . . . . . . . . . . LIBLLIB Name Libraries . . . . . . . . . . . > PROD Name > TEST > ACCTG > PERSONNEL > SCRATCH > TAATOOL > QGPL + for more values > QTEMP Text . . . . . . . . . . . . . . Wayne's library list Bottom F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys 
Treating Library Lists As Objects

Figure 2A The CRTLIBLOBJ Command

 CRTLIBLOBJ: CMD PROMPT('Create Library List Object') PARM KWD(LIBL) TYPE(Q1) MIN(1) PROMPT('Name of + library list') PARM KWD(LIBS) TYPE(*SNAME) LEN(10) MIN(1) + MAX(25) PROMPT('Libraries') PARM KWD(TEXT) TYPE(*CHAR) LEN(50) PROMPT('Text') PARM KWD(ACTION) TYPE(*CHAR) LEN(4) CONSTANT(*CRT) Q1: QUAL TYPE(*SNAME) LEN(10) MIN(1) QUAL TYPE(*SNAME) LEN(10) DFT(LIBLLIB) + PROMPT('Library') 
Treating Library Lists As Objects

Figure 2B The CHGLIBLOBJ Command

 CHGLIBLOBJ: CMD PROMPT('Change Library List Object') PARM KWD(LIBL) TYPE(Q1) MIN(1) KEYPARM(*YES) + PROMPT('Name of library list') PARM KWD(LIBS) TYPE(*SNAME) LEN(10) MIN(1) + MAX(25) PROMPT('Libraries') PARM KWD(TEXT) TYPE(*CHAR) LEN(50) PROMPT('Text') PARM KWD(ACTION) TYPE(*CHAR) LEN(4) CONSTANT(*CHG) Q1: QUAL TYPE(*SNAME) LEN(10) MIN(1) QUAL TYPE(*SNAME) LEN(10) DFT(LIBLLIB) + PROMPT('Library') 
Treating Library Lists As Objects

Figure 2C The DLTLIBLOBJ Command

 DLTLIBLOBJ: CMD PROMPT('Delete Library List Object') PARM KWD(LIBL) TYPE(Q1) MIN(1) PROMPT('Name of + library list') PARM KWD(LIBS) TYPE(*ZEROELEM) PARM KWD(TEXT) TYPE(*ZEROELEM) PARM KWD(ACTION) TYPE(*CHAR) LEN(4) CONSTANT(*DLT) Q1: QUAL TYPE(*SNAME) LEN(10) MIN(1) QUAL TYPE(*SNAME) LEN(10) DFT(LIBLLIB) + PROMPT('Library') 
Treating Library Lists As Objects

Figure 3A The LIBL001CL CL Program

 LIBL001CL: + PGM PARM(&QLL &LIBS &TEXT &ACTION) DCL VAR(&QLL) TYPE(*CHAR) LEN(20) DCL VAR(&LIBS) TYPE(*CHAR) LEN(252) DCL VAR(&TEXT) TYPE(*CHAR) LEN(50) DCL VAR(&ACTION) TYPE(*CHAR) LEN(4) DCL VAR(&LLOBJ) TYPE(*CHAR) LEN(10) DCL VAR(&LLLIB) TYPE(*CHAR) LEN(10) DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(80) DCL VAR(&TWO_BYTES) TYPE(*CHAR) LEN(2) DCL VAR(&NBR_LIBS) TYPE(*DEC) LEN(5 0) DCL VAR(&COUNTER) TYPE(*DEC) LEN(2 0) DCL VAR(&OFFSET_1) TYPE(*DEC) LEN(3 0) DCL VAR(&OFFSET_2) TYPE(*DEC) LEN(3 0) DCL VAR(&ONE_LIB) TYPE(*CHAR) LEN(10) DCL VAR(&ERRORS) TYPE(*DEC) LEN(2 0) /* Break qualified name */ CHGVAR VAR(&LLOBJ) VALUE(%SST(&QLL 1 10)) CHGVAR VAR(&LLLIB) VALUE(%SST(&QLL 11 10)) /* Validate input */ CHKOBJ OBJ(&LLLIB) OBJTYPE(*LIB) MONMSG MSGID(CPF9801) EXEC(DO) CHGVAR VAR(&MSGDTA) VALUE('Library' *BCAT &LLLIB *BCAT 'not + found') GOTO CMDLBL(ERROR) ENDDO /* Process *CRT action */ IF COND(&ACTION *EQ '*CRT') THEN(DO) CHKOBJ OBJ(&LLLIB/&LLOBJ) OBJTYPE(*DTAARA) MONMSG MSGID(CPF9801) EXEC(GOTO CMDLBL(CRT_OK)) CHGVAR VAR(&MSGDTA) VALUE('Library list' *BCAT &LLOBJ *BCAT + 'already exists in' *BCAT &LLLIB) GOTO CMDLBL(ERROR) CRT_OK: + CRTDTAARA DTAARA(&LLLIB/&LLOBJ) TYPE(*CHAR) LEN(250) + TEXT(&TEXT) AUT(*ALL) GOTO CMDLBL(CHG_OK) ENDDO ELSE CMD(DO) CHKOBJ OBJ(&LLLIB/&LLOBJ) OBJTYPE(*DTAARA) MONMSG MSGID(CPF9801) EXEC(DO) CHGVAR VAR(&MSGDTA) VALUE('Library list' *BCAT &LLOBJ + *BCAT 'not found in' *BCAT &LLLIB) GOTO CMDLBL(ERROR) ENDDO ENDDO /* Process *CHG action */ IF COND(&ACTION *EQ '*CHG') THEN(DO) CHGOBJD OBJ(&LLLIB/&LLOBJ) OBJTYPE(*DTAARA) TEXT(&TEXT) CHG_OK: + CHGVAR VAR(&TWO_BYTES) VALUE(%SST(&LIBS 1 2)) CVTBINDEC FROMBIN(&TWO_BYTES) TODEC(&NBR_LIBS) CHGVAR VAR(&ERRORS) VALUE(0) CHGVAR VAR(&COUNTER) VALUE(1) CHGVAR VAR(&OFFSET_1) VALUE(1) CHGVAR VAR(&OFFSET_2) VALUE(3) LOOP: + CHGVAR VAR(&ONE_LIB) VALUE(%SST(&LIBS &OFFSET_2 10)) CHGDTAARA DTAARA(&LLLIB/&LLOBJ (&OFFSET_1 10)) VALUE(&ONE_LIB) CHKOBJ OBJ(&ONE_LIB) OBJTYPE(*LIB) MONMSG MSGID(CPF9801) EXEC(DO) CHGVAR VAR(&ERRORS) VALUE(&ERRORS + 1) CHGVAR VAR(&MSGDTA) VALUE('Component library' *BCAT + &ONE_LIB *BCAT 'not found') SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA(&MSGDTA) + MSGTYPE(*DIAG) ENDDO CHGVAR VAR(&COUNTER) VALUE(&COUNTER + 1) CHGVAR VAR(&OFFSET_1) VALUE(&OFFSET_1 + 10) CHGVAR VAR(&OFFSET_2) VALUE(&OFFSET_2 + 10) IF COND(&COUNTER *LE &NBR_LIBS) THEN(GOTO CMDLBL(LOOP)) GOTO CMDLBL(ENDPGM) ENDDO /* Process *DLT action */ IF COND(&ACTION *EQ '*DLT') THEN(DO) DLTDTAARA DTAARA(&LLLIB/&LLOBJ) GOTO CMDLBL(ENDPGM) ENDDO /* Send error messages */ ERROR: + SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA(&MSGDTA) + MSGTYPE(*DIAG) SNDPGMMSG MSGID(CPF0002) MSGF(QCPFMSG) MSGTYPE(*ESCAPE) /* End program */ ENDPGM: + IF COND(&ERRORS *GT 0) THEN(DO) CHGVAR VAR(&MSGDTA) VALUE('Library list updated, but errors + exist') SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA(&MSGDTA) + MSGTYPE(*INFO) ENDDO ENDPGM 
Treating Library Lists As Objects

Figure 3B The LIBL003CL Program

 LIBL003CL: + PGM PARM(&QUALCMD &QUALLIBL &RTNSTRING) DCL VAR(&QUALCMD) TYPE(*CHAR) LEN(20) DCL VAR(&QUALLIBL) TYPE(*CHAR) LEN(20) DCL VAR(&RTNSTRING) TYPE(*CHAR) LEN(5700) DCL VAR(&LIBL) TYPE(*CHAR) LEN(10) DCL VAR(&LIBLLIB) TYPE(*CHAR) LEN(10) DCL VAR(&TWO_BYTES) TYPE(*CHAR) LEN(2) DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(80) DCL VAR(&LIB01) TYPE(*CHAR) LEN(10) DCL VAR(&LIB02) TYPE(*CHAR) LEN(10) DCL VAR(&LIB03) TYPE(*CHAR) LEN(10) DCL VAR(&LIB04) TYPE(*CHAR) LEN(10) DCL VAR(&LIB05) TYPE(*CHAR) LEN(10) DCL VAR(&LIB06) TYPE(*CHAR) LEN(10) DCL VAR(&LIB07) TYPE(*CHAR) LEN(10) DCL VAR(&LIB08) TYPE(*CHAR) LEN(10) DCL VAR(&LIB09) TYPE(*CHAR) LEN(10) DCL VAR(&LIB10) TYPE(*CHAR) LEN(10) DCL VAR(&LIB11) TYPE(*CHAR) LEN(10) DCL VAR(&LIB12) TYPE(*CHAR) LEN(10) DCL VAR(&LIB13) TYPE(*CHAR) LEN(10) DCL VAR(&LIB14) TYPE(*CHAR) LEN(10) DCL VAR(&LIB15) TYPE(*CHAR) LEN(10) DCL VAR(&LIB16) TYPE(*CHAR) LEN(10) DCL VAR(&LIB17) TYPE(*CHAR) LEN(10) DCL VAR(&LIB18) TYPE(*CHAR) LEN(10) DCL VAR(&LIB19) TYPE(*CHAR) LEN(10) DCL VAR(&LIB20) TYPE(*CHAR) LEN(10) DCL VAR(&LIB21) TYPE(*CHAR) LEN(10) DCL VAR(&LIB22) TYPE(*CHAR) LEN(10) DCL VAR(&LIB23) TYPE(*CHAR) LEN(10) DCL VAR(&LIB24) TYPE(*CHAR) LEN(10) DCL VAR(&LIB25) TYPE(*CHAR) LEN(10) DCL VAR(&OLD_TEXT) TYPE(*CHAR) LEN(50) DCL VAR(&NEW_TEXT) TYPE(*CHAR) LEN(100) DCL VAR(&OLD_POS) TYPE(*DEC) LEN(3 0) DCL VAR(&NEW_POS) TYPE(*DEC) LEN(3 0) /* Break qualified name of library list object */ CHGVAR VAR(&LIBL) VALUE(%SST(&QUALLIBL 1 10)) CHGVAR VAR(&LIBLLIB) VALUE(%SST(&QUALLIBL 11 10)) /* Validate library list object */ CHKOBJ OBJ(&LIBLLIB/&LIBL) OBJTYPE(*DTAARA) MONMSG MSGID(CPF9801) EXEC(DO) CVTDECBIN FROMDEC(0) TOBIN(&TWO_BYTES) CHGVAR VAR(&RTNSTRING) VALUE(&TWO_BYTES) CHGVAR VAR(&MSGDTA) VALUE('Library list' *BCAT &LIBL *BCAT + 'not found in' *BCAT &LIBL) SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA(&MSGDTA) + MSGTYPE(*DIAG) SNDPGMMSG MSGID(CPF0011) MSGF(QCPFMSG) MSGTYPE(*ESCAPE) GOTO CMDLBL(ENDPGM) ENDDO /* Retrieve library names */ RTVDTAARA DTAARA(&LIBLLIB/&LIBL (1 10)) RTNVAR(&LIB01) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (11 10)) RTNVAR(&LIB02) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (21 10)) RTNVAR(&LIB03) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (31 10)) RTNVAR(&LIB04) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (41 10)) RTNVAR(&LIB05) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (51 10)) RTNVAR(&LIB06) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (61 10)) RTNVAR(&LIB07) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (71 10)) RTNVAR(&LIB08) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (81 10)) RTNVAR(&LIB09) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (91 10)) RTNVAR(&LIB10) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (101 10)) RTNVAR(&LIB11) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (111 10)) RTNVAR(&LIB12) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (121 10)) RTNVAR(&LIB13) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (131 10)) RTNVAR(&LIB14) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (141 10)) RTNVAR(&LIB15) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (151 10)) RTNVAR(&LIB16) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (161 10)) RTNVAR(&LIB17) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (171 10)) RTNVAR(&LIB18) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (181 10)) RTNVAR(&LIB19) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (191 10)) RTNVAR(&LIB20) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (201 10)) RTNVAR(&LIB21) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (211 10)) RTNVAR(&LIB22) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (221 10)) RTNVAR(&LIB23) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (231 10)) RTNVAR(&LIB24) RTVDTAARA DTAARA(&LIBLLIB/&LIBL (241 10)) RTNVAR(&LIB25) /* Retrieve library list description */ RTVOBJD OBJ(&LIBLLIB/&LIBL) OBJTYPE(*DTAARA) TEXT(&OLD_TEXT) /* Change all single apostrophes for double apostrophes */ CHGVAR VAR(&OLD_POS) VALUE(1) CHGVAR VAR(&NEW_POS) VALUE(1) LOOP: + IF COND(%SST(&OLD_TEXT &OLD_POS 1) *EQ '''') THEN(DO) CHGVAR VAR(%SST(&NEW_TEXT &NEW_POS 2)) VALUE('''''') CHGVAR VAR(&NEW_POS) VALUE(&NEW_POS + 2) ENDDO ELSE CMD(DO) CHGVAR VAR(%SST(&NEW_TEXT &NEW_POS 1)) VALUE(%SST(&OLD_TEXT + &OLD_POS 1)) CHGVAR VAR(&NEW_POS) VALUE(&NEW_POS + 1) ENDDO CHGVAR VAR(&OLD_POS) VALUE(&OLD_POS + 1) IF COND(&OLD_POS *LE 50) THEN(GOTO CMDLBL(LOOP)) /* Build the return string */ CVTDECBIN FROMDEC(400) TOBIN(&TWO_BYTES) CHGVAR VAR(&RTNSTRING) VALUE(&TWO_BYTES *CAT '??LIBS(' *CAT + &LIB01 *BCAT &LIB02 *BCAT &LIB03 *BCAT &LIB04 *BCAT &LIB05 + *BCAT &LIB06 *BCAT &LIB07 *BCAT &LIB08 *BCAT &LIB09 *BCAT + &LIB10 *BCAT &LIB11 *BCAT &LIB12 *BCAT &LIB13 *BCAT &LIB14 + *BCAT &LIB15 *BCAT &LIB16 *BCAT &LIB17 *BCAT &LIB18 *BCAT + &LIB19 *BCAT &LIB20 *BCAT &LIB21 *BCAT &LIB22 *BCAT &LIB23 + *BCAT &LIB24 *BCAT &LIB25 *TCAT ') ??TEXT(''' *CAT &NEW_TEXT + *TCAT ''')') ENDPGM: + ENDPGM 
Treating Library Lists As Objects

Figure 4 The SETLIBL Command

 SETLIBL: CMD PROMPT('Set Library List') PARM KWD(LIBL) TYPE(Q1) PROMPT('Library list') Q1: QUAL TYPE(*SNAME) LEN(10) MIN(1) QUAL TYPE(*SNAME) LEN(10) DFT(LIBLLIB) + PROMPT('Library') 
Treating Library Lists As Objects

Figure 5 The LIBL002CL Program

 LIBL002CL: + PGM PARM(&QLL) DCL VAR(&QLL) TYPE(*CHAR) LEN(20) DCL VAR(&LLOBJ) TYPE(*CHAR) LEN(10) DCL VAR(&LLLIB) TYPE(*CHAR) LEN(10) DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(80) DCL VAR(&LIBS) TYPE(*CHAR) LEN(250) DCL VAR(&CMD) TYPE(*CHAR) LEN(300) DCL VAR(&OFFSET) TYPE(*DEC) LEN(3 0) DCL VAR(&LIBNAM) TYPE(*CHAR) LEN(10) DCL VAR(&ERRORS) TYPE(*DEC) LEN(2 0) /* Break qualified name */ CHGVAR VAR(&LLOBJ) VALUE(%SST(&QLL 1 10)) CHGVAR VAR(&LLLIB) VALUE(%SST(&QLL 11 10)) /* Validate input */ CHKOBJ OBJ(&LLLIB) OBJTYPE(*LIB) MONMSG MSGID(CPF9801) EXEC(DO) CHGVAR VAR(&MSGDTA) VALUE('Library' *BCAT &LLLIB *BCAT 'not + found') GOTO CMDLBL(ERROR) ENDDO CHKOBJ OBJ(&LLLIB/&LLOBJ) OBJTYPE(*DTAARA) MONMSG MSGID(CPF9801) EXEC(DO) CHGVAR VAR(&MSGDTA) VALUE('Library list' *BCAT &LLOBJ *BCAT + 'not found in' *BCAT &LLLIB) GOTO CMDLBL(ERROR) ENDDO /* Set library list */ RTVDTAARA DTAARA(&LLLIB/&LLOBJ *ALL) RTNVAR(&LIBS) CHGVAR VAR(&CMD) VALUE('CHGLIBL LIBL(') CHGVAR VAR(&OFFSET) VALUE(1) CHGVAR VAR(&ERRORS) VALUE(0) LOOP: + CHGVAR VAR(&LIBNAM) VALUE(%SST(&LIBS &OFFSET 10)) IF COND(&LIBNAM *NE ' ') THEN(DO) CHKOBJ OBJ(&LIBNAM) OBJTYPE(*LIB) MONMSG MSGID(CPF9801) EXEC(DO) CHGVAR VAR(&ERRORS) VALUE(&ERRORS + 1) CHGVAR VAR(&MSGDTA) VALUE('Component library' *BCAT + &LIBNAM *BCAT 'not found') SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA(&MSGDTA) + MSGTYPE(*DIAG) ENDDO CHGVAR VAR(&CMD) VALUE(&CMD *BCAT &LIBNAM) ENDDO CHGVAR VAR(&OFFSET) VALUE(&OFFSET + 10) IF COND(&OFFSET *LT 250) THEN(GOTO CMDLBL(LOOP)) ELSE CMD(DO) CHGVAR VAR(&CMD) VALUE(&CMD *TCAT ')') ENDDO IF COND(&ERRORS *EQ 0) THEN(DO) CALL PGM(QCMDEXC) PARM(&CMD 300) GOTO CMDLBL(ENDPGM) ENDDO ELSE CMD(DO) CHGVAR VAR(&MSGDTA) VALUE('Library list not set') ENDDO /* Send error messages */ ERROR: + SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA(&MSGDTA) + MSGTYPE(*DIAG) SNDPGMMSG MSGID(CPF0002) MSGF(QCPFMSG) MSGTYPE(*ESCAPE) /* End program */ ENDPGM: + ENDPGM 
BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: