Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Verify function

8 views
Skip to first unread message

Lindy Mayfield

unread,
Aug 15, 2008, 10:45:31 PM8/15/08
to
An interesting thing about Rexx is that there aren't really a lot of
built-in functions, so it doesn't take long to learn most of them. Some
I've never used before, though, but not because I didn't want to.

I'm getting the jobname from a control block but in some cases (don't
know why, don't too much care) it is all garbage. So I wanted to
display N/A if the data is all bad.

Whenever I need to do something I've not done before I always go down
the functions in the Rexx reference to see if any of them might help.
Then I ran into Verify. It seems to do everything I need.

JUSERID = storage(d2x(JSAB+44),8) /* jsab+2c -> jsabusid */

ValidChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#$@ '
If Verify(JUSERID,ValidChars,'N') > 0
Then JUSERID = 'N/A'

I need to play around with it a bit more, but it seems to be doing the
trick.

--Lindy

----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to LIST...@VM.MARIST.EDU with the message: INFO TSO-REXX

Lee, Bill

unread,
Aug 17, 2008, 8:15:30 AM8/17/08
to
Good tip Lindy, thanks for sharing.

--Lindy

--------------------------------------------------
This e-mail transmission contains information intended only for the use of the
recipient(s) named above. Further, it contains information that may be privileged
and confidential. If you are not the intended recipient, you are hereby notified
that any dissemination, distribution, or copying of this message (including any
attachments) is strictly prohibited. If you have received this e-mail in error,
please notify the sender by reply e-mail and then delete this message from your mail
system. Thank you for your compliance.

Hamilton, Robert L

unread,
Aug 17, 2008, 8:23:42 AM8/17/08
to
I think the JOBNAME must start with @,#,$ or 'A-Z'; no?

bobh

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf
Of Lindy Mayfield
Sent: Friday, August 15, 2008 9:45 PM
To: TSO-...@VM.MARIST.EDU
Subject: Verify function

Binyamin Dissen

unread,
Aug 17, 2008, 9:31:47 AM8/17/08
to
On Sat, 16 Aug 2008 07:48:52 -0500 "Hamilton, Robert L" <rob...@UTDALLAS.EDU>
wrote:

:>I think the JOBNAME must start with @,#,$ or 'A-Z'; no?

A better solution would be looking for a zero address/value.

:>-----Original Message-----


:>From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf
:>Of Lindy Mayfield
:>Sent: Friday, August 15, 2008 9:45 PM
:>To: TSO-...@VM.MARIST.EDU
:>Subject: Verify function

:>An interesting thing about Rexx is that there aren't really a lot of
:>built-in functions, so it doesn't take long to learn most of them. Some
:>I've never used before, though, but not because I didn't want to.

:>I'm getting the jobname from a control block but in some cases (don't
:>know why, don't too much care) it is all garbage. So I wanted to
:>display N/A if the data is all bad.

:>Whenever I need to do something I've not done before I always go down
:>the functions in the Rexx reference to see if any of them might help.
:>Then I ran into Verify. It seems to do everything I need.

:>JUSERID = storage(d2x(JSAB+44),8) /* jsab+2c -> jsabusid */

:>ValidChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#$@ '
:>If Verify(JUSERID,ValidChars,'N') > 0
:> Then JUSERID = 'N/A'

:>I need to play around with it a bit more, but it seems to be doing the
:>trick.

--
Binyamin Dissen <bdi...@dissensoftware.com>
http://www.dissensoftware.com

Director, Dissen Software, Bar & Grill - Israel


Should you use the mailblocks package and expect a response from me,
you should preauthorize the dissensoftware.com domain.

I very rarely bother responding to challenge/response systems,
especially those from irresponsible companies.

Lindy Mayfield

unread,
Aug 17, 2008, 9:48:59 AM8/17/08
to
Good point, Binyamin. Not only did I learn to use a new Rexx function,
I've now fixed a bug in my program.

I need to only get user if JSAB not 0:

