Rexx Primer - 2

  • June 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Rexx Primer - 2 as PDF for free.

More details

  • Words: 1,847
  • Pages: 7
Quick REXX Part II By Alok Devtale

I hope that the first document was helpful. If you have tried all the syntax given in the first part, you know just enough of REXX. Let’s move forward. 1. PARSE is a very powerful verb. One use of PARSE that we have seen is to accept data from the external source or the terminal (i.e. the user). PULL can be used instead of PARSE in some cases to accept the data. PULL NAME1 Will behave as PARSE EXTERNAL NAME1 as long as you are not using Stack. You can even use PARSE PULL or PARSE UPPER PULL (Try out and see what happens. Just give the input in different cases). The general structure of PARSE is something like this PARSE [UPPER] [(EXTERNAL ARG VAR VALUE)] [INPUT STRING/VARIABLE] [O/P TEMPLATE or VARIABLE] I will mainly talk about VAR. If we have a variable STRING1 = ‘THIS IS A SENTENCE’ Then the following code PARSE VAR STRING1 WORD1 WORD2 WORD3 WORD4 WORD5 will populate WORD1 with “THIS”, WORD2 with “IS” and so on. WORD5 will have nothing as the string will be eaten up by the first four variables. Suppose you want to split a sentence and put its words in an array, this is what you do: STRING1 = “ONE TWO THREE FOUR A B C D” I = 1 DO UNTIL STRING1 = “” PARSE VAR STRING1 ARRAY1.I STRING1 SAY ARRAY1.I I = I + 1 END As you can see SPACE has been treated as a delimiter in the above example. You can specify your own delimiter. Say you had a string STRING1 = “ONE,TWO,THREE,FOUR,A,B,C,D” (say a line from a CSV format file) Following code will do exactly the same thing as the above given code I = 1 DO UNTIL STRING1 = “” PARSE VAR STRING1 ARRAY1.I “,” STRING1 SAY ARRAY1.I I = I + 1 END See how “,” has been used as delimiter. Yet another way PARSE can be used is by providing position and length of the string. Look at the following code: STRING1 = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”

If you want to have 4 letters per element of the array, this is what you code: I = 1 DO UNTIL STRING1 = “” PARSE VAR STRING1 1 ARRAY1.I 5 STRING1 SAY ARRAY1.I I = I + 1 END Here “1” and “5” specify the starting position of the elements. Same results can be achieved if you write following PARSE statement in the DO loop. PARSE VAR STRING1 ARRAY1.I 5 STRING1 (1 has been omitted. It is optional and default is 1) PARSE VAR STRING1 1 ARRAY1.1 5 ARRAY1.2 9 ARRAY1.3... (This code will work without the DO loop) There are many other variants of PARSE which can be found out from reference material. But the variants given here will do lot of the stuff that you may want to do. 2. Let’s move on to the concept of data stack. It is simple. Stack is an array, which can be used in two ways: FIFO and LIFO. FIFO means First in First out and LIFO means Last in first out. How it works? Simple. FIFO is like a pipe. You queue the elements from one end of the pipe and PULL them from the other end. So, the elements that you queue first will be available for PULLing first. And LIFO is like a container. The things that you put in the container in the first place can be removed only at the end. Hope this is clear. How do you achieve this? To get the FIFO effect, that is the pipe effect, you make queue by using the QUEUE syntax and then PULL the elements from the start of the QUEUE. See the following code and see if it makes sense. QUEUE ONE QUEUE TWO QUEUE THREE DO I = 1 BY 1 UNTIL I = 3 PULL VAR1 SAY VAR1 END This code will produce following o/p ONE TWO THREE And the LIFO effect, that is the container effect is achieved by first PUSHing the elements in the container and then PULLing them from the top. See the following example. PUSH ONE PUSH TWO PUSH THREE DO I = 1 BY 1 UNTIL I = 3 PULL VAR1 SAY VAR1 END This code will produce following o/p

