Thursday, November 29, 2007

ISPF is a harsh Mistress...

Whew, the past month or so has been more painful than usual. As much as I love the mainframe, there are times where I feel like working on these machines is akin to hammering a nail into a wall with your forehead. Developing an ISPF interface has proven to be one of those times.

Essentially, I'm creating an interface for an in-house tool that reads and parses source code. To do this, I'm using ISPF for the user interface and a bit of REXX to handle the processing. Essentially, a large block of source code gets written into a table which is then displayed to the user. The user is able to view and manipulate the table by removing blocks of code that are irrelevant. The program aids the user in determining what sections of the code are important. When all is said and done, the user then has the option to save the table to a dataset.

The main sticking points have been:

1) Figuring out what defaults get set when you engage ISPF panel services

2) How to create/manage dynamic content

3) How to efficiently manage the interactions between ISPF and the code that is driving it

Before I go on, I'm going to show you what the panel code looks like that drives the main page:

+ !MSG
# -----------------------------------------------------------------------------
+>_IN @AA

First off, note the spacing in the ")ATTR" section. That's important. It seems that ISPF, much like JCL, is sensitive to row/column position of code. I should say that there is another way to develop ISPF panels called Dialog Tag Language (DTL). DTL appears to have more functionality, but there is a trade-off. In order to keep everything compatible, you write a panel in DTL, then run it through a conversion program by typing ISPDTLC at the command line. Once you do this, the panel gets converted into something that is non-human readable, but is compatible with ISPF. I found this to be problematic, as I have no idea what my DTL is getting turned into. True, the conversion utility has error checking, but it's not able to find logic errors. So there are instances where you attempt to develop a dialog via DTL, you wash it through the conversion utility, run the panel, and find out it's not doing what it's supposed to be doing. Now you can't tell if the problem is the DTL you wrote, or the manner in which ISPDTLC interpreted your DTL.

So why bother with it you ask? Well, from the looks of it, DTL provides functionality that the normal ISPF panel language does not provide. If you look at the panel code I showed you (go ahead and scroll up, I'll wait), you'll see that there is only one line of code in the "(MODEL" section. that line, specifically the "@AA" part, is what displays the table information. Every row of the table is displayed in the same way. This means that I can't dynamically change the color of a particular row of the table based on context. DTL would, in theory, allow me to do that. The problem is that DTL will ignore the profile keylist (the thing that defines what the PFKeys are set to). This means that you have to define them yourself, but the figuring out how to define the APPL that would drive that is akin to learning Mandrin Chinese in an hour. So in the end, it seems that the ISPF Panel language is the best way to go.

So let's take a quick tour of the panel code I showed you:


Panel section. Specifies a keylist to be used during the display of the panel, and identifies where to find the keylist


Attribute section. Defines the special characters in the body of the panel definition that represent attribute (start of field) bytes. ISPF panels are defined line-by-line with control characters. So in the case of + TYPE (TEXT ) INTENS(LOW) COLOR (WHITE), a line that starts with the control character "+" will be displayed as plain text, low intensity (brightness), and will be white.


Body section. Defines the format of the panel as seen by the user and defines the name of each variable field on the panel. In the case of the sample above, WIDTH(132) pertains to the number of character columns that will be displayed when the panel is shown.

Now is a good time to note that there are built-in control characters. One of them is "_". This denotes an input field. So by saying _CMDFLD, I am defining an input field with the variable name CMDFLD.

In the sample above, you'll also note a message field. This is where any messages will be displayed in the panel.


Model section. Defines the format of each row of scrollable data. This section is required for table display panels. Only one )MODEL section is allowed per panel.

In the sample panel I've shown you, I've defined +>_IN @AA in the model section. This means a table will be displayed here. Each row will start with a ">", which will be displayed with the characteristics mapped to control character "+". Then, an input field called "IN" will be created, then the table row called "AA". Note that "IN" and "AA" have different control characters, and thus are displayed differently.


Initialization section. Specifies the initial processing that is to occur before the panel is displayed. This section is typically used to define how variables are to be initialized.


Processing section. Specifies processing that is to occur after the panel has been displayed or redisplayed. This section is typically used to define how variables are to be verified and translated.


End section. Specifies the end of the panel definition, and consists only of the )END statement. ISPF ignores any data that appears on lines following the )END statement.

That about covers the ISPF end of things. The next post will go over the REXX that's driving everything. I hope this has been helpful :-)

The postings on this site are my own and don’t necessarily represent IBM’s positions, strategies or opinions.

No comments:

Post a Comment