How to Write a CLIST

A CLIST (pronounced SEE LIST) is the simplest form of TSO command you can create.  It is basically a list of other TSO commands. (Get it, C List, where C stands for Command.)  This is an introduction to using CLISTs.

The CLIST “Language” also offers you rudimentary programming constructs such as IF-THEN-ELSE and DO logic, GOTO, writing lines to the screen, reading input from the screen, and some CONTROL functions (such as tracing and interrupt handling).  Since CALL is a TSO command, you can CALL other programs from within your CLIST, passing them PARM strings if you like.  You have some builtin substitution variables which the system replaces with a current value; For example, if you code &SYSUID. , then when the CLIST runs the system will substitute whatever TSO userid is in use at the time.  You can also make up your own symbolic variables, assign them default values, reassign the values during execution, and insist that the user specify values on the command line at execution time when they run your CLIST.

You can also make a special kind of CLIST called an ISPF EDIT MACRO, which you run from within the ISPF editor to execute a specific sequence of edit subcommands.  That is to be the topic of a separate post, right after this one.  Halfway into writing that, I realized that you need to know CLIST basics first. So back to CLIST basics.

Since an ordinary CLIST is a TSO command, a CLIST can invoke another CLIST.  Hence you can devise elaborate systems, but do yourself a favor and keep it simple: CLIST processing is fairly slow, comparatively speaking, because it is interpreted at run time (like basic forms of BASIC and REXX), rather than being compiled.  This makes CLISTs quick and easy to develop and modify, but relatively slow at run time.

Before we go any further into the syntax and structure of your CLIST itself, you probably want to know where to house your CLIST so that the system will be able to find it when you want to run it.

First you create a CLIST library as follows.

Go into TSO ISRDDN (which you remember from the article on A FEW GOOD TSO COMMANDS).  Find the ddname SYSPROC within the displayed list of datasets that you have currently allocated to your TSO session. Grab a copy of the first dataset name in the list of DSNs allocated to SYSPROC – use CTRL+c to copy it if your keyboard is set up for that, otherwise just write it down.

Near the end of the article on TSO Screen Size, we touched briefly on how to modify your keyboard settings when using IBM PC3270 emulation; Here’s an even more brief synopsis, if you want to set up cut-and-paste keys right now (Skip ahead past the digression if you have this set up already)

Digression: How to set your Cut-and-paste keys

Find the emulator-specific choice bar that should be at the very top of your TSO (3270 emulation) window.  Get to a dropdown menu from that bar by clicking the sequence

Edit -> Preferences -> Keyboard 

on the PC3270  configuration choices.  That should show you a map of the keyboard.  You can click on an individual key within the map, and then the  lower-right hand corner of the screen will show you a box with the current values for that key as well as its combination values when pressed in conjunction with SHIFT,   CTRL , or ALT.

You can overtype the values shown, or select new values from one of the lists shown near the bottom left of the screen.  CTRL+C should be mapped to copy text, CTRL+X to cut text, and CTRL+V to paste text.

While you are there, map "Page Up" to F7 and "Page Down" to F8.

Also while you are still  there, map some key to PA1.   I use Alt+Delete (or Ctrl+Delete), with Delete in this case being the key that is below Insert and left of End, at the far left of the small block of six keys that contains Page Up and Page Down.  Your own best choice will depend on the layout of your keyboard, of course.

Similarly I assign PA2 to be ALT+End (or Ctrl+End), using  the End key that sits between Delete and Page Down.   Hence PA2  sits to the right of PA1 .

Under TSO, as mentioned in other write-ups,
PA1  works like ATTN,
and  PA2  can be pressed to redisplay a garbled screen.

You need both PA1 and PA2 if you are to find happiness within TSO/ISPF.   Okay, you can almost always substitute ATTN for PA1 if you only use it within TSO.