if JSAB /= 0
then Do
JOBID = storage(d2x(JSAB+20),8) /* jsab+14 -> jobid */

JUSERID = storage(d2x(JSAB+44),8) /* jsab+2c -> jsabusid */

end
else JUSERID = 'N/A'

Ryerse, Robin

unread,
Aug 18, 2008, 12:14:43 PM8/18/08
to
VERIFY is also handy with the 'Match' option. For example you need to
extract the dataset name from a string representing the JCL for a DD
statement. Therefore the DSN= operand can be delimited by a blank, by a
comma, or by end-of-string. Note that the example will yield a null
string when DSN= does not exist in the source.

parse var jcl_string 'DSN=' dsn_string
dsname = left(dsn_string,verify(dsn_string" ", " ,", "M")-1)

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf
Of Lindy Mayfield
Sent: August 15, 2008 10:45 PM
To: TSO-...@VM.MARIST.EDU
Subject: Verify function

Lindy Mayfield

unread,
Aug 18, 2008, 2:00:41 PM8/18/08
to
That's a great tip. Thanks. I'm going to use that, by the way.

I have an edit macro that I wrote may years ago when I first learned
Rexx. I can type XED and put the cursor on a dataset name and it will
edit the dataset.

I'm not too ashamed of the code since it was one of the very first Rexx
programs I wrote. But it really is funny as H - E - double hockey
sticks. Thought I'd put a bit of it here for laughs. (-:


"Isredit (line, col) = Cursor"
"Isredit (datline) = LINE " line
Valid = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@$#().'
/* Parse right ... */
Do idx = col to Length(datline)
If Pos(Substr(datline,idx,1),Valid) = 0
Then Do
Rpos = Idx - 1
Leave
End
End
/* Parse left ... */
Do idx = col to 1 by -1
If Pos(Substr(datline,idx,1),Valid) = 0
Then Do
Lpos = Idx + 1
Leave
End
End
Dsname = Substr(datline,lpos, rpos - lpos + 1)


-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf

Of Ryerse, Robin
Sent: 18. elokuuta 2008 19:12
To: TSO-...@VM.MARIST.EDU
Subject: Re: [TSO-REXX] Verify function

VERIFY is also handy with the 'Match' option. For example you need to
extract the dataset name from a string representing the JCL for a DD
statement. Therefore the DSN= operand can be delimited by a blank, by a
comma, or by end-of-string. Note that the example will yield a null
string when DSN= does not exist in the source.

parse var jcl_string 'DSN=' dsn_string
dsname = left(dsn_string,verify(dsn_string" ", " ,", "M")-1)

----------------------------------------------------------------------

Hamilton, Robert L

unread,
Aug 18, 2008, 2:06:20 PM8/18/08
to
/* You might want to consider */

Jcl_string = strip(jcl_string);

bobh

Ryerse, Robin

unread,
Aug 18, 2008, 2:25:32 PM8/18/08
to
You should review my post of the @CURSOR function. With that you can
"cursor select" a string from any ISPF panel (even ISPF messages) rather
than just an EDIT macro.

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf

Of Lindy Mayfield
Sent: August 18, 2008 2:00 PM
To: TSO-...@VM.MARIST.EDU
Subject: Re: Verify function

Lindy Mayfield

unread,
Aug 18, 2008, 3:00:20 PM8/18/08
to
The macro works by either being on a line that has DSN= and picking up
the dataset name. If there is no DSN=, then if the cursor is anywhere
on a (valid) dataset name and it picks it out of the whole line of data.
So what I did was go backward and forwards looking for the beginning and
end.

Live and learn.

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf
Of Hamilton, Robert L
Sent: 18. elokuuta 2008 21:06
To: TSO-...@VM.MARIST.EDU
Subject: Re: [TSO-REXX] Verify function

/* You might want to consider */

Jcl_string = strip(jcl_string);

bobh

----------------------------------------------------------------------

Ryerse, Robin

unread,
Aug 19, 2008, 10:59:31 AM8/19/08
to
Unnecessary code is my pet peeve. The example I cited does not require
the STRIP function in any circumstance. Using "just-in-case I missed
something" rationale implies your analysis is incomplete.

Bob Bridges

unread,
Sep 10, 2008, 12:49:58 PM9/10/08
to
I'm catching up on old discussions and this comment of Robin's caught my
eye. This isn't quite what Robin was addressing, but he reminded me of
something I do deliberately that might trigger his pet peeve, not so much
because my analysis is incomplete as because I see a cheap way of covering
myself in case I discover so later. Suppose I have already determined,
earlier in the code, that myvalue is either 'G', 'S' or '*':

select
when myvalue='G' then ...
when myvalue='S' then ...
when myvalue='*' then ...
otherwise call abend 'Impossible condition: myvalue='myvalue
end

I don't always stick in extra ImpCond abends like this, but once in a while
I see a place for one that costs me very little. I know that sometimes an
impossible condition turns out to be just a little less impossible than I
believed; on such occasions it's nice when the program actually tells me
about it rather than running on as though nothing was wrong, stopping only
later with misleading symptoms....or worse, not stopping at all, just
handing back bogus results with no indication that they're wrong.

...Not that I disagree with Robin in principle; clean code is better for
maintenance.

---
Bob Bridges, rhb...@attglobal.net
cell 336 382-7313

/* Science is a way of trying not to fool yourself. -Richard Feynman */

-----Original Message-----
From: Ryerse, Robin
Sent: Tuesday, August 19, 2008 10:59

Unnecessary code is my pet peeve. The example I cited does not require
the STRIP function in any circumstance. Using "just-in-case I missed
something" rationale implies your analysis is incomplete.

-----Original Message-----
From: Hamilton, Robert L
Sent: August 18, 2008 2:06 PM

/* You might want to consider */

Jcl_string = strip(jcl_string);

----------------------------------------------------------------------

Michael Giaquinto

unread,
Sep 10, 2008, 12:59:16 PM9/10/08
to
Bob,
I agree with you. A large percentage of the code I write (rexx or
otherwise) is what I call "defensive programming". While we strive to
be 100% accurate with our analysis, it is only accurate at that moment
in time. Things change, and these little "CYA" techniques may save your
derriere some day.

Mike Giaquinto
AVP/CICS Technical Lead - Wells Fargo
This message may contain confidential and/or privileged information. If
you are not the addressee or authorized to receive this for the
addressee, you must not use, copy, disclose, or take any action based on
this message or any information herein. If you have received this
message in error, please advise the sender immediately by reply e-mail
and delete this message. Thank you for your cooperation

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf

Thomas Berg

unread,
Sep 10, 2008, 1:14:50 PM9/10/08
to
I do also agree with You.
That's because of two things:
1. We are not foolproof, however bright we are.
2. Testing is a very expensive task. (If the outcome is important.)

"Current condition out of bound" test saves time
when You are outlining the "analysis". That's
mainly because environment trumphs logic...


Regards,
Thomas
__________________________________________
Thomas Berg Specialist IT-U SWEDBANK

> -----Ursprungligt meddelande-----
> Från: TSO REXX Discussion List
> [mailto:TSO-...@VM.MARIST.EDU] För Bob Bridges
> Skickat: den 10 september 2008 18:49
> Till: TSO-...@VM.MARIST.EDU
> Ämne: [TSO-REXX] Impossible conditions

Rick Woods

unread,
Sep 10, 2008, 1:43:58 PM9/10/08
to
I agree too.
For one thing, saying "your analysis is incomplete" if you put in catch-all code smacks of elitism. On one level, your analysis can never be complete; s*** happens, and I've had crazy things happen on software that had been running for years, which I corrected by using STRIP(var). That one crazy condition that just didn't occur to me (or whoever wrote it).
On another level, production is no time to find out that you missed something. Your customers will forgive an extra instruction that you may or may not need, far more than they'll forgive a process that fails because you assumed you had thought of everything!
The point isn't to CYA - it's to C your client's A!

Who said "Trust, but verify"? Too true!
- Rick

>>> "Bob Bridges" <rhb...@ATTGLOBAL.NET> 9/10/2008 9:49 AM >>>

Bob Hamilton

unread,
Sep 10, 2008, 2:28:58 PM9/10/08
to
Not really; It means I remember all the times I've been bit
by a customer telling me that so-and-so will never contain.
. . . . . . .

bobh

Phil Smith III

unread,
Sep 11, 2008, 12:56:36 AM9/11/08
to
The difference between applications people and systems people:
Applications people worry about how it will work.
Systems people worry about how it will fail.
-- me

Adding error handlers for "impossible" conditions is the mark of an experienced system programmer who understands that it is the "impossible" error that will bite you where it hurts.

There's a difference between "It doesn't hurt to be too careful" and "This really, really can never happen because doing so would violate the language (or hardware) specification". (If you're going to do that, then you'll need an error handler after every instruction. Of course, the error handler *itself* executes instructions, so they'll need error handlers...)

The key is that any time there is user input, or a command is executed, you don't have full control and cannot predict the results. In the original example, there is no way for the string to have leading/trailing blanks *if the statement it is parsing was valid to begin with*. So perhaps it is unnecessary code, perhaps not: we don't know what the original statement looks like. For my money, I'd probably do a STRIP in this case, although not the one suggested, since "...a string representing the JCL for a DD statement" could be:
DSN= SOME.DSN
So a STRIP of dsn_string after the PARSE would be of value.

Actually, instead of the STRIP, I would have made the PARSE template into:
parse var jcl_string 'DSN=' dsn_string .
and avoided the whole issue that way.

Better yet:
parse value translate(jcl_string, ' ', ',') with 'DSN=' dsname .
which solves the whole problem in a single statement ("translate any commas to blanks, then take the first token after DSN= and stuff it into dsname"). Depending on the environment, you might want to PARSE UPPER as well.

...phsiii

Lindy Mayfield

unread,
Sep 11, 2008, 2:59:08 AM9/11/08
to
I think that a basic rule, at least for me, is to check every return
code (rc) value. That takes care of all outside commands and
environments that Rexx interfaces with and catches a large percentage of
errors.

For me the next step is handling data within the Rexx program. People
have already given examples of this sort of thing, from user input to
reading external data. Taking care that the data is correct before
calling any external Rexx commands is good programming practice, but
difficult to code for every situation.

And then there are the flat our Rexx syntax (also signal on xxx) and
other Rexx errors. In my opinion if a Rexx error is encountered and
fixed then all along it was just a bug in the code.

Lindy

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf
Of Phil Smith III
Sent: 11. syyskuuta 2008 7:56
To: TSO-...@VM.MARIST.EDU

Gardiner, Roy

unread,
Sep 11, 2008, 4:20:23 AM9/11/08
to
'Call on error' was put in to cater for generic error handling. I only
ever check return codes for 'possible' values; the 'impossible' are
handled by the generic code - you never need to add special code for
such, IMO

You obviously can't allow your program to be broken by primary (typed,
for instance) data; but you can't check *everything* - you'd never write
any actual code.


-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf
Of Lindy Mayfield
Subject: Re: Impossible conditions

I think that a basic rule, at least for me, is to check every return
code (rc) value. That takes care of all outside commands and
environments that Rexx interfaces with and catches a large percentage of
errors.

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf
Of Phil Smith III
Subject: Re: [TSO-REXX] Impossible conditions

Adding error handlers for "impossible" conditions is the mark of an
experienced system programmer who understands that it is the
"impossible" error that will bite you where it hurts.

The Royal Bank of Scotland plc, Registered in Scotland No. 90312. Registered Office: 36 St Andrew Square, Edinburgh EH2 2YB

Authorised and regulated by the Financial Services Authority.

This e-mail message is confidential and for use by the addressee only. If the message is received by anyone other than the addressee, please return the message to the sender by replying to it and then delete the message from your computer. Internet e-mails are not necessarily secure. The Royal Bank of Scotland plc does not accept responsibility for changes made to this message after it was sent.

Whilst all reasonable care has been taken to avoid the transmission of viruses, it is the responsibility of the recipient to ensure that the onward transmission, opening or use of this message and any attachments will not adversely affect its systems or data. No responsibility is accepted by The Royal Bank of Scotland plc in this regard and the recipient should carry out such virus and other checks as it considers appropriate.

Thomas Berg

unread,
Sep 11, 2008, 5:26:02 AM9/11/08
to
As I see it: You don't check everything.
You check for the valid condition.
And abend when not.

E g Your code depends on some valid data.
That valid data depends on a successfull read of a file.
That read depends on a successfull allocation of the dataset.
That allocation depends on a valid dataset name.
That depends on... etc.

In this case, if You only test on the first mentioned condition,
the "valid data", You implicitly do a check on all
the other actions that lead to that.

Of course, in practice I have implemented automatic
error handling in e g all my allocation routines,
but with this example I want to point to the fact
that You don't *need* to check *everything* *always*,
You just creates "logic walls" in the programs at
strategic places so invalid conditions can't pass.

That doesn't neccessarely means that things like this
in subroutines:
datasetname = Strip(Translate(Arg(1))
..doesn't save time in the developement stage.
(As a way to herald "Do as I mean, not as I say".)

Regard,
Thomas Berg


__________________________________________
Thomas Berg Specialist IT-U SWEDBANK

> -----Ursprungligt meddelande-----
> Från: TSO REXX Discussion List
> [mailto:TSO-...@VM.MARIST.EDU] För Gardiner, Roy
> Skickat: den 11 september 2008 10:20
> Till: TSO-...@VM.MARIST.EDU
> Ämne: Re: [TSO-REXX] Impossible conditions

adrianstern

unread,
Sep 12, 2008, 3:45:28 AM9/12/08
to
> > [mailto:TSO-R...@VM.MARIST.EDU] För Gardiner, Roy

> > Skickat: den 11 september 2008 10:20
> > Till: TSO-R...@VM.MARIST.EDU
> > instructions, send email to LISTS...@VM.MARIST.EDU with the

> > message: INFO TSO-REXX
>
> ----------------------------------------------------------------------
> For TSO-REXX subscribe / signoff / archive access instructions,
> send email to LISTS...@VM.MARIST.EDU with the message: INFO TSO-REXX- Hide quoted text -
>
> - Show quoted text -

Now there's a construct I never use! "arg(n)". Since passed arguments
are going to be used in the routine I always use "arg dsn .", for
example. Would there be any advantage to using argument number
instead?
And note the full stop! Really unnecessary code, but protects against
many errors.

Adrian

Fogg, George C

unread,
Oct 16, 2008, 1:35:21 PM10/16/08
to
Cross posted on IBM-MAIN

Anyone written a Health Checker routine in SYSREXX to check if a
specific job or stc has reached a certain threshold of CPU% usage?


George Fogg
Boeing Company
z/OS Enterprise Server Design/Build
MS: 7M-RE PH: (425) 865-1576
email: george...@boeing.com

Diehl, Gary

unread,
Oct 17, 2008, 9:55:53 AM10/17/08
to
George,

I'd like to see that too, SYSREXX looks like it's pretty neat. I wrote
one of these task monitoring jobs a while back that starts as a started
task, runs SDSF in batch to gather a half-dozen or so samples of DA
output, and runs a REXX to read that data and report the overall CPU
usage and three highest CPU using tasks/jobs in a WTO. We start it via
automation every 10 minutes or so. Not sure if you'd be interested in
that, but it'd be easy enough to throw some code on the bottom of the
REXX to monitor for specific jobs/tasks and take appropriate action.

Best regards,

Gary Diehl
Systems Administration
"One machine can do the work of fifty ordinary people. No machine can do
the work of one extraordinary person." -Elbert Hubbard

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf

0 new messages