Professional Documents
Culture Documents
New Rexx Training
New Rexx Training
SESSION 1
Introduction to REXX REXX basics REXX Instructions REXX Built-in Functions REXX External functions REXX TSO/E External commands
SESSION 2
Executing REXX in BATCH mode Introduction to REXX Edit macros Examples on REXX Edit macros File Tailoring ISPF Tables REXX Quiz
USAGE of REXX
Automating repetitive tasks - Increases productivity - Ex : Allocation of datasets for a release - Ex : Deleting 7th char in all records of a file Interacting with TSO/ISPF dialog manager - to create and display custom-made panels - can store and retrieve variables Creating new commands - Like TIME command, DATE can be created For personal programming tasks - to send a mesg to other MVS users everytime you logon
Implicit execution requires the PDS library to be concatenated to either SYSEXEC or the SYSPROC system DDNAMEs.
READY ALLOC DD(SYSEXEC) DSN(TATA.REXX.EXEC) SHR REUSE
READY
%MYFIRST From ISPF,one can execute it by issuing the following command at command prompt
TSO MYFIRST
It can only be executed using the explicit method or the long form
From READY prompt, READY EXEC TATA.SEQ.EXEC EXEC READY CTP LOGON ALLOCATION In CTP main panel, Select 0 --> CTP parms
Add
Subtract Multiply
/
% // **
Divide
Divide and return a whole number without a remainder Divide and return the remainder only Raise a number to a whole number power
Note: The not character, "", is synonymous with the backslash ("\").
REXX Symbols
A REXX symbol can consist of
A...Z a...z 0...9 @#$?!._ uppercase alphabetic lowercase alphabetic numbers special characters
The first character cannot be 0 through 9 or a period (.) The variable name cannot exceed 250 bytes The variable name should not be RC, SIGL, or RESULT, which are REXX special variables
SIGL: The SIGL special variable is used in connection with a transfer of control within an exec because of a function, or a SIGNAL or CALL instruction. When the language processor transfers control to another routine or another part of the exec, it sets the SIGL special variable to the line number from which the transfer occurred.
RESULT : When an exec calls a subroutine ,the calling exec receives the value returned by the subroutine in the REXX special variable RESULT
REXX Instructions
REXX Instructions
A line contains usually one instruction
name=Kennedy
say Name is name upper name say Now name is name
exit
Output
Name is Kennedy Now name is KENNEDY
REXX Instruction - IF
Used to conditionally execute a single REXX stmt or a group of REXX statements Syntax : If expression then stmt; else stmt;
If expression is evaluated TRUE(1) then the THEN part is performed and if FALSE(0) then the ELSE part is performed.
A group of REXX statements can be grouped together by using DOEND Nested IFs are allowed in REXX.
Syntax : NOP;
When the input is blank or other than AM/PM , the instruction that gets executed is NOP Also note that the ELSE clause is not mandatory When the ELSE clause is removed ,the functionality of the program will still be the same
REXX Instructions - DO
Used to execute a group of REXX statements under the control of an expression Has several formats The repetitive DO construct
DO 5
say hi there!!! END
REXX Instructions - DO
Do with loop counter
/*REXX*/
Do I = 1 to 7 by 2 say I End I /* optional to specify the variable */ /* 2 is the step value */
REXX Instructions - DO
Do..While construct
/*REXX*/
I=1 Do while I < 3 say I I=I+1 End
The output
1 2 Contd...
REXX Instructions - DO
Do..Until construct
/*REXX*/
I=1 Do until I > 3 say I I= I+ 1 End
Contd...
REXX Instructions - DO
The Do..Forever special construct
/*REXX*/
Do forever say infinite loop end The above exec results into an infinite loop
Enough care should be taken to check the exit criteria of the loop, before executing the exec
The LEAVE instruction can be used to exit from the loop
control passes to the next statement after the END of the DO-END pair
Example
/*REXX*/ Do I = 1 to 3 by 1 If I = 2 then iterate I; say I = I /* name is not required */
end Output
I=1 I=3
When the input is anything other than 1 or 2 then the control is transferred to OTHERWISE clause.
out='say hi there!!!' Interpret out stmts='do 3; say 'loop'; end' Interpret stmts exit
Output will be HI THERE!!! LOOP LOOP LOOP
Output
EQUAL Since the FUZZ value is 1,the rightmost is not considered
in the comparison. In the same example ,note that when B takes value 1005 and numeric digit is 5 ,the output is UNEQUAL ,as REXX rounds off the value of B to 101,while eliminating its rightmost digit
/* 1.2345E+13 SCIENTIFIC */
/* 12.345E+12 ENGINEERING */
PARSE NUMERIC name returns the current settings of numeric options DIGITS,FUZZ and FORM
PARSE PULL makes REXX get the string from the REXX data stack.If the stack is empty,REXX will get the string from the terminal PARSE VALUE parses a string under the control of the template PARSE VALUE expression WITH template PARSE VAR indicates that the string to be parsed is not a literal but a variable PARSE VERSION returns REXX interpreter level and the date released
Examples
drop a drop z.5 drop d. /* Unassigns the variable a*/ /* Unassigns the stem variable z.5 */ /* Unassigns all the vars starting with d. */
name1, name2 are not protected from the subroutine.That is they are exposed to the subroutine
If the RETURN instruction doesnt have any expression , then a null string is passed to the caller
Note that the say instruction after signal will never get executed
The PULL instruction is used extract an element from the top of the REXX data stack
REXX Functions
REXX Functions
A function is a sequence of instructions that can receive data, process that data, and return a value. In REXX, there are several kinds of functions: Built-in functions -- These functions are built into the language processor. More about built-in functions appears later in this topic. User-written functions -- These functions are written by an individual user or supplied by an installation and can be internal or external.An internal function is part of the current exec that starts at a label. An external function is a selfcontained program or exec outside of the calling exec
say center(uswest,10,*)
returns **USWEST**
used to compare two strings and return a zero if the strings are the same ,or a non-zero number if they are not
If the optional padding character is specified,then the shorter string is padded and compared
Examples :
COMPARE('123','123') COMPARE('FO?? ','FO','?') COMPARE('abc','ak') COMPARE('ZZ ','ZZ','x') COMPARE('MA ','MA') COMPARE('xy ','xy',' ') returns a 0 (exact match) returns a 5 (1st mismatch after padding) returns a 2 (first mismatching char) returns a 3 (1st mismatch found 3 chars in) returns a 0 (exact match with padding) returns a 0 (exact match with padding)
Examples
DATATYPE(' 44 ') returns NUM (numeric) DATATYPE('*1**') returns CHAR (caharcter string) DATATYPE('Wally','M') returns a 1 (mixed case) DATATYPE('75.54','W') returns a 0 (not a whole number)
Examples
say date() say date('U') say date('J') say date('W') /* returns 17 Dec 1999 */ /* returns 12/17/99 */ /* returns 99351 */ /* returns Friday */
Example
DIGITS() /* returns a 9 if REXX default hasn't been changed */
Example
say from() numeric form engineering say form() /* returns engineering */ /* returns default scientific */
Syntax : FORMAT(number{,{before}}{,{after}})
If before and after are not specified ,the number of digits that are needed to present the rounded number are used
Examples
FORMAT('78',3) returns rounded number ' 78' FORMAT(' - 8.7',,2) returns rounded number '-8.70' FORMAT('5.46',3,0) returns rounded number ' 5'
say fuzz()
numeric fuzz 2 say fuzz()
/* returns 2 */
'start' is an optional starting character position for the search within string
Examples
INDEX('hello','ll') INDEX('say what','w ') INDEX('zyxwvu','vu',6) INDEX('zyxwvu','vu',2) returns a 3 returns a 0 returns a 0 returns a 5
Syntax : LENGTH(string)
Examples :
LENGTH('LIFO') returns 4 LENGTH('Rubber baby buggy bumpers') returns 25 LENGTH('') returns 0 (null string)
/* returns 2 */
This function reverses the order of all characters in a string Syntax : REVERSE( string) Example say reverse(TCSUSWEST)
returns TSEWSUSCT
Syntax : SUBSTR(string,n{,{length}{,pad}})
length is the length of extracted substring if length is omitted,the remainder of the string from char number n is extracted The extract string is padded on the right with pad char, if there are not enough characters in the extracted substring to reach length Examples :
SUBSTR('Hi there',4) returns 'there' SUBSTR('MVS',1,5) returns 'MVS ' SUBSTR('December 7, 1941',6,15,'-') + 'ber 7, 1941----'
Syntax : SYMBOL(name)
Returns BAD if the name is not a valid REXX symbol If name is name of the variable with a value assigned to it,VAR is returned In other cases, LIT is returned Examples :
j='TSO/E Version 2.1' Symbol('J') Drop j Symbol('J') Symbol('.variable') /* assign value to variable J */ /* returns VAR since assigned */ /* returns LIT after Drop */ /* returns BAD since 1st character is a '.' */
Examples :
TIME() returns 09:18:04 TIME('L') returns 11:00:32.672567 TIME('M') returns 840 /* at 2 in the afternoon */ TIME('H') returns 12 /* at noon */ TIME('R') returns 0 /* The first call */ TIME('E') returns 18.278190 /* about 18 seconds later */
'n' is the number of decimal places to retain to the right of the decimal point.If n is omitted,no decimal places are returned
Examples:
TRUNC(4096.6904) /* returns 4096, dropping decimal fraction */ TRUNC(0.3,3) /* returns 0.300 */
say sysvar(sysuid)
displays the user id. The arguments corresponding to user information are SYSPREF - Prefix as defined in user profile SYSPROC - Logon procedure of current session SYSUID - User id of current session
Example
"NEWSTACK" Push tcs Push uswest pull data say from the stack data pull data say from the stack data pull data "DELSTACK" /* creates new stack */ /* puts tcs in top of stack */ /* puts uswest over tcs */ /* pulls data from the top of stack */ /* displays uswest */ /* pulls data from top of stack */ /* displays tcs */ /* obtains input from tso terminal */ /* delete stack */
Example :
NEWSTACK push a queue b NEWSTACK push c say queued() DELSTACK say queued() DELSTACK /* new stack is created */ /* a is stored on top */ /* b is stored at the bottom */ /* new stack is created */ /* c is stored on top */ /* displays 1 */ /* deletes the current stack */ /* displays 2 */ /* deletes the stack */
returns the relative number of the buffer on the stack in the special variable RC
Its a temporary extension to the data stack and used when need arises to pass some of the elements to a subroutine Example :
NEWSTACK Push elem1 "MAKEBUF" saverc = RC Push elem1 Push saverc Call subrtn1 "DROPBUF" /* creates new stack */ /* add an element */ /* add a buffer to stack */ /* save number of buffer */ /* add contents of variable elem1 to data stack */ /* pass buffer number too */ /* call subroutine to handle elements */ /* delete buffer,but not stack before makebuf */
A JCL as shown in the next slide can be used to invoke a REXX exec.
The following points are to be noted : IKJEFT01 - TSO command processor program
Contd..
SYSTSIN - Instream card wherein TSO commands or invocation of REXX execs can be issued
The dataset TCS.REXX.EXEC is a PDS and has a member of the name SETUP. The Instream data can be used to invoke an REXX exec either implicitly or explicitly as indicated below
%SETUP >>>> Implicit EXEC TCS.REXX.EXEC(SETUP) EXEC >>>> Explicit
Any parameters to the exec can be passed as below %SETUP parm1 parm2
Invoke the above exec as ===> TSO CUSER TATA001 A similar exec can be written to display all the users
Edit macro is a series of edit commands placed in a dataset or a member of partitioned dataset
- To find lines with char a in Col. 31 and char b in Col. 35
Consists of two parts ,values and key-phrases,which are separated by an equal sign
Value segment is the data in the macro and key-phrase segment represents the data in the editor
Can be used to pass data from the edit macro to the editor or to transfer data from the editor to the edit macro
Data is always transferred from the right hand side of the equal sign in an assignment statement to the left hand side
If there are more variable names than parameters, the unused variables are set to nulls.
The macro statement should be the first executable statement in a macro
A label must begin with a period (.) and be followed by no more than 8 alphabetic characters, the first of which cannot be Z. No special characters or numeric characters are allowed.
The editor-assigned labels are: .ZCSR The data line on which the cursor is currently positioned .ZFIRST The first data line Can be abbreviated .ZF .ZLAST The last data line. Can be abbreviated .ZL .ZFRANGE The first line in a range specified by you. .ZLRANGE The last line in a range specified by you.
LOCATE
Used to position the cursor in a particular line using label or the line number ISREDIT LOCATE .ZCSR
EXIT
FIND macro commands It displays only the lines with the string passed to the macro
LABEL
sets or retrieves the values for the label on the specified line and places the values in variables ISREDIT (var1) = LABEL .ZCSR ISREDIT LABEL .ZCSR = (.here) LINENUM retrieves the current relative line number of a specified label ISREDIT (lnum) = LINENUM .ZL
Sets or retrieves the data from the data line specified by the line pointer ISREDIT (lndata) = LINE .ZCSR ISREDIT LINE .ZCSR = (datavar) LINE_AFTER Adds a line after a specified line in the current dataset
ISREDIT LINE_AFTER lptr = <DATALINE> data <INFOLINE> <MSGLINE > <NOTELINE> ISREDIT LINE_AFTER .ZCSR = DATALINE (datavar)
LINE_BEFORE Similar to the LINE_AFTER stmt except that it adds a line before the specified the line
The macro can be used to save a member of a PDS,when it is opened in view mode. It checks whether the dataset being edited is a PDS It also checks whether the EDIT is in VIEW mode by trying to save the dataset After these checks,the REPL command is issued. Note : CREATE command can be used to create a new member with the same data
the line command N must be entered prior to invoking the macro Line command - N , NN-NN , Nn Note the use of NOTELINE SHIFT command shifts chars to right To remove the comments,use the built-in (( left shift line command
used to browse a copybook mentioned in a COPY verb of a COBOL program Note the use of SIGNAL instruction The macro command can be typed at the command prompt and cursor can be moved to the COPY verb This macro can also be assigned to a function key using KEYS command and may be invoked by pressing the particular key when the cursor is over the COPY verb
FILE TAILORING
FT - Skeletons
Skeletons are members of a PDS that have variables and fixed text.They may be part of a JCL.(Ex JOB stmt) The skeleton files can contain variable-length records, with a maximum record length of 255. Skeletons can be included in a dataset to build a complete JCL during the run time Skeleton libraries are to be allocated to the application library ddname ISPSLIB The allocation should be done before invoking ISPF Allocation can be done temporarily using ISPF service LIBDEF
LIBDEF ISPSLIB DATASET ID(TATA.PDS.SKELS)
If the output is to be saved in a PS or PDS , the particular library has to allocated to the ddname ISPFILE
Call invocation format ISPEXEC FTOPEN [TEMP] TEMP specifies whether the output is to be placed in temporary file or not If TEMP is not specified,then the ddname ISPFILE should
NOREPL specifies that FTCLOSE is not to overlay an existing member in the output library NAME specifies the name of the member in the output library that is to contain the file tailoring output LIBRARY specifies the name of a DD statement or lib-type on the LIBDEF service request that defines the output library in which the member-name exists. If specified, a generic (non-ISPF) DD name must be used. If this parameter is omitted, the default is ISPFILE.
These are the two skeletons we will be using in the REXX exec to build the sort jcl
Note that all three variables have been substituted with appropriate values Note the single ampersand in the NOTIFY parameter
ISPF Panels
A simple REXX Exec that displays a panel that prompts for the user name After the panel is submitted, the name entered is displayed After the panel is displayed and inputs are entered,if enter is pressed RC is zero and if PF3 pressed, RC will be 8
ISPF TABLES
ISPF Tables
ISPF tables are analogous to arrays A table can exist with or without a key
and must begin with an alphabet name-list are the list of variables that forms the columns of the table
Example
ISPEXEC TBOPEN FSTATUS WRITE and
ISPEXEC TBOPEN FSTATUS are the same as WRITE is the default option
For tables without keys,the row is added after the current row
For tables with keys ,the table is searched to ensure that the new row has a unique key Command invocation format
ISPEXEC TBADD table-name [SAVE(name-list)] [ORDER]
Example
ISPEXEC TBSCAN FSTATUS ARGLIST(FCODE)
Searches the table FSTATUS using the argument FCODE and fetches the error message associated with it.If the row exists in the table, the error message will be stored in the variable MESSAGE as in the TBCREATE service
TBSKIP has many other parameters which are beyond the scope of this training
/*REXX*/ address ispexec "libdef isptabl dataset id('rhkrish.test.tables')" "tbopen rexxerr nowrite" say 'enter the error code (1-49) :' pull ecode "tbscan rexxerr arglist(ecode)" if rc = 0 then say 'The error mesg is ' etext else say 'row does not exist' "tbclose rexxerr" say 'Error mesg using function-' errortext(ecode) exit
List of References
REXX in the TSO Environment - Gabriel F.Gargiulo
IKJ2C307
ISPEEM01 ISPSRV01