How to REXXSKEL

How to REXXSKEL

REXXSKEL is the kernel around which all of my tools are built.   Some minimal understanding of what REXXSKEL is and what it does is a prerequisite for understanding or maintaining the code you'll find here.

REXXSKEL, unfortunately, is not a static entity.   It changes over time, and it is normal to find a dozen different versions in current use throughout the codebase.   I try very hard to keep REXXSKEL 'backward-compatible' so that retrofitting does not become necessary but I have no compunctions about improving it when and as necessary.   The current version is '20020513'.

All code which has been fitted for REXXSKEL exhibits a certain behavior:

  1. if the first argument passed to the routine is a question mark ("?"), any available HELP-text is displayed and the routine ends;
  2. arguments passed to these routines are logically divided by the presence of a double open parenthesis ("((") into "parms" before the "((" and "opts" after.   These may be thought of, respectively, as "what shall we do" and "how shall we do it".


KEYWD and SWITCH

Key to the operation of REXXSKEL and independently usable by the application code itself are two internal subroutines: KEYWD and SWITCH.   Both of these subroutines examine the contents of variable "info" which must be populated prior to calling either of them.

KEYWD examines "info" for the presence of the token which has been passed as its sole argument.   (The 'token' may actually be more than one word, but spacing between words then becomes significant.)   If that token exists in "info", the token which follows it immediately (in the string of "info") is returned as the function value, and both tokens are removed from "info" to prevent duplicate processing.

SWITCH examines "info" for the presence of the token which has been passed as its sole argument.   If that token exists in "info", a '1' bit is returned as the function value and the token is removed from "info" to prevent duplicate processing; if the token does not exist, a '0' bit is returned.

TOOLKIT_INIT establishes "info" by loading "opts", so that TV, TRAPOUT, BRANCH, MONITOR, and NOUPDT (the items parsed-out in TOOLKIT_INIT) are all derived by default from "opts", the portion of the argument following the "((".  Before it returns control to the mainline, TOOLKIT_INIT calls LOCAL_PREINIT, a stub routine which may be used by the application programmer to process any locally-defined opts-values.   (LOCAL_PREINIT is placed before HELP in the standard REXXSKEL to indicate that it is not intended to be replaced when upgrading to a more recent version.)

On return from TOOLKIT_INIT (into the mainline), "info" is refreshed from "parms", so that all other switches and keyword values will be determined from that portion of the argument preceeding the "((".


KEYPHRS

This variant of KEYWD exists for passing multiple values.   Naturally, the syntax of KEYPHRS is a little different than KEYWD: KEYPHRS expects to find a 2-character marker immediately following the KEYPHRS argument in "info"; it also expects to find this same marker further along in info.   The text between the markers is returned as the function.  The marker can be any two characters except, obviously, '40'x.

A parameter might include the string

TEXT :{ this is text to be parsed :{
which would be parsed out by
text_phrase = KEYPHRS("TEXT")


CLKWD

Just recently I have had to add another variant of KEYWD to handle parameters passed as for CLISTs.  

A parameter might include the string

TEXT(this is text to be parsed)
which would be parsed out by
text_phrase = CLKWD("TEXT")


HELP

A pro-forma HELP paragraph is provided as a guide.   Most of it is commented out; the only section which is active in the unaltered REXXSKEL writes "helpmsg" if it is not blank.   Pro-forma blocks are provided for functional description, syntax, and parameters, and the nature and uses of the standard diagnostic parameters is also covered.


SYNTAX

Debugging tools can be accessed in the following manner:

 
 TSO exec_name  parameters  ((  debug-options 
  
                                BRANCH
                                MONITOR
                                NOUPDT
                                TRACE tv
                                TRAPOUT
                                'exec specific'


OPERANDS

BRANCH an indicator that causes the name of any internal subroutine to be printed as control is transferred to it;
MONITOR an indicator which may be used by the application code to control the display of diagnostic messages and progress notes during execution;
NOUPDT an indicator which may be used by the application code to suppress WRITE operations to its outputs;
TRAPOUT an indicator that routine TRAPOUT is to be started as a shell around this routine; TRAPOUT will produce a dataset under the caller's ID containing "TRACE R" output;
tv a value used by the application code to set up tracing; specifying (e.g.) "TRACE ?R" will cause the called routine to begin tracing in 'interactive-results' mode immediately after its return from TOOLKIT_INIT
exec-specific Programmer-provided facilities designed to be customized debugging features.


Philosophy

REXXSKEL developed over a long period starting, as you might expect, as a very simple, straight-forward cluster of diagnostic and parsing subroutines.   Various people have contributed various improvements as it evolved and I am indebted to them for their innovations.   But always the thrust has been to provide a compact package of easily understood and broadly-useful routines that will enable the application programmer to quickly generate and easily debug routines of any arbitrary complexity.   Naturally, this requires a certain discipline.

While REXX itself allows the programmer to "get away with" many shortcuts, a complex or elaborate program will quickly grow fragile if such shortcuts are tolerated.   REXXSKEL, therefore, begins with a "signal on novalue"; that is: uninitialized variables are not permitted.   Real programmers don't rely on defaults.   It also issues a "signal on syntax" to trap the odd development error.   Both NOSYNTAX and NOVALUE invoke SHOW_SOURCE to display the failing line.   SHOW_SOURCE calls DUMP_QUEUE to clear any outstanding stacks.   These filigrees are not absolutely necessary, but their inclusion as part of REXXSKEL means the programmer doesn't have to write them and, more importantly, doesn't have to worry about leaving them out.  

It is better to have and not need than to need and not have.  That, in a nutshell, is the basic philosophy of REXXSKEL.