THREE TWO ONE Note that you do not have to declare an stack. The QUEUE and PUSH commands will directly populate the system data stack. And as you go on pulling from the stack those elements will get deleted from the stack. So, if you PUSH or QUEUE three elements and PULL three elements, the stack is empty now. The next PULL instruction will find nothing in the stack and will look for the external source (terminal) for input. That is why, if you have an empty stack, you can use PULL to accept value from the user. Obvious question is what is the use of Stack? The answer is: it depends on your creativity! One simple use is for reversing the order of elements. It is more useful while you do file operations. 3. I will give the basic file operation syntax. To open and read the file you simply have to write following code: "EXECIO * DISKR ddname (FINIS" where, EXECIO is the main verb, * will specify that all the lines are to be read (till the end of file). DISKR specifies that the file is opened for reading purpose. Ddname is the ddname to which you assigned the physical file using ALLOCATE. And (FINIS specifies that the file has to be closed after reading. It is that simple! And where does all the data from the file go? It is QUEUEd to the Stack. So, you can get the data by PULLing one recode at a time from the stack. See the following example: ADDRESS TSO "ALLOCATE DD(DD1) DSN('dsname')" "EXECIO * DISKR DD1 (FINIS" PULL VAR1 DO UNTIL VAR1 = "" SAY VAR1 PULL VAR1 END "FREE DD(DD1)" See some more variants: "EXECIO 1 DISKR ddname" Here, we will be reading only one record from the file. Note that the (FINIS is missing. So, the file is not closed yet. You will have to close it or it will be closed automatically at the end of the procedure. You can read any number of records at a time. Remember they will be QUEUEd to the stack. Another variant: "EXECIO * DISKR ddname (STEM ARRAY1." Here the file will be read to an array ARRAY1 because of the (STEM parameter. So, the code given in the above example will become even more compact: "ALLOCATE DD(DD1) DSN('R1LTPB.J1LTBRP.TRSRPT1')" "EXECIO * DISKR DD1 (STEM ARRAY1." DO I = 1 BY 1 UNTIL I > ARRAY1.0 SAY ARRAY1.I END "FREE DD(DD1)"

Look how the 0th element is used in the example. It was automatically populated by the EXECIO command. Let’s move on to the DISKW operation. As is obvious from the name this parameter when used in EXECIO will write to a file. It behaves like DISKR with only difference that DISKW will write to a file whereas DISKR will read from a file. DISKR reads from a file into stack or Array where as DISKW will write to a file from stack or array. One tricky situation arises when the Stack has a blank element. While writing from such stack the EXECIO DISKW operation stops at the black line thinking that the stack is empty. Try out and you will see what I mean. This problem can be avoided by using array instead of stack. I am attaching a sample program which will make more sense now that you know the basics. I have not talked about the very basic things like IF and other controlling statements. Only one peculiar thing about IF is that, if you want to have more than one statement inside an IF, you have to use DO and END to encompass those statements. e.g IF a=b THEN DO Statement1 Statement2 END ELSE... Also, look in the code for how to call sub-procedures and for the moment ignore the ISPF related commands. Assignment for this part would be: Keep information about employees in a file (Like employee number, name, and daily salary). From the user accept employee ID and number of days he attended. From the input file find out the details for this employee. Create his salary slip and write to an o/p file. How about making this o/p file a member of a PDS? One member per employee? SAMPLE CODE: /*REXX*/ ADDRESS "TSO" /*"FREE DDNAME(INPFIL)" "FREE DDNAME(UPDFIL)" "FREE DDNAME(OPFIL)"*/ ADDRESS "ISPEXEC" "LIBDEF ISPPLIB DATASET ID('xxxx.xxxxx.xxxxx')" "DISPLAY PANEL(UPDATED)" IF RC <> 8 THEN DO ADDRESS "TSO" "ALLOCATE DDNAME(INPFIL)", "DSNAME('"INPFILE"')" "ALLOCATE DDNAME(UPDFIL)", "DSNAME('yyyyy.yyyyy.yyy')" "ALLOCATE DDNAME(EXTFIL)", "DSNAME('T906.QTRTOOL.EXTJOBS')"

/*"ALLOCATE DDNAME(OPFIL) DSNAME('"OPFILE"')", "LIKE('"INPFILE"')"*/ "ALLOCATE DDNAME(LJOBFIL)", "DSNAME('nnnn.nnnnn.nnnnn')" ADDRESS "TSO" "EXECIO * DISKR INPFIL (STEM RECOI. FINIS" "EXECIO * DISKR UPDFIL (STEM RECOU. FINIS" "DELSTACK" COUNTI = RECOI.0 COUNTU = RECOU.0 I = 1 J = 1 IF COUNTU = 0 THEN DO "FREE DDNAME(INPFIL)" "FREE DDNAME(EXTFIL)" "FREE DDNAME(UPDFIL)" "FREE DDNAME(LJOBFIL)" EXIT END DO J = 1 BY 1 UNTIL J = COUNTI RECI = RECOI.J STR = SUBSTR(RECI,1,2) IF STR = 'J9' THEN CALL VALIDATE QUEUE RECI END ADDRESS "TSO" "FREE DDNAME(INPFIL)" "ALLOCATE DDNAME(OPFIL) DSNAME('"INPFILE"')" "EXECIO * DISKW OPFIL (FINIS" CALL UPDATE CALL LASTJOB "FREE DDNAME(OPFIL)" "FREE DDNAME(EXTFIL)" "FREE DDNAME(UPDFIL)" "FREE DDNAME(LJOBFIL)" END EXIT VALIDATE: DO I = 1 BY 1 UNTIL I > COUNTU RECU = RECOU.I JOBNMPR = SUBSTR(RECU,1,8) IF JOBNMPR <> '' THEN DO JOBNMU = WORD(RECU,1) JOBNM = WORD(RECI,1) IF JOBNM = JOBNMU THEN DO STDTU = WORD(RECU,2) STTMU = WORD(RECU,3) EDDTU = WORD(RECU,4) EDTMU = WORD(RECU,5) CPUTU = WORD(RECU,6) TOTMU = WORD(RECU,7) RECI = OVERLAY(STDTU,RECI,10,5) RECI = OVERLAY(STTMU,RECI,16,5) RECI = OVERLAY(EDDTU,RECI,22,5)

RECI = OVERLAY(EDTMU,RECI,28,5) RECI = OVERLAY(TOTMU,RECI,34,5) RECI = OVERLAY(CPUTU,RECI,40,5) JOBNMU = ' ' RECU = OVERLAY(JOBNMU,RECU,1,8) RECOU.I = RECU END END END RETURN UPDATE: ADDRESS "TSO" "DELSTACK" "EXECIO * DISKR EXTFIL (FINIS" DO I = 1 BY 1 UNTIL I = COUNTU RECU = RECOU.I JOBNMPR = SUBSTR(RECU,1,8) IF JOBNMPR <> '' THEN DO QUEUE RECU END END ADDRESS "TSO" "EXECIO * DISKW EXTFIL (FINIS" RETURN LASTJOB: ADDRESS "TSO" "EXECIO * DISKR UPDFIL (STEM RECOU. FINIS" "EXECIO * DISKR LJOBFIL (STEM RECOJ. FINIS" "DELSTACK" COUNTU = RECOU.0 RECJ1 = RECOJ.1 RECJ2 = RECOJ.2 PUSH 'EOF' DO I = 1 BY 1 UNTIL I = COUNTU RECU = RECOU.I PUSH RECU END SWITCHA = 0 RECU = '' DO UNTIL SWITCHA = 1 | RECU = 'EOF' PULL RECU JOBINIT = SUBSTR(RECU,1,4) IF JOBINIT = 'J906' THEN DO SWITCHA = 1 JOBNM = WORD(RECU,1) RECJ1 = JOBNM END END ADDRESS "TSO" "DELSTACK" PUSH 'EOF' DO I = 1 BY 1 UNTIL I = COUNTU RECU = RECOU.I PUSH RECU END SWITCHP = 0

RECU = '' DO UNTIL SWITCHP = 1 | RECU = 'EOF' PULL RECU JOBINIT = SUBSTR(RECU,1,4) IF JOBINIT = 'J9DP' THEN DO SWITCHP = 1 JOBNM = WORD(RECU,1) RECJ2 = JOBNM END END ADDRESS "TSO" "DELSTACK" QUEUE RECJ1 QUEUE RECJ2 ADDRESS "TSO" "EXECIO * DISKW LJOBFIL (FINIS" RETURN

Related Documents

Rexx Primer - 2
June 2020 2
Rexx Primer -1
June 2020 2
Rexx
November 2019 24
Rexx
November 2019 25
Rexx-vse
November 2019 20
Rexx Training
November 2019 17