Calling the Rexx Interpreter

A Rexx program can be run directly from the command prompt of the operating system, or from within an application.

From the Operating System

You can run a Rexx program directly from the operating system command prompt using Rexx followed by the program name. See Running a Rexx Program.

From within an Application

The Rexx interpreter is a dynamic-link library (DLL) routine (or Unix/Linux shared object). Any application can call the Rexx interpreter to run a Rexx program. The interpreter is fully reentrant and supports Rexx procedures running on several threads within the same process.

A C-language prototype for calling Rexx is in the rexx.h include file.

The RexxStart Function

RexxStart calls the Rexx interpreter to run a Rexx procedure.

retc = RexxStart(ArgCount, ArgList, ProgramName, Instore, EnvName,
                 CallType, Exits, ReturnCode, Result);

Parameters

ArgCount (size_t) - input

is the number of elements in the ArgList array. This is the value that the ARG() built-in function in the Rexx program returns. ArgCount includes RXSTRINGs that represent omitted arguments. Omitted arguments are empty RXSTRINGs (strptr is null).

ArgList (PCONSTRXSTRING) - input

is an array of CONSTRXSTRING structures that are the Rexx program arguments.

ProgramName (const char *) - input

is the address of the ASCII name of the Rexx procedure. If Instore is null, ProgramName must contain at least the file name of the Rexx procedure. You can also provide an extension, drive, and path. If you do not specify a file extension, the default is .REX. A Rexx program can use any extension. If you do not provide the path and the drive, the Rexx interpreter uses the usual file search order to locate the file.

If Instore is not null, ProgramName is the name used in the PARSE SOURCE instruction. If Instore requests a Rexx procedure from the macrospace, ProgramName is the macrospace function name (see Macrospace Interface).

Instore (PRXSTRING) - input

is an array of two RXSTRING descriptors for in-storage Rexx procedures. If the strptr fields of both RXSTRINGs are null, the interpreter searches for Rexx procedure ProgramName in the Rexx macrospace (see Macrospace Interface). If the procedure is not in the macrospace, the call to RexxStart terminates with an error return code.

If either Instore strptr field is not null, Instore is used to run a Rexx procedure directly from storage.

Instore[0]

is an RXSTRING describing a memory buffer that contains the Rexx procedure source. The source must be an exact image of a Rexx procedure disk file, complete with carriage returns, line feeds, and end-of-file characters.

Instore[1]

is an RXSTRING containing the translated image of the Rexx procedure. If Instore[1] is empty, the Rexx interpreter returns the translated image in Instore[1] when the Rexx procedure finishes running. The translated image may be used in Instore[1] on subsequent RexxStart calls.

If Instore[1] is not empty, the interpreter runs the translated image directly. The program source provided in Instore[0] is used only if the Rexx procedure uses the SOURCELINE built-in function. Instore[0] can be empty if SOURCELINE is not used. If Instore[0] is empty and the procedure uses the SOURCELINE built-in function, SOURCELINE() returns no lines and any attempt to access the source returns Error 40.

If Instore[1] is not empty, but does not contain a valid Rexx translated image, unpredictable results can occur. The Rexx interpreter might be able to determine that the translated image is incorrect and translate the source again.

Instore[1] is both an input and an output parameter.

If the procedure is executed from disk, the Instore pointer must be null. If the first argument string in Arglist is exactly the string "//T" and the CallType is RXCOMMAND, the interpreter performs a syntax check on the procedure source, but does not execute it and does not store any images.

The program calling RexxStart must release Instore[1] using RexxFreeMemory(ptr) when the translated image is no longer needed.

Only the interpreter version that created the image can run the translated image. Therefore, neither change the format of the translated image of a Rexx program, nor move a translated image to other systems or save it for later use. You can, however, use the translated image several times during a single application execution.

EnvName (const char *) - input

is the address of the initial ADDRESS environment name. The ADDRESS environment is a subcommand handler registered using RexxRegisterSubcomExe or RexxRegisterSubcomDll. EnvName is used as the initial setting for the Rexx ADDRESS instruction.

If EnvName is null, the file extension is used as the initial ADDRESS environment. The environment name cannot be longer than 250 characters.

