8.4.1 The RexxStart() function

This function is used to invoke the REXX interpreter in order to
execute a piece of REXX code, which may be located on disk, as a
pre-tokenized macro, or as ASCII source code in memory.

     APIRET APIENTRY RexxStart(
           LONG ArgCount,
           PRXSTRING ArgList,
           PSZ ProgramName,
           PRXSTRING Instore,
           PSZ EnvName,
           LONG CallType,
           PRXSYSEXIT Exits,
           PUSHORT ReturnCode,
           PRXSTRING Result
     ) ;

Of these parameters, ReturnCode and Result are output-only, while
Instore is both input and output. The rest of the parameters are
input-only. The significance of the parameters are:

     [ArgCount]
          The number of parameter strings given to the procedure.
          This is the number of defined REXX-strings pointed to by
          the ArgList parameter.
     [ArgList]
          Pointer to an array of REXX-strings, constituting the
          parameters to this call to REXX. The size of this array
          is given by the parameter ArgCount. If ArgCount is
          greater than one, the first and last parameters are
          ArgList[0] and ArgList[ArgCount-1].  If ArgCount is 0,
          the value of  ArgList is irrelevant.
     
          If the strptr of one of the elements in the array
          pointed to by ArgList is NULL, that means that this
          parameter is empty (i.e. unspecified, as opposed to a
          string of zero size).
     [ProgName]
          An ASCII NUL terminated string, specifying the name of
          the REXX script to be executed. The value of Instore
          will determine whether this value is interpreted as the
          name of a (on-disk) script, or a pre-tokenized macro. If
          it refers to a filename, the syntax of the contents of
          this parameter depends on the operating system.
     [Instore]
          Parameter used for storing tokenized REXX scripts. This
          parameter might either be NULL, else it will be a
          pointer to two RXSTRING structures, the first holding
          the ASCII version of a REXX program, the other holding
          the tokenized version of  that program. See below for
          more information about how to use Instore.
     [EnvName]
          Pointer to ASCII NUL terminated string naming the
          environment which  is to be the initial current
          environment when the script is started. If this
          parameter is set to NULL, the filetype is used as the
          initial environment name. What the filetype is, may
          depend on your operating system, but in general it is
          everything after the last period ‘.’ in the filename.
     [CallType]
          A value describing whether the REXX interpreter is to be
          invoked  in command, function or subroutine mode.
          Actually, this has little significance. The main
          difference is that in command mode, only one parameter
          string can be passed, and in function mode, a value
          must be returned. In addition, the mode chosen will
          affect the output of the PARSE SOURCE instruction in
          REXX.
          
          Three symbolic values of integral type are defined,
          which can be used for this parameter: RXCOMMAND,
          RXFUNCTION and RXSUBROUTINE.
     [SysExists]
          A pointer to an array of exit handlers to be used. If no
          exit  handlers are to be defined, NULL may be specified.
          Each element in the array defines one exit handler, and
          the element  immediately following the last definition
          must have a sysexit_code set to RXENDLST.
     [ReturnCode]
          Pointer to a SHORT integer where the return code is
          stored, provided that the returned value is numeric, and
          within the range  -(2**15) to 2**15-1. I don't know what
          happens to ReturnCode if either of these conditions is
          not satisfied. It probably becomes undefined, which
          means that it is totally useless since the program  has
          to inspect the return string in order to determine
          whether ReturnCode is valid.
     [Result]
          Points to a REXX string into which the result string is
          written.  The caller may or may not let the strptr field
          be supplied.  If supplied (i.e. it is non-NULL), that
          area will be used, else a new area will be allocated. If
          the supplied area is used, its size is supposed to be
          given by the strlength field. If the size if not
          sufficient, a new area will be allocated, by some system
          dependent channel (i.e. malloc()), and the caller must
          see to that it is properly de-allocated (using  free()).

Note that the ArgCount parameter need not be the same as the ARG()
built-in function would return. Differences will occur if the last
entries in ArgList are null strings.

The Instore parameter needs some special attention. It is used to
directly or indirectly specify where to fetch the code to execute.
The following algorithm is used to determine what to execute:

     If  Instore is NULL, then ProgName names the filename of an
     on-disk REXX script which it to be read and executed.
     
     Else, if Instore is not NULL, the script is somewhere in
     memory, and no reading from disk is performed.  If both
     Instore[0].strptr and Instore[1].strptr are NULL, then the
     script to execute is a pre-loaded macro which must have been
     loaded with a call to either RexxAddMacro() or
     RexxLoadMacroSpace(); and ProgName is the name of the macro
     to execute.
     
     Else, if Instore[1].strptr is non-NULL, then Instore[1]
     contains the pre-tokenized image of a REXX script, and it is
     used for the execution.
     
     Else, if  Instore[0].strptr is non-NULL, then Instore[0]}
     contains the ASCII image of a REXX script, just as if the
     script had been read directly from the disk (i.e. including
     linefeeds and such). This image is passed to the interpreter,
     which tokenizes it, and stores the tokenized script in the
     Instore[1] string, and then proceeds to execute that script.
     Upon return, the Instore[1] will be set, and can later be
     used to re-execute the script within the same process,
     without the overhead of tokenizing.
     
     The user is responsible for de-allocating any storage used by
     Instore[1]. Note that after tokenizing, the source code in
     Instore[0] is strictly speaking not needed anymore. It will
     only be consulted if the user calls the SOURCELINE() built-in
     function. It is not an error to use SOURCELINE() if the
     source is not present, but nullstrings and zero will be
     returned.
     
     Regina does not currently return any tokenized data in
     Instore[1] that can be used in a later call to RexxStart,
     outside of the current process.  What Regina returns in
     Instore[1], is an index into an in-memory tokenized version
     of the source code.  Once the process that parsed the source
     has stopped, the tokenized code is lost.

The valid return values from RexxStart() are:

     [Negative]
          indicates that a syntax error occurred during
          interpretation. In general, you can expect the error
          value to have the same absolute value as the REXX syntax
          error (but opposite signs, of course).
     [Zero]
          indicates that the interpreter finished executing the
          script without errors.
     [Positive]
          indicates probably that some problem occurred, that made
          it impossible to execute the script, e.g. a bad
          parameter value.  However, I can't find any references
          in the documentation which  states which values it is
          supposed to return.

During the course of an execution of  RexxStart(), subcommand
handlers and exit handlers might be called. These may call any
function in the application interface, including another
invocation of
RexxStart().

Often, the application programmer is interested in providing
support simplifying the specification of filenames, like an
environment variable search path or a default file type. The REXX
interface does support a default file type:  .CMD, but the user
may not set this to anything else. Therefore, it is generally up
to the application programmer to handle search paths, and also
default file types (unless .CMD is OK).

If the initial environment name (EvnName) is NULL, then the
initial environment during interpretation will be set equal to the
file type of the script to execute. If the script does not have a
file
type, it is probably set to some interpreter specific value.



PREV NEXT