What do binding directories and binder language have in common? Answer: The use of the word "bind" in their titles. Other than that, they really have nothing else to do with one another.
Binder language is stored in source file members. It's easily accessible and modifiable, and since you can use a source editor, you have all the copy/paste/find functions of the SEU or WDSc environment.
Binding directories, on the other hand, are a joke. They are unique object types (space-based objects) that cannot be easily modified, searched, or—most often requested—reordered. I remember that 11 or 12 years ago people complained about binding directories being a new object instead of a source member, but those complaints obviously did no good.
So here it is, a decade later, and people are finally using binding directories. Suddenly, all of the shortcomings we noticed in the mid-1990s are coming to light. "How do I reorder or move entries in my binding directory?" Short answer: You can't. "How do I update a binding directory entry (to change the library name, for example)?" Again, you can't. "How do I insert a new entry between two existing entries?" You can't use WRKBNDDIRE; you have to use ADDBNDDIRE instead.
Binding directories clearly should have been stored in source members to give us the ability to rename, reorder, and add and remove entries with ease. Certainly, this kind of work is not done every day. In fact, it is rarely done. But nonetheless, it is one more thing that should be there to make things easier.
To that end, I started looking for an API that would give me access to binding directories. I wanted to be able to list the entries, display them in a subfile, and allow those entries to be moved, deleted, added, and even sorted. Alas, no binding directory APIs exist. Of course, being an old System/38 hack, I dumped a binding directory object and discovered that it is a simple user-space type of object that contains a header followed by a list of entries. After a few minutes of looking at the dump, I had the structure figured out.
The bad news: User-state programs can't play at this level with binding directories. So if you have security level 40 or higher, you wouldn't be able to use any new utility I might create.
So I had to resort to 20-year-old programming techniques. I had to use an OUTFILE. While doing so did make things more complicated and gave me a sense of humiliation (I'm a firm believer in APIs, not OUTFILEs), I was able to make it work.
The first thing I had to do was to realize that the DSPBNDDIR command has an OUTPUT(*OUTFILE) parameter option. Being accustomed to using WRKxxxx (Work With...) commands, I sometimes don't even consider that there might be a corresponding DSPxxxx command; in this case, there was.
Since the new IBM V5R3 Info Center seems like it was designed by a hurricane (compared to prior releases), finding things is a bit bewildering. So rather than attempt to look up the record layout of the output from DSPBNDDIR, I decided to do it the old-fashioned way—create the output file and read the format from the outfile using the DSPFFD command.
The following is the record format of the output file generated by the DSPBNDDIR command:
Record Format: QBNDSPBD
|
||
BNDCEN
|
Char(1)
|
Display Century
|
BNDDAT
|
Char(6)
|
Display Date: format—Job
|
BNDTIM
|
Char(6)
|
Display Time
|
BNOLNM
|
Char(10)
|
Library Name
|
BNOBNM
|
Char(10)
|
Object Name
|
BNOBTP
|
Char(7)
|
Object Type
|
BNOCEN
|
Char(1)
|
Object Create Century
|
BNODAT
|
Char(6)
|
Object Create Date
|
BNOTIM
|
Char(6)
|
Object Create Time
|
BNDRLB
|
Char(10)
|
Binding Directory Library
|
BNDRNM
|
Char(10)
|
Binding Directory
|
BNMOSY
|
Char(8)
|
System Name
|
This output file has what we need to write our own Work With panel. The sad thing is that we have to write it ourselves. So rather than build a rarely used WRKBD command, I decided to create something much more simple—a Retrieve Binder Directory Source (RTVBDSRC) CL command. There is already a Retrieve Binder Language Source (RTVBNDSRC) so why not RTVBDSRC?
This is the kind of tool I used to build back in the old System/38 days (when I wrote, edited, and published the "Q38" newsletter (anybody remember that?)
The command looks like this:
SRCFILE( [library/] [QCLSRC] )
SRCMBR( [*BNDDIR | name ] ) +
REPLACE( [*NO | *YES ] )
The source for the command definition object is listed below. When you compile it with CRTCMD, be sure to specify the name of the CL program, also named RTVBDSRC, as the command processing program.
|
The CL program that this RTVBDSRC command runs to do the actual work is also named RTVBDSRC. The program does some routine verification and then dumps the named binder directory to an output file in QTEMP. Then, within the same CL program, it reads the outfile and creates a source member that includes an ADDBNDDIRE CL command for each entry in the binding directory.
That source member can then be edited with SEU or WDSc and modified to your satisfaction. Compile the source member created by RTVBDSRC and run it to recreate the binding directory. Note that the old binding directory will be moved to QTEMP (which you could probably change to QRPLOBJ if necessary).
Here is the CL source for RTVBDSRC:
|
The output from DSPBNDDIR is generated at the statement tagged with the DSPBD label. This creates in QTEMP the output file of all the entries in the specified binding directory.
The statement tagged with the READNEXT label reads each record out of the output file. Then, at the statement tagged with WRTSRC, an ADDBNDDIRE command is written to the user-specified source file member.
WRTSRCREC is a simple output routine I slapped together to write to a known source file member from within CL programs. The source member must already exist, and the name must be correct. It does no error checking. The WRTSRCREC CL command and the RPG IV command processing program is listed below.
Command Source: WRTSRCREC
|
RPG IV Source: WRTSRCREC
|
This program writes out a line to a source file member. If the input line length is longer than the source member record length, it breaks the line into two parts and writes out two lines. Obviously, if you want it to paginate CL commands, you'll have to add your own logic.
As always, the source code for this command is available for free download at www.rpgiv.com/downloads. Just click on the RPG Developer downloads link at the top of the page.
While binding directories are not necessarily something that we need to maintain on a frequent basis, having the basic tools necessary to maintain them is important. RTVBDSRC is one small step toward making things a bit less frustrating.
Bob Cozzi is a programmer/consultant, writer/author, and software developer of the RPG xTools, a popular add-on subprocedure library for RPG IV. His book The Modern RPG Language has been the most widely used RPG programming book for nearly two decades. He, along with others, speaks at and runs the highly-popular RPG World conference for RPG programmers.
LATEST COMMENTS
MC Press Online