Parameter Parsing in REXX

Every time I create a new REXX routine, I always use a template source program for consistency, but more than that, there are features I have developed over time which simplifies the coding effort.  In this example, I will focus on parameter handling.

As we know in REXX, there is positional parameters when invoking directly from a batch rexx interface.  I never liked having to know the order of parameters and although not a big fan of CLIST, I did like how it handled keyword parameters.  I developed a similar feature in REXX and have used it ever since.

There six aspects to using this feature:

  1. Parameter Definition
  2. Parameter Parsing
  3. Parameter Verification
  4. Application Entry
  5. Parameter Reference
  6. Parameter Specification

Parameter Definition

Parameter definition is normally set up as a straight two dimensional array/stem variable.  I always have a paragraph in my REXX program that contains all variables so they are located in one place;  the stem also contains a corresponding stem defaults that contains the default value for each corresponding parameter.  The internal routine is called CheckParms.

/*********************************************************************/
/* Change the “keywords” and “defaults” stem variables to reflect the*/
/* Input parameters required by your program.  Setting the defaults  */
/* for each corresponding keywords variable ensures the variable will*/
/* be defined when referenced in the program (even if it is set to   */
/* a null string.                                                    */
/*********************************************************************/

CheckParms:

   keywords.1  = ‘MyParm1’     ;  defaults.1  = ‘MyValue1’      ;
   keywords.2  = ‘MyParm2’     ;  defaults.2  = ‘MyValue2’      ;
   keywords.0  = 2             ;  defaults.0  = 2          ;

   do i = 1 to keywords.0
      if symbol(keywords.i) = ‘LIT’ then /* not defined */
      do
        interpret keywords.i’ = ‘defaults.i
      end
   end
return

As the loop is executed, for any valid parm in the list of keywords, the corresponding value that is passed from the caller is stored in the REXX variable.  If you look at the code closely, you will notice that if the caller passed an unknown parameter through (e.g. assume the above definition), if the user passed MyParm3 to the program, it would be ignored. 

Parameter Parsing

Parameter parsing is the logic to parse keywords of the form keyword(value) and place the contents of the value in the REXX variable for later reference.  I have not had to modify this logic since I started using it.

/*********************************************************************/
/* Parse input parameters of the form keyword(value)                 */
/*********************************************************************/

ParseParms:
arg aString

   /* Ensure there are no spaces between the ( ) and the value */
   do while pos(‘( ‘,aString) > 0
      aString = delstr(aString,pos(‘( ‘,aString)+1,1)
   end
   do while pos(‘ )’,aString) > 0
      aString = delstr(aString,pos(‘ )’,aString),1)
   end

   do w = 1 to words(aString)
      if (pos(‘(‘,word(aString,w)) <= 0) |,
         (pos(‘)’,word(aString,w)) <= 0) then
      do
         say ‘Input parameter ‘word(aString,w)’ is invalid.’
         say ‘Input parameters are of the form:  keyword(value)’
         exit(0)
      end
   end

   do While aString = ”
      parse upper value aString with kw “(” kv “)” aString
      kw = translate(strip(kw))          /* convert to upper case */
      kv = translate(strip(kv))          /* convert to upper case */
      interpret kw’= “‘kv'”‘
   end
return 0

Parameter Verification

Technorati Tags:

I like to isolate all code which verifies input parameter values so it is in one section.

/*********************************************************************/
/* Application Parameter Checking                                    */
/*********************************************************************/
CheckApplParms:

   if MyParm1 = ” then   do
      say ‘Batch execution error – MyParm1 is required.’
      exit(-1)
   end

return

You can enter whatever application logic you need here, but the idea is to minimize the amount of this code to strictly verifying the input parameters, so any remaining coding logic can assume there are valid values in all subsequent references to the list of input parameter variables.

Application Entry

Application Entry refers to the code required to start the parameter handling process.  This is fairly straightforward.  I always include the following as the first lines in my REXX programs:

arg InputParms
   call Init                          /* Setup and check input       */
   call ParseParms InputParms         /* Parse keywords              */
   call CheckParms                    /* Verify parms; set defaults  */
   call CheckApplParms                /* Application parm processing */

This invokes the previously defined routines.

Parameter Reference

Assuming you have consistently defined valid parameter names, you should be able to reference them with confidence throughout the rest of your REXX program.  

Example:

MyNewVar = MyParm1

If you want to display the interpreted value, you can add a loop to display each variable and its corresponding value:

do i = 1 to keywords.0
   interpret say keywords.i’ = ‘defaults.I  

end

Parameter Specification

You pass the parameters in the keyword(value) format.  Based on the parsing logic, you can specify the keyword value pair in any order.  Assuming I had a REXX program MyProgram with two parameters Color and Name, you would call it as:

%MyProgram color(blue) name(jane smith)

%MyProgram name(john smith) color(yellow)

In this manner, you can consistently pass parameters into your program while increasing the usability, readability and flexibility to the caller and reducing the overall complexity and maintainability of your REXX program.

Leave a Reply

Your email address will not be published. Required fields are marked *