|
Fuss Free Dataset Name Format Checking
|
|
|
upper dsname /* Make it upper case */
dsname = STRIP(dsname,,'''') /* Remove quotes */
x = MSG('OFF')
TrapON=OutTrap('ON')
Dsnstat = SYSDSN("'"dsname"'") /* Check dataset name */
TrapON=OutTrap('OFF')
x = MSG('ON')
if word(dsnstat,1) = 'INVALID' then do
Say 'Dataset name invalid 'dsname
Signal dosomething
end
|
The technique shown in this example will quickly let you know if the dataset name passed in the variable is in a
valid format or not.
You could use Case logic to trap so many more things but if you are just looking to see if
the format of the dataset is valid, then this technique will do nicely.
|
|
|
| |
|
Zeller's Congruence |
|
|
day.0 = Saturday
day.1 = Sunday
day.2 = Monday
day.3 = Tuesday
day.4 = Wednesday
day.5 = Thursday
day.6 = Friday
temp1 = ((mm+1)*26)%10
temp2 = yy%4
temp3 = 6*(yy%100)
temp4 = yy%400
temp1 = dd+temp1+temp2+temp3+temp4+yy
if yy < 1751 then do
temp1 = temp1 + 11
end
if yy = 1752 then do
if mm <= 3 then do
if mm = 3 then do
if dd <= 24 then do
temp1 = temp1 - 11
end
end
temp1 = temp1 + 11
end
end
temp4 = temp1%7
temp2 = temp4*7
temp3 = temp1-temp2
say day.temp3 dd mm yy
|
Zeller's Congruence (explained here) will calculate the day of the week for a given date.
This sample code shows how to calculate Zeller's congruence in a way such that it is easier to
follow the steps. The code alongside is stripped down for example purposes but a working copy is available here
|
|
|
| |
|
Discovering What LPAR
You Are Running On |
|
|
CVTECVT=D2X(C2D(STORAGE(10,4))+140)
lparname=STRIP(STORAGE(D2X(C2D(STORAGE(CVTECVT,4))+344),8))
permitted_on = "SYS2SYS3" /* only allow it on these systems */
If POS(lparname,permitted_on) = 0 then do
say "Not allowed on "lparname
end
else do say "OK to run on "lparname
end
Example of how to use CPUCHECK
cpucheck
if rc = 0 then
say ‘allowed’
else
say ‘denied’
|
Sometimes you may want to restrict which
LPAR a Rexx exec can execute on.
This code will allow to you find
out which LPAR the exec is running on. The first two lines return the LPAR name and the next few lines
show how to prevent/allow the exec to run.
In this example we
set a list of LPAR names that the exec is allowed to execute on (SYS2 &
SYS3) so that we don't have to code lots of SELECTS just one
simple POS. However you may have to reconsider the POS technique if you
have an LPAR named anything that may get inadvertently matched e.g. YS2S
Of course you could also flip the logic a little and make the name
specified the name of the LPAR that this exec is not allowed to execute
on.
We have a Rexx EXEC named CPUCHECK (available here)
that can be called by any Rexx EXEC and it will set a return code that indicates if the Rexx EXEC
is running on an allowed system or not. An example of how to use this is shown here. It will save you having to
repeat the checking code. Again you can always flip the logic if desired.
It is important to note that CPUCHECK uses a system variable (sysname) that is set on our system. If
you prefer you could navigate the control blocks in the example above. |
|
|
| |
|
Discovering What
Jobname Is Running The Rexx Exec In Batch. |
|
|
CVT =
STORAGE(10,4)
TCBP = STORAGE(D2X(C2D(CVT)),4) /* CVTTCBP */
TCB = STORAGE(D2X(C2D(TCBP)+4),4)
TIOT = STORAGE(D2X(C2D(TCB)+12),4) /* TCBTIO */
job = STRIP(STORAGE(D2X(C2D(TIOT)),8)) /* TIOCNJOB */
|
This code can be used to discover the job
name that is running the Rexx exec in batch.
If you do it under TSO it
will return your own TSO name.
Once you have the jobname you can make lots of choices based on the
jobname...like use it for a dataset level or, if you have good naming
standards you can take a different logic flow based on whether it is a
production or development job. |
|
|
| |
|
Discovering The
Job Number of The Job Running The Exec. |
|
|
CVT = STORAGE(10,4)
TCBP = STORAGE(D2X(C2D(CVT)),4) /* CVTTCBP */
TCB = STORAGE(D2X(C2D(TCBP)+4),4)
JSCB = STORAGE(D2X(C2D(TCB)+180),4) /* JSCB */
SSIB = STORAGE(D2X(C2D(JSCB)+316),4) /* SSIB */
jobnum = STRIP(STORAGE(D2X(C2D(SSIB)+12),8)) /* Get jobnum */
|
This code can be used to discover the job
number that is running the Rexx exec in batch.
If you do it under TSO it
will return your own TSO number.
|
|
|
| |
|
Replacing a String In
a Rexx Exec |
|
|
/* Rexx */
input = 'my favorite color is red'
input = strrepl(input,'red','green')
say input
exit
StrRepl:
Orig = ARG(1)
Oldtxt = ARG(2)
Newtxt = ARG(3)
Newstr = ''
Work = Orig
Do while POS(Oldtxt,Work) > 0
Newstr = Newstr||SUBSTR(Work,1,pos(Oldtxt,Work)-1)||Newtxt
Work= SUBSTR(Work,pos(Oldtxt,Work)+LENGTH(Oldtxt))
end
Newstr = Newstr||SUBSTR(Work,1)
return Newstr
|
We use this routine in many of our Rexx execs.
It will
replace the second value with the third value in the field specified by
the first value. The string lengths don't matter so it makes this code
pretty slick.
In the example here we replace the sting 'red' with the
string 'green' in the field 'input' which contains the string 'my
favorite color is red'.
Note: The StrRepl routine here is a subroutine and so it
can be copied and pasted in its entirety into any exec and be ready to
be used.
A text version of StrRepl subroutine is available from here. |
|
|
| |
|
Finding The Name of The Current Exec
|
|
|
/* Rexx */
dialogid = sysvar(sysicmd)
parse source Exec_String
excnme = word(Exec_String,3) /* Get EXEC's name */
say excnme ' Starting.' date() time()
final = TIME('Reset ')
say excnme 'Finished :' date() time() 'Elapsed time 'time(e) 'seconds'
exit
|
This snippet of code will return the name of the executing Rexx exec.
In
this sample code we also demonstrate how to display the time that the Rexx exec took
to execute.
|
|
|
| |
|
Convert A Month Number To Month Name
|
|
|
/* Rexx */
Mon.01="January"
Mon.02="February"
Mon.03="March"
Mon.04="April"
Mon.05="May"
Mon.06="June"
Mon.07="July"
Mon.08="August"
Mon.09="September"
Mon.10="October"
Mon.11="November"
Mon.12="December"
myDate= "1999/12/25" /* This is a sample date in yyyy/mm/dd format */
year = substr(myDate,1,4) /* Year portion (change as appropriate) */
day = substr(myDate,9,2) /* Day portion (change as appropriate) */
mon = substr(myDate,6,2) /* Month portion (change as appropriate) */
monname=MON.mon /* translate to name */
say day monname year /* show the date */
exit
|
Sometimes a date is in all numeric format and you may want the full month name
in this case this sample code will do the trick.
Any value can be placed in the 'table'. In
other words if you only want the first three characters, then simply enter them instead of the full
month name.
You will need to tweak the code to accommodate the date format if it isn't yyyy/mm/dd.
A text version of this code can be found here.
|
|
|
| |
|
Building a Delay Into a Rexx Exec (Sleep)
|
|
|
/* Rexx */
parse upper arg time value
If value <> "" then do
value = substr(value,1,1)
/* If you don't pass a value seconds are assumed otherwise:*/
/* use M for minutes or H for hours */
if value = "M" then time = time * 60
if value = "H" then time = time * 60 * 60
end
if time = "" then time = '1'
hit = 0
Do while hit < time
hit = TIME('Elapsed ')
end = lastpos('.',hit)
hit = substr(hit,1,end)
end
exit
|
Occasionally you may want to delay an Exec for a couple of seconds or more. There is currently no inbuilt
Rexx function for this. This Exec will delay the execution of the calling Exec for the number of seconds, minute or hours that
are passed to it.
*** WARNING *** This Exec takes no prisoners! If you say sleep for an extended duration
it will do just that and will lock out the TSO id or job for that long.
A text version of this code can be found here.
|
|
|
| |
|
Converting a String to Proper Name Format
|
|
|
/* Rexx */
input = 'ABBYDALE'
input = Proper(input)
say input
exit
Proper:
Orig = ARG(1)
if length(orig) > 1 then do /* Ensure there is more than one char */
UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
LOWER = "abcdefghijklmnopqrstuvwxyz"
tempName = TRANSLATE(Orig,LOWER,UPPER)
build = substr(tempName,2,Length(tempName)-1)
initial = substr(tempName,1,1)
initial = TRANSLATE(initial,UPPER,LOWER)
newname = initial||build
end
else do
newname = Orig
end
return newname
|
When you are dealing with proper names (People's name, place names etc.) the correct format is to start them with
a capital letter. Unlike some languages there is no built in Rexx function for doing this therefore we use this
subroutine for achieving this.
In the example shown the name ABBYDALE will be converted to Abbydale by the subroutine. It should
be noted that even if the name is already in lower case this routine will work.
Note: The Proper routine here is a subroutine and so it
can be copied and pasted in its entirety into any exec and be ready to
be used.
A text version of Proper subroutine is available from here.
A brief demonstration is available here.
|
|
|
| |
|
Dropping the Last Level From a Dataset Name
|
|
|
dsname = SUBSTR(dsname,1,(LASTPOS('.',dsname)-1))
|
If you ever want to drop the last level from a dataset name, you can do it by using this code.
You can use this for generic LISTCATs etc.
Looping through this process will drop you down more levels.
|
|
|
| |
|
Obtaining the Current TSO PROFILE PREFIX
|
|
|
/* rexx */
prof = getprof(prof) /* Get current prefix */
say "Value of prof="Prof /* Show answer */
"Profile noprefix" /* Profile NOPREFIX */
prof = getprof(prof) /* Get current prefix */
say "Value of prof="Prof /* Show answer */
"Profile PREFIX("userid()")" /* Set to our userid */
prof = getprof(prof) /* Get current prefix */
say "Current profile "prof /* Show answer */
"Profile noprefix" /* Set NOPREFIX */
"Profile" /* Show our profile */
say
say "Value of prof="Prof /* Show answer */
say
if Prof/='N' then do /* Prof = our userid */
"Profile PREFIX("Prof")" /* Reset prefix */
end
"Profile" /* Show our profile */
exit
|
It is sometimes useful to store the TSO PREFIX in use when a Rexx is executing. It is extremely useful
when you want to set the PROFILE to NOPREFIX but want to reset it back to what it was when the exec was called.
GETPROF can provide this function.
The GETPROF routine is available from here.
The code alongside is NOT GETPROF but a demonstration of how to use GETPROF.
A copy of the code alongside is available from here. |
|
|
| |
|
Counting Occurances of a String
|
|
|
Usage x=CountStr(find,where)
Sample of use:
x = CountStr('.','ABBYDALE.ALLFREE.REXX')
This would return 2 as the value of x.
If you need to know if this is an odd or even number you can use:
x = CountStr('.','ABBYDALE.ALLFREE.REXX')//2
if x > 0 say 'Odd'
|
This function will count the number of times a passed string occurs in another passed string.
This is useful if you want to count the number of levels in a dataset name.
The COUNTSTR routine is available from here.
|
|