While you are coding procedures, you will often have a need to test whether REXX reacts the way you expect. Running the exec you are writing is often not possible as it is either not completed or too long to execute...
You can of course write a small procedure that contains the statement(s) to test. This is fine, especially to test a whole routine, but there is better if you have to test only a few statements...
This goodie is an improved version of the original
REXTRY(footnote 1)
tool provided by the author of REXX, Mike Cowlishaw. Both tools
will prompt you for REXX statements and execute them.
You can execute almost everything (e.g. DO loops) as long as you can
type it on the input area (some 140 chars). REXTRY is in fact a
procedure that uses INTERPRET to interpret the commands you
enter at the
console. You will therefore often have to use SAY commands to
see the results.
You can use REXTRY:
These are examples of commands you can use while executing REXTRY
a=10 b=20 c=a*b say c
or, in one shot:
a=10;b=20;c=a*b;say c
This is how you can use it as a calculator :
say 104203*1.195
or to test a loop:
do i=1 to 10;say i**2;end
or a test for parsing :
parse value 'PROFILE XEDIT A (WIDTH 120) MYPAR' with . ')' options;say options
The TSTREX goodie further improves REXTRY in following areas:
do until rc¬=0;'FIND :fig';end or 'COMMAND EXTRACT /CURLINE/' ; say curline.3
Note: When XEDIT is not active, the default is ADDRESS CMS, but nobody forbids you to enter ADDRESS COMMAND or even ADDRESS ISPEXEC.
If you want, you could try to practice TSTREX now and try to find the answer to following questions:
OS/2 REXX has equivalent tools: REXXTRY (note 2 X characters) for normal line mode procedures and PMREXX for procedures using OS/2 Presentation Manager features or if you want to switch interactive trace on or off on the fly (equivalent to TS | TE in CMS). For more information, see the online HELP of OS/2.
This goodie is the best choice when you have to execute only one statement from within XEDIT. For example:
DOREXX msg 1024*1024 DOREXX msg datatype('','W') /* see if REXX considers "null" as numeric */ DOREXX parse value '1234567890' with A 2 B +4 c; msg a ? b ? c
Note: DOREXX can also be used to execute the REXX statement displayed at the current line: if you issue DOREXX without parameters, then it interprets the current line.
When you issue the command CKRX from the XEDIT command line, while you are editing a procedure, the goodie will run the procedure with the trace Scan option, and, if errors are detected, the scan will be presented in another Xedit screen. This is an example:
1 *-* /**T EXEC A1**/Trace Scan *-* /* Procedure T */ 2 *-* address command 3 +++ bfm='T ;todayb=date('B DMSREX462E Error 15, line 3: Invalid hexadecimal or binary string
The message is misleading here, as the real reason for the error is that there is a quote missing in the statement bfm='T. As a consequence, ;todayb=date( is considered to be part of a constant string, and hence, the subsequent B makes is look like a binary string. Anyway, without CKRX, the error would only appear when the procedure is running life.
When you develop an application such as a REXX procedure, it is normal that you have to test this application frequently. And you want to do this as easy and quickly as possible.
That's exactly the domain that the EXECCALL goodie wants to address.
EXECCALL includes intelligence in order to recognize what you want to test. Originally it was meant for testing EXEC and XEDIT macros, but now EXECCALL also recognizes FILELISTs, PACKAGEs, HELP files, SCRIPT sources (Document Composition Facility), and CMS Communications Directories (SCOMDIR and UCOMDIR).
EXECCALL is meant to be executed from XEDIT's environment. The procedure will first save your file if it is changed, and then execute it. When execution is finished, you're back in XEDIT and you can continue your development or correct any errors you discovered while testing your procedure.
EXECCALL can be executed from XEDIT's command line, but it is by far more convenient to assign the function to a PF-key in XEDIT.
++--EXECCALL---+-----+-+---------------------+--+--------------+-+ +-.TS-+ +--.MACRO boot-macro--+ +--parameters--+ +--.EXEC boot-exec----+
Where:
EXEC | execute the EXEC with your parameters |
XEDIT | execute the XEDIT macro with your parameters |
REXX | execute the CMS Pipelines user-written stage. |
HELPxxxx | execute the command help xxxx filename, and is thus useful when designing your own HELP files (see Tailoring the HELP Facility in SC24-5460 - CMS User's Guide for more details on this). |
FILELIST | execute the command filelist fn ft (filelist. If you edit a file that contains a list of fileids, then EXECCALL will actually show you the FILELIST of the files referenced in your edited file. |
PACKAGE | analog to FILELIST. |
SYNONYM | activate the synonyms coded in the file by issuing the set synonym fn ft command. |
NAMES | if the filename is UCOMDIR or SCOMDIR, this CMS "communications directory" will be re-activated by EXECCALL. It will execute the set comdir file user|system fileid and the set comdir reload commands. See the Connectivity Planning, Administration, and Operation (SC24-5448) manual for more details on communications directories. |
As already said, most benefits are obtained if EXECCALL is assigned to a PF-key (if not, we bet you will not use it). The goodies provide a PROFILE XEDIT that assigns PF10 and PF22 to EXECCALL as follows:
If find('XEDIT EXEC SCRIPT SYNONYM FILELIST PACKAGE',ftype.1)¬=0 |, ft4='HELP' | fnft='UCOMDIR NAMES' | fntft='SCOMDIR NAMES' then do 'SET PF10 MACRO EXECCALL' /* execute this EXEC */ 'SET PF22 MACRO EXECCALL .TS' /* execute this exec in TRACE mode*/ end
We suppose that you're editing procedure MYEXEC EXEC.
- SET PF10 EXECCALL - press PF10 ==> EXECCALL issues : EXEC MYEXEC
- SET PF10 EXECCALL - type myparms in XEDITs command line & press PF10 ==> EXECCALL issues : EXEC MYEXEC myparms
or with enabling interactive trace :
- SET PF22 EXECCALL .TS - type myparms in XEDITs command line & press PF10 ==> EXECCALL issues : SET EXECTRAC ON ; EXEC MYEXEC myparms
- SET PF10 EXECCALL testparms - press PF10 ==> EXECCALL issues : EXEC MYEXEC testparms
but with the same PF10 :
- type myparms in XEDITs command line & press PF10 ==> EXECCALL issues : EXEC MYEXEC myparms
- SET PF10 EXECCALL testp .&1 (opt .&2 rest - type myparms myoption in XEDITs command line & press PF10 ==> EXECCALL issues : EXEC MYEXEC testp myparm (opt myoption rest
- XEDIT SOME XEDIT (xedit my SOME macro to be called by MYEXEC) - SET PF10 EXECCALL .EXEC MYEXEC testp .&1 (opt .&2 rest - type myparms myoption in XEDITs command line & press PF10 ==> EXECCALL issues : EXEC MYEXEC testp myparm (opt myoption rest
Note: valid run-time variables are :
The BENCH goodie allows you to measure the performance of a procedure.
The format of the command is:
>>--BENCH--+--------------------------------------+-cmd_to_measure-->< +-(-! Bench Options !--+-----------+-)-+ +-,-comment-+ Bench options: !-+----------------------------------------------------------------------------+--! ! +-Times--1-+ +-Run-1----+ +-+-Times--n-+-+-Run-n----+-+---------------+-+----+-+----------+-+--------+-+ !-Run-=----! +-Address-envir-+ +-HT-+ +-EXECLOAD-+ +-FORGET-+ +-Run-Next-+
where:
Times | specifies the number of times the command_to_measure is to be run. Default is 1. |
Run |
identifies the benchmark run to allow for comparison with
other runs. The default is 1, but you can specify
|
Address | To (re-)define the addressing environment of the procedure to be benchmarked (e.g. Address ISPEXEC). Default is CMS. |
HT | To suppress the CMS line output |
EXECLOAD | To force the procedure to be loaded in storage before the benchmark runs (in order to eliminate the I/O for loading from the I/O count). |
FORGET | To forget any information stored in GLOBALV by BENCH. |
comment | To associate a comment to the run. It will be displayed in the run results. |
BENCH uses the information provided by the CP INDICATE command to calculate the resource consumptions for the procedure.
For example, to compare the performance of procedures TEST1 and TEST2, issue the following commands:
BENCH (Times 100 Run 1 EXECLOAD Run with EXECIO) TEST1 BENCH (Times 100 Run 2 EXECLOAD Run with PIPES) TEST2
The output may look like this:
R V.cpu T.cpu SIO IO Servce Elaps Page Page ! Comment/Command U time time time time time rds wrts ! N (Secs) (Secs) nbr (Secs) (Secs) (Secs) ! --------------------------------------------------------+---------------------- 1 0.30013 0.31015 0 0.000 0.3101 0.320 0 0 EXEC TEST1 Run with EXECIO 2 0.21012 0.22013 0 0.000 0.2201 0.230 0 0 EXEC TEST2 Run with PIPES
Where:
Vtime | The virtual CPU time in seconds. |
Ttime | The total CPU time in seconds. |
SIO | The number of Virtual I/O operations. Note that if the procedure performs I/O through SFS, SQL or any other server, these I/O operations will not be seen and reported. |
IO time | The estimated execution time taking the I/O into account. I/O service times have a broad range of values, as these depend on the technology, whether caching is active or not, etc. This figure gives you an indication of the I/O part of the application. We use 25 msec per I/O. |
Service time | Is an approximation of the total internal response time (ITR). |
Elapsed time | The duration of the procedure as seen by the user. This is highly dependent on the load of the system and should therefore normally be ignored. |
Page | Number of page reads and writes. |
The consumption of the BENCH procedure itself is of course not included in the results. In order to exclude the CMS overhead associated to loading of your procedure, you may want to EXECLOAD it before launching the benchmark, or to add the EXECLOAD option to let BENCH do this for you.
For more examples, see the documents discussing the solutions for the coding exercises.
BENCH2 is yet another goodie that can be used to measure only parts of procedures. Is basically used as follows:
/* My procedure */ address command 'EXEC BENCH2 INIT' /* initialize BENCH2 environment */ /* do some processing you want to measure */ ... 'EXEC BENCH2 SHOW' /* what did we consume till now */ /* do other stuff */ 'EXEC BENCH2 SHOW' /* what did we consume for this step */ /* this is last alternative we want to test */ 'EXEC BENCH2 LAST' /* show final results and cleanup */ exit
More information can be found in the prologue of BENCH2 EXEC.
Why was there only one X in REXTRY ? Well, before REXX got included
in VM/SP Release 3, the interpreter was internally available in IBM
under the name REX. For legal reasons, as REX was already a registered
trademark, IBM added a second X when making the product
general available.
Back to text