Safe REXX on the Desktop,
COMPATIBILITY AND ENVIRONMENTAL ASPECTS
REXX has some specific features that you can exploit to make your programs more compatible across platforms, or between environments on the same platforms. REXX also has some features that hinder compatibility.
ADDRESS and the default environment
If you write a command file that issues host commands, ie. OS/2, CMS, TSO, DOS commands, do not assume that the default environment is that of the host itself. by including ADDRESS CMD in your code, you will enable the routine for use from within other environments, e.g., editors that use REXX as their macro language.
REXX does not shield you from the underlying environment; in writing a REXX program you must understand the behavior of your operating system and user interface if you want to avoid nasty surprises. As an example, if you invoke a REXX program in an OS/2 CMD file and scan the argument looking for the string "/Q", you will not find it because CMD.EXE will have taken the string "/Q" to be a "quiet" option and removed it.
If you must use binary or hexadecimal constants for character data, be aware that character encoding varies among systems. DOS and OS/2 use ASCII, CMS and TSO use EBCDIC. Even then, the correct value may depend upon the code page or national language in use. Be aware of the character sets used in each of your target systems, and program accordingly. Segregate system-dependent values and code page-dependent values to make your code easier to maintain.
The I/O model in REXX is based on the file system in the CMS component of IBM 's VM/SP. Most other systems, like DOS, OS/2, and TSO, do not have an orientation towards line numbers. For this reason, SAA REXX in OS/2 differs from the REXX standard, in that the LINES function only returns values of 0 and 1. See Figure 10. The TSO/E support in OS/390 2.4 does not include charin et. al, and has not been upgraded as of 2.6; however, VM/ESA 2.2 appears to include those functions. I'm not sure exactly when they came in. CMS uses EXECIO, and TSO uses a subset of EXECIO. Note that the CMS option of EXECIO for reading a single line into a simple variable is highly nonportable. Code written in accordance with the standard may fail in OS/2, and _will_ fail in CMS and TSO.
Further, a faithful implementation could be horribly inefficient if the file system in the host operating system does not maintain line counts.
Figure 10: LINES examples
/* In standard REXX */
REXX provides no good way to detect end-of-file. You could use STREAM(file,"State") and check for a value of "NOTREADY", but there is no guarantee that end-of-file is the only condition causing NOTREADY.
The safest thing is to encapsulate your input/output code and then take advantage of whatever facilities may exist in each target system, e.g., EXECIO with the STEM option, REXXLIB from Quercus. Any such code should be thoroughly documented. Be aware that EXECIO in TSO/E supports only the stem and stack forms of EXECIO; it does not support the variable name form.
PARSE SOURCE and VERSION
The PARSE SOURCE statement allows your code to determine the operating system and file from which it was invoked, as well as the type of invocation. You can take advantage of this in order to maintain a single version of a REXX program for two different systems, to detect inappropriate invocations, to select character encoding, etc. If you have data files that, by default, should be in the same directory as your code, you can use this statement to locate them. See Figure 11.
Figure 11: Parse examples
parse source system invocation origin
The PARSE VERSION statement allows you to determine the language level of REXX that your program has available. This allows you to write code that exploits new features of REXX, yet include alternate code that will be used when running on an older platform. See Figure 11.
REXXUTIL and emergency boot disks
If you might want to use your REXX code from an emergency boot disk, include code that does not depend on REXXUTIL. See Figure 12. This is because PM is too large to include on an emergency 1.44 MB floppy, and REXXUTIL requires PM.
Figure 12: Boot-disk examples
if REXXUTIL_loaded then do
If you use variable patterns in the templates of your PARSE statements, be aware that some older implementations of REXX do not support all forms, e.g., in MVS/XA the form "+(variable)" is not available. It is available in CMS as of VM/ESA 1.2.0 (CMS9) and in MVS/ESA as of TSO/E 2.4. If you need to run on multiple platforms, check which forms are supported on each and program accordingly.
You can make your use of REXX more enjoyable and productive by following a few basic rules. Learn REXX on its own terms. Be careful and consistent in your use of abutment and continuation. Do not use keywords or single letters as variable names. Use SIGNAL only for error handling. Do not attempt to use the same lines as both inline code and out of line code. Place a PROCEDURE at the beginning of every subroutine, and carefully analyze which variables to expose, especially if you will be passing the names of variables. Be careful in your use of uninitialized variables. Adopt a clear and consistent programming style. Understand the vagaries of REXX parsing. Try to make your code portable across platforms and usable in multiple environments.
These rules will not, of course, eliminate all errors, but they will certainly eliminate many errors that would otherwise be highly likely. Good luck, and practice Safe REXX!
Note: The portability considerations are based on experience with REXX in CMS (VM/SP), DOS (Personal REXX), MVS (TSO/E) and OS/2 (SAA REXX). I have not used other implementations such as AREXX, Object REXX and Regina. I welcome comments on portability issues going to or from these other implementations.
OS/2 Procedures Language 2/REXX Reference, S10G-6268
OS/2 Procedures Language 2/REXX User's Guide, S10G-6269
SAA Common Programming Interface Procedures Language Reference, SC26-4358
TSO Extensions Version 2 REXX Reference, SC28-1883
TSO Extensions Version 2 REXX User's Guide, SC28-1882
The REXX Language
IBM, MVS/ESA, OS/2, VM/ESA, and VM/SP are trademarks of IBM Corporation. Unix is a trademark of The Open Group.
Shmuel (Seymour J.) Metz, Digital Solutions, Inc. (DSI). Mr. Metz is a Senior MVS Systems Programmer supporting a Federal Government facilities management contract. He has worked with computers for 38 years. He has been involved in the development of two different operating systems. He has experience on a wide variety of languages and platforms, and has used REXX on four of them. Mr. Metz has an MA in Mathematics from the State University of New York at Buffalo.
He can be reached at 703-256-4764 between 6:00 PM and 9:00 PM EST, at his office at 703-306-1185, X3095, and as SHMUEL@ACM.ORG on the Internet.
A slightly different version of this article was printed in the February 1995 OS/2 Magazine.
Copyright 1998 by Shmuel (Seymour J.) Metz. All rights reserved. Permission for reproduction in whole or in part is hereby granted to educational, non-profit and computer user groups for internal, non-profit use, provided credit is given and this notice is included. All other reproduction without the author's prior written permission is prohibited.