CallType (int) - input

is the type of the Rexx procedure execution. Allowed execution types are:

RXCOMMAND

The Rexx procedure is a system or application command. Rexx commands usually have a single argument string. The Rexx PARSE SOURCE instruction returns COMMAND as the second token.

RXSUBROUTINE

The Rexx procedure is a subroutine of another program. The subroutine can have several arguments and does not need to return a result. The Rexx PARSE SOURCE instruction returns SUBROUTINE as the second token.

RXFUNCTION

The Rexx procedure is a function called from another program. The subroutine can have several arguments and must return a result. The Rexx PARSE SOURCE instruction returns FUNCTION as the second token.

Exits (PRXSYSEXIT) - input

is an array of RXSYSEXIT structures defining exits for the Rexx interpreter to be used. The RXSYSEXIT structures have the following form:

typedef struct {
   const char *    sysexit_name;  /* name of exit handler        */
   int             sysexit_code;  /* system exit function code   */
} RXSYSEXIT;

The sysexit_name is the address of an ASCII exit handler name registered with RexxRegisterExitExe or RexxRegisterExitDll. Sysexit_code is a code identifying the handler exit type. See System Exit Interface for exit code definitions. An RXENDLST entry identifies the system-exit list end. Exits must be null if exits are not used.

ReturnCode (short *) - output

is the integer form of the Result string. If the Result string is a whole number in the range -(2**15) to 2**15-1, it is converted to an integer and also returned in ReturnCode.

Result (PRXSTRING) - output

is the string returned from the Rexx procedure with the Rexx RETURN or EXIT instruction. A default RXSTRING can be provided for the returned result. If a default RXSTRING is not provided or the default is too small for the returned result, the Rexx interpreter allocates an RXSTRING using RexxAllocateMemory(size). The caller of RexxStart is responsible for releasing the RXSTRING storage with RexxFreeMemory(ptr).

The Rexx interpreter does not add a terminating null to Result.

Return Codes

The possible RexxStart return codes are:

negative

Interpreter errors. See the Appendix in the Open Object Rexx: Reference for the list of Rexx errors.

0

No errors occurred. The Rexx procedure ran normally.

positive

A system return code that indicates problems finding or loading the interpreter.

When a macrospace Rexx procedure (see Macrospace Interface) is not loaded in the macrospace, the return code is -3 ("Program is unreadable").

Example

int       return_code;                 /* interpreter return code    */
CONSTRXSTRING  argv[1];                /* program argument string    */
RXSTRING  retstr;                      /* program return value       */
short     rc;                          /* converted return code      */
char      return_buffer[250];          /* returned buffer            */

                                       /* build the argument string  */
   MAKERXSTRING(argv[0], macro_argument,
       strlen(macro_argument));
                                       /* set up default return      */
   MAKERXSTRING(retstr, return_buffer, sizeof(return_buffer));

   return_code = RexxStart(1,          /* one argument               */
                          argv,        /* argument array             */
                          "CHANGE.ED", /* Rexx procedure name        */
                          NULL,        /* use disk version           */
                          "Editor",    /* default address name       */
                          RXCOMMAND,   /* calling as a subcommand    */
                          NULL,        /* no exits used              */
                          &rc,         /* converted return code      */
                          &retstr);    /* returned result            */

                                       /* process return value       */
...
                                       /* need to return storage?    */
   if (RXSTRPTR(retval) != return_buffer)
     RexxFreeMemory(RXSTRPTR(retval)); /* release the RXSTRING       */

When RexxStart is executed within an external program (usually a C program), the main Rexx thread runs on the same thread as the RexxStart invocation. When the main thread terminates, the interpreter will wait until all additional threads created from the main thread terminate before returning control to the invoking program.

The RexxWaitForTermination Function (Deprecated)

RexxWaitForTermination is not supported in 4.0 and will return immediately if called. This is maintained for binary compatibility with previous releases.

The RexxDidRexxTerminate Function (Deprecated)

RexxDidRexxTerminate always returns 1 for 4.0. This is maintained for binary compatibility with early releases.

retc = RexxDidRexxTerminate();