═══ 1. Notices ═══ First Edition (December 1991) The following paragraph does not apply to the United Kingdom or any country where such provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or implied warranties in certain transactions, therefore, this statement may not apply to you. This publication could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein; these changes will be incorporated in new editions of the publication. IBM may make improvements and/or changes in the product(s) and/or the program(s) described in this publication at any time. It is possible that this publication may contain reference to, or information about, IBM products (machines and programs), programming, or services that are not announced in your country. Such references or information must not be construed to mean that IBM intends to announce such IBM products, programming, or services in your country. Requests for technical information about IBM products should be made to your IBM authorized reseller or IBM marketing representative. ═══ 1.1. Copyright Notices ═══ COPYRIGHT LICENSE: This publication contains printed sample application programs in source language, which illustrate OS/2 programming techniques. You may copy, modify, and distribute these sample programs in any form without payment to IBM, for the purposes of developing, using, marketing or distributing application programs conforming to the OS/2 application programming interface. Each copy of any portion of these sample programs or any derivative work, which is distributed to others, must include a copyright notice as follows: "(C) (your company name) (year). All rights reserved." (C) Copyright International Business Machines Corporation 1994. All rights reserved. Note to U.S. Government Users - Documentation related to restricted rights - Use, duplication or disclosure is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp. ═══ 1.2. Disclaimers ═══ References in this publication to IBM products, programs, or services do not imply that IBM intends to make these available in all countries in which IBM operates. Any reference to an IBM product, program or service is not intended to state or imply that only IBM's product, program, or service may be used. Any functionally equivalent product, program, or service that does not infringe any of IBM's intellectual property rights or other legally protectable rights may be used instead of the IBM product, program, or service. Evaluation and verification of operation in conjunction with other products, programs, or services, except those expressly designated by IBM, are the user's responsibility. IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to the IBM Director of Licensing, IBM Corporation, 500 Columbus Avenue, Thornwood NY 10594, U.S.A. ═══ 1.3. Trademarks ═══ The following terms, denoted by an asterisk (*) in this publication, are trademarks of the IBM Corporation in the United States or other countries: IBM PM Presentation Manager OS/2 SAA System Application Architecture Workplace Shell The following terms, denoted by a double asterisk (**) in this publication, are trademarks of other companies as follows. Other trademarks are trademarks of their respective companies. C++ AT&T, Inc. Helvetica Linotype ═══ 2. How to Use the Program Reference ═══ The REXX Program Reference is a detailed technical reference for application programmers. It gives reference information and code examples to enable you to write source code using REXX Program functions. Before you begin to use this information, it would be helpful to understand how you can: o Expand the Contents to see all available topics o Obtain additional information for a highlighted word or phrase o Use action bar choices o Use the programming information. How to Use the Contents When the Contents window first appears, some topics have a plus (+) sign beside them. The plus sign indicates that additional topics are available. To expand the Contents if you are using a mouse, click on the plus sign. If you are using the keyboard, use the Up or Down Arrow key to highlight the topic, and press the plus (+) key. For example, File System has a plus sign beside it. To see additional topics for that heading, click on the plus sign or highlight that topic and press the plus (+) key. To view a topic, double-click on the topic (or press the Up or Down Arrow key to highlight the topic, and then press the Enter key). How to Obtain Additional Information After you select a topic, the information for that topic appears in a window. Highlighted words or phrases indicate that additional information is available. You will notice that certain words and phrases are highlighted in green letters, or in white letters on a black background. These are called hypertext terms. If you are using a mouse, double-click on the highlighted word. If you are using a keyboard, press the Tab key to move to the highlighted word, and then press the Enter key. Additional information then appears in a window. How to Use Action Bar Choices Several choices are available for managing information presented in the OS/2* 2.0 Control Program Reference. There are three pull-down menus on the action bar: the Services menu, the Options menu, and the Help menu. The actions that are selectable from the Services menu operate on the active window currently displayed on the screen. These actions include the following: Bookmark Allows you to set a placeholder so you can retrieve information of interest to you. When you place a bookmark on a topic, it is added to a list of bookmarks you have previously set. You can view the list, and you can remove one or all bookmarks from the list. If you have not set any bookmarks, the list is empty. To set a bookmark, do the following: 1. Select a topic from the Contents. 2. When that topic appears, choose the Bookmark option from the Services pull-down. 3. If you want to change the name used for the bookmark, type the new name in the field. 4. Click on the Place radio button (or press the Up or Down Arrow key to select it). 5. Click on OK (or select it and press Enter). The bookmark is then added to the bookmark list. Search Allows you to find occurrences of a word or phrase in the current topic, selected topics, or all topics. You can specify a word or phrase to be searched. You can also limit the search to a set of topics by first marking the topics in the Contents list. To search for a word or phrase in all topics, do the following: 1. Choose the Search option from the Services pull-down. 2. Type the word or words to be searched for. 3. Click on All sections (or press the Up or Down Arrow keys to select it). 4. Click on Search (or select it and press Enter) to begin the search. 5. The list of topics where the word or phrase appears is displayed. Print Allows you to print one or more topics. You can also print a set of topics by first marking the topics in the Contents list. To print the document Contents list, do the following: 1. Choose Print from the Services pull-down. 2. Click on Contents (or press the Up or Down Arrow key to select it). 3. Click on Print (or select it and press Enter). 4. The Contents list is printed on your printer. Copy Allows you to copy a topic that you are viewing to the System Clipboard or to a file that you can edit. You will find this particularly useful for copying syntax definitions and program samples into the application that you are developing. You can copy a topic that you are viewing in two ways: o Copy copies the topic that you are viewing into the System Clipboard. If you are using a Presentation Manager* (PM) editor (for example, the System Editor) that copies or cuts (or both) to the System Clipboard, and pastes to the System Clipboard, you can easily add the copied information to your program source module. o Copy to file copies the topic that you are viewing into a temporary file named TEXT.TMP. You can later edit that file by using any editor. You will find TEXT.TMP in the directory where your viewable document resides. To copy a topic, do the following: 1. Expand the Contents list and select a topic. 2. When the topic appears, choose Copy to file from the Services pull-down. 3. The system puts the text pertaining to that topic into the temporary file named TEXT.TMP. For information on one of the other choices in the Services pull-down, highlight the choice and press the F1 key. The actions that are selectable from the Options menu allow you to change the way your Contents list is displayed. To expand the Contents and show all levels for all topics, choose Expand all from the Options pull-down. You can also press the Ctrl and * keys together. For information on one of the other choices in the Options pull-down, highlight the choice and press the F1 key. The actions that are selectable from the Help menu allow you to select different types of help information. You can also press the F1 key for help information about the Information Presentation Facility (IPF). How to Use the Programming Information The REXX Program Reference consists of reference information that provides a detailed description of each REXX function. REXX Program programming information is presented by component, such as Subcommmand Interface Functions, System Exit Functions and Macrospace Functions, for example: ┌─────────────────────────────────────────┐ │ Contents │ ├─────────────────────────────────────────┤ │ │ │ + Subcommand Interface Functions │ │ + System Exit Functions │ │ + Macrospace Functions │ │ │ └─────────────────────────────────────────┘ By clicking on the plus sign beside 'Subcommand Interface Functions', you see an alphabetic list of the REXX functions for the subcommand interface. Selecting a function takes you directly into the reference information for that function. Units of reference information are presented in selectable multiple windows or viewports. A viewport is a Presentation Manager window that can be sized, moved, minimized, maximized, or closed. By selecting a unit (in this case, an entry on the Contents list), you will see two windows displayed: ┌───────────────┬─────────────────────────────┐ │ Unit Title │ Selection Title │ ├───────────────┼─────────────────────────────┤ │ Select one: │ │ │ . │ │ │ . │ │ │ . │ │ │ Return Values │ │ │ Errors │ │ │ Notes │ │ │ │ │ │ │ │ └───────────────┴─────────────────────────────┘ The window on the left is the primary window. It contains a list of items that are always available to you. The window on the right is the secondary window. It contains a 'snapshot' of the unit information. For reference units (that is, function descriptions), this window contains the Call Syntax. All of the information needed to understand a reference unit (or topic) is readily available to you through the primary window. The information is divided into discrete information groups, and only the appropriate information group appears for the topic that you are viewing. The information groups for a reference unit (that is, a function description) can include the following: o Call Syntax o Uses o Parameters o Data Structures o Return Values o Errors o Notes o Related Functions o Examples o Sample Programs This list may vary. Uses, Data Structures, Notes, Related Functions, Examples, and Sample Programs may be omitted when they do not apply. In other instances, information may be added when appropriate. For example, when viewing the RexxStart function, you will see the Data Structures topic and the Examples topic in the primary window. Information groups are displayed in separate viewports that are stacked in a third window location that overlaps the secondary window. By selecting an item (information group) in the primary window, the item is displayed in the third window location: ┌──────────────┬───────────────┬───────────────┐ │ Unit Title │ Selection Ti│ Data Types │ ├──────────────┼───────────────┼───────────────┤ │ Select one: │ │ BOOL │ │ │ │ BYTE │ │ . │ │ CHAR │ │ . │ │ . │ │ . │ │ . │ │ Data Types │ │ . │ │ Errors │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └──────────────┴───────────────┴───────────────┘ By selecting successive items from the primary window, additional windows are displayed on top of the previous windows displayed in the third window location. For example, in a function description, Parameters and Return Values are items listed in the primary window. When selected, they appear one on top of the other in the third window location. Because of this, you may move the first selected (topmost) window to the left before selecting the next item. This allows simultaneous display of two related pieces of information from the 'stack' of windows in the third window location: ┌───────────────┬───────────────┬───────────────┐ │ Unit Title │ Parameters │ Return Values │ ├───────────────┼───────────────┼───────────────┤ │ Select one: │ │ RXSUBCOM_NOER│ │ . │ │ RXSUBCOM_NOTR│ │ . │ │ RXSUBCOM_NOEM│ │ . │ │ RXSUBCOM_BADT│ │ Parameters │ │ . │ │ Return Values │ │ . │ │ Errors │ │ . │ │ Examples │ │ │ │ │ │ │ │ │ │ │ └───────────────┴───────────────┴───────────────┘ Each window can be individually closed from its system menu. All windows are closed when you close the primary window. Some secondary windows may have the appearance of a split screen. For example, an illustration may appear in the left half of the window, and scrollable, explanatory information may appear in the right half of the window. Because illustrations may not necessarily fit into the small window size on your screen, you may maximize the secondary window for better readability. ═══ IBM Trademark ═══ Trademark of the IBM Corporation. ═══ 3. REXX Functions ═══ The following functions can interface with the REXX interpreter: RexxAddMacro RexxClearMacroSpace RexxDeregisterExit RexxDeregisterFunction RexxDeregisterSubcom RexxDropMacro RexxLoadMacroSpace RexxQueryExit RexxQueryFunction RexxQueryMacro RexxQuerySubcom RexxRegisterExitExe RexxRegisterExitDll RexxRegisterFunctionExe RexxRegisterFunctionDll RexxRegisterSubcomExe RexxRegisterSubcomDll RexxReorderMacro RexxResetTrace RexxSaveMacroSpace RexxSetHalt RexxSetTrace RexxStart RexxVariablePool ═══ 4. Using REXX Interfaces ═══ This chapter is addressed mainly to professional systems and application programmers. It describes: o RXSTRINGs o Invoking the REXX Interpreter o Subcommand Handlers o External Functions o System Exits o Variable Pool Interface o Macrospace Interface o Halt and Trace Functions In this chapter, the term application refers to programs written in languages other than REXX. The features described here allow an application to extend many parts of the REXX language or extend an application with REXX. This includes creating handlers for subcommands, external functions and system exits. Subcommands Commands issued from a REXX program. A REXX expression is evaluated and the result is passed as a command to the currently "addressed" subcommand handler. Subcommands are used in REXX programs running as application macros. Functions Direct extensions of the REXX language. An application can create functions that extend the native REXX function set. Functions may be general purpose extensions or specific to an application. System Exits Create programmer-defined variations of the operating system. The application programmer can tailor the REXX interpreter behavior by replacing the OS/2* operating system for REXX system requests. Subcommand, function and exit handlers have similar coding, compilation and packaging characteristics. In addition, applications can manipulate the variables in REXX programs (the Variable Pool Interface), and execute REXX routines directly from memory (the Macrospace Interface). ═══ 4.1. General Characteristics ═══ The basic requirements for subcommand, function and system exit handlers are: o REXX handlers must use the system linkage convention. Handler functions must be declared with the appropriate type definition from the REXXSAA.H include file: - RexxSubcomHandler - RexxFunctionHandler - RexxExitHandler o A REXX handler must be packaged as either: - An exported routine within a Dynamic Link Library (a dynalink or DLL) - An entry point within an executable (EXE) module. o A handler must be registered with REXX before it can be used. REXX uses the registration information to locate and call the handler. For example, external function registration of a dynamic link library external function identifies both the dynamic link library and routine that contains the external function. Also note: - Dynamic link library handlers are global to the OS/2* operating system; they can be used by any REXX program. - EXE file handlers are local to the registering process; handlers packaged within an EXE module can only be used by a REXX program running in the same process as the EXE module. ═══ 5. RXSTRINGs ═══ Many of the REXX interfaces pass REXX character strings to and from a REXX procedure. The RXSTRING data structure is used to describe REXX character strings. An RXSTRING is a content-insensitive, flat model character string with a theoretical maximum length of 4 gigabytes. The following structure defines an RXSTRING: RXSTRING Data Structure typedef struct { ULONG strlength; /* length of string */ PCH strptr; /* pointer to string */ } RXSTRING; typedef RXSTRING *PRXSTRING; /* pointer to an RXSTRING */ 1. The REXXSAA.H include file contains a number of convenient macros for setting and testing RXSTRING values. 2. An RXSTRING can have a value (including the null string, "") or it can be empty. o If an RXSTRING has a value, the strptr field will be non-NULL. The RXSTRING macro RXVALIDSTRING(string) will return TRUE. o If an RXSTRING is the REXX null string (""), the strptr field will be non-NULL and the strlength field will be 0. The RXSTRING macro RXZEROLENSTRING(string) will return TRUE. o If an RXSTRING is empty, the field strptr will be NULL. The RXSTRING macro RXNULLSTRING(string) will return TRUE. 3. When the REXX interpreter passes an RXSTRING to a subcommand handler, external function, or exit handler, the interpreter adds a null character (hexadecimal zero) at the end of the RXSTRING data. The C string library functions can be used on these strings. However, the RXSTRING data can also contain null characters. There is no guarantee that the first null character encountered in an RXSTRING marks the end of the string. The C string functions should only be used when null characters are not expected in the RXSTRINGs (such a file names passed to external functions). The strlength field in the RXSTRING does not include the terminating null character. 4. When the REXX interpreter calls subcommand handlers, external functions, and some exit handlers, the interpreter expects an RXSTRING value returned. The interpreter provides a default RXSTRING with a strlength of 256 for the returned information. If the returned data is shorter than 256 characters, the handler can copy the data into the default RXSTRING and set the strlength field to the length returned. If the returned data is longer than 256 characters, a new RXSTRING can be allocated using "DosAllocMem". The strptr field must point to the new storage and the strlength must be set to the string length. The REXX interpreter will return the newly allocated storage to the system for the handler routine. ═══ 6. Invoking the REXX Interpreter ═══ A REXX program can be executed directly by the operating system or from within an application program. ═══ 6.1. From the Operating System ═══ The CMD.EXE command shell calls the REXX interpreter for the user: o at command prompts o in calls from CMD (batch) files Note: Use the OS/2* operating system CALL command to invoke a REXX program in a batch file if you want control to return to the caller. o from the object that represents the program on the OS/2 operating system Desktop. ═══ 6.2. From Within an Application ═══ The REXX interpreter is a dynamic link library (DLL) routine. Any application can call the REXX interpreter to execute a REXX program. The interpreter is fully re-entrant and supports REXX procedures running on multiple threads within the same process. A C-language prototype for the RexxStart function in the Developer's Toolkit REXXSAA.H include file. ═══ 6.3. RexxStart ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Data Structures Return Values Notes Related Functions Examples ═══ Call Syntax - RexxStart ═══ /*******************************************/ /* RexxStart invokes the REXX interpreter */ /* to execute a REXX procedure. */ /*******************************************/ LONG return_code; /* interpreter return code */ RXSTRING argv[1]; /* program argument string */ RXSTRING retstr; /* program return value */ LONG rc; /* converted return code */ return_code = RexxStart(1, argv, "CHANGE.ED", NULL, "Editor", RXCOMMAND, NULL, &rc, &retstr); ═══ Uses - RexxStart ═══ RexxStart invokes the REXX interpreter to execute a REXX procedure. ═══ Parameters - RexxStart ═══ RexxStart (ArgCount, ArgList, ProgramName, Instore, EnvName, CallType, Exits, ReturnCode, Result) Parameters: ArgCount (LONG) - input The number of elements in the ArgList array. This is the value that will be returned by the ARG() built-in function in the REXX program. ArgCount includes RXSTRINGs which represent omitted arguments. Omitted arguments will be empty RXSTRINGs (strptr will be NULL). ArgList (PRXSTRING) - input An array of RXSTRING structures that are the REXX program arguments. ProgramName (PSZ) - input Address of the ASCIIZ name of the REXX procedure. If Instore is NULL, string must contain at least the file name of the REXX procedure. An extension, drive, and path specification can also be provided. If a file extension is not specified, a default of ".CMD" is supplied. A REXX program can use any extension. If the path and drive are not provided, the REXX interpreter uses the normal OS/2* operating system file search (current directory, then environment path). 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 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 RexxStart function terminates with an error return code. If either Instore strptr field is not NULL, Instore is used to execute a REXX procedure directly from storage. Instore[0] An RXSTRING describing a memory buffer containing 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] An RXSTRING containing the tokenized image of the REXX procedure. If Instore[1] is empty, the REXX interpreter will return the tokenized image in Instore[1] when the REXX procedure finishes executing. The tokenized image can be used in Instore[1] on subsequent RexxStart function calls. If Instore[1] is not empty, interpreter will execute the tokenized image directly. The program source provided in Instore[0] is only used 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 SOURCELINE built-in function is used, SOURCELINE will return null strings for the REXX procedure source lines. If Instore[1] is not empty, but does not contain a valid REXX tokenized image, unpredictable results can occur. The REXX interpreter might be able to determine that the tokenized image is incorrect and retokenize the source. 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 contains the string "//T" and the CallType is RXCOMMAND, the interpreter will tokenize the procedure source and return the tokenized image without running the program. The program using the RexxStart function must release Instore[1] using "DosFreeMem" when the tokenized image is no longer needed. The format of the tokenized image of a REXX program is not a programming interface. The tokenized image can only be executed by the same interpreter version used to create the image. Therefore, a tokenized image must not be moved to other systems or saved for later use. The tokenized image can, however, be used multiple times during a single application instance. EnvName (PSZ) - input Address of the ASCIIZ 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 (LONG) - input The type of REXX procedure execution. Allowed execution types are: RXCOMMAND The REXX procedure is an OS/2 operating system command or application command. REXX commands normally have a single argument string. The REXX PARSE SOURCE instruction will return COMMAND as the second token. RXSUBROUTINE The REXX procedure is a subroutine of another program. The subroutine can have multiple arguments and does not need to return a result. The REXX PARSE SOURCE instruction will return SUBROUTINE as the second token. RXFUNCTION The REXX procedure is a function called from another program. The subroutine can have multiple arguments and must return a result. The REXX PARSE SOURCE instruction will return FUNCTION as the second token. Exits (PRXSYSEXIT) - input An array of RXSYSEXIT structures defining exits the REXX interpreter will use. The RXSYSEXIT structures have the following form: RXSYSEXIT Data Structure typedef struct { PSZ sysexit_name; /* name of exit handler */ LONG sysexit_code; /* system exit function code */ } RXSYSEXIT; The sysexit_name is the address of an ASCIIZ exit handler name registered with RexxRegisterExitExe or RexxRegisterExitDll. sysexit_code is a code identifying the handler exit type. See System Exits for exit code definitions. The system exit list end is identified by an RXENDLST entry. Exits must be NULL if exits are not used. ReturnCode (PLONG) - output 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 will be converted to an integer and and also returned in ReturnCode. Result (PRXSTRING) - output 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 will allocate an RXSTRING using "DosAllocMem". The caller of the RexxStart function must release the RXSTRING storage with "DosFreeMem". The REXX interpreter does not add a terminating null to Result. ═══ Data Structures - RexxStart ═══ RexxStart uses the following data structures: typedef struct { ULONG strlength; /* length of string */ PCH strptr; /* pointer to string */ } RXSTRING; typedef RXSTRING *PRXSTRING; /* pointer to an RXSTRING */ typedef struct { PSZ sysexit_name; /* name of exit handler */ LONG sysexit_code; /* system exit function code */ } RXSYSEXIT; ═══ Return Values - RexxStart ═══ RexxStart returns the following values: negative Interpreter errors. 0 No errors occurred. The REXX procedure executed normally. When a macrospace REXX procedure is not loaded in the macrospace, the return code is -3 ("Program is unreadable"). ═══ Notes - RexxStart ═══ The REXX interpreter is a dynamic link library (DLL) routine. Any application can use the REXX interpreter to execute a REXX program. The interpreter is fully re-entrant and supports REXX procedures running on multiple threads within the same process. ═══ Related Functions - RexxStart ═══ The following functions are related to RexxStart: RexxAddMacro RexxRegisterSubcomExe RexxRegisterFunctionExe ═══ Examples - RexxStart ═══ The following example shows the use of RexxStart: LONG return_code; /* interpreter return code */ RXSTRING argv[1]; /* program argument string */ RXSTRING retstr; /* program return value */ LONG 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) DosFreeMem(RXSTRPTR(retval)); /* release the RXSTRING */ ═══ 7. Subcommand Interfaces ═══ An application can create named handlers to process commands from a REXX programs. Once created, the subcommand handler name can be used with the RexxStart function or the REXX ADDRESS instruction. Subcommand handlers must be registered with the RexxRegisterSubcomExe or RexxRegisterSubcomDll function before use. ═══ 7.1. Registering Subcommand Handlers ═══ A subcommand handler can reside in the same module (EXE or DLL) as an application, or it can reside in a separate dynamic link library. An application that executes REXX procedures with RexxStart should use RexxRegisterSubcomExe to register subcommand handlers. The REXX interpreter passes commands to the application subcommand handler entry point. Subcommand handlers created using RexxRegisterSubcomExe are available only to REXX programs invoked from the registering application. The RexxRegisterSubcomDll function creates subcommand handlers which reside in a dynamic link library. A dynamic link library subcommand handler can be accessed by any REXX program using the REXX ADDRESS instruction. A dynamic link library subcommand handler can also be registered directly from a REXX program using the RXSUBCOM command. ═══ 7.2. Creating Subcommand Handlers ═══ The following example is a sample subcommand handler definition. Sample Definition of a Subcommand Handler ULONG command_handler( PRXSTRING Command, /* Command string from REXX */ PUSHORT Flags, /* Returned Error/Failure flags */ PRXSTRING Retstr) /* Returned RC string */ Where: Command The command string created by REXX. Command is a null-terminated RXSTRING containing the issued command. Flags Subcommand completion status. The subcommand handler can indicate success, error, or failure status. The subcommand handler can set Flags to one of the following value: RXSUBCOM_OK The subcommand completed normally. No errors occurred during subcommand processing and the REXX procedure will continue when the subcommand handler returns. RXSUBCOM_ERROR A subcommand error occurred. RXSUBCOM_ERROR indicates a subcommand error occurred, for example, incorrect command options or syntax. If the subcommand handler sets Flags to RXSUBCOM_ERROR, the REXX interpreter will raise an ERROR condition if SIGNAL ON ERROR or CALL ON ERROR traps have been created. If TRACE ERRORS has been issued, REXX will trace the command when the subcommand handler returns. RXSUBCOM_FAILURE A subcommand failure occurred. RXSUBCOM_FAILURE indicates that general subcommand processing errors have occurred. For example, unknown commands normally return RXSUBCOM_FAILURE. If the subcommand handler sets Flags to RXSUBCOM_FAILURE, the REXX interpreter will raise a FAILUREcondition if SIGNAL ON FAILURE or CALL ON FAILURE traps have been created. If TRACE FAILURES has been issued, REXX will trace the command when the subcommand handler returns. Retstr Address of an RXSTRING for the return code. Retstr is a character string return code that will be assigned to the REXX special variable RC when the subcommand handler returns to REXX. The REXX interpreter provides a default 256-byte RXSTRING in Retstr. A longer RXSTRING can allocated with "DosAllocMem" if the return string is longer than the default RXSTRING. If the subcommand handler sets Retval to an empty RXSTRING (a NULL strptr), REXX will assign the string "0" to RC. ═══ Sample Sucommand Handler ═══ ULONG Edit_Commands( PRXSTRING Command, /* Command string passed from the caller */ PUSHORT Flags, /* pointer to short for return of flags */ PRXSTRING Retstr) /* pointer to RXSTRING for RC return */ { LONG command_id; /* command to process */ LONG rc; /* return code */ PSZ scan_pointer; /* current command scan */ PSZ target; /* general editor target */ scan_pointer = command->strptr; /* point to the command */ /* resolve command */ command_id = resolve_command(&scan_pointer); switch (command_id) { /* process based on command */ case LOCATE: /* locate command */ /* validate rest of command */ if (rc = get_target(&scan_pointer, &target)) { *Flags = RXSUBCOM_ERROR; /* raise an error condition */ break; /* return to REXX */ } rc = locate(target); /* look target in the file */ *Flags = RXSUBCOM_OK; /* not found is not an error */ break; /* go finish up */ . . . default: /* unknown command */ rc = 1; /* return code for unknown */ *Flags = RXSUBCOM_FAILURE; /* this is a command failure */ break; } sprintf(Retstr->strptr, "%d", rc); /* format return code string */ /* and set the correct length */ Retstr->strlength = strlen(Retstr->strptr); return 0; /* processing completed */ } ═══ 8. Subcommand Interface Functions ═══ o RexxRegisterSubcomDll registers a subcommand handler that resides in a dynamic link library routine. o RexxRegisterSubcomExe registers a subcommand handler that resides within application code. o RexxDeregisterSubcom deregisters a subcommand handler. o RexxQuerySubcom queries a subcommand handler and retrieves saved user information. ═══ 8.1. RexxRegisterSubcomDll ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Notes Related Functions Sample Programs ═══ Call Syntax - RexxRegisterSubcomDll ═══ /*******************************************/ /* RexxRegisterSubcomDll registers a */ /* subcommand handler that resides in a */ /* dynamic link library routine. */ /*******************************************/ #define INCL_RXSUBCOM /* Subcommand handler values */ PSZ name; /* handler name */ PSZ library; /* DLL name */ PSZ routine; /* routine name */ ULONG rc; /* Return code */ ULONG userdata[2]; /* save userdata*/ rc = RexxRegisterSubcomDll(name, library, routine, userdata, RXSUBCOM_DROPPABLE); ═══ Uses - RexxRegisterSubcomDll ═══ RexxRegisterSubcomDll registers a subcommand handler that resides in a dynamic link library routine. ═══ Parameters - RexxRegisterSubcomDll ═══ RexxRegisterSubcomDll (EnvName, ModuleName, EntryPoint, UserArea, DropAuth) Parameters: EnvName (PSZ) - input Address of an ASCIIZ subcommand handler name. ModuleName (PSZ) - input Address of an ASCIIZ dynamic link library name. ModuleName is the DLL file containing the subcommand handler routine. EntryPoint (PSZ) - input Address of an ASCIIZ dynamic link library procedure name. EntryPoint is the name of the exported routine within ModuleName that is the REXX subcommand handler. UserArea (PUCHAR) - input Address of an 8-byte area of user defined information. The 8 bytes addressed by UserArea will be saved with the subcommand handler registration. UserArea can be NULL if there is no user information to save. The saved user information can be retrieved with the RexxQuerySubcom function. DropAuth (ULONG) - input The drop authority. DropAuth identifies the processes that can deregister the subcommand handler. The possible DropAuth values are: RXSUBCOM_DROPPABLE Any process can deregister the subcommand handler with RexxDeregisterSubcom. RXSUBCOM_NONDROP Only a thread within the same process as the thread that registered the handler can deregister the handler with RexxDeregisterSubcom. ═══ Return Values - RexxRegisterSubcomDll ═══ RexxRegisterSubcomDll returns the following values: 0 RXSUBCOM_OK 10 RXSUBCOM_DUP 1002 RXSUBCOM_NOEMEM 1003 RXSUBCOM_BADTYPE ═══ Notes - RexxRegisterSubcomDll ═══ EntryPoint can be either a 16-bit or a 32-bit routine. REXX will invoke the handler in the correct addressing mode. A REXX procedure can register dynamic link library subcommand handlers with the RXSUBCOM command. For example: /* register Dialog Manager */ /* subcommand handler */ 'RXSUBCOM REGISTER ISPCIR ISPCIR ISPCIR' Address ispcir /* send commands to dialog mgr */ The RXSUBCOM command registers the Dialog Manager subcommand handler ISPCIR as routine ISPCIR in the ISPCIR dynamic link library. ═══ Related Functions - RexxRegisterSubcomDll ═══ The following functions are related to RexxRegisterSubcomDll: RexxRegisterSubcomExe RexxDeregisterSubcom RexxQuerySubcom RexxStart ═══ 8.2. RexxRegisterSubcomExe ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Notes Related Functions Examples Sample Programs ═══ Call Syntax - RexxRegisterSubcomExe ═══ /*******************************************/ /* RexxRegisterSubcomExe registers a */ /* subcommand handler that resides within */ /* application code . */ /*******************************************/ #define INCL_RXSUBCOM /* Subcommand handler values */ PSZ name; /* handler name */ ULONG rc; /* Return code */ ULONG userdata[2]; /* save userdata*/ rc = RexxRegisterSubcomExe(name, &handler_routine, userdata); ═══ Uses - RexxRegisterSubcomExe ═══ RexxRegisterSubcomExe registers a subcommand handler that resides within application code. ═══ Parameters - RexxRegisterSubcomExe ═══ RexxRegisterSubcomExe (EnvName, EntryPoint, UserArea) Parameters: EnvName (PSZ) - input Address of an ASCIIZ subcommand handler name. EntryPoint (PFN) - input Address of the subcommand handler entry point within the application EXE code. pt.UserArea (PUCHAR) - input pd. Address of an 8-byte area of user defined information. The 8 bytes addressed by UserArea will be saved with the subcommand handler registration. UserArea can be NULL if there is no user information to save. The user information can be retrieved with the RexxQuerySubcom function. ═══ Return Values - RexxRegisterSubcomExe ═══ RexxRegisterSubcomExe returns the following values: 0 RXSUBCOM_OK 10 RXSUBCOM_DUP 30 RXSUBCOM_NOTREG 1002 RXSUBCOM_NOEMEM 1003 RXSUBCOM_BADTYPE ═══ Notes - RexxRegisterSubcomExe ═══ If EnvName is same as a subcommand handler already registered with RexxRegisterSubcomDll, RexxRegisterSubcomExe will return RXSUBCOM_DUP. This is not an error condition. RexxRegisterSubcomExe has successfully registered the new subcommand handler. ═══ Related Functions - RexxRegisterSubcomExe ═══ The following functions are related to RexxRegisterSubcomExe: RexxRegisterSubcomDll RexxDeregisterSubcom RexxQuerySubcom RexxStart ═══ Examples - RexxRegisterSubcomExe ═══ The following example shows the use of RexxRegisterSubcomExe: WORKAREARECORD *user_info[2]; /* saved user information */ user_info[0] = global_workarea; /* save global work area for */ user_info[1] = NULL; /* re-entrancy */ rc = RexxRegisterSubcomExe("Editor", /* register editor handler */ &Edit_Commands, /* located at this address */ user_info); /* save global pointer */ ═══ 8.3. RexxDeregisterSubcom ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Notes Related Functions ═══ Call Syntax - RexxDeregisterSubcom ═══ /*******************************************/ /* RexxDeregisterSubcom deregisters a */ /* subcommand handler. */ /*******************************************/ #define INCL_RXSUBCOM /* Subcommand handler values */ PSZ name; /* handler name */ PSZ library /* handler dll */ ULONG rc; /* Return code */ rc = RexxDeregisterSubcom(name, library); ═══ Uses - RexxDeregisterSubcom ═══ RexxDeregisterSubcom deregisters a subcommand handler. ═══ Parameters - RexxDeregisterSubcom ═══ RexxDeregisterSubcom (EnvName, ModuleName) Parameters: EnvName (PSZ) - input Address of an ASCIIZ subcommand handler name. ModuleName (PSZ) - input Address of an ASCIIZ dynalink library name. ModuleName is the name of the dynalink library containing the registered subcommand handler. When ModuleName is NULL, RexxDeregisterSubcom searches the RexxRegisterSubcomExe subcommand handler list for a handler within the current process. If RexxDeregisterSubcom does not find a RexxRegisterSubcomExe handler, it will search the RexxRegisterSubcomDll subcommand handler list. ═══ Return Values - RexxDeregisterSubcom ═══ RexxDeregisterSubcom returns the following values: 0 RXSUBCOM_OK 30 RXSUBCOM_NOTREG 40 RXSUBCOM_NOCANDROP 1003 RXSUBCOM_BADTYPE ═══ Notes - RexxDeregisterSubcom ═══ The handler is removed from the active subcommand handler list. ═══ Related Functions - RexxDeregisterSubcom ═══ The following functions are related to RexxDeregisterSubcom: RexxRegisterSubcomDll RexxRegisterSubcomExe RexxQuerySubcom ═══ 8.4. RexxQuerySubcom ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Related Functions Examples ═══ Call Syntax - RexxQuerySubcom ═══ /*******************************************/ /* RexxQuerySubcom queries a subcommand */ /* handler and retrieves saved user */ /* information. */ /*******************************************/ #define INCL_RXSUBCOM /* subcommand handler values */ PSZ name; /* handler name */ PSZ library; /* DLL name */ ULONG userdata[2]; /* saved information */ ULONG rc; /* Return code */ rc = RexxQuerySubcom(name, library, userdata); ═══ Uses - RexxQuerySubcom ═══ RexxQuerySubcom queries a subcommand handler and retrieves saved user information. ═══ Parameters - RexxQuerySubcom ═══ RexxQuerySubcom (EnvName, ModuleName, Flag, UserWord) Parameters: EnvName (PSZ) - input Address of an ASCIIZ subcommand handler name. ModuleName (PSZ) - input Address of an ASCIIZ dynamic link library name. ModuleName restricts the query to a subcommand handler within the ModuleName dynamic link library. When ModuleName is NULL, RexxQuerySubcom searches the RexxRegisterSubcomExe subcommand handler list for a handler within the current process. If RexxQuerySubcom does not find a RexxRegisterSubcomExe handler, it will search the RexxRegisterSubcomDll subcommand handler list. Flag (PUSHORT) - output Subcommand handler registration flag. Flag is the EnvName subcommand handler registration status. When RexxQuerySubcom returns RXSUBCOM_OK, the EnvName subcommand handler is currently registered. When RexxQuerySubcom returns RXSUBCOM_NOTREG, the EnvName subcommand handler is not registered. UserWord (PUCHAR) - output Address of an 8-byte area to receive the user information saved with RexxRegisterSubcomExe or RexxRegisterSubcomDll. UserWord can be NULL if the saved user information is not required. ═══ Return Values - RexxQuerySubcom ═══ RexxQuerySubcom returns the following values: 0 RXSUBCOM_OK 30 RXSUBCOM_NOTREG 1003 RXSUBCOM_BADTYPE ═══ Related Functions - RexxQuerySubcom ═══ The following functions are related to RexxQuerySubcom: RexxRegisterSubcomDll RexxRegisterSubcomExe RexxDeregisterSubcom ═══ Examples - RexxQuerySubcom ═══ The following examples show the use of RexxQuerySubcom: ULONG Edit_Commands( PRXSTRING Command, /* Command string passed from the caller */ PUSHORT Flags, /* pointer to short for return of flags */ PRXSTRING Retstr) /* pointer to RXSTRING for RC return */ { WORKAREARECORD *user_info[2]; /* saved user information */ WORKAREARECORD global_workarea; /* application data anchor */ USHORT query_flag; /* flag for handler query */ rc = RexxQuerySubcom("Editor", /* retrieve application work */ NULL, /* area anchor from REXX. */ &query_flag, user_info); global_workarea = user_info[0]; /* set the global anchor */ ═══ Subcommand Interface Errors ═══ The following are the subcommand handler function errors.: RXSUBCOM_NOEMEM There is insufficient memory available to complete this request. RXSUBCOM_OK A subcommand function has executed successfully. RXSUBCOM_DUP A duplicate handler name has been successfully registered; there is either: o an EXE handler with the same name registered in another process, or o a DLL handler with the same name registered in another DLL; to address this subcommand, its library name must be specified. RXSUBCOM_NOTREG This indicates: o registration was unsuccessful due to duplicate handler and dynalink names (RexxRegisterSubcomExe or RexxRegisterSubcomDll) o the subcommand handler is not registered (other REXX subcommand functions). RXSUBCOM_NOCANDROP The subcommand handler has been registered as "not droppable". ═══ 9. External Functions ═══ There are two types of REXX external functions: 1. Routines written in REXX 2. Routines written in other OS/2* operating system supported languages. External functions written in the REXX language are not registered with REXX. the REXX functions are found by a disk search for a REXX procedure file that matches the function name. Functions written in other languages, however, must be registered with the REXX interpeter. ═══ 9.1. Registering External Functions ═══ An external function can reside in the same module (EXE or DLL) as an application, or it can reside in a separate dynamic link library. RexxRegisterFunctionExe registers external functions within an application module. External functions registered with RexxRegisterFunctionExe The RexxRegisterFunctionDll function registers external functions that reside in a dynamic link library. Once registered, a dynamic link library external function can be accessed by any REXX program. A dynamic link library external function can also be registered directly from a REXX program using the REXX RxFuncAdd built-in function. ═══ 9.2. Creating External Functions ═══ The following is a sample external function definition: Sample External Function Definition ULONG SysLoadFuncs( PSZ Name, /* name of the function */ LONG Argc, /* number of arguments */ RXSTRING Argv[], /* list of argument strings */ PSZ Queuename, /* current queue name */ PRXSTRING Retstr) /* returned result string */ Where Name Address of ASCIIZ external function name. Argc The size of the argument list. Argv will contain Argc RXSTRINGs. Argv An array of null-terminated RXSTRINGs for the function arguments. Queue The name of the currently defined REXX external data queue. Retstr Address of an RXSTRING for the returned value. Retstr is a character string function or subroutine return value. When a REXX program calls an external function with the REXX CALL instruction, Retstr is assigned to the REXX special variable RESULT. When the REXX program calls an external function as a function, Retstr is used directly within the REXX expression. The REXX interpreter provides a default 256-byte RXSTRING in Retstr. A longer RXSTRING can allocated with "DosAllocMem" if the returned string is longer name 256 bytes. The REXX interpreter releases Retstr with "DosFreeMem" when the external function completes. Returns An integer return code from the function. When the external function returns 0, the function completed successfully. Retstr contains the function return value. When external function return code is not 0, the REXX interpreter raises REXX error 40 ("Invalid call to routine"). The Retstr value is ignored. If the external function does not have a return value, the function must set Retstr to an an empty RXSTRING (NULL strptr). When a function does not return a value, the interpreter raises error 44, "Function did not return data". When an external function invoked with the REXX CALL instruction does not return a value, the REXX interpreter drops (unassigns) the special variable RESULT. ═══ 9.3. Calling External Functions ═══ RexxRegisterFunctionExe Only REXX procedures running in the same process can use the registered external function. It is possible to register functions with the same external function name if they are registered from different processes. However, RexxRegisterFunctionDll functions are available from all processes. The function names cannot be duplicated. ═══ 9.4. Sample External Function ═══ ULONG SysMkDir( PSZ Name, /* name of the function */ LONG Argc, /* number of arguments */ RXSTRING Argv[], /* list of argument strings */ PSZ Queuename, /* current queue name */ PRXSTRING Retstr) /* returned result string */ { ULONG rc; /* Return code of function */ if (Argc != 1) /* must be 1 argument */ return 40; /* incorrect call if not */ /* make the directory using */ /* the null-terminated */ rc = DosMkDir(Argv[0].strptr, 0L); /* directly */ sprintf(Retstr->strptr, "%d", rc); /* result is return code */ /* set proper string length */ Retstr->strlength = strlen(Retstr->strptr); return 0; /* successful completion */ } ═══ 10. External Function Interface Functions ═══ o RexxRegisterFunctionDll registers an external function that resides in a dynamic link library routine. o RexxRegisterFunctionExe registers an external function that resides within application code. o RexxDeregisterFunction deregisters an external function. o RexxQueryFunction queries the existence of a registered external function. ═══ 10.1. RexxRegisterFunctionDll ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Notes Related Functions Examples ═══ Call Syntax - RexxRegisterFunctionDll ═══ /*******************************************/ /* RexxRegisterFunctionDll registers an */ /* external function that resides in a */ /* dynamic link library routine. */ /*******************************************/ #define INCL_RXFUNC /* External function values */ PSZ name; /* function name */ PSZ library; /* DLL name */ PSZ routine; /* routine name */ ULONG rc; /* Return code */ rc = RexxRegisterFunctionDll(name, library, routine); ═══ Uses - RexxRegisterFunctionDll ═══ RexxRegisterFunctionDll registers an external function that resides in a dynamic link library routine. ═══ Parameters - RexxRegisterFunctionDll ═══ RexxRegisterFunctionDll (FuncName, ModuleName, EntryPoint) Parameters: FuncName (PSZ) - input Address of an ASCIIZ external function name. ModuleName (PSZ) - input Address of an ASCIIZ dynamic link library name. ModuleName is the DLL file containing the external function routine. EntryPoint (PSZ) - input Address of an ASCIIZ dynamic link procedure name. EntryPoint is exported external function routine within ModuleName. ═══ Return Values - RexxRegisterFunctionDll ═══ RexxRegisterFunctionDll returns the following values: 0 RXFUNC_OK 10 RXFUNC_DEFINED 20 RXFUNC_NOMEM ═══ Notes - RexxRegisterFunctionDll ═══ EntryPoint can be either a 16-bit or 32-bit routine. REXX will invoke the function in the correct addressing mode. A REXX procedure can register dynamic link library subcommand handlers with the RxFuncAdd built-in function. For example: /* register function SysLoadFuncs*/ /* in dynalink library REXXUTIL */ Call RxFuncAdd 'SysLoadFuncs', 'REXXUTIL', 'SysLoadFuncs' Call SysLoadFuncs /* call to load other functions */ The RxFuncAdd registers the external function SysLoadFuncs as routine SysLoadFuncs in the REXXUTIL dynamic link library. SysLoadFuncs registers additional functions in REXXUTIL.DLL with RexxRegisterFunctionDll. ═══ Related Functions - RexxRegisterFunctionDll ═══ The following functions are related to RexxRegisterFunctionDll: RexxRegisterFunctionExe RexxDeregisterFunction RexxQueryFunction ═══ Examples - RexxRegisterFunctionDll ═══ The following example shows the use of RexxRegisterFunctionDll: static PSZ RxFncTable[] = /* function package list */ { "SysCls", "SysCurpos", "SysCurState", "SysDriveInfo", } ULONG SysLoadFuncs( PSZ Name, /* name of the function */ LONG Argc, /* number of arguments */ RXSTRING Argv[], /* list of argument strings */ PSZ Queuename, /* current queue name */ PRXSTRING Retstr) /* returned result string */ { INT entries; /* Num of entries */ INT j; /* Counter */ Retstr->strlength = 0; /* set null string return */ if (Argc > 0) /* check arguments */ return 40; /* too many, raise an error */ /* get count of arguments */ entries = sizeof(RxFncTable)/sizeof(PSZ); /* register each function in */ for (j = 0; j < entries; j++) { /* the table */ RexxRegisterFunctionDll(RxFncTable[j], "REXXUTIL", RxFncTable[j]); } return 0; /* successful completion */ } ═══ 10.2. RexxRegisterFunctionExe ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Related Functions ═══ Call Syntax - RexxRegisterFunctionExe ═══ /*******************************************/ /* RexxRegisterFunctionExe registers an */ /* external function that resides within */ /* application code. */ /*******************************************/ #define INCL_RXFUNC /* external function values */ PSZ name; /* handler name */ ULONG rc; /* Return code */ rc = RexxRegisterFunctionExe(name, &external_function); ═══ Uses - RexxRegisterFunctionExe ═══ RexxRegisterFunctionExe registers an external function that resides within application code. ═══ Parameters - RexxRegisterFunctionExe ═══ RexxRegisterFunctionExe (FuncName, EntryPoint) Parameters: FuncName (PSZ) - input Address of an ASCIIZ external function name. EntryPoint (PFN) - input Address of the external function entry point within the application EXE file. Functions registered with RexxRegisterFunctionExe are local to the current process. REXX procedures in the same process as the RexxRegisterFunctionExe function caller can use local external functions. ═══ Return Values - RexxRegisterFunctionExe ═══ RexxRegisterFunctionExe returns the following values: 0 RXFUNC_OK 10 RXFUNC_DEFINED 20 RXFUNC_NOMEM ═══ Related Functions - RexxRegisterFunctionExe ═══ The following functions are related to RexxRegisterFunctionExe: RexxRegisterFunctionDll RexxDeregisterFunction RexxQueryFunction ═══ 10.3. RexxDeregisterFunction ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Related Functions ═══ Call Syntax - RexxDeregisterFunction ═══ /*******************************************/ /* RexxDeregisterFunction deregisters an */ /* external function. */ /*******************************************/ #define INCL_RXFUNC /* External Function values */ PSZ name; /* function name */ ULONG rc; /* Return code */ rc = RexxDeregisterFunction(name); ═══ Uses - RexxDeregisterFunction ═══ RexxDeregisterFunction deregisters an external function. ═══ Parameters - RexxDeregisterFunction ═══ RexxDeregisterFunction (FuncName) Parameters: FuncName (PSZ) - input Address of an ASCIIZ external function name to deregister. ═══ Return Values - RexxDeregisterFunction ═══ RexxDeregisterFunction returns the following values: 0 RXFUNC_OK 30 RXFUNC_NOTREG ═══ Related Functions - RexxDeregisterFunction ═══ The following functions are related to RexxDeregisterFunction: RexxRegisterFunctionDll RexxRegisterFunctionExe RexxQueryFunction ═══ 10.4. RexxQueryFunction ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Notes Related Functions ═══ Call Syntax - RexxQueryFunction ═══ /*******************************************/ /* RexxQueryFunction queries the */ /* existence of a registered external */ /* function. */ /*******************************************/ #define INCL_RXFUNC /* External function values */ PSZ name; /* function name */ ULONG rc; /* Return code */ rc = RexxQueryFunction(name); ═══ Uses - RexxQueryFunction ═══ RexxQueryFunction queries the existence of a registered external function. ═══ Parameters - RexxQueryFunction ═══ RexxQueryFunction (FuncName) Parameters: FuncName (PSZ) - input Address of an ASCIIZ external function name to query. ═══ Return Values - RexxQueryFunction ═══ RexxQueryFunction returns the following values: 0 RXFUNC_OK 30 RXFUNC_NOTREG ═══ Notes - RexxQueryFunction ═══ RexxQueryFunction will only return RXFUNC_OK if the requested function is available to the current process. If a function is not available to the current process, RexxQueryFunction search will search the RexxRegisterFunctionDll external function list. ═══ Related Functions - RexxQueryFunction ═══ The following functions are related to RexxQueryFunction: RexxRegisterFunctionDll RexxRegisterFunctionExe RexxDeregisterFunction ═══ External Function Interface Errors ═══ The following are the external function interface errors.: RXFUNC_OK The function call completed successfully. RXFUNC_DEFINED The requested function is already registered. RXFUNC_NOMEM There is not enough memory to register a new function. RXFUNC_NOTREG The requested function is not registered. ═══ 11. System Exits ═══ The REXX System Exits create user-define REXX interpreter operating environment. Application defined exit handlers process specified REXX interpreter activities. Applications can create exits for: o The administration of resources at the beginning and end of interpretation. o Linkages to external functions and subcommand handlers. o Special language features. For example, input and output to standard resources. o Polling for halt and external trace events. Exit handlers are similar to subcommand handlers and external functions: o Applications must registers named exit handlers with the REXX interpreter. o Exit handlers can reside in dynamic link libraries or within an application EXE module. ═══ 11.1. Writing System Exit Handlers ═══ The following is a sample exit handler definition: Sample System Exit Handler Definition LONG Rexx_IO_exit( LONG ExitNumber, /* code defining the exit function */ LONG Subfunction, /* code defining the exit subfunction */ PEXIT ParmBlock) /* function dependent control block */ Where: ExitNumber The major function code defining the type of exit. Subfunction The subfunction code defining the exit event. ParmBlock A pointer to the exit parameter list. The exit parameter list contains exit specific information. See the exit descriptions below parameter list formats. Note: Some exit subfunctions do not have parameters. ParmBlock for exit subfunctions without parameters. ═══ 11.1.1. Exit Return Codes ═══ Exit handlers return an integer value that signals one of three actions: RXEXIT_HANDLED The exit handler processed the exit subfunction and updated the subfunction parameter list as required. The REXX interpreter continues with normal processing. RXEXIT_NOT_HANDLED The exit handler did not process the exit subfunction. The REXX interpreter processes the subfunction as if the exit handler was not called. RXEXIT_RAISE_ERROR A fatal error occurred in the exit handler. The REXX interpreter raises REXX error 48 ("Failure in system service"). For example, if an application creates an input/output exit handler: o When the exit handler returns RXEXIT_NOT_HANDLED for an RXSIOSAY subfunction, the REXX interpreter writes the output line to STDOUT. o When the exit handler returns RXEXIT_HANDLED for an RXSIOSAY subfunction, the REXX interpreter assumes the exit handler has performed all required output. The interpreter will not write the output line to STDOUT. o When the exit handler returns RXEXIT_RAISE_ERROR for an RXSIOSAY subfunction, the interpreter raise REXX error 48, "Failure in system service". ═══ 11.1.2. Exit Parameters ═══ Each exit subfunction has a different parameter list. All RXSTRING exit subfunction parameters are passed as null-terminated RXSTRINGs. It is possible that the RXSTRING value will contain null characters also. For some exit subfunctions, the exit handler can return an RXSTRING character result in the parameter list. The interpreter provides a default 256-byte for RXSTRING result strings. If the result is longer than 256 bytes, a new RXSTRING can be allocated using "DosAllocMem". The REXX interpreter will return the RXSTRING storage for the exit handler. ═══ 11.1.3. Identifying Exit Handlers to REXX ═══ System exit handlers must be registered with RexxRegisterExitDll or RexxRegisterExitExe The system exit handler registration is similar to subcommand handler registration. The REXX system exits are enabled with the RexxStart function parameter Exits. Exits is a pointer to an array of RXSYSEXIT structures. Each RXSYSEXIT structure in the array contains a REXX exit code and the address of an ASCIIZ exit handler name. The RXENDLST exit code marks the exit list end. The REXX interpreter calls the registered exit handler in sysexit_name for all sysexit_code subfunctions. Example Sample System Exit Usage WORKAREARECORD *user_info[2]; /* saved user information */ RXSYSEXIT exit_list[2]; /* system exit list */ user_info[0] = global_workarea; /* save global work area for */ user_info[1] = NULL; /* re-entrancy */ rc = RexxRegisterExitExe("EditInit", /* register exit handler */ &Init_exit, /* located at this address */ user_info); /* save global pointer */ /* set up for RXINI exit */ exit_list[0].sysexit_name = "EditInit"; exit_list[0].sysexit_code = RXINI; exit_list[1].sysexit_code = RXENDLST; 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 */ exit_list, /* no exits used */ &rc, /* converted return code */ &retstr); /* returned result */ /* process return value */ . . . } LONG Init_exit( LONG ExitNumber, /* code defining the exit function */ LONG Subfunction, /* code defining the exit subfunction */ PEXIT ParmBlock) /* function dependent control block */ { WORKAREARECORD *user_info[2]; /* saved user information */ WORKAREARECORD global_workarea; /* application data anchor */ USHORT query_flag; /* flag for handler query */ rc = RexxQueryExit("EditInit", /* retrieve application work */ NULL, /* area anchor from REXX. */ &query_flag, user_info); global_workarea = user_info[0]; /* set the global anchor */ if (global_workarea->rexx_trace) /* trace at start? */ /* turn on macro tracing */ RexxSetTrace(global_workarea->rexx_pid, global_workarea->rexx_tid); return RXEXIT_HANDLED; /* successfully handled */ } ═══ 11.2. System Exit Definitions ═══ The REXX interpreter supports the following system exits: RXFNC External function call exit RXFNCCAL Call an external function RXCMD Subcommand call exit RXCMDHST Call a subcommand handler RXMSQ External data queue exit RXMSQPLL Pull a line from the external data queue. RXMSQPSH Place a line on the external data queue. RXMSQSIZ Return number of lines on the external data queue. RXMSQNAM Set active external data queue name. RXSIO Standard input and output exit. RXSIOSAY Write a line to the standard output stream for the SAY instruction. RXSIOTRC Write a line to the standard error stream for REXX trace or REXX error messages. RXSIOTRD Read a line from the standard input stream for PULL or PARSE PULL. RXSIODTR Read a line from the standard input stream for interactive debug. RXHLT Halt processing exit RXHLTTST Test for a HALT condition. RXHLTCLR Clear a HALT condition. RXTRC External trace exit RXTRCTST Test for an external trace event. RXINI Initialization exit RXINIEXT Allow additional REXX procedure initialization. RXTER Termination exit RXTEREXT Process REXX procedure termination. Each exit subfunction has the following characteristics: o When REXX calls the exit handler. o The default action when the exit is not provided or the exit handler does not process the subfunction. o The subfunction parameter list. o The service the subfunction provides. o The state of the variable pool interface during the exit handler call. The variable pool interface is fully enabled for the RXCMD, RXFNC, RXINT, and RXTER exit handler calls. The variable pool interface is enabled for RXSHV_EXIT requests for RXHLT, RXCMD, RXFNC, RXSIO, and RXMSQ exit handler calls. ═══ 11.3. RXFNC ═══ Process external function calls. The RXFNC exit has the following subfunction: RXFNCCAL Process external function calls. ═══ 11.3.1. RXFNCCAL ═══ ═══ Characteristics - RXFNCCAL ═══ Process external function calls. When called: When a REXX program calls an external subroutine or function. Default action: Call the external routine using the normal external function search order. Exit Action: Call the external routine, if possible. Continuation: If necessary, raise REXX error 40 ("Invalid call to routine"), 43 ("Routine not found"), or 44 ("Function did not return data"). Note: The variable pool interface is fully enabled during RXFNC exit handler calls. ═══ Parameters - RXFNCCAL ═══ typedef struct { struct { unsigned rxfferr : 1; /* Invalid call to routine. */ unsigned rxffnfnd : 1; /* Function not found. */ unsigned rxffsub : 1; /* Called as a subroutine if */ /* TRUE. Return values are */ /* optional for subroutines, */ /* required for functions. */ } rxfnc_flags ; PUCHAR rxfnc_name; /* Pointer to function name. */ USHORT rxfnc_namel; /* Length of function name. */ PUCHAR rxfnc_que; /* Current queue name. */ USHORT rxfnc_quel; /* Length of queue name. */ USHORT rxfnc_argc; /* Number of args in list. */ PRXSTRING rxfnc_argv; /* Pointer to argument list. */ /* List mimics argv list for */ /* function calls, an array of */ /* RXSTRINGs. */ RXSTRING rxfnc_retc; /* Return value. */ } RXFNCCAL_PARM; The name of the external function is defined by rxfnc_name and rxfnc_namel. The arguments to the function are in rxfnc_argc and rxfnc_argv. If the named external function is invoked by the REXX CALL instruction (rather than as a function call), the flag rxffsub is TRUE. The exit handler can set rxfnc_flags to indicate the external function success. If neither rxfferr or rxffnfnd is TRUE, the exit hander successfully called the external function. The error flags are checked only when the exit handler handles the the request. The exit handler sets rxffnfnd to TRUE when the exit handler could not locate the external function. The interpreter raises REXX error 43, "Routine not found". The exit handler sets rxfferr to TRUE when the exit handler located the external function, but the external function returned an error return code. The REXX interpreter raises error 40, "Invalid call to routine". The exit handler returns the external function result in the rxfnc_retc RXSTRING. The REXX interpreter will raise error 44, "Function did not return data" when the external routine is invoked as a function and the exit handler does not return a result. When the external routine is invoked by the REXX CALL instruction, the exit handler a result is not required. ═══ 11.4. RXCMD ═══ Process subcommand handler calls. The RXCMD exit has the following subfunction: RXCMDHST Call a named subcommand handler. ═══ 11.4.1. RXCMDHST ═══ ═══ Characteristics - RXCMDHST ═══ Call a named subcommand handler. When called: When a REXX procedure issues a command. Default action: Call the named subcommand handler specified by the current REXX ADDRESS setting. Exit Action: Process the call to a named subcommand handler. Continuation: Raise the ERROR or FAILURE condition when indicated by the parameter list flags, Note: The variable pool interface function is fully enabled during RXCMD exit handler calls. ═══ Parameters - RXCMDHST ═══ typedef struct { struct { /* Condition flags */ unsigned rxfcfail : 1; /* Command failed. Trap with */ /* CALL or SIGNAL on FAILURE. */ unsigned rxfcerr : 1; /* Command ERROR occurred. */ /* Trap with CALL or SIGNAL on */ /* ERROR. */ } rxcmd_flags; PUCHAR rxcmd_address; /* Pointer to address name. */ USHORT rxcmd_addressl; /* Length of address name. */ PUCHAR rxcmd_dll; /* dll name for command. */ USHORT rxcmd_dll_len; /* Length of dll name. 0 ==> */ /* .EXE file. */ RXSTRING rxcmd_command; /* The command string. */ RXSTRING rxcmd_retc; /* Pointer to return code */ /* buffer. User allocated. */ } RXCMDHST_PARM; The rxcmd_command field contains the issued command. rxcmd_address, rxcmd_addressl, rxcmd_dll, and rxcmd_dll_len fully define the current ADDRESS setting. rxcmd_retc is an RXSTRING for the return code value assigned to REXX special variable RC. The exit handler can set rxfcfail or rxfcerr to TRUE to raise an ERROR or FAILURE condition. ═══ 11.5. RXMSQ ═══ External data queue exit. The RXMSQ exit has the following subfunctions: RXMSQPLL Pull a line from the external data queue. RXMSQPSH Place a line on the external data queue. RXMSQSIZ Return the number of lines in the external data queue. RXMSQNAM Set the name of the active external data queue. ═══ 11.5.1. RXMSQPLL ═══ ═══ Characteristics - RXMSQPLL ═══ Pull a line from the external data queue. When called: When a REXX PULL instruction, PARSE PULL instruction, or LINEIN() built-in function reads a line from the external data queue. Default action: Remove a line from the current REXX data queue. Exit Action: Return a line from the exit handler provided data queue. ═══ Parameters - RXMSQPLL ═══ typedef struct { RXSTRING rxmsq_retc; /* Pointer to dequeued entry */ /* buffer. User allocated. */ } RXMSQPLL_PARM; The exit handler returns the queue line in the rxmsq_retc RXSTRING. ═══ 11.5.2. RXMSQPSH ═══ ═══ Characteristics - RXMSQPSH ═══ Place a line on the external data queue. When called: Called by the REXX PUSH instruction, QUEUE instruction, or LINEOUT() built-in function to add a line to the data queue. Default action: Add the line to the current REXX data queue. Exit Action: Add the line to the exit handler provided data queue. ═══ Parameters - RXMSQPSH ═══ typedef struct { struct { /* Operation flag */ unsigned rxfmlifo : 1; /* Stack entry LIFO when TRUE, */ /* FIFO when FALSE. */ } rxmsq_flags; RXSTRING rxmsq_value; /* The entry to be pushed. */ } RXMSQPSH_PARM; The rxmsq_value RXSTRING contains the line added to the queue. It is the responsibility of the exit handler to truncate the string if the exit handler data queue has a maximum length restriction. rxfmlifo is the stacking order (LIFO or FIFO). ═══ 11.5.3. RXMSQSIZ ═══ ═══ Characteristics - RXMSQSIZ ═══ Return the number of lines in the external data queue. When called: When the REXX QUEUED() built-in function requests the size of the external data queue. Default action: Request the size from the current REXX data queue. Exit Action: Return the size of the exit handler provided data queue. ═══ Parameters - RXMSQSIZ ═══ typedef struct { ULONG rxmsq_size; /* Number of Lines in Queue */ } RXMSQSIZ_PARM; The exit handler returns the number of queue lines in rxmsq_size. ═══ 11.5.4. RXMSQNAM ═══ ═══ Characteristics - RXMSQNAM ═══ Set the name of the active external data queue. When called: Called by the RXQUEUE("Set",newname) built-in function. Default action: Change the current default queue to newname. Exit Action: Change the default queue name for the exit handler provided data queue. ═══ Parameters - RXMSQNAM ═══ typedef struct { RXSTRING rxmsq_name; /* RXSTRING containing */ /* queue name. */ } RXMSQNAM_PARM; rxmsq_name contains the new queue name. ═══ 11.6. RXSIO ═══ Standard input and output. The RXMSQ exit has the following subfunctions: RXSIOSAY Write a line to the standard output stream (STDOUT). RXSIOTRC Write trace and error message output to the standard error stream. RXSIOTRD Read from standard input stream. RXSIODTR Interactive debug input. Note: The PARSE LINEIN instruction and the LINEIN, LINEOUT, LINES, CHARIN, CHAROUT, and CHARS built-in functions do not call the RXSIO exit handler. ═══ 11.6.1. RXSIOSAY ═══ ═══ Characteristics - RXSIOSAY ═══ Write a line to the standard output stream (STDOUT). When called: By the SAY instruction to write a line to the standard output stream. Default action: Write to the standard output stream. Exit Action: Write the line to the exit handler provided output stream. ═══ Parameters - RXSIOSAY ═══ typedef struct { RXSTRING rxsio_string; /* String to display. */ } RXSIOSAY_PARM; The output line is contained in rxsio_string. The output line can be any length. It is the responsibility of the exit handler to truncate or split the line if necessary. ═══ 11.6.2. RXSIOTRC ═══ ═══ Characteristics - RXSIOTRC ═══ Write trace and error message output to the standard error stream. When called: To output lines of trace output and REXX error messages. Default action: Write the line to the standard error stream (STDERR). Exit Action: Write tine to the exit handler provided error output stream. ═══ Parameters - RXSIOTRC ═══ typedef struct { RXSTRING rxsio_string; /* Trace line to display. */ } RXSIOTRC_PARM; The output line is contained in rxsio_string. The output line can be of any length. It is the responsibility of the exit handler to truncate or split the line if necessary. ═══ 11.6.3. RXSIOTRD ═══ ═══ Characteristics - RXSIOTRD ═══ Read from standard input stream. When called: To read from the standard input stream for the REXX PULL and PARSE PULL instructions. Default action: Read a line from the standard input stream (STDIN). Exit Action: Return a line from the exit handler provided standard input stream. ═══ Parameters - RXSIOTRD ═══ typedef struct { RXSTRING rxsiotrd_retc; /* RXSTRING for output. */ } RXSIOTRD_PARM; The input stream line is returned in the rxsiotrd_retc RXSTRING. ═══ 11.6.4. RXSIODTR ═══ ═══ Characteristics - RXSIODTR ═══ Interactive debug input. When called: To read from the debug input stream for interactive debug prompts. Default action: Read a line from the standard input stream (STDIN). Exit Action: Return a line from the exit handler provided standard debug stream. ═══ Parameters - RXSIODTR ═══ typedef struct { RXSTRING rxsiodtr_retc; /* RXSTRING for output. */ } RXSIODTR_PARM; The input stream line is returned in the rxsiodtr_retc RXSTRING. ═══ 11.7. RXHLT ═══ HALT condition processing. The RXHLT exit has the following subfunctions: RXHLTTST Test HALT indicator. RXHLTCLR Clear HALT condition. Note: Since the RXHLT exit handler is called after every REXX instruction, this exit will slow REXX program execution. The RexxSetHalt function can halt a REXX program without between-instruction polling. ═══ 11.7.1. RXHLTTST ═══ ═══ Characteristics - RXHLTTST ═══ Test HALT indicator. When called: When the interpreter polls externally raised HALT conditions. The exit is called after completion of every REXX instruction. Default action: The interpreter uses the system facilities for trapping Cntrl-Break signals. Exit Action: Return the current state of the HALT condition (either TRUE or FALSE). Continuation: Raise the REXX HALT condition if the exit handler returns TRUE. ═══ Parameters - RXHLTTST ═══ typedef struct { struct { /* Halt flag */ unsigned rxfhhalt : 1; /* Set if HALT occurred. */ } rxhlt_flags; } RXHLTTST_PARM; If the exit handler sets rxfhhalt to TRUE, the HALT condition will be raised in the REXX program. When the exit handler has set rxfhhalt to TRUE, it can also use the RXSHV_EXIT operation of RexxVariablePool to return a string describing the HALT condition reason. The REXX program can retrieve the reason string using the CONDITION("D") built-in function. ═══ 11.7.2. RXHLTCLR ═══ ═══ Characteristics - RXHLTCLR ═══ Clear HALT condition. When called: To acknowledge processing of the HALT condition when the interpreter has recognized and raised a HALT condition Default action: The interpreter resets the Cntrl-Break signal handlers. Exit Action: Reset exit handler HALT state to FALSE. ═══ Parameters - RXHLTCLR ═══ (None) ═══ 11.8. RXTRC ═══ Test external trace indicator. The RXTRC exit has the following subfunction: RXTRCTST Test external trace indicator. Note: Since the RXTST exit is called after every REXX instruction, these exits will slow REXX procedure execution. The RexxSetTrace function can turn on REXX tracing without between-instruction polling. ═══ 11.8.1. RXTRCTST ═══ ═══ Characteristics - RXTRCTST ═══ Test external trace indicator. When called: When the interpreter polls poll for an external trace event. The exit is called after completion of every REXX instruction. Default action: None. Exit Action: Return the current state of external tracing (either TRUE or FALSE). Continuation: When the exit handler switches from FALSE to TRUE, the REXX interpreter enters REXX interactive debug mode using TRACE ?R level of tracing. When the exit handler switches from TRUE to FALSE, the REXX interpreter will exit interactived debug mode. ═══ Parameters - RXTRCTST ═══ struct rxtrc_parm { struct { unsigned rxftrace : 1; /* External trace setting */ } rxtrc_flags; } If the exit handler switches rxftrace to TRUE, REXX will switch on interactive debug mode. It the exit handler switches rxftrace to FALSE, REXX will switch off interactive debug mode. ═══ 11.9. RXINI ═══ Initialization processing. The RXINT exit has the following subfunction: RXINIEXT Initialization exit. ═══ 11.9.1. RXINIEXT ═══ ═══ Characteristics - RXINIEXT ═══ Initialization exit. The RXINI exit is called as the last step of REXX program initialization. The exit handler can perform additional initialization. For example: o Use RexxVariablePool to initialize application specific variables o Use RexxSetTrace to switch on REXX interactive debug mode. When called: Before the first instruction of the REXX procedure is interpreted. Default action: None. Exit Action: The exit handler can perform additional initialization. For example: o Use RexxVariablePool to initialize application specific variables o Use RexxSetTrace to switch on REXX interactive debug mode. Note: The variable pool interface is fully enabled for this exit. ═══ Parameters - RXINIEXT ═══ (None) ═══ 11.10. RXTER ═══ Termination processing. The RXTER exit has the following subfunction: RXTEREXT Termination exit ═══ 11.10.1. RXTEREXT ═══ ═══ Characteristics - RXTEREXT ═══ Termination exit the RXTER exit is called as the first step of REXX program termination. When called: After the last instruction of the REXX procedure has been interpreted. Default action: None. Exit Action: The exit handler can perform additional termination activities For example, the exit handler can use RexxVariablePool to retrieve REXX variables values. Note: The variable pool interface is fully enabled for this exit. ═══ Parameters - RXTEREXT ═══ (None) ═══ 12. System Exit Functions ═══ o RexxRegisterExitDll registers an exit handler that resides in a dynalink library routine. o RexxRegisterExitExe registers an exit handler that resides within application code. o RexxDeregisterExit deregisters an exit handler. o RexxQueryExit queries an exit handler and retrieves saved user information. ═══ 12.1. RexxRegisterExitDll ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Notes Related Functions ═══ Call Syntax - RexxRegisterExitDll ═══ /*******************************************/ /* RexxRegisterExitDll registers an */ /* exit handler that resides in a */ /* dynamic link library routine. */ /*******************************************/ #define INCL_RXSYSEXIT /* Exit handler values */ PSZ name; /* handler name */ PSZ library; /* DLL name */ PSZ routine; /* routine name */ ULONG rc; /* Return code */ ULONG userdata[2]; /* save userdata*/ rc = RexxRegisterExitDll(name, library, routine, userdata, RXEXIT_DROPPABLE); ═══ Uses - RexxRegisterExitDll ═══ RexxRegisterExitDll registers an exit handler that resides in a dynalink library routine. ═══ Parameters - RexxRegisterExitDll ═══ RexxRegisterExitDll (ExitName, ModuleName, EntryPoint, UserArea, DropAuth) Parameters: EnvName (PSZ) - input Address of an ASCIIZ exit handler name. ModuleName (PSZ) - input Address of an ASCIIZ dynamic link library name. ModuleName is the DLL file containing the exit handler routine. EntryPoint (PSZ) - input Address of an ASCIIZ dynalink procedure name. EntryPoint is the exit handler routine within ModuleName. UserArea (PUCHAR) - input Address of an 8-byte area of user defined information. The 8 bytes addressed by UserArea will be saved with the exit handler registration. UserArea can be NULL if there is no user information to save. The saved user information can be retrieved with the RexxQueryExit function. DropAuth (ULONG) - input The drop authority. DropAuth identifies the processes that can deregister the exit handler. The possible DropAuth values are: RXEXIT_DROPPABLE Any process can deregister the exit handler with RexxDeregisterExit. RXEXIT_NONDROP Only a thread within the same process as the thread that registered the handler can deregister the handler with RexxDeregisterExit. ═══ Return Values - RexxRegisterExitDll ═══ RexxRegisterExitDll returns the following values: 0 RXEXIT_OK 10 RXEXIT_DUP 1002 RXEXIT_NOEMEM 1003 RXEXIT_BADTYPE ═══ Notes - RexxRegisterExitDll ═══ EntryPoint can be either a 16-bit or a 32-bit routine. REXX will invoke the exit handler in the correct addressing mode. ═══ Related Functions - RexxRegisterExitDll ═══ The following functions are related to RexxRegisterExitDll: RexxRegisterExitExe RexxDeregisterExit RexxQueryExit ═══ 12.2. RexxRegisterExitExe ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Notes Related Functions Examples ═══ Call Syntax - RexxRegisterExitExe ═══ /*******************************************/ /* RexxRegisterExitDll registers an */ /* exit handler that resides in a */ /* dynamic link library routine. */ /*******************************************/ #define INCL_RXSYSEXITS /* Exit handler values */ PSZ name; /* handler name */ PSZ library; /* DLL name */ PSZ routine; /* routine name */ ULONG rc; /* Return code */ ULONG userdata[2]; /* save userdata*/ rc = RexxRegisterExitDll(name, library, routine, userdata, RXEXIT_DROPPABLE); ═══ Uses - RexxRegisterExitExe ═══ RexxRegisterExitExe registers an exit handler that resides within application code. ═══ Parameters - RexxRegisterExitExe ═══ RexxRegisterExitExe (EnvName, EntryPoint, UserArea) Parameters: EnvName (PSZ) - input Address of an ASCIIZ exit handler name. EntryPoint (PFN) - input Address of the exit handler entry point within the application EXE file. UserArea (PUCHAR) - input Address of an 8-byte area of user defined information. The 8 bytes addressed by UserArea will be saved with the exit handler registration. UserArea can be NULL if there is no user information to save. The user information can be retrieved with the RexxQueryExit function. ═══ Return Values - RexxRegisterExitExe ═══ RexxRegisterExitExe returns the following values: 0 RXEXIT_OK 10 RXEXIT_DUP 30 RXEXIT_NOTREG 1002 RXEXIT_NOEMEM 1003 RXEXIT_BADTYPE ═══ Notes - RexxRegisterExitExe ═══ If EnvName has the same name as a handler registered with RexxRegisterExitDll, RexxRegisterExitExe will return RXEXIT_DUP. This is not an error and the new exit handler has been properly registered. ═══ Related Functions - RexxRegisterExitExe ═══ The following functions are related to RexxRegisterExitExe: RexxRegisterExitDll RexxDeregisterExit RexxQueryExit ═══ Examples - RexxRegisterExitExe ═══ The following example shows the use of RexxRegisterExitExe: WORKAREARECORD *user_info[2]; /* saved user information */ user_info[0] = global_workarea; /* save global work area for */ user_info[1] = NULL; /* re-entrancy */ rc = RexxRegisterExitExe("IO_Exit", /* register editor handler */ &Edit_IO_Exit, /* located at this address */ user_info); /* save global pointer */ ═══ 12.3. RexxDeregisterExit ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Notes Related Functions ═══ Call Syntax - RexxDeregisterExit ═══ /*******************************************/ /* RexxDeregisterExit deregisters an */ /* exit handler. */ /*******************************************/ #define INCL_RXSYSEXIT /* Exit handler values */ PSZ name; /* handler name */ PSZ library /* handler dll */ ULONG rc; /* Return code */ rc = RexxDeregisterExit(name, library); ═══ Uses - RexxDeregisterExit ═══ RexxDeregisterExit deregisters an exit handler. ═══ Parameters - RexxDeregisterExit ═══ RexxDeregisterExit (EnvName, ModuleName) Parameters: EnvName (PSZ) - input Address of an ASCIIZ exit handler name. ModuleName (PSZ) - input Address of an ASCIIZ dynamic link library name. ModuleName restricts the query to an exit handler within the ModuleName dynamic link library. When ModuleName is NULL, RexxDeregisterExit searches the RexxRegisterExitExe exit handler list for a handler within the current process. If RexxDeregisterExit does not find a RexxRegisterExitExe handler, it will search the RexxRegisterExitDll exit handler list. ═══ Return Values - RexxDeregisterExit ═══ RexxDeregisterExit returns the following values: 0 RXEXIT_OK 30 RXEXIT_NOTREG 40 RXEXIT_NOCANDROP 1003 RXEXIT_BADTYPE ═══ Notes - RexxDeregisterExit ═══ The handler is removed from the exit handler list. ═══ Related Functions - RexxDeregisterExit ═══ The following functions are related to RexxDeregisterExit: RexxRegisterExitDll RexxRegisterExitExe RexxQueryExit ═══ 12.4. RexxQueryExit ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Related Functions Examples ═══ Call Syntax - RexxQueryExit ═══ /*******************************************/ /* RexxQueryExit queries an exit */ /* handler and retrieves saved user */ /* information. */ /*******************************************/ #define INCL_RXSYSEXIT /* subcommand handler values */ PSZ name; /* handler name */ PSZ library; /* DLL name */ ULONG userdata[2]; /* saved information */ ULONG rc; /* Return code */ rc = RexxQueryExit(name, library, userdata); ═══ Uses - RexxQueryExit ═══ RexxQueryExit queries an exit handler and retrieves saved user information. ═══ Parameters - RexxQueryExit ═══ RexxQueryExit (EnvName, ModuleName, Flag, UserWord) Parameters: EnvName (PSZ) - input Address of an ASCIIZ exit handler name. ModuleName (PSZ) - input ModuleName restricts the query to an exit handler within the ModuleName dynamic link library. When ModuleName is NULL, RexxQueryExit searches the RexxRegisterExitExe exit handler list for a handler within the current process. If RexxQueryExit does not find a RexxRegisterExitExe handler, it will search the RexxRegisterExitDll exit handler list. Flag (PUSHORT) - output Exit handler registration flag. Flag is the EnvName exit handler registration status. When RexxQueryExit returns RXEXIT_OK, the EnvName exit handler is currently registered. When RexxQueryExit returns RXEXIT_NOTREG, the EnvName exit handler is not registered. Flag (PUSHORT) - output Exit handler registration flag. Flag indicates if the EnvName exit handler is registered. If Flag is RXEXIT_OK, the EnvName exit handler is not registered. If Flag is RXEXIT_NOTREG, the EnvName exit handler is registered. UserWord (PUCHAR) - output Address of an 8-byte area to receive the user information saved with RexxRegisterExitExe or RexxRegisterExitDll. UserWord can be NULL if the saved user information is not required. ═══ Return Values - RexxQueryExit ═══ RexxQueryExit returns the following values: 0 RXEXIT_OK 30 RXEXIT_NOTREG 1003 RXEXIT_BADTYPE ═══ Related Functions - RexxQueryExit ═══ The following functions are related to RexxQueryExit: RexxRegisterExitDll RexxRegisterExitExe RexxDeregisterExit ═══ Examples - RexxQueryExit ═══ The following example shows the use of RexxQueryExit: ULONG Edit_IO_Exit( PRXSTRING Command, /* Command string passed from the caller */ PUSHORT Flags, /* pointer to short for return of flags */ PRXSTRING Retstr) /* pointer to RXSTRING for RC return */ { WORKAREARECORD *user_info[2]; /* saved user information */ WORKAREARECORD global_workarea; /* application data anchor */ USHORT query_flag; /* flag for handler query */ rc = RexxQueryExit("IO_Exit", /* retrieve application work */ NULL, /* area anchor from REXX. */ &query_flag, user_info); global_workarea = user_info[0]; /* set the global anchor */ ═══ System Exit Interface Errors ═══ The following are the exit handler function errors.: RXEXIT_NOEMEM There is insufficient memory available to complete this request. RXEXIT_OK An exit function has executed successfully. RXEXIT_DUP A duplicate exit handler name has been successfully registered; there is either: o an EXE handler with the same name registered in another process, or o a DLL handler with the same name registered in another DLL; to address this exit, its library name must be specified. RXEXIT_NOTREG This indicates: o registration was unsuccessful due to duplicate handler and dynalink names (RexxRegisterExitExe or RexxRegisterExitDll) o the exit handler is not registered (other REXX exit functions). RXEXIT_NOCANDROP The exit handler has been registered as "not droppable". ═══ 13. Variable Pool Interface ═══ Application programs can use the REXX Variable Pool Interface to manipulate the variables of a currently active REXX procedure. ═══ 13.1. Interface Types ═══ Three of the Variable Pool Interface functions (set, fetch and drop) have dual interfaces. ═══ 13.1.1. Symbolic Interface ═══ The symbolic interface uses normal REXX variable rules when interpreting variables. Variable names are valid REXX symbols (in mixed case if desired) including compound symbols. Compound symbols will be referenced with tail substitution. The functions that use the symbolic interface are RXSHV_SYSET, RXSHV_SYFET, and RXSHV_SYDRO. ═══ 13.1.2. Direct Interface ═══ The direct interface uses no substitution or case translation. Simple symbols must be valid REXX variable names. A valid REXX variable name: o Does not begin with a digit or period o Contains only uppercase A to Z, the digits 0 - 9, or the characters _, ! or ? before the first period of the name. o Can contain any characters after the first period of the name. Compound variables are specified using the derived name of the variable. Any characters (including blanks) can appear after the first period of the name. No additional variable sustitution is used. The direct interface is used by RXSHV_SET, RXSHV_FETCH, and RXSHV_DROP. ═══ 13.2. RexxVariablePool Restrictions ═══ Only the main thread of an application can access the REXX variable pool. Applications can create and use new threads, but only the original thread that called the RexxStart function can use RexxVariablePool. OS/2* operating system EXE modules invoked from a REXX procedure execute in a new process. Because the modules are not using the same process and thread as the REXX procedure, the modules cannot use RexxVariablePool to access REXX variables. RexxVariablePool can be used from subcommand handlers, external functions and exit handlers. ═══ 14. RexxVariablePool Interface Function ═══ REXX procedure variables are accessed using the RexxVariablePool function. ═══ 14.1. RexxVariablePool ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Data Structures Return Values Notes Examples ═══ Call Syntax - RexxVariablePool ═══ /*******************************************/ /* RexxVariablePool accesses variables */ /* of a currently active REXX procedure. */ /*******************************************/ #define INCL_RXSHV /* Shared variable values */ SHVBLOCK request; /* request block */ ULONG rc; /* Return code */ rc = RexxVariablePool(&request); ═══ Uses - RexxVariablePool ═══ RexxVariablePool accesses variables of a currently active REXX procedure. ═══ Parameters - RexxVariablePool ═══ RexxVariablePool (RequestBlockList) Parameters: RequestBlockList (PSHVBLOCK) - input A linked list of shared variable request blocks (SHVBLOCK). Each shared variable request block in the linked list is a separate variable access request. ═══ Data Structures - RexxVariablePool ═══ typedef struct shvnode { struct shvnode *shvnext; RXSTRING shvname; RXSTRING shvvalue; ULONG shvnamelen; ULONG shvvaluelen; UCHAR shvcode; UCHAR shvret; } SHVBLOCK; Where: shvnext The address of the next SHVBLOCK in the request list. shvnext is NULL for the last request block. shvcode The shared variable block request code. The request codes are: RXSHV_SET RXSHV_SYSET Assign a new value to a REXX procedure variable. RXSHV_FETCH RXSHV_SYFETCH Retrieve the value of a REXX procedure variable. RXSHV_DROPV RXSHV_SYDRO Drop (unassign) a REXX procedure variable. RXSHV_PRIV Fetch REXX procedure private information. The following information items can be retrieved by name: PARM The number of arguments supplied to the REXX procedure. The number will be formatted as a character string. PARM.n The Nth argument string to the REXX procedure. If the Nth argument was not supplied to the procedure (either omitted or fewer than N parameters were specified), a null string will be returned. QUENAME The current REXX data queue name. SOURCE The REXX procedure source string used for the PARSE SOURCE instruction. VERSION The REXX interpreter version string used for the PARSE SOURCE instruction. RXSHV_NEXTV Fetch next variable. RXSHV_NEXTV traverses the variables in the current generation of REXX variables, excluding variables hidden by PROCEDURE instructions. The variables will not be returned in any specified order. The REXX interpreter maintains an internal pointer to its list of variables. The variable pointers is reset to the first REXX variable whenever: c. 1. An external program returns control to the interpreter 2. A set, fetch or drop RexxVariablePool function is used. RXSHV_NEXTV returns both the name and the value of REXX variables until the end of the variable list is reached. If no REXX variables are left to return, RexxVariablePool will set the RXSHV_LVAR bit in shvret. RXSHV_EXIT Set a return value for an external function or exit handler. RXSHV_EXIT is only valid from external functions or exit events that return a string value. RXSHV_EXIT can only be used once by an external function or exit handler. shvret Individual shared variable request return code. shvret is a 1-byte field of status flags for the individual shared variable request. The shvret fields for all request blocks in the list are ORed together to form the RexxVariablePool return code. The individual status conditions are: RXSHV_OK The request was processed with out error (all flag bits are FALSE). RXSHV_NEWV The named variable was uninitialized. RXSHV_LVAR No more variables are available for an RXSHV_NEXTV operation. RXSHV_TRUNC A variable value or variable name was truncated because the supplied RXSTRING was too small for the copied value. RXSHV_BADN The variable name specified in shvname was invalid for the requested operation. RXSHV_MEMFL The REXX interpreter was unable to obtain the storage required to complete the request. RXSHV_BADF The shared variable request block contains an invalid function code. shvname An RXSTRING containing a REXX variable name. shvname usage varies for the different SHVBLOCK request codes: RXSHV_SET RXSHV_SYSET RXSHV_FETCH RXSHV_SYFET RXSHV_DROPV RXSHV_SYDRO RXSHV_PRIV shvname is an RXSTRING pointing to the name of the REXX variable accessed by the shared variable request block. RXSHV_NEXTV shvname is an RXSTRING defining an area of storage to receive the name of the next variable. shvnamelen is the length of the RXSTRING area. If the variable name is longer than shvnamelen characters, the name will be truncated and the RXSHV_TRUNC bit of shvret will be set. On return, shvname.strlength will contain the length of the variable name; shvnamelen will be unchanged. If shvname is an empty RXSTRING (strptr is NULL), the REXX interpreter will allocate and return an RXSTRING to hold the variable name. If the REXX interpreter allocates the RXSTRING, an RXSHV_TRUNC condition cannot occur. However, RXSHV_MEMFL errors are possible for these operations. If an RXSHV_MEMFL condition occurs, memory will not be allocated for that request block. The RexxVariablePool function caller must release the storage with "DosFreeMem". Note: The RexxVariablePool does not add a terminating null character to the variable name. RXSHV_EXIT shvname is unused for the RXSHV_EXIT function. shvvalue An RXSTRING containing a REXX variable value. shvvalue meaning varies for the different SHVBLOCK request codes: RXSHV_SET RXSHV_SYSET shvvalue is the value assigned to the REXX variable in shvname. shvvaluelen contains the length of the variable value. RXSHV_EXIT shvvalue is the value assigned to the exit handler return value. shvvaluelen contains the length of the variable value. RXSHV_FETCH RXSHV_SYFET RXSHV_PRIV RXSHV_NEXT shvvalue is a buffer the REXX interpreter uses to return a copy of REXX variable shvname. shvvaluelen contains the length of the value buffer. On return, shvvalue.strlength will be set to the length of the returned value and shvvaluelen will be unchanged. If the variable value is longer than shvvaluelen characters, the value will be truncated and the RXSHV_TRUNC bit of shvret will be set. On return, shvvalue.strlength will be set to the length of the returned value; shvvaluelen will be unchanged. If shvvalue is an empty RXSTRING (strptr is NULL), the REXX interpreter will allocate and return an RXSTRING to hold the variable value. If the REXX interpreter allocates the RXSTRING, an RXSHV_TRUNC condition cannot occur. However, RXSHV_MEMFL errors are possible for these operations. If an RXSHV_MEMFL condition occurs, memory will not be allocated for that request block. The RexxVariablePool function caller must release the storage with "DosFreeMem". Note: RexxVariablePool does not add a terminating null character to the variable value. RXSHV_DROPV RXSHV_SYDRO shvvalue is not used. ═══ Return Values - RexxVariablePool ═══ RexxVariablePool returns the following values: 0 to 127 RexxVariablePool has processed the entire shared variable request block list. The RexxVariablePool function return code is a composite return code for the entire set of shared variable requests. The low-order 6 bits of the the shvret fields for all request blocks are ORed together to form the composite return code. Individual shared variable request status flags are returned in the shared variable request block shvret field. RXSHV_NOAVL The variable pool interface was not enabled. ═══ Notes - RexxVariablePool ═══ The REXX interpreter processes each request block in the order provided; the RexxVariablePool function returns when the last block is processed or after a severe error (such as an out-of-memory condition). The RexxVariablePool function return code is a composite return code for the entire set of shared variable requests. The return codes for all of the individual requests are ORed together to form the composite return code. Individual shared variable request return code are returned in the request shared variable blocks. ═══ Examples - RexxVariablePool ═══ /*********************************************************************/ /* */ /* SetRexxVariable - Set the value of a REXX variable */ /* */ /*********************************************************************/ INT SetRexxVariable( PSZ name, /* REXX variable to set */ PSZ value); /* value to assign */ { SHVBLOCK block; /* variable pool control block*/ block.shvcode = RXSHV_SYSET; /* do a symbolic set operation*/ block.shvret=(UCHAR)0; /* clear return code field */ block.shvnext=(PSHVBLOCK)0; /* no next block */ /* set variable name string */ MAKERXSTRING(block.shvname, name, strlen(name)); /* set value string */ MAKERXSTRING(block.shvvalue, value, strlen(value)); block.shvvaluelen=strlen(value); /* set value length */ return RexxVariablePool(&block); /* set the variable */ } ═══ 15. Halt and Trace Interface ═══ The halt and trace functions raise a REXX HALT condition or change the REXX interactive debug mode while a REXX procedure is running. These interfaces may be preferred over the RXHLT and RXTRC system exits. The REXX calls the RXTRC exit handler after each REXX instruction completes. This might cause a noticable performance degradation. The Halt and Trace functions are a single request to change the halt or trace state, and do not degrade the REXX procedure performance. o RexxSetHalt raises a HALT condition in a running REXX program. o RexxSetTrace turns on interactive debug mode for a REXX procedure. o RexxResetTrace turns off interactive debug mode for a REXX procedure. ═══ 16. Halt and Trace Functions ═══ o RexxSetHalt raises a HALT condition in a running REXX program. o RexxSetTrace turns on interactive debug mode for a REXX procedure. o RexxResetTrace turns off interactive debug mode for a REXX procedure. ═══ 16.1. RexxSetHalt ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Notes ═══ Call Syntax - RexxSetHalt ═══ /*******************************************/ /* RexxSetHalt raises a HALT condition */ /* in a running REXX program. */ /*******************************************/ #define INCL_RXARI /* Halt and Trace values */ TID ThreadId; /* Thread of REXX program */ PID ProcessId; /* Process of REXX program */ ULONG rc; /* Return code */ rc = RexxSetHalt(ProcessId, ThreadId); ═══ Uses - RexxSetHalt ═══ RexxSetHalt raises a HALT condition in a running REXX program. ═══ Parameters - RexxSetHalt ═══ RexxSetHalt (ProcessId, ThreadId) Parameters: ProcessId (PID) - input The process ID of the target REXX procedure. ProcessId is the application process that called the RexxStart function. ThreadId (TID) - input The thread ID of the target REXX procedure. ThreadId is the application thread that called the RexxStart function. ═══ Return Values - RexxSetHalt ═══ RexxSetHalt returns the following values: 0 RXARI_OK 1 RXARI_PID_TID_NOT_FOUND 2 RXARI_PROCESSING_ERROR ═══ Notes - RexxSetHalt ═══ This function will not be processed if the target REXX program is executing with the RXHLT exit enabled. ═══ Related Functions - RexxSetHalt ═══ The following functions are related to RexxSetHalt: RexxSetTrace RexxResetTrace ═══ 16.2. RexxSetTrace ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Notes ═══ Call Syntax - RexxSetTrace ═══ /*******************************************/ /* RexxSetTrace turns on interactive */ /* debug mode for REXX procedure. */ /*******************************************/ #define INCL_RXARI /* Halt and Trace values */ TID ThreadId; /* Thread of REXX program */ PID ProcessId; /* Process of REXX program */ ULONG rc; /* Return code */ rc = RexxSetTrace(ProcessId, ThreadId); ═══ Uses - RexxSetTrace ═══ RexxSetTrace turns on interactive debug mode for a REXX procedure. ═══ Parameters - RexxSetTrace ═══ RexxSetTrace (ProcessId, ThreadId) Parameters: ProcessId (PID) - input The process ID of the target REXX procedure. ProcessId is the application process that called the RexxStart function. ThreadId (TID) - input The thread ID of the target REXX procedure. ThreadId is the application thread that called the RexxStart function. ═══ Return Values - RexxSetTrace ═══ RexxSetTrace returns the following values: 0 RXARI_OK 1 RXARI_PID_TID_NOT_FOUND 2 RXARI_PROCESSING_ERROR ═══ Notes - RexxSetTrace ═══ The RexxSetTrace function is not processed if the REXX procedure is using the RXTRC exit. ═══ Related Functions - RexxSetTrace ═══ The following functions are related to RexxSetTrace: RexxSetHalt RexxResetTrace ═══ 16.3. RexxResetTrace ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Notes ═══ Call Syntax - RexxResetTrace ═══ /*******************************************/ /* RexxResetTrace turns off interactive */ /* debug mode for REXX procedure. */ /*******************************************/ #define INCL_RXARI /* Halt and Trace values */ TID ThreadId; /* Thread of REXX program */ PID ProcessId; /* Process of REXX program */ ULONG rc; /* Return code */ rc = RexxResetTrace(ProcessId, ThreadId); ═══ Uses - RexxResetTrace ═══ RexxResetTrace turns off interactive debug mode for a REXX procedure. ═══ Parameters - RexxResetTrace ═══ RexxResetTrace (ProcessId,ThreadId) Parameters: ProcessId (PID) - input The process ID of the target REXX procedure. ProcessId is the application process that called the RexxStart function. ThreadId (TID) - input The thread ID of the target REXX procedure. The thread ID of the target REXX procedure. ThreadId is the application thread that called the RexxStart function. ═══ Return Values - RexxResetTrace ═══ RexxResetTrace returns the following values: 0 RXARI_OK 1 RXARI_PID_TID_NOT_FOUND 2 RXARI_PROCESSING_ERROR ═══ Notes - RexxResetTrace ═══ The RexxResetTrace function is not processed if the REXX procedure is using the RXTRC exit. Interactive debug will not be turned off unless interactive debug mode was originally started with RexxSetTrace. ═══ Related Functions - RexxResetTrace ═══ The following functions are related to RexxResetTrace: RexxSetHalt RexxSetTrace ═══ 17. Macrospace Interface ═══ The macrospace can improve the performance of REXX procedures by maintaining REXX procecure images in memory for immediate load and execution. This is useful for frequently used procedures and functions such as editor macros. Programs registered in the REXX macrospace are available to all processes. They can be executed using the RexxStart function or called as functions or subroutines from other REXX procedures. Macrospace procedures are called as other REXX external functions are called. However, the macrospace REXX procedures can be placed at the front or at the end of the external function search order. REXX procedures in the macrospace can be saved to a disk file. A saved macrospace file can be reloaded with the RexxLoadMacroSpace function. An application, such as an editor, can create a library of frequently-used functions and load the library into the macrospace for fast access. Multiple macrospace libraries can be created and loaded. Search Order When RexxAddMacro loads a REXX procecure into the macrospace, the position in the external function search order is specified. The REXX procedure can be placed before all other forms of external function or after all other external functions. RXMACRO_SEARCH_BEFORE A function registered with RXMACRO_SEARCH_BEFORE will be located by the REXX interpreter before any registered functions or external REXX files. SEARCH_AFTER Function Registration A function registered with RXMACRO_SEARCH_AFTER will be located by the REXX interpreter after any registered functions or external REXX files. Storage of Macrospace Libraries Note: The REXX macrospace is placed in shared memory. The size of the macrospace is only limited by the amount of memory and swap space available to the system. However, as the macrospace grows, it limits the memory available to other processes in the system. Allowing the macrospace to grow too large might degrade overall system performance due to increased system swap file access. It is recommended that only the most frequently used functions be placed in the macrospace. ═══ 18. Macrospace Interface Functions ═══ o RexxAddMacro loads a REXX procedure into the macrospace. o RexxDropMacro removes a REXX procedure from the macrospace. o RexxClearMacroSpace removes all loaded REXX procedures from the macrospace. o RexxSaveMacroSpace saves all or part of the macrospace REXX procedures o RexxLoadMacroSpace loads all or part of the REXX procedures from a saved macrospace file. o RexxQueryMacro searches the macrospace for a specified function. o RexxReorderMacro changes the search order position of a loaded macrospace ═══ 18.1. RexxAddMacro ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Related Functions Examples ═══ Call Syntax - RexxAddMacro ═══ /*******************************************/ /* RexxAddMacro loads a REXX procedure */ /* into the macrospace. */ /*******************************************/ #define INCL_RXMACRO /* Macrospace values */ PSZ name; /* function name */ PSZ file; /* REXX source file */ ULONG rc; /* Return code */ rc = RexxAddMacro(name, file, RXMACRO_SEARCH_BEFORE); ═══ Uses - RexxAddMacro ═══ RexxAddMacro loads a REXX procedure into the macrospace. ═══ Parameters - RexxAddMacro ═══ RexxAddMacro (FuncName, SourceFile, Position) Parameters: FuncName (PSZ) - input Address of the ASCIIZ function name. Macrospace REXX procedures are called using FuncName. SourceFile (PSZ) - input Address of the ASCIIZ file specification for the REXX procedure source file. When a file extension is not supplied, .CMD is used. When the full path is not specified, the current directory and path is searched. Position (ULONG) - input Position in the REXX external function search order. Possible values are: RXMACRO_SEARCH_BEFORE The function will be located by the REXX interpreter before any registered functions or external REXX files. RXMACRO_SEARCH_AFTER The function will be located by the REXX interpreter after any registered functions or external REXX files. ═══ Return Values - RexxAddMacro ═══ RexxAddMacro returns the following values: 0 RXMACRO_OK 1 RXMACRO_NO_STORAGE 7 RXMACRO_SOURCE_NOT_FOUND 8 RXMACRO_INVALID_POSITION ═══ Related Functions - RexxAddMacro ═══ The following functions are related to RexxAddMacro: RexxDropMacro RexxClearMacroSpace RexxSaveMacroSpace RexxLoadMacroSpace RexxQueryMacro RexxReorderMacro ═══ 18.2. RexxDropMacro ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Related Functions ═══ Call Syntax - RexxDropMacro ═══ /*******************************************/ /* RexxDropMacro removes a REXX */ /* procedure from the macrospace. */ /*******************************************/ #define INCL_RXMACRO /* Macrospace values */ PSZ name; /* function name */ ULONG rc; /* Return code */ rc = RexxDropMacro(name); ═══ Uses - RexxDropMacro ═══ RexxDropMacro removes a REXX procedure from the macrospace. ═══ Parameters - RexxDropMacro ═══ RexxDropMacro (FuncName) Parameters: FuncName (PSZ) - input Address of the ASCIIZ function name. ═══ Return Values - RexxDropMacro ═══ RexxDropMacro returns the following values: 0 RXMACRO_OK 2 RXMACRO_NOT_FOUND ═══ Related Functions - RexxDropMacro ═══ The following functions are related to RexxDropMacro: RexxAddMacro RexxClearMacroSpace RexxSaveMacroSpace RexxLoadMacroSpace RexxQueryMacro RexxReorderMacro ═══ 18.3. RexxClearMacroSpace ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Notes Related Functions ═══ Call Syntax - RexxClearMacroSpace ═══ /*******************************************/ /* RexxClearMacroSpace removes all */ /* REXX procedures from the macrospace */ /*******************************************/ #define INCL_RXMACRO /* Macrospace values */ ULONG rc; /* Return code */ rc = RexxClearMacroSpace(); ═══ Uses - RexxClearMacroSpace ═══ RexxClearMacroSpace removes all loaded REXX procedures from the macrospace. ═══ Parameters - RexxClearMacroSpace ═══ RexxClearMacroSpace () Parameters: (None) ═══ Return Values - RexxClearMacroSpace ═══ RexxClearMacroSpace returns the following values: 0 RXMACRO_OK 2 RXMACRO_NOT_FOUND ═══ Notes - RexxClearMacroSpace ═══ RexxClearMacroSpace must be used with care. This function will remove all functions from the macrospace, including functions loaded by other processes. ═══ Related Functions - RexxClearMacroSpace ═══ The following functions are related to RexxClearMacroSpace: RexxAddMacro RexxDropMacro RexxSaveMacroSpace RexxLoadMacroSpace RexxQueryMacro RexxReorderMacro ═══ 18.4. RexxSaveMacroSpace ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Notes Related Functions Examples ═══ Call Syntax - RexxSaveMacroSpace ═══ /*******************************************/ /* RexxSaveMacroSpace saves all or part */ /* of the macrospace REXX procedures */ /*******************************************/ #define INCL_RXMACRO /* Macrospace values */ PSZ macrolist; /* list of macros */ ULONG count; /* size of macrolist */ PSZ file; /* name of savefile */ ULONG rc; /* Return code */ rc = RexxSaveMacroSpace(count, macrolist, file); ═══ Uses - RexxSaveMacroSpace ═══ RexxSaveMacroSpace saves all or part of the macrospace REXX procedures to a disk file. ═══ Parameters - RexxSaveMacroSpace ═══ RexxSaveMacroSpace (FuncCount, FuncNames, MacroLibFile) Parameters: FuncCount (ULONG) - input Number of REXX procedures to save. FuncNames (PSZ *) - input Address of a list of ASCIIZ function names. FuncCount gives the size of the function list. MacroLibFile (PSZ) - input Address of the ASCIIZ macrospace file name. If MacroLibFile already exists, it is replaced with the new file. ═══ Return Values - RexxSaveMacroSpace ═══ RexxSaveMacroSpace returns the following values: 0 RXMACRO_OK 2 RXMACRO_NOT_FOUND 3 RXMACRO_EXTENSION_REQUIRED 5 RXMACRO_FILE_ERROR ═══ Notes - RexxSaveMacroSpace ═══ When FuncCount is 0 or FuncNames is NULL, RexxSaveMacroSpace saves all functions in the macrospace. Saved macrospace files can only be used with the same interpreter version that created the images. If the RexxLoadMacroSpace function is called to load a saved macrospace, and the release level or service level is incorrect, the RexxLoadMacroSpace function will fail. If RexxLoadMacroSpace fails, the REXX procedures must be reloaded individually from the original source programs. ═══ Related Functions - RexxSaveMacroSpace ═══ The following functions are related to RexxSaveMacroSpace: RexxAddMacro RexxDropMacro RexxClearMacroSpace RexxLoadMacroSpace RexxQueryMacro RexxReorderMacro ═══ 18.5. RexxLoadMacroSpace ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Notes Related Functions Examples ═══ Call Syntax - RexxLoadMacroSpace ═══ /*******************************************/ /* RexxLoadMacroSpace loads all or part */ /* of the REXX procedures from a saved */ /* macrospace file. */ /*******************************************/ #define INCL_RXMACRO /* Macrospace values */ PSZ macrolist; /* list of macros */ ULONG count; /* size of macrolist */ PSZ file; /* name of savefile */ ULONG rc; /* Return code */ rc = RexxLoadMacroSpace(count, macrolist, file); ═══ Uses - RexxLoadMacroSpace ═══ RexxLoadMacroSpace loads all or part of the REXX procedures from a saved macrospace file. ═══ Parameters - RexxLoadMacroSpace ═══ RexxLoadMacroSpace (FuncCount, FuncNames, MacroLibFile) Parameters: FuncCount (ULONG) - input Number of REXX procedures to load from the saved macrospace. FuncNames (PSZ *) - input Address of a list of ASCIIZ REXX function names. FuncCount gives the size of the function list. MacroLibFile (PSZ) - input Address of the ASCIIZ saved macrospace file name. ═══ Return Values - RexxLoadMacroSpace ═══ RexxLoadMacroSpace returns the following values: 0 RXMACRO_OK 1 RXMACRO_NO_STORAGE 2 RXMACRO_NOT_FOUND 4 RXMACRO_ALREADY_EXISTS 5 RXMACRO_FILE_ERROR 6 RXMACRO_SIGNATURE_ERROR ═══ Notes - RexxLoadMacroSpace ═══ When FuncCount is 0 or FuncNames is NULL, RexxLoadMacroSpace loads all REXX procedures from the saved file. If the RexxLoadMacroSpace function must replace an existing macrospace REXX procedure, the entire load request is discarded and the macrospace remains unchanged. ═══ Related Functions - RexxLoadMacroSpace ═══ The following functions are related to RexxLoadMacroSpace: RexxAddMacro RexxDropMacro RexxClearMacroSpace RexxSaveMacroSpace RexxQueryMacro RexxReorderMacro ═══ 18.6. RexxQueryMacro ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Related Functions Examples ═══ Call Syntax - RexxQueryMacro ═══ /*******************************************/ /* RexxQueryMacro searches the */ /* macrospace for a specified function. */ /*******************************************/ #define INCL_RXMACRO /* Macrospace values */ PSZ name; /* function name */ USHORT position; /* search order position */ ULONG rc; /* Return code */ rc = RexxQueryMacro(name, &position); ═══ Uses - RexxQueryMacro ═══ RexxQueryMacro searches the macrospace for a specified function. ═══ Parameters - RexxQueryMacro ═══ RexxQueryMacro (FuncName, Position) Parameters: FuncName (PSZ) - input Address of an ASCIIZ function name. Position (PUSHORT) - output Address of an unsigned short integer flag. If the function is loaded in the macrospace, Position is set to the current function search-order position. ═══ Return Values - RexxQueryMacro ═══ RexxQueryMacro returns the following values: 0 RXMACRO_OK 2 RXMACRO_NOT_FOUND ═══ Related Functions - RexxQueryMacro ═══ The following functions are related to RexxQueryMacro: RexxAddMacro RexxDropMacro RexxClearMacroSpace RexxSaveMacroSpace RexxLoadMacroSpace RexxReorderMacro ═══ 18.7. RexxReorderMacro ═══ ═══ Instructions ═══ Topics: Call Syntax Uses Parameters Return Values Errors Related Functions ═══ Call Syntax - RexxReorderMacro ═══ /*******************************************/ /* RexxReorderMacro changes the search */ /* order position of a loaded macrospace */ /* function. */ /*******************************************/ #define INCL_RXMACRO /* Macrospace values */ PSZ name; /* function name */ ULONG rc; /* Return code */ rc = RexxReorderMacro(name, RXMACRO_SEARCH_AFTER); ═══ Uses - RexxReorderMacro ═══ RexxReorderMacro changes the search order position of a loaded macrospace function. ═══ Parameters - RexxReorderMacro ═══ RexxReorderMacro (FuncName, Position) Parameters: FuncName (PSZ) - input Address of an ASCIIZ macrospace function name. Position (ULONG) - input New search-order position of the macrospace function. Possible values are: RXMACRO_SEARCH_BEFORE The function will be located by the REXX interpreter before any registered functions or external REXX files. RXMACRO_SEARCH_AFTER The function will be located by the REXX interpreter after any registered functions or external REXX files. ═══ Return Values - RexxReorderMacro ═══ RexxReorderMacro returns the following values: 0 RXMACRO_OK 2 RXMACRO_NOT_FOUND 8 RXMACRO_INVALID_POSITION ═══ Related Functions - RexxReorderMacro ═══ The following functions are related to RexxReorderMacro: RexxAddMacro RexxDropMacro RexxClearMacroSpace RexxSaveMacroSpace RexxLoadMacroSpace RexxQueryMacro ═══ Macrospace Interface Errors ═══ The follow return codes can be returned from the macrospace functions. These values signify the causes for a failure, in these functions. RXMACRO_OK The function completed successfully RXMACRO_NO_STORAGE There was not enough memory to complete the requested function. RXMACRO_NOT_FOUND The requested procedure was not found in the macrospace. RXMACRO_EXTENSION_REQUIRED An extension is required for the macrospace file name. RXMACRO_ALREADY_EXISTS Duplicate functions cannot be loaded from a macrospace file. RXMACRO_FILE_ERROR An error occurred accessing a macro space file. RXMACRO_SIGNATURE_ERROR A macrospace save file does not contain valid function images. RXMACRO_SOURCE_NOT_FOUND The requested file was not found. RXMACRO_INVALID_POSITION An invalid search-order position request flag was used. ═══ Examples - RexxReorderMacro ═══ The following example shows the use of RexxAddMacro, RexxQueryMacro, RexxLoadMacroSpace, and RexxSaveMacroSpace. /* first load entire package */ RexxLoadMacroSpace(0, NULL, "EDITOR.MAC"); for (i = 0; i < MACRO_COUNT; i++) { /* verify each macro */ /* if not there */ if (RexxQueryMacro(macro[i], &position)) /* add to list */ RexxAddMacro(macro[i], macro_files[i], RXMACRO_SEARCH_BEFORE); } /* rebuild the macrospace */ RexxSaveMacroSpace(0, NULL, "EDITOR.MAC"); . . . /* build the argument string */ MAKERXSTRING(argv[0], macro_argument, strlen(macro_argument)); /* set up default return */ MAKERXSTRING(retstr, return_buffer, sizeof(return_buffer)); /* set up for macrospace call */ MAKERXSTRING(macrospace[0],NULL, 0); MAKERXSTRING(macrospace[1],NULL, 0); return_code = RexxStart(1, /* one argument */ argv, /* argument array */ macro[pos], /* REXX procedure name */ macrospace, /* use macrospace version */ "Editor", /* default address name */ RXCOMMAND, /* calling as a subcommand */ NULL, /* no exits used */ &rc, /* converted return code */ &retstr); /* returned result */