If you also use IMS, you want the full set of PA keys, so (since you're right there setting up keys) set PA3.   If you followed my suggestions on PA1 and PA2, then put PA3 to the right of PA1 and PA2, so they'll all be in a row and hence easy to remember:  Assign Alt+PageDown  (or Ctrl+PageDown ) to PA3.  and you will have PA1, PA2, and PA3 next to each other in a neat row, making them easier to remember.

When you’re done setting up keys, click File in the upper left corner of the keyboard mapping screen and then select Save from the drop-down to save your changes in the same .kmp (keyboard map) file on the PC.

End of Digression on setting Cut-and-paste keys

 Now that you have used ISRDDN to find the DSN of the library that is currently at the top of your SYSPROC concatenation, go to ISPF option 3.2 and paste (or enter) that name into the Dataset Name field, and enclose the DSN within single quote marks (apostrophes).  Press the enter key to get ISPF to display the attributes of that dataset (library), and then press F3 to get back to the basic ISPF 3.2 screen.  Specify Allocate, and change the DSN field to use some name you choose for your new library – Let’s assume you specify ‘Myuserid.TSO.CLIST’, so we can use that DSN in examples in this article.  Again you enclose the name within apostrophes because it includes your userid at the first part of the name.  Capture that new DSN in your cut-and-paste clipboard, for later use. With the new DSN on the screen, and having Allocate selected as your chosen action, you press the enter key again.  The same attribute display screen should be reshown, this time pairing your new DSN with the attributes from the other dataset.  Press enter and your new dataset should be created.

What do you want to call your first new CLIST?  My1stTry? Okay, go into ISPF option 2, Edit, and use the “Other Dataset Name” field to paste in the name of your new CLIST library.  Amend the DSN so the member name is in parentheses: ‘Myuserid.TSO.CLIST(MY1STTRY)’, press enter, and you are ready to create a TSO command.

Just to get started quickly, put the word PROC on the first line with a zero after it to indicate that the CLIST can be executed without specifying any parameters.  You can put in an optional parameter for fun, let’s say you call it TRYWHAT; so your complete first line will say PROC 0 TRYWHAT(VANILLA) which means that there are zero required parameters and the optional symbolic parameter TRYWHAT will default to having the value VANILLA.

On the next few lines put something super simple like — well, like the lines shown below.  Here, then, is the complete text of your hypothetical TSO command My1stTRY:

PROC 0 TRYWHAT(VANILLA)
TIME
WRITE HELLO WORLD
WRITE HELLO from My 1St Try – Try what? &TRYWHAT
END

Save it and end the edit session.  Now you might reasonably ask: How do you execute your CLIST?

You want to execute it by saying  TSO MY1STTRY  on the ISPF command line, but you have not yet told TSO that it should add the name of your new CLIST library to the list of datasets it searches when looking for TSO commands.

You remember that you found the existing CLIST concatenation in TSO ISRDDN on the ddname SYSPROC, so it occurs to you that you might reallocate SYSPROC to use the same list of existing dataset names but with the name of your new library added at the beginning of the list.

True that’s an option, but it’s easier if you just use the SYSUPROC ddname, invented to cover just such a situation as your own.

Are you still in edit, ISPF option 2 ?  Good.  Make up another member name, we’ll call it USEMYDSN, and put into it the following lines:

PROC 0
ALLOCATE DD(SYSUPROC) DSN(‘Myuserid.TSO.CLIST’) REUSE
END

Why put it into a CLIST?  So you can set it up to run every time you Logon TSO.

So, save member USEMYDSN, exit ISPF, and Logoff.  Then go immediately into Logon again, but stop at the Logon screen, before you get into TSO – stop at the screen where you put in your password.  Look down near the bottom of that screen.  There should be a line that says Command ===> and that is where you will tell the system that whenever you Logon to TSO it should automatically execute your USEMYDSN CLIST.

First, however, observe whether there is already a command there.

If the Command field is already occupied, do the following (otherwise skip this paragraph).  Copy the existing Command (Ctrl+C if you’ve set that up).  Note we said Copy, not Cut.  Open Notepad on your PC and Paste that command into it for safekeeping. Go back to the TSO Logon screen and press enter, that is, Logon to TSO again without changing the existing command.  Go into ISPF edit again, and edit your new USEMYDSN CLIST.  As another line after your ALLOCATE statement, add (paste) the command that you just tucked away in Notepad on the PC for safekeeping.  Save the member, end edit, exit ISPF, Logoff TSO, and as before go immediately into Logon again, but stop at the Logon screen, before you get into TSO.

Blank out the field labeled Command ===> and paste in the text EXEC ‘Myuserid.TSO.CLIST(USEMYDSN)’, So the line looks like this:

Command ===> EXEC ‘Myuserid.TSO.CLIST(USEMYDSN)’

Press enter and Logon to TSO again.

Now you can say TSO MY1STTRY on the ISPF command line, and it should find and run your CLIST, that is, it should tell you the time and then say HELLO WORLD followed by another line saying HELLO FROM MY 1ST TRY – TRY WHAT? VANILLA

And that will be followed by a line containing three asterisks:

***

As you may know, TSO adds the three-asterisk line at the end when it finishes writing to the screen in line mode rather than full screen mode.  You just press enter whenever TSO displays the three-asterisk line.

You are happy that the CLIST runs – whoopee – but disappointed that the text came out entirely upper case.  You realize that TSO itself translates commands you enter into upper case, but within the CLIST you thought you could use lower case.  You can.  We’ll go back and fix it by adding a line at the beginning that says CONTROL NOCAPS . . .  but first execute the command again, specifying a parameter:

TSO MY1STTRY TRYWHAT(‘Chocolate Cake’) 

. . . Okay, so now you see how you can specify an optional parameter.  Go back to ISPF edit and add the CONTROL NOCAPS line the top:

PROC 0 TRYWHAT(VANILLA)
CONTROL NOCAPS
TIME
WRITE HELLO WORLD
WRITE HELLO from My 1St Try – Try what? &TRYWHAT
END

Save the member and again execute it, from the command line right there in Edit:

TSO  MY1STTRY

And voila, it should print the mixed case line correctly:

HELLO from My 1St Try – Try what? VANILLA

You can write in full screen mode (rather than line mode) by using ISPF Dialog Services, which we do not cover in this introductory article.  Basically it requires you to create an ISPF “panel” (screen) in ISPF format, put it into the ISPF panel library, and then call the ISPEXEC interface to display the panel.  The resulting line in the CLIST would say ISPEXEC DISPLAY PANEL(screen-name)  . . .   but that is a topic unto itself.  A link to the IBM manual on that is included at the end of this article, however, if you want to look it up there.

So now you know the rudiments of how to create a CLIST and run it.  Let’s provide a little more detail so you can actually use your CLIST to do something useful.

If you are really only interested in writing Edit Macros, but are reading this article for the purpose of finding out how to allocate your CLIST library so that the system will include it when searching for TSO commands, you can stop here and, if it’s been posted yet, go directly to the article on ISPF Edit Macros  (though maybe you might be interested in some of the SYNTAX rules below, before you go). There is a link to the IBM manual on ISPF Edit Macros among the links at the end of this article, which you might also want.

If you intend to write your TSO commands only in REXX, you can put your REXX commands into the same CLIST library you use for SYSUPROC, and they will be found as long as the first line contains a REXX comment identifier ( /* REXX */ ), so in that case also you do not need to continue reading.

If you actually want to write CLISTs, keep reading.

Cautionary note about selecting a name for your EXEC (be it CLIST or REXX) :

When the system is looking for a TSO command, it searches through all of the executable programs – compiled programs, load modules – before it looks for an EXEC file such as a CLIST or REXX.  So if you call your CLIST by a name that is already in use – something like IEFBR14, IEBGENER or SORT — or STATUS, TIME, DATE, and so on – the system will not execute your CLIST because it will find the program of the same name before it ever gets around to looking for a CLIST or REXX.  How do you know if the name is already in use?  There are hundreds, probably thousands, of names already in use, so here is a quick test: You can go up to the command line and enter TSO XYZ and press enter (but you replace XYZ with the name you are planning to use for your EXEC).  If you get a message saying “Command XYZ not found”, then the name XYZ is not in use, and it is probably safe for you to pick the name XYZ.  If you get any other response, then it probably found something called XYZ and tried to execute it, and you should pick a different name.

(Caveat — right, always with the caveats — and this one is pretty unlikely, so feel free to skip this paragraph — there are some special command tables that are probably not being used at your location, but possibly might be — there's a slight chance — and in such command tables the person responsible for their setup can set it up such that command XYZ is only valid if it comes from some particular source or is invoked in some particular way.  If you had the extremely unlikely bad luck to pick a name that is in such a table, then TSO might tell you the "command not found" message when the reality is that it found the name perfectly well, but the member with that name was not in the designated place, or you called it the wrong way, and, yes, in that case TSO misleads you (let's not say lies to you) and says command not found.  This is super unlikely ever to happen, but it is kind of ironically funny that it happened to IBM's SDSF command one time when IBM changed something.  Just thought I'd mention it, because it can be a real puzzler in the exceedingly rare cases where it happens.

Also, you can speed up the process of TSO finding your EXEC by telling TSO to skip all that program-searching and start with the EXEC part of the search.  You do this by preceding the CLIST name with a per cent sign ( % )– this works in most places where you specify a command name, but not absolutely everyplace.  You should be able to say TSO %XYZ  on the command line, and the system should then just look for an EXEC named XYZ, so the search should go a bit faster.

Okay, so let’s talk about writing your CLIST . . .  and this is just a basic introduction, believe it or not; there are a lot of features we aren’t covering here.  (There is a link to the IBM manual at the end of the article, if you need more . . .)

SYNTAX:
 
Comments: You can include a comment by enclosing the comment within slash-asterisk + asterisk-slash delimiters, as you would do in PL/I, and which you also have among other commenting options in C, C++, and Java :  /* this is a comment */ . . . Exceptions: You cannot say /* REXX */ as a comment on the first line of a CLIST, because that is a special code used to identify a REXX exec.  Another quirk is that when a comment is the last or only thing on a line, you can omit the terminating */ at the end of the comment.

Long lines :  You can end a line with a hyphen (minus sign) or a plus sign if you want to continue the line onto the next line.  The difference is that using the plus sign causes the removal of any leading blanks on the second line, whereas using the traditionally English-like hyphen leaves the blanks intact when the lines are stitched together.  According to the manual, the maximum total length of a statement is 32756 characters altogether.

Capitalization : CLIST statement names, if any exist, have to be capitalized.  Most other things can be capitalized or not; they will be automatically converted to capitals; the exception is that text parameters are not converted to capitals when you have CONTROL NOCAPS or ASIS in effect.

Hilite in Edit: This isn’t strictly speaking a syntax rule, but when you are editing a CLIST in ISPF edit you can enter
HILITE ON CLIST
on the command line and ISPF will highlight the syntax with different colors, making it easier to read.  (Yes, you can also specify other types of highlighting besides CLIST, and you can even say
HILITE ON AUTO
if you want the system to try to figure it out for you.

Labels : A statement label is an alphanumeric string up to 31 characters long (starting with a letter), with a colon( : ). The label has to have an actual statement on the same line right after the label (or, of course, on the following line if the first line ends with a plus or a minus continuation character after the colon).

LABEL1:  WRITE Hello
LABEL002: +
WRITE Greetings, &SYSUID

Operators:
Math: You can use +, -, *, and / (plus, minus, asterisk, and slash) to do addition, subtraction, multiplication and division.  You can also use a double asterisk ** for exponentiation and a double slash // for a remainder.

Logic: You can use the logical operator AND, also specified as double ampersand &&, plus the logical operator OR, also specified as a vertical bar |

Comparison: You have the basic equal, specified as the equal sign = or the abbreviation EQ, and you have both Less Than (< or LT) and Greater Than (> or GT).   The NOT sign used in CLIST processing is the same as the PL/I NOT sign, which might be an upper case 6 on your keyboard (or not, depending on how you have it set up).  It looks sort of like the upper right hand corner of a square, or like a hyphen with a small vertical bit hanging down at the end of it. (On some setups the NOT character may display as a carat, that is, an upside-down v, but may still work as a NOT sign.)  If you don’t have a NOT sign you can use, and you don’t want to do the setup to get it, then you can use the character combination alternatives: NE for Not Equal, NG for Not Greater Than, and NL for Not Less Than.   Other combinations you can use are Greater Than or Equal (>= or GE) and Less Than or Equal (<= or LE).

Parentheses: You can use parentheses in expressions, just like in regular math.

Order: Without parentheses to change the order, exponentiation is done first, then multiplication and division, then addition and subtraction (again, like real math).  Comparisons are done after the math has been evaluated.  The logical AND and OR are evaluated last (with AND evaluated prior to OR).

Opinion: Don’t rely on the software to get the order of operations right, just put in the parentheses.  This has the benefit of being easier for a person reading your code to understand the meaning without ambiguity.  Ever since the advent of hand-held calculators, many people have come to expect mathematical evaluations to be done in a left-to-right sequence, apparently just because they’re used to seeing calculators do it that way. So if you use parentheses, it reduces the chance that someone updating your CLIST in the future will mess up the calculation.

Getting Input from the User:

Method 1:

Remember how you write a line to the terminal using WRITE?  It has two cousins.  One is WRITENR, which means Write with No Return : In other words, the cursor remains at the end of the line, right after whatever is written, making it look as though it is waiting for input.  The other is READ, which takes whatever the user enters and puts it into the variable you designate on the READ statement.  For example:

PROC 0
CONTROL NOCAPS
WRITENR &STR(Hello. What’s your name?  === >)
READ &NAME
WRITE &STR(Well, hello &NAME then;+
 glad you’re here.)
WRITE &STR(Whatever else this CLIST might say)
/* etc etc */
END

Method 2:

Require parameters on the PROC statement (the first line of the CLIST).  Instead of specifying zero, you specify the number of required parameters, followed by their parameter names.  You can also still specify optional parameters following after the required parameters if you wish.

PROC 2 NAME SURNAME COMPANY(Compostware)
CONTROL NOCAPS
WRITE &STR(Hello, &NAME &SURNAME., +
welcome to &COMPANY TSO)
/* etc */
END

We’ll call the above CLIST by the name TRY2.  If the user executes TRY2, they need to specify two parameters on the same line.  For example, from the ISPF command line, a user might say:

Command ===> TRY2  Mary Smith

If users fail to enter the parameters they will be prompted, asked something like “enter parameter NAME” and then “enter parameter SURNAME”.  The standard prompt tells the user the name of the parameter that is missing, whatever name you have chosen.  So choose names that are descriptive of what the user is expected to enter, so that, when prompted, they can guess what is wanted.

If you want more information on getting input from the user, look for TERMIN, &SYSDLM, and &SYSDVAL at about page 47 in the IBM manual on CLISTs : z/OS TSO/E CLISTs  and also, in that same manual,  Chapter 9:  Communicating with the terminal user, starting on page 85.

BUILTIN FUNCTIONS:

Use &STR to indicate that a string of characters (including math symbols) is to be treated as a string:

WRITE  The formula is &STR(X = (A**2 +B**2))

SET LETTERS = &STR(ABCDEFGHIJK)

Use &SUBSTR to capture a substring from a longer text string.  The &SUBSTR function needs to be told the starting and ending positions you want to capture from the longer string, in the format (start:end), and you also need to give it the string, or the name of the string, from which you want it to extract those characters.

For example, the following lines could be used as an awkward method for writing the word South:

SET TVSHOW = &STR(Due South)
SET WHICHWAY = &SUBSTR( (5:9),&TVSHOW )
WRITE &WHICHWAY

Use &LENGTH to get the length of a string:

SET X = &LENGTH(&WHICHWAY)

Use &SYSINDEX to find the starting position of a short character string within a longer character string.  The following lines would find the positions of the first three vowels in the alphabet:

SET ALPHABET = &STR(ABCDEFGHIJK . . . XYZ)
SET A =  &STR(A)
SET E =  &STR(E)
SET I =  &STR(I)
SET APOS = &SYSINDEX(&A,&ALPHABET)
SET EPOS = &SYSINDEX(&E,&ALPHABET)
SET IPOS = &SYSINDEX(&I,&ALPHABET)

It is left as an exercise for the reader to locate the other vowels in the alphabet; or just pretend you did, and keep reading.  Probably you can find a more productive use for &SYSINDEX – maybe use it to parse out the levels of a dataset name.

There are many more functions available, if you want them, and you can find them described in the IBM manual on CLISTs : z/OS TSO/E CLISTs , Chapter 7, “Using built-infunctions,” page 53.

CLIST Statements (keywords, instructions):

SET

Use SET to assign a value to a variable:

SET  K = 27

CONTROL

Use CONTROL to set control conditions for the CLIST.  Immediately after the word CONTROL you specify the settings of the features you want to control.  You can put multiple CONTROL statements into your CLIST to turn various CONTROL features on and off at various places.

Some of the features you can specify, and their meanings, are:

MSG or NOMSG : Setting NOMSG is like QUIET mode.  It suppresses output messages from other commands that your CLIST invokes. The default is MSG, meaning messages are displayed.  In practice people often use CONTROL NOMSG to turn off messages just before a command that they know is likely to display unwanted messages.  For example, if you invoke the FREE command to free a dataset that happens not to be currently allocated, it issues a message telling you so.  Hence people often put CONTROL NOMSG just before FREE commands, to suppress that, and then put CONTROL MSG to turn normal message generation back on after the FREE commands.

LIST or NOLIST : Setting LIST causes every command (and subcommand) in the CLIST to be displayed at the terminal before it is executed.  Tracing, basically.  The default is NOLIST.

CONLIST or NOCONLIST : Same as LIST/NOLIST except it controls “CLIST statements” rather than “commands and subcommands”.

SYMLIST or NOSYMLIST : SYMLIST Displays both commands and CLIST statements as they appear BEFORE symbolic substitution.  LIST and CONLIST, on the other hand, display them AFTER substitution of symbolic variables has been done.

CAPS or NOCAPS (or ASIS, which is the same as NOCAPS) : The default, CAPS, causes character strings to be converted to uppercase.  NOCAPS (or ASIS) suppresses that conversion.

DO and END

These are pretty much what they look like.  You also have DO WHILE and DO UNTIL as variations.  You also have the TO and BY construction, but you can look that up yourself if you want to use it.

GOTO

This, too, is just what it looks like.  The target of GOTO has to be the label of a statement that has a label.  A label ends with a colon(:), and it should come on the same line as a statement, at the beginning of the line; otherwise, the label should have a plus or minus as a continuation character right after it, to link it to the statement on the following line.  I mention this because omitting the + or hyphen is a common oversight, and a little hard to figure out at first.

IF – THEN – ELSE

Again, these are just what they look like.

Simple examples combining IF-THEN-ELSE with DO and GOTO:

IF &STR(&SYSUID) = &STR(myTSOid) THEN +
  DO
    CONTROL MSG LIST CONLIST
  END
. . .
YIKES: +
IF &STR(&SYSUID) = &STR(myTSOid) THEN +
 DO
   WRITE Here we are at Label YIKES
   WRITE The value of variable WHATSIT is &WHATSIT
 END
GOTO ERREXIT
. . .
ERREXIT:+
WRITE Processing error.
IF &STR(A&NAME) > &STR(A) THEN +
  WRITE Sorry about this, &NAME
ELSE +
  WRITE Sorry, &SYSUID
EXIT 8
END

READ, WRITE, and WRITENR
You already know these.  You use these to read input from the user and write lines to the screen, as already shown.

OPENFILE, GETFILE, PUTFILE, and CLOSFILE

These can be used to read and write ordinary flat files  The ddnames should already be assigned using ALLOCATE statements to associate actual datasets with the ddnames (file names).  If you’re going to do this, you’re going beyond the introductory spirit of this article and should look in the manual (the link has already been pasted a few times, and appears again at the end of this article).  I just wanted you to know that this capability exists.  Usually if people want to read and write files from CLISTs, they write programs to do the file processing, and then call the programs from the CLISTs.

EXIT

Use EXIT to leave the CLIST and return to the caller.

LISTDSI

Use LISTDSI to fetch dataset information (DSI = Data Set Information, right?).  Stuff like DCB attributes, SMS Data Class, lots of information.

In case the dataset might have been migrated when your CLIST runs, You can optionally specify the parameter RECALL or NORECALL to control whether or not the system will recall the dataset so it can obtain the information.

You can also specify SMSINFO if you want the system to get SMS information for you, such as Data Class, Storage Class, dataset type, amount of disk space used, and so on.  This takes a little longer to run if you want this, so NOSMSINFO is the default if you don’t specify otherwise.

You specify DIRECTORY or NODIRECTORY to indicate whether or not, again with some cost in time, the system will obtain directory information about a PDS or PDSE (Library).

There are other options also; as described in the IBM manual on CLISTs.

Where is the LISTDSI  information returned?

Using LISTDSI  causes a set of builtin/symbolic CLIST variables to be populated with values taken from the system’s information about the dataset.  Remember that not all of these variables are populated if you did not specify the relevant optional parameters (as mentioned in the preceding paragraph) Shown below are some of the variables where your information comes back after you invoke LISTDSI.

&LASTCC is the return code fron LISTDSI (but only until you execute another line, so use it immediately)

&SYSMSGLVL1 and &SYSMSGLVL2 contain error messages if LISTDSI failed.

&SYSDSORG   (same as DSORG in JCL)

&SYSRECFM   (RECFM : Record Format)

&SYSLRECL   (LRECL)

&SYSBLKSIZE (BLKSIZE)

&SYSKEYLEN  (Key Length)

&SYSUNIT (generic device type, not to be confused with &SYSUNITS)

&SYSUNITS (space allocation units)

&SYSALLOC (allocated space, in terms of &SYSUNITS – not valid for PDSE)

&SYSUSED (used space, also in terms of &SYSUNITS)

&SYSCREATE (date created)

&SYSDATACLASS (SMS data class if you asked for SMSINFO)

Numerous additional variables populated by LISTDSI are described around page 161 – 166 of the IBM manual on CLISTs : z/OS TSO/E CLISTs .

Builtin variables you can use:

&SYSUID    – – TSO userid when the CLIST runs

&SYSPREF   – –  Dataset PREFIX setting, if any

 &SYS4SDATE – –  Date when the CLIST runs yyyy/mm/dd

&SYS4DATE  – –  Date when the CLIST runs mm/dd/yyyy

&SYSTIME   – –  Time when the CLIST runs hh:mm:ss

&LASTCC    – –  Return code from last statement or command

&MAXCC     – –  Highest return code so far in the CLIST

&SYSENV    – –  FORE or BACK, meaning FOREground (the CLIST is running under TSO) or BACKground (the CLIST is being run in a batch job, as in // EXEC PGM=IKJEFT01)

See the IBM manual on CLISTs for:

a List of all the builtin functions

all the CLIST statements

and control variables

a List of ALL the &variables returned by LISTDSI

Sample CLISTs

. . . and of course more stuff besides.

—————–

Addendum:
Run faster by minimizing the use of the FREE command

The easiest and most effective method to improve the run time of most CLISTs is to minimize the number of times you invoke the FREE command within the CLIST.

FREE is the opposite of ALLOCATE.  Okay, but what’s ALLOCATE?  You use ALLOCATE in the CLIST the same way you use a DD statement in a batch job: You use it to hook up a DDNAME with a DATASET. For example, say you want to run a program, and that program reads from a file it calls SYSUT1. In a batch job, you might put this type of DD statement following your EXEC statement that calls the program:

//SYSUT1  DD  DISP=SHR,DSN=input.file

In your CLIST, the equivalent thing would be to put an ALLOCATE statement before the line that will call the program:

ALLOCATE DD(SYSUT1)  DSN(input.file)  SHR  REUSE

Why do you say REUSE on that? Because it means you do not need to precede the ALLOCATE with a precautionary FREE statement.  Suppose the ddname SYSUT1 happened to be allocated already when your CLIST runs.  Without REUSE, it would stop running when it hit the ALLOCATE statement, delivering an error message bemoaning the situation, possibly prompting the user to tell it whether to FREE the ddname so it can proceed with the allocation, or END the whole thing right there. Who needs that?  So just get in the habit of specifying REUSE on every ALLOCATE.

In the syntax of the DD statement, you can use the word FILE or the abbreviation F instead of DD, and you can use DATASET or the abbreviation DA instead of DSN.  F/FILE and DA/DATASET are the original forms; DD and DSN are extensions, and I prefer them because it is easier to understand, at a glance, that these parameters are equivalent to their DD statement counterparts.  REUSE is also an extension to the original syntax.

Hence when and if you look at old CLISTs, you will see many ALLOCATE statements that use F(ddname) and DA(datasetname), and without REUSE; usually they are preceded with precautionary FREE statements, because originally REUSE was not available.  Those FREE statements are then duplicated at the end of the CLIST, because of course, laudably enough, the authors did not want to leave datasets tied to your TSO session so nobody and nothing else could use them.  You also see this practice in CLISTs that are NOT decades old, however, and that is because people are so good at copying.  Okay, you can see that REUSE cuts out half the FREE statements, and that’s obviously good; but what about freeing the datasets at the end?  You need to do that, don’t you?  Well, yes, but here’s what you can do:  Consolidate many FREE invocations into one (1).

You may see the following type of thing in an existing CLIST:

FREE F(SYSUT1)
FREE F(SYSUT2)
FREE F(ddname3)
.
.
.
FREE F(ddname27)

Do not be beguiled by the ease and allure of copying!

Do the following instead:

FREE DD(SYSUT1,SYSUT2,ddname3, . . .,ddname27)

As usual you do not need to take my word for this. The difference in run time is so stunning you can detect it without measuring it.  Create two copies of your CLIST, one with dozens of FREE statements, the other with one consolidated FREE. Try running each one in turn. Remember “Trust no one”? Go ahead and try it for yourself.  Anyway time passes and things change, and the time may come when IBM will make the CLIST interpreter smart enough to read ahead and consolidate multiple FREE statements into one invocation. It could happen. Also, if you’re the only one on the system late at night, and it is a very fast system, maybe you wouldn’t notice the difference in elapsed time, and if you’re sure your CLIST will never be copied or executed in some other time and place, well, like most things: in the end, it’s up to you.  As a general approach I recommend consolidating FREE statements as the single most effective thing you can do to speed up CLIST processing.

End of addendum about speeding up CLIST execution by minimizing use of FREE

 —————

 For further reading

 Links to IBM doc:

Link to IBM manual on CLISTs – This is the main reference on CLISTs:  
z/OS TSO/E CLISTs
http://publibz.boulder.ibm.com/epubs/pdf/ikj2i210.pdf

Mostly, where possible, I give links to the PDF versions of the IBM manuals, which can be downloaded in their entirety for future use.  In this case I'm also showing you a link to the read-it-online IBM Knowledge Center version, which has the advantage of being easy to navigate online:

Click here for the TSO/E Clist IBM manual, online-only non-pdf version

Link to complete index of IBM manuals on TSO :
http://www-03.ibm.com/systems/z/os/zos/library/bkserv/v2r2pdf/#IKJ

Link to complete index of IBM manuals on ISPF :
http://www-03.ibm.com/systems/z/os/zos/library/bkserv/v2r2pdf/#ISP

Link to ISPF Dialog Services (for full screen displays etc) :
ISPF Services Guide:
(page 48 for ISPEXEC DISPLAY PANEL(panel-name):
http://publibz.boulder.ibm.com/epubs/pdf/isp2sg10.pdf

ISPF Dialog Developer's Guide and Reference
http://publibz.boulder.ibm.com/epubs/pdf/isp2dg10.pdf

ISPF Edit and Edit Macros
http://publibz.boulder.ibm.com/epubs/pdf/isp2em10.pdf

————–

Updated slightly May 3rd 2016, and again May 10th

2 comments on “How to Write a CLIST

  1. Shivan, Thanks for your comment(s). I've provided more details on alternate methods of doing that in the next post, on ISPF edit macros, http://www.askthezoslady.com/ispf-edit-macros/
    . . . Note that the disadvantage of using ALTLIB is that it does not survive logging off and hence must be repeated at the next LOGON. If you are playing with the idea of reallocating SYSPROC to a list of datasets with your own at the top, consider using the IBM-supplied SPROC to do that for you, since it dynamically figures out what datasets are in SYSPROC at the time, rather than relying on a hard-coded list; a hard-coded list can go out of date and cause things to stop working. This is all covered in the aforementioned post on ISPF Edit macros (http://www.askthezoslady.com/ispf-edit-macros/).

  2. I not quiet sure why, but, in my shop doesnt work the SYSUPROC option. But in a ibm manual found this command: "ALTLIB ACTIVATE APPLICATION(CLIST) DATASET(new.clib)" and it work for me.
    Thanks for the post, very interesting.

Comments are closed.