Re: [U2] [UV] Programmatic Verification of Globally Cataloged Subroutine
Bruce Decker <[email protected]>
| Newsgroups | gmane.comp.db.u2.general |
|---|---|
| Message-ID | <[email protected]> |
Not sure if this is helpful or not but I write software that allows
users to create their own subroutines that plug into my architecture.
Users can forget to catalog or have other issues with their subroutine.
So, I require the user subroutine to accept an argument called 'mode'.
In my system, mode=2 means 'test mode'. If a user subroutine is called
with mode set to 2, then it should set test data and when processing is
complete, output the string /%%validated%%/ to standard out.
In my program where I will be calling the subroutine, I reference it
twice. First to validate the subroutine and second to actually call the
subroutine. I use the EXECUTE/CAPTURING on the first pass using a
special test executable to validate the subroutine then if I find
%%validated%% in the captured output, then I mke the second pass and
actually call the subroutine with CALL @. On the first pass, I EXECUTE
using my validator program so that even if the subroutine fails or dies,
only that execute levels is affected. i.e., you can execute a program
that calls a failing subroutine and the main program that executed will
carry on after the failure. I leveraged this behavior to mitigate the
chance that a user subroutine would cause my main program to abort.
Yes, I understand the EXECUTE is expensive but it's less expensive than
me having to spend my time helping a user restart my process because one
of their subroutines failed. This technique might be used in
combination with the global catalog checker to provide a richer level
of validation. Here are some code fragments is case anyone finds this
technique useful:
*The Main Program*
userSubroutineName = \MY.SUBROUTINE.NAME\
* check the subroutine to make sure it is valid before calling
EXECUTE \bpixmlize.validateSubroutine \:userSubroutineName CAPTURING result
* check result to see if the subroutine responded cordially
IF (INDEX(reuslt, \%%validated%%\, 1) THEN
* yep, the subroutine is alive and well, it's okay to call it.
itemId=\\
mode=1; * 1 means 'run' mode
error = \\
CALL @userSubroutineName(itemId, mode, error)
END ELSE
* not sure what happened but subroutine is not playing nicely
CRT \So sorry, but \:userSubroutineName:\ does not appear to be valid\
CRT \result=\:result
END
------------------------------------------------------------------------
* The subroutine validator program*
*bpixmlize.validateSubroutine
*a executable program that will attempt to call subroutine or error if not
*to be executed in a basic program with captured output. Evaluate the
captured
*result and it should contain the string %%validated%% otherwise it's a bad
*or invalid subroutine. The prevents the caller from crashing with
object not
*found so that it can wrap-up normally. It's the job of the called
subroutine
*to output %%validated%% or something agreed by the caller in order to
validate
*the subroutine. Since this is executed and not called, it will fail
but return
*control to the calling program after failing.
*
------------------------------------------------------------------------------
INCLUDE bpi.xml.bp bpixmlize.common ; * to get common variables
GOSUB ParseSentence
GOSUB Validate
GOTO Exit
*
------------------------------------------------------------------------------
Validate:
IF subroutine.name NE \\ THEN
item.id = \\; mode=2; error = \\
CALL @subroutine.name( item.id, mode, error)
END
RETURN
*
ParseSentence:
pgm.id = \bpixmlize.validateSubroutine\
start = @FALSE
sentence = CHANGE( @SENTENCE, SPACE(1), @AM)
max.words = DCOUNT( sentence, @AM)
subroutine.name = \\
FOR i = 1 to max.words
BEGIN CASE
CASE start
BEGIN CASE
CASE subroutine.name EQ \\
subroutine.name = sentence< i >
CASE @TRUE
* ignore
END CASE
CASE sentence<i> EQ pgm.id
start = @TRUE
CASE @TRUE
* ignore
END CASE
NEXT i
RETURN
*
Exit:
STOP
------------------------------------------------------------------------
*
**A sample user subroutine:*
SUBROUTINE MY.SUBROUTINE.NAME(item.id, mode, error)
* Copyright (c) 2013 by Blue Prairie, Inc.
* All Rights Reserved
*
* item.id is the item ID of the main file to process
* mode If caller sets mode=2, then subroutine will simply
output
* string '%%validated%%\ and return. This is so that the
* caller can use the subroutine test program to
validate that
* the subroutine name is valid and callable before
actually
* calling it. If the subroutine sets mode to zero,
the calling
* program should consider this a signal that
something is wrong
* and it should stop processing. The caller should
normally set
* mode to 1 for normal processing.
* error is an error code to be returned to caller.
*-------------------------------------------------------------------------------
*
INCLUDE bpi.xml.bp bpixmlize.common ; * to get common variables
BEGIN CASE
CASE UNASSIGNED(mode)
mode = 1
CASE mode EQ 2
GOSUB Validate
GOTO Exit
CASE @TRUE
* allow to drop through
END CASE
*
pgm.id = \MY.SUBROUTINE.NAME\
*
GOSUB DoSomethingUseful
GOTO Exit
*-------------------------------------------------------------------------------
DoSomethingUseful:
* here is where we do the main task of this subroutine
RETURN
*
Validate:
*do some sanity checks, make sure subroutine can function (i.e.,
open files, etc)
*then if all looks good, simply output th %%validated%% string
CRT \%%validated%%\
RETURN
*
Exit:
RETURN
------------------------------------------------------------------------
Bruce Decker
Blue Prairie, Inc.
http://www.bluepinc.com
720.733.0459
On 1/30/2014 8:13 AM, Daniel McGrath wrote:
> In particular, when using the CALL @ syntax to dynamically call something.
>
> Dan
>
> -----Original Message-----
> From: [email protected] [mailto:[email protected]] On Behalf Of Ross Ferris
> Sent: Wednesday, January 29, 2014 10:56 PM
> To: U2 Users List
> Subject: Re: [U2] [UV] Programmatic Verification of Globally Cataloged Subroutine
>
> Knowing how many arguments a subroutine is expecting is a good way to check/confirm that the call you are about to make isn't going to blow up in your face!
>
> Ross Ferris
> Stamina Software
> Visage > Better by Design!
>
> -----Original Message-----
> From: [email protected] [mailto:[email protected]] On Behalf Of Wjhonson
> Sent: Wednesday, January 29, 2014 10:15 AM
> To: [email protected]
> Subject: Re: [U2] [UV] Programmatic Verification of Globally Cataloged Subroutine
>
>
> I was just trying to think of a reason why I'd want specifically to know how many arguments the subroutine has.
> That is, why was this particular fact chosen as the returned status code ?
>
>
>
> -----Original Message-----
> From: Keith Johnson [DATACOM] <[email protected]>
> To: '[email protected]' <[email protected]>
> Sent: Tue, Jan 28, 2014 3:10 pm
> Subject: Re: [U2] [UV] Programmatic Verification of Globally Cataloged Subroutine
>
>
> Hi,
>
> LeRoy Dreyfuss said that you would have to change 52 to 12 for EXIST to work.
>
> The globally cataloged programs have an extra 40 characters put on the front, so that would cause a problem.
>
> @RECORD[1,4] is a count of the number of times the program has been used.
>
> @RECORD[5,8] is who cataloged it
>
> @RECORD[13,4] are the date and time (I think)
>
>
> Regards, Keith
>
>
>
> _______________________________________________
> U2-Users mailing list
> [email protected]
> http://listserver.u2ug.org/mailman/listinfo/u2-users
>
>
> _______________________________________________
> U2-Users mailing list
> [email protected]
> http://listserver.u2ug.org/mailman/listinfo/u2-users
> _______________________________________________
> U2-Users mailing list
> [email protected]
> http://listserver.u2ug.org/mailman/listinfo/u2-users
> _______________________________________________
> U2-Users mailing list
> [email protected]
> http://listserver.u2ug.org/mailman/listinfo/u2-users
_______________________________________________
U2-Users mailing list
[email protected]
http://listserver.u2ug.org/mailman/listinfo/u2-users