Friday, November 30, 2007

What the $#@! is does ABEND 0E37 mean?

Lemmie guess, you were working with a dataset via ISPF and tried to save your work and got an 0E37 abend. Sound about right? Well don't fret, it's an easy fix. Any x37 abend is an error having to do with space. You're going to have to free some space.

One way to do this is to create a new, bigger data set for your stuff. You'll copy the old data set into the new one, and work with the copy. Ready? lets get started!

First, exit out of the dataset by entering CANCEL at the command line. You'll lose any changes you've made since your last save, so cut-and-paste anything critical. Go into the UTILITY menu, then into the DATA SET sub menu (option 3.2 at the command line). Get the attributes of the data set you were using by entering its name on the NAME field under the heading OTHER PARTITIONED, SEQUENTIAL OR VSAM DATA SET. Once you do this, you should see a screen listing the attributes of the Data Set you were working with. Exit out of this screen.

Now we're going to create a new data set. At the same line you entered your data set name, enter a name for your new data set. Before you hit enter, type A at the OPTION line. This tells the mainframe you want to allocate a new data set. Go ahead and hit Enter. You'll see the same attributes screen you saw before. Here's where you are going to make your changes. Increase the size of your data set, then hit enter. You should see a message that says the data set has been allocated. Exit out to the UTILITY menu.

Now we are going to copy your old data into the new data set. Go into the MOVE/COPY sub-menu in the UTILITY menu (option 3.3). Under the heading FROM OTHER PARTITIONED OR SEQUENTIAL DATA SET, on the line entitled NAME, enter the name of the data set from which you want to copy. Don't hit the ENTER key just yet.

*IMPORTANT!* If you do not enter this name in quotes, z/OS will attach your user name as a high-level qualifier. For example, if your username is JSMITH, and you enter PROGRAMS.WORKING
as the dataset name (note the lack of quotes), z/OS will change the name you entered to JSMITH.PROGRAMS.WORKING.

Okay, now that you've got the correct data set name entered, go ahead and type C at the OPTION line and hit ENTER. Now the system will want to know where you want to place the copied files. Under the heading TO OTHER PARTITIONED OR SEQUENTIAL DATA SET, on the line entitled NAME, enter the name of the data set from which you want to copy. Hit the ENTER key.

Now you see a list of all the members of the data set from which you want to copy. Select the members you want to copy by entering S next to the member name. You can copy more than one member at a time by selecting multiple members before hitting the ENTER key. When you are done, exit out of this screen. Check your new data set to make sure the copy went alright (ISPF option 3.4). Once you are satisfied with how everything turned out, delete the old dataset and rename the new one (if your old dataset was called PROGRAMS.WORKING and you copied everything into PROGRAMS.WORKING.TEMP, we need to delete PROGRAMS.WORKING and rename PROGRAMS.WORKING.TEMP to PROGRAMS.WORKING).

Deleting and renaming data sets is fairly painless. Via ISPF option 3.4, enter the name of the old dataset on the line titled DSNAME LEVEL and hit ENTER. You should end up at the DSLIST panel. type DELETE at the command field (the space to the left of your dataset name). Once you've deleted the old dataset, you can rename the new one. Return to ISPF option 3.4 and enter the name of the new dataset and hit enter. At the command field type RENAME and hit ENTER. You will be asked to enter a new data set name. Type the name of the data set you just deleted and hit ENTER.

All done! Now you've got a bigger, badder data set to work with and you shouldn't have to worry about Abend 0E37 for a while :-)

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:

)PANEL
)ATTR
! TYPE (OUTPUT)
+ TYPE (TEXT ) INTENS(LOW) COLOR (WHITE)
@ TYPE (OUTPUT) INTENS(LOW) COLOR (YELLOW) JUST(ASIS)
# TYPE (TEXT) INTENS(LOW) COLOR (GREEN) JUST(ASIS)
* TYPE (OUTPUT) INTENS(LOW) COLOR (WHITE) JUST(ASIS)
% TYPE (TEXT) INTENS(LOW) COLOR(RED) JUST(ASIS)
)BODY WIDTH(132)
+
+COMMAND -=>_CMDFLD +SCROLL -=>_SAMT+
+
+ TYPE "?" FOR ONLINE HELP
+ !MSG
+
# MVS SYSTEM INTEGRITY SCANNER: OUTPUT ANALYSIS TOOL
#
# ROW LOC OFFSET OBJECT CODE ADDR1 ADDR2 STMT SRC STATEMENT
# -----------------------------------------------------------------------------
)MODEL
+>_IN @AA
)INIT
&SAMT=PAGE
)PROC
)END

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

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

)ATTR

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

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

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.

)INIT

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.

)PROC

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

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.