Open Object Rexx Programming Guide
Open Object Rexx Programming Guide
Programming Guide
Version 3.0.0 Revision 3 Edition
November 11, 2005
Open Object Rexx: Programming Guide
Version 3.0.0 Revision 3 Edition
Published November 11, 2005
Copyright © 1995, 2004 IBM Corporation and others. All rights reserved.
Copyright © 2005 Rexx Language Association. All rights reserved.
This document was originally owned and copyrighted by IBM Corporation 1995, 2004. It was donated as open source under the Common Public
License Version 1.0 to the Rexx Language Association in 2004.
Before using this information and the product it supports, be sure to read the general information under Notices.
This program and the accompanying materials are made available under the terms of the Common Public License Version 1.0.
Many thanks to Julian Choy for the ooRexx logo design.
Table of Contents
1. About This Book ....................................................................................................................................1
1.1. Who Should Read This Book......................................................................................................1
1.2. What You Should Know before Reading This Book ..................................................................1
1.3. Related Information ....................................................................................................................1
1.4. A Note About Program Examples in this Document ..................................................................1
2. Meet Object Rexx ..................................................................................................................................3
2.1. The Main Attractions ..................................................................................................................3
2.1.1. Object-Oriented Programming .......................................................................................3
2.1.2. An English-Like Language.............................................................................................3
2.1.3. Cross-Platform Versatility ..............................................................................................3
2.1.4. Fewer Rules ....................................................................................................................3
2.1.5. Interpreted, Not Compiled..............................................................................................4
2.1.6. Built-In Functions and Methods.....................................................................................4
2.1.7. Typeless Variables ..........................................................................................................4
2.1.8. String Handling ..............................................................................................................4
2.1.9. Clear Error Messages and Powerful Debugging ............................................................4
2.1.10. Impressive Development Tools.....................................................................................4
2.2. Rexx and the Operating System..................................................................................................4
2.3. A Classic Language Gets Classier ..............................................................................................4
2.3.1. From Traditional Rexx to Object Rexx ..........................................................................5
2.4. The Object Advantage.................................................................................................................6
2.5. The Next Step..............................................................................................................................7
3. A Quick Tour of Traditional Rexx .......................................................................................................9
3.1. What Is a Rexx Program? ...........................................................................................................9
3.2. Running a Rexx Program ............................................................................................................9
3.3. Elements of Rexx ......................................................................................................................10
3.4. Writing Your Program...............................................................................................................10
3.5. Testing Your Program ...............................................................................................................11
3.6. Improving Startup Time ............................................................................................................12
3.7. Variables, Constants, and Literal Strings ..................................................................................12
3.8. Assignments ..............................................................................................................................13
3.9. Using Functions ........................................................................................................................14
3.10. Program Control......................................................................................................................14
3.11. Subroutines and Procedures ....................................................................................................18
4. Into the Object World .........................................................................................................................21
4.1. What Is Object-Oriented Programming? ..................................................................................21
4.2. Modularizing Data ....................................................................................................................21
4.3. Modeling Objects ......................................................................................................................22
4.4. How Objects Interact.................................................................................................................24
4.5. Methods.....................................................................................................................................24
4.6. Polymorphism ...........................................................................................................................25
4.7. Classes and Instances ................................................................................................................25
4.8. Data Abstraction .......................................................................................................................27
4.9. Subclasses, Superclasses, and Inheritance ................................................................................27
iii
5. The Basics of Classes ...........................................................................................................................29
5.1. Rexx Classes for Programming.................................................................................................29
5.1.1. The Alarm Class ...........................................................................................................29
5.1.2. The Collection Classes .................................................................................................29
5.1.3. The Message Class .......................................................................................................30
5.1.4. The Monitor Class ........................................................................................................30
5.1.5. The Stem Class .............................................................................................................31
5.1.6. The Stream Class..........................................................................................................31
5.1.7. The String Class ...........................................................................................................31
5.1.8. The Supplier Class........................................................................................................31
5.2. Rexx Classes for Organizing Objects........................................................................................32
5.2.1. The Object Class...........................................................................................................32
5.2.2. The Class Class.............................................................................................................32
5.3. Rexx Classes: The Big Picture..................................................................................................33
5.4. Creating Your Own Classes Using Directives...........................................................................37
5.4.1. What Are Directives? ...................................................................................................37
5.4.2. The Directives Rexx Provides ......................................................................................37
5.4.2.1. The ::CLASS Directive....................................................................................37
5.4.2.2. The ::METHOD Directive ...............................................................................38
5.4.2.3. The ::ROUTINE Directive ...............................................................................38
5.4.2.4. The ::REQUIRES Directive.............................................................................39
5.4.3. How Directives Are Processed .....................................................................................39
5.4.4. A Sample Program Using Directives............................................................................39
5.4.5. Another Sample Program .............................................................................................40
5.5. Creating Classes Using Messages.............................................................................................41
5.5.1. Defining a New Class ...................................................................................................41
5.5.2. Adding a Method to a Class .........................................................................................42
5.5.3. Defining a Subclass of the New Class ..........................................................................42
5.5.4. Defining an Instance .....................................................................................................42
5.6. Types of Classes ........................................................................................................................42
5.6.1. Object Classes ..............................................................................................................43
5.6.2. Abstract Classes............................................................................................................43
5.6.3. Mixin Classes ...............................................................................................................43
5.7. Metaclasses ...............................................................................................................................44
6. A Closer Look at Objects ....................................................................................................................47
6.1. Using Objects in Rexx Clauses .................................................................................................47
6.2. Common Methods.....................................................................................................................49
6.2.1. Initializing Instances Using INIT .................................................................................49
6.2.2. Returning String Data Using STRING.........................................................................49
6.2.3. Uninitializing and Deleting Instances Using UNINIT .................................................52
6.3. Special Variables .......................................................................................................................53
6.4. Public, Local, and Built-In Environment Objects .....................................................................55
6.4.1. The Public Environment Object (.environment)...........................................................55
6.4.1.1. The NIL Object (.nil) .......................................................................................55
6.4.2. The Local Environment Object (.local) ........................................................................55
6.4.3. Built-In Environment Objects ......................................................................................56
6.4.4. The Default Search Order for Environment Objects ....................................................57
iv
6.5. Determining the Scope of Methods and Variables....................................................................57
6.5.1. Objects with a Class Scope...........................................................................................58
6.5.2. Objects with Their Own Unique Scope........................................................................58
6.6. More about Methods .................................................................................................................59
6.6.1. The Default Search Order for Selecting a Method .......................................................59
6.6.2. Changing the Search Order for Methods......................................................................61
6.6.3. Public versus Private Methods......................................................................................62
6.6.4. Defining an UNKNOWN Method ................................................................................62
6.7. Concurrency ..............................................................................................................................62
6.7.1. Inter-Object Concurrency .............................................................................................62
6.7.1.1. Object Variable Pools.......................................................................................63
6.7.1.2. Prioritizing Access to Variables .......................................................................64
6.7.1.3. Sending Messages within an Activity..............................................................64
6.7.2. Intra-Object Concurrency .............................................................................................64
6.7.2.1. Activating Methods..........................................................................................65
7. Commands............................................................................................................................................67
7.1. How to Issue Commands ..........................................................................................................67
7.2. Command Echo.........................................................................................................................69
7.3. Rexx and Batch Files ................................................................................................................69
7.4. Issuing a Command to Call a .CMD File..................................................................................70
7.5. Using Variables to Build Commands ........................................................................................71
7.6. Using Quotation Marks .............................................................................................................72
7.7. ADDRESS Instruction ..............................................................................................................73
7.8. Using Return Codes from Commands ......................................................................................73
7.9. Subcommand Processing ..........................................................................................................74
7.10. Trapping Command Errors......................................................................................................74
7.10.1. Instructions and Conditions........................................................................................75
7.10.2. Disabling Traps...........................................................................................................75
7.10.3. Using SIGNAL ON ERROR ......................................................................................75
7.10.4. Using CALL ON ERROR ..........................................................................................76
7.10.5. A Common Error-Handling Routine ..........................................................................76
8. Input and Output.................................................................................................................................79
8.1. More about Stream Objects.......................................................................................................79
8.2. Reading a Text File ...................................................................................................................80
8.3. Reading a Text File into an Array .............................................................................................81
8.4. Reading Specific Lines of a Text File .......................................................................................81
8.5. Writing a Text File ....................................................................................................................82
8.6. Reading Binary Files.................................................................................................................83
8.7. Reading Text Files a Character at a Time .................................................................................83
8.8. Writing Binary Files..................................................................................................................85
8.9. Closing Files .............................................................................................................................85
8.10. Direct File Access ...................................................................................................................85
8.11. Checking for the Existence of a File .......................................................................................88
8.12. Getting Other Information about a File...................................................................................88
8.13. Using Standard I/O..................................................................................................................89
8.14. Using Windows Devices .........................................................................................................90
v
A. Rexx Application Programming Interfaces......................................................................................93
A.1. Handler Characteristics ............................................................................................................93
A.2. RXSTRINGs ............................................................................................................................94
A.3. Calling the Rexx Interpreter.....................................................................................................95
A.3.1. From the Operating System.........................................................................................95
A.3.2. From within an Application.........................................................................................95
A.3.3. The RexxStart Function...............................................................................................95
A.3.3.1. Parameters.......................................................................................................95
A.3.3.2. Return Codes...................................................................................................98
A.3.3.3. Example ..........................................................................................................98
A.3.4. The RexxWaitForTermination Function ....................................................................101
A.3.5. The RexxDidRexxTerminate Function......................................................................101
A.3.5.1. Return Codes.................................................................................................101
A.3.5.2. Example ........................................................................................................102
A.4. Subcommand Interface...........................................................................................................102
A.4.1. Registering Subcommand Handlers ..........................................................................102
A.4.1.1. Creating Subcommand Handlers ..................................................................102
A.4.1.1.1. Example............................................................................................103
A.4.2. Subcommand Interface Functions .............................................................................104
A.4.2.1. RexxRegisterSubcomDll...............................................................................104
A.4.2.1.1. Parameters ........................................................................................104
A.4.2.1.2. Return Codes ....................................................................................105
A.4.2.1.3. Remarks............................................................................................106
A.4.2.2. RexxRegisterSubcomExe..............................................................................106
A.4.2.2.1. Parameters ........................................................................................106
A.4.2.2.2. Return Codes ....................................................................................106
A.4.2.2.3. Remarks............................................................................................107
A.4.2.2.4. Example............................................................................................107
A.4.2.3. RexxDeregisterSubcom.................................................................................107
A.4.2.3.1. Parameters ........................................................................................107
A.4.2.3.2. Return Codes ....................................................................................108
A.4.2.3.3. Remarks............................................................................................108
A.4.2.4. RexxQuerySubcom .......................................................................................108
A.4.2.4.1. Parameters ........................................................................................108
A.4.2.4.2. Return Codes ....................................................................................109
A.4.2.4.3. Example............................................................................................109
A.5. External Function Interface....................................................................................................109
A.5.1. Registering External Functions .................................................................................110
A.5.1.1. Creating External Functions..........................................................................110
A.5.2. Calling External Functions ........................................................................................111
A.5.2.1. Example ........................................................................................................111
A.5.3. External Function Interface Functions ......................................................................112
A.5.3.1. RexxRegisterFunctionDll..............................................................................112
A.5.3.1.1. Parameters ........................................................................................112
A.5.3.1.2. Return Codes ....................................................................................112
A.5.3.1.3. Remarks............................................................................................112
A.5.3.1.4. Example............................................................................................113
A.5.3.2. RexxRegisterFunctionExe.............................................................................113
vi
A.5.3.2.1. Parameters ........................................................................................114
A.5.3.2.2. Return Codes ....................................................................................114
A.5.3.3. RexxDeregisterFunction ...............................................................................114
A.5.3.3.1. Parameters ........................................................................................114
A.5.3.3.2. Return Codes ....................................................................................114
A.5.3.4. RexxQueryFunction ......................................................................................114
A.5.3.4.1. Parameters ........................................................................................115
A.5.3.4.2. Return Codes ....................................................................................115
A.5.3.4.3. Remarks............................................................................................115
A.6. System Exit Interface .............................................................................................................115
A.6.1. Writing System Exit Handlers...................................................................................115
A.6.1.1. Exit Return Codes .........................................................................................116
A.6.1.2. Exit Parameters .............................................................................................117
A.6.1.3. Identifying Exit Handlers to Rexx ................................................................117
A.6.1.3.1. Example............................................................................................117
A.6.2. System Exit Definitions .............................................................................................118
A.6.2.1. RXFNC .........................................................................................................120
A.6.2.2. RXCMD ........................................................................................................122
A.6.2.3. RXMSQ ........................................................................................................122
A.6.2.4. RXSIO...........................................................................................................124
A.6.2.5. RXHLT..........................................................................................................126
A.6.2.6. RXTRC .........................................................................................................126
A.6.2.7. RXINI............................................................................................................127
A.6.2.8. RXTER..........................................................................................................128
A.6.3. System Exit Interface Functions................................................................................128
A.6.3.1. RexxRegisterExitDll .....................................................................................128
A.6.3.1.1. Parameters ........................................................................................128
A.6.3.1.2. Return Codes ....................................................................................129
A.6.3.1.3. Remarks............................................................................................129
A.6.3.2. RexxRegisterExitExe ....................................................................................129
A.6.3.2.1. Parameters ........................................................................................130
A.6.3.2.2. Return Codes ....................................................................................130
A.6.3.2.3. Remarks............................................................................................130
A.6.3.2.4. Example............................................................................................130
A.6.3.3. RexxDeregisterExit .......................................................................................131
A.6.3.3.1. Parameters ........................................................................................131
A.6.3.3.2. Return Codes ....................................................................................131
A.6.3.3.3. Remarks............................................................................................131
A.6.3.4. RexxQueryExit..............................................................................................131
A.6.3.4.1. Parameters ........................................................................................132
A.6.3.4.2. Return Codes ....................................................................................132
A.6.3.4.3. Example............................................................................................132
A.7. Variable Pool Interface ...........................................................................................................133
A.7.1. Interface Types...........................................................................................................133
A.7.1.1. Symbolic Interface ........................................................................................133
A.7.1.2. Direct Interface .............................................................................................133
A.7.2. RexxVariablePool Restrictions ..................................................................................133
A.7.3. RexxVariablePool Interface Function........................................................................134
vii
A.7.3.1. RexxVariablePool..........................................................................................134
A.7.3.1.1. Parameters ........................................................................................134
A.7.3.1.2. RexxVariablePool Return Codes ......................................................138
A.7.3.1.3. Example............................................................................................138
A.8. Dynamically Allocating and De-allocating Memory .............................................................139
A.8.1. The RexxAllocateMemory() Function ......................................................................139
A.8.2. The RexxFreeMemory() Function.............................................................................139
A.9. Queue Interface ......................................................................................................................140
A.9.1. Queue Interface Functions.........................................................................................140
A.9.1.1. RexxCreateQueue .........................................................................................140
A.9.1.1.1. Parameters ........................................................................................140
A.9.1.1.2. Return Codes ....................................................................................141
A.9.1.1.3. Remarks............................................................................................141
A.9.1.2. RexxDeleteQueue .........................................................................................141
A.9.1.2.1. Parameters ........................................................................................141
A.9.1.2.2. Return Codes ....................................................................................141
A.9.1.2.3. Remarks............................................................................................141
A.9.1.3. RexxQueryQueue..........................................................................................142
A.9.1.3.1. Parameters ........................................................................................142
A.9.1.3.2. Return Codes ....................................................................................142
A.9.1.4. RexxAddQueue.............................................................................................142
A.9.1.4.1. Parameters ........................................................................................142
A.9.1.4.2. Return Codes ....................................................................................143
A.9.1.5. RexxPullQueue .............................................................................................143
A.9.1.5.1. Parameters ........................................................................................143
A.9.1.5.2. Return Codes ....................................................................................143
A.9.1.5.3. Remarks............................................................................................144
A.10. Halt and Trace Interface .......................................................................................................144
A.10.1. Halt and Trace Interface Functions..........................................................................144
A.10.1.1. RexxSetHalt ................................................................................................144
A.10.1.1.1. Parameters ......................................................................................144
A.10.1.1.2. Return Codes ..................................................................................145
A.10.1.1.3. Remarks..........................................................................................145
A.10.1.2. RexxSetTrace ..............................................................................................145
A.10.1.2.1. Parameters ......................................................................................145
A.10.1.2.2. Return Codes ..................................................................................145
A.10.1.2.3. Remarks..........................................................................................145
A.10.1.3. RexxResetTrace ..........................................................................................145
A.10.1.3.1. Parameters ......................................................................................146
A.10.1.3.2. Return Codes ..................................................................................146
A.10.1.3.3. Remarks..........................................................................................146
A.11. Macrospace Interface ...........................................................................................................146
A.11.1. Search Order ............................................................................................................147
A.11.2. Storage of Macrospace Libraries.............................................................................147
A.11.3. Macrospace Interface Functions ..............................................................................147
A.11.3.1. RexxAddMacro...........................................................................................147
A.11.3.1.1. Parameters ......................................................................................147
A.11.3.1.2. Return Codes ..................................................................................148
viii
A.11.3.2. RexxDropMacro..........................................................................................148
A.11.3.2.1. Parameter........................................................................................148
A.11.3.2.2. Return Codes ..................................................................................148
A.11.3.3. RexxClearMacroSpace................................................................................149
A.11.3.3.1. Return Codes ..................................................................................149
A.11.3.3.2. Remarks..........................................................................................149
A.11.3.4. RexxSaveMacroSpace.................................................................................149
A.11.3.4.1. Parameters ......................................................................................149
A.11.3.4.2. Return Codes ..................................................................................149
A.11.3.4.3. Remarks..........................................................................................150
A.11.3.5. RexxLoadMacroSpace ................................................................................150
A.11.3.5.1. Parameters ......................................................................................150
A.11.3.5.2. Return Codes ..................................................................................150
A.11.3.5.3. Remarks..........................................................................................151
A.11.3.6. RexxQueryMacro........................................................................................151
A.11.3.6.1. Parameters ......................................................................................151
A.11.3.6.2. Return Codes ..................................................................................151
A.11.3.7. RexxReorderMacro .....................................................................................151
A.11.3.7.1. Parameters ......................................................................................152
A.11.3.7.2. Return Codes ..................................................................................152
A.12. Windows Scripting Host Interface .......................................................................................152
A.12.1. Concurrency.............................................................................................................152
A.12.2. WSH Features..........................................................................................................153
A.12.2.1. COM Interfaces...........................................................................................153
A.12.2.2. Script Debugging ........................................................................................154
A.12.2.3. DCOM.........................................................................................................154
B. Object Rexx Runtime........................................................................................................................155
B.1. Distributing Programs without Source ...................................................................................155
C. Sample Rexx Programs ....................................................................................................................157
D. Notices ................................................................................................................................................163
D.1. Trademarks.............................................................................................................................163
D.2. Source Code For This Document ...........................................................................................164
E. Common Public License Version 1.0 ...............................................................................................165
E.1. Definitions ..............................................................................................................................165
E.2. Grant of Rights .......................................................................................................................165
E.3. Requirements ..........................................................................................................................166
E.4. Commercial Distribution ........................................................................................................166
E.5. No Warranty............................................................................................................................167
E.6. Disclaimer of Liability............................................................................................................167
E.7. General....................................................................................................................................168
Index........................................................................................................................................................169
ix
x
List of Figures
2-1. Objects in a Billing Application...........................................................................................................5
4-1. Modular Data--a Report Object..........................................................................................................22
4-2. A Ball Object......................................................................................................................................22
4-3. Ball Object with Variable Names and Values.....................................................................................23
4-4. Encapsulated 5 Object ........................................................................................................................23
4-5. A Simple Class ...................................................................................................................................25
4-6. Icon Class ...........................................................................................................................................26
4-7. Instances of the Icon Class .................................................................................................................26
4-8. Superclass and Subclasses..................................................................................................................27
4-9. The Screen-Object Superclass............................................................................................................28
4-10. Multiple Inheritance .........................................................................................................................28
5-1. How Subclasses Inherit Instance Methods from the Class Class .......................................................32
5-2. Classes and Inheritance of Methods (part 1 of 4)...............................................................................33
5-3. Classes and Inheritance of Methods (Part 2 of 4) ..............................................................................34
5-4. Classes and Inheritance of Methods (Part 3 of 4) ..............................................................................35
5-5. Classes and Inheritance of Methods (Part 4 of 4) ..............................................................................36
6-1. Instance Methods and Class Methods ................................................................................................47
6-2. Instances in the Part Class ..................................................................................................................50
6-3. Scope of the Number Class ................................................................................................................58
6-4. Searching the Hierarchy for a Method ...............................................................................................60
xi
xii
Chapter 1. About This Book
This book describes the Open Object Rexx, or Object Rexx programming language. In the following, it
is called Rexx unless compared to its traditional predecessor.
This book is aimed at developers familiar with Windows® and Unix® who want to use Rexx for
object-oriented programming, or a mix of traditional and object-oriented programming.
This book assumes you are already familiar with the techniques of traditional structured programming,
and uses them as a springboard for quickly understanding Rexx and, in particular, Object Rexx. This
approach is designed to help experienced programmers get involved quickly with the Rexx language,
exploit its virtues, and become productive fast.
1
Chapter 1. About This Book
2
Chapter 2. Meet Object Rexx
Rexx is a versatile, free-format language. Its simplicity makes it a good first language for beginners. For
more experienced users and computer professionals, Rexx offers powerful functions and the ability to
issue commands to several environments.
3
Chapter 2. Meet Object Rexx
4
Chapter 2. Meet Object Rexx
Each instance contains all the data associated with it (such as customer name or descriptions and prices
of items purchased). To get at the data, you write instructions that send messages to the objects. These
messages activate coded actions called methods. For an invoice object, you might need CREATE,
DISPLAY, PRINT, UPDATE, and ERASE methods.
5
Chapter 2. Meet Object Rexx
s=substr(name,2,3)
s=name~substr(2,3)
The tilde (~) character is the Rexx message send operator, called twiddle. The object receiving the
message is to the left of the twiddle. The message sent is to the right. In this example, the Name object is
sent the SUBSTR message. The numbers in parentheses (2,3) are arguments sent as part of the message.
The SUBSTR method is run for the Name object, and the result is assigned to the s string object.
For the new classes (such as array or queue), methods are provided, but not equivalent functions. For
example, suppose you want to use a Rexx array object instead of the traditional string-based stem
variables (such as text.1 or text.2). To create an array object of five elements, you would send a NEW
message to the array class as follows:
myarray=.array~new(5)
A new instance, named Myarray, of the Array class is created. A period and the class name identify the
class. The period is necessary because it precedes the class name in an expression. The Myarray array
object has five elements. Some of the other methods, besides NEW, for array objects are PUT, AT,
REMOVE, SIZE, [], and []=.
By adding object technology to its repertoire of traditional programming techniques, Rexx has evolved
into an object-oriented language, like Smalltalk. Object Rexx accommodates the programming
techniques of traditional Rexx while adding new ones. With Object Rexx, you can use the new
technology as much or as little as you like, at whatever pace you like. You can mix classic and object
techniques. You can ease into the object world gradually, building on the Rexx skills and knowledge you
already have.
6
Chapter 2. Meet Object Rexx
• Cost-savings potential
• Increased adaptability and scalability
With Object Rexx, you get the user-friendliness of Rexx in an object-oriented environment.
Object Rexx provides a Sockets API for Rexx. So you can script Object Rexx clients and servers, and
run them in the Internet.
Object Rexx also provides access to FTP commands by means of its RxFtp package, and to the use of
mathematical functions by means of its RxMath utility package. The Sockets, FTP, and mathematical
functions packages are each supplied with separate, full documentation.
7
Chapter 2. Meet Object Rexx
8
Chapter 3. A Quick Tour of Traditional Rexx
Because this book is for Windows and Unix programmers, it is assumed that you are familiar with at
least one other language. This chapter gives an overview of the basic Rexx rules and shows you in which
respects Rexx is similar to, or different from, other languages you may already know.
The program begins with a comment. This is not a requirement, but it is recommended to ensure
compatibility with other operating systems, such as OS/2, where the first line in a Rexx program must be
a comment line.
The Object Rexx interpreter is invoked by the command
9
Chapter 3. A Quick Tour of Traditional Rexx
Rexx
To run the program MYRexx.CMD, for example, use the command Rexx MYRexx.CMD.
ORXWB
If you want to run your Rexx program in silent mode without creating a console window on Windows,
you can invoke RexxHIDE.EXE followed by the program name and the program arguments from a
program item. If RexxHIDE is called from within a console window, no output is displayed in the
console window.
SAY is a Rexx instruction that displays a message (like PRINT in Basic or printf in C). The message to
be displayed follows the SAY keyword. The single quotes are necessary to delimit a character string. In
this case, the character string is Please enter your name. You can use double quotes (") instead of
single quotes.
The PULL instruction reads a line of text from the standard input (the keyboard), and returns the text in
the variable specified with the instruction. In our example, the text is returned in the variable name.
The next SAY instruction provides a glimpse of what can be done with Rexx strings. It displays the
word Hello followed by the name of the user, which is stored in variable name. Rexx substitutes the
value of name and displays the resulting string. You do not need a separate format string as you do with
C or Basic.
The final instruction, EXIT, ends the Rexx program. Control returns to Windows or Unix/Linux. EXIT
can also return a value. In our example, 0 is returned. The EXIT instruction is optional.
You can terminate a running Rexx program by pressing the Ctrl+Break key combination. Rexx stops
running the program and control returns to Windows or Unix/Linux.
10
Chapter 3. A Quick Tour of Traditional Rexx
To continue a clause on a second line, put a comma at the end of the line:
say, /* Continuation */
"It isn’t so"
Rexx automatically adds a blank after continue. If you need to split a string, but do not want to have a
blank inserted when Rexx puts the string back together, use the Rexx concatenation operator (||):
REXXTRY describes itself and asks you for a Rexx statement to test. Enter your statement; REXXTRY
then runs it and returns any information available, or displays an error message if a problem is
encountered. REXXTRY remembers any previous statements you have entered during the session. To
continue, just type the next line in your program and REXXTRY will check it for you.
Enter an equal sign (=) to repeat your previous statement, or a question mark (?) to invoke
system-provided online information about the Rexx language.
When you are done, type:
11
Chapter 3. A Quick Tour of Traditional Rexx
exit
In this case, entering CALL SHOW displays the user variables provided by RexxTRY.
• The first character must be A-Z, a-z, !, ?, or _ . Rexx translates lowercase letters to uppercase before
using them.
• The rest of the characters may be A-Z, a-z, !, ?, or _, ., or 0-9.
• The period (.) has a special meaning for Rexx variables. Do not use it in a variable name until you
understand the rules for forming compound symbols.
The variable name can be typed and queried in uppercase, mixed-case, or lowercase characters. A
variable name in uppercase characters, for example, can also be queried in lowercase or mixed-case
characters. If you query a variable name that has not yet been set, the name is returned in uppercase
characters.
Literal strings in Rexx are delimited by quotation marks (either ’ or "). Examples of literal strings are:
’Hello’
"Final result:"
If you need to use quotation marks within a literal string, use quotation marks of the other type to delimit
the string. For example:
12
Chapter 3. A Quick Tour of Traditional Rexx
"Don’t panic"
’He said, "Bother"’
There is another way to do this. Within a literal string, a pair of quotation marks (the same type that
delimits the string) is interpreted as one of that type. For example:
3.8. Assignments
Assignments in Rexx usually take this form:
name = expression
For name, specify any valid variable name. For expression, specify the information to be stored, such as a
number, a string, or some calculation. Here are some examples:
a=1+2
b=a*1.5
c="This is a string assignment. No memory allocation needed!"
The PARSE instruction and its variants PULL and ARG also assign values to variables. PARSE assigns
data from various sources to one or more variables according to the rules of parsing. PARSE PULL, for
example, is often used to read data from the keyboard:
Other operands of PARSE indicate the source of the data. PARSE ARG, for example, retrieves command
line arguments. PARSE VERSION retrieves the information about the version of the Rexx interpreter
being used.
The most powerful feature of PARSE, however, is its ability to parse data according to a template that
you supply. The various pieces of data are assigned to variables that are part of the template. The
following example prompts the user for a date, and assigns the month, day, and year to different
variables. (In a real application, you would want to add instructions to verify the input.)
The template in this example contains two literal strings ("/"). The PARSE instruction uses these literals
to determine how to split the data.
13
Chapter 3. A Quick Tour of Traditional Rexx
The PULL and ARG instructions are short forms of the PARSE instruction. See the Object Rexx:
Reference for more information on Rexx parsing.
Literal strings can be supplied as arguments to functions, so the previous program can be rewritten as
follows:
Because an expression can be used with the SAY instruction, you can further reduce the program to:
Functions can be nested. Suppose you want to display only the first two letters of the third word, Public.
The LEFT function can return the first two letters, but you need to give it the third word. LEFT expects
the input string as its first argument and the number of characters to return as its second argument:
14
Chapter 3. A Quick Tour of Traditional Rexx
The Rexx relational operator for a logical AND is different from the operator in C, which is &&. Other
relational operators differ as well, so you may want to review the appropriate section in the Open Object
Rexx: Reference.
Here is a list of some Rexx comparison operators and operations:
=
True if the terms are equal (numerically, when padded, and so on)
\=, ¬=
True if the terms are not equal (inverse of =)
>
Greater than
<
Less than
<>
Greater than or less than (same as not equal)
>=
Greater than or equal to
<=
Less than or equal to
==
True if terms are strictly equal (identical)
\==, ¬==
True if the terms are NOT strictly equal (inverse of ==)
Note: Throughout the language, the NOT character, ¬, is synonymous with the backslash (\). You
can use both characters. The backslash can appear in the \ (prefix not), \=, and \== operators.
A character string has the value false if it is 0, and true if it is 1. A logical operator can take at least two
values and return 0 or 1 as appropriate:
&
AND - returns 1 if both terms are true.
|
Inclusive OR - returns 1 if either term or both terms are true.
15
Chapter 3. A Quick Tour of Traditional Rexx
&&
Exclusive OR - returns 1 if either term, but not both terms, is true.
Prefix \,¬
Logical NOT - negates; 1 becomes 0, and 0 becomes 1.
Note: On ASCII systems, Rexx recognizes the ASCII character encoding 124 as the logical OR
character. Depending on the code page or keyboard you are using for your particular country, the
logical OR character is shown as a solid vertical bar (|) or a split vertical bar ( ). The appearance of
¦
the character on your screen might not match the character engraved on the key. If you receive error
13, invalid character in program, on an instruction including a vertical bar, make sure this
character is ASCII character encoding 124.
Using the wrong relational or comparison operator is a common mistake when switching between C and
Rexx. The familiar C language braces { } are not used in Rexx for blocks of instructions. Instead, Rexx
uses DO/END pairs. The THEN keyword is always required.
Here is an IF instruction with an ELSE:
You can omit the DO/END pairs if only one clause follows the THEN or ELSE keyword:
count=words(myvar)
if count > 5 then
say "Variable MYVAR has more than five words."
else if count >3 then
say "Variable MYVAR has more than three, but fewer than six words."
else
say "Variable MYVAR has fewer than four words."
The SELECT instruction in Rexx is similar to the SELECT CASE statement in Basic and the switch
statement in C. SELECT executes a block of statements based on the value of an expression. Rexx’s
SELECT differs from the equivalent statements in Basic and C in that the SELECT keyword is not
followed by an expression. Instead, expressions are placed in WHEN clauses:
16
Chapter 3. A Quick Tour of Traditional Rexx
select
when name="Bob" then
say "It’s Bob!"
when name="Mary" then
say "Hello, Mary."
otherwise
end /* select */
WHEN clauses are evaluated sequentially. When one of the expressions is true, the statement, or block of
statements, is executed. All the other blocks are skipped, even if their WHEN clauses would have
evaluated to true. Notice that statements like the break statement in C are not needed.
The OTHERWISE keyword is used without an instruction following it. Rexx does not require an
OTHERWISE clause. However, if none of the WHEN clauses evaluates to true and you omit
OTHERWISE, an error occurs. Therefore, always include an OTHERWISE.
As with the IF instruction, you can use DO/END pairs for several clauses within SELECT cases. You do
not need a DO/END pair if several clauses follow the OTHERWISE keyword:
select
when name="Bob" then
say "It’s Bob"
when name="Mary" then do
say "Hello Mary"
marycount=marycount+1
end
otherwise
say "I’m sorry. I don’t know you."
anonymous=anonymous+1
end /* select */
Many Basic implementations have several different instructions for loops. Rexx only knows the
DO/END pair. All of the traditional looping variations are incorporated into the DO instruction:
17
Chapter 3. A Quick Tour of Traditional Rexx
Rexx also has a FOREVER keyword. Use the LEAVE, RETURN, or EXIT instructions to break out of
the loop:
Rexx also includes an ITERATE instruction, which skips the rest of the instructions in that iteration of
the loop:
do i=1 to 100
/* Iterate when the "special case" value is reached */
if i=5 then iterate
end
There is an equivalent to the Basic GOTO statement: the Rexx SIGNAL instruction. SIGNAL causes
control to branch to a label:
As with GOTO, you need to be careful about how you use SIGNAL. In particular, do not place SIGNAL
in the middle of a DO/END block or into a SELECT structure.
18
Chapter 3. A Quick Tour of Traditional Rexx
/* Routine example */
i=10 /* Initialize I */
call myroutine /* Call routine */
say i /* Displays 22 */
exit /* End main program */
myroutine: /* Label */
i=i+12 /* Increment I */
return
The CALL instruction calls routine MYROUTINE. A label (note the colon) marks the start of the
routine. A RETURN instruction ends the routine. Notice that an EXIT instruction is required in this
case to end the main program. If EXIT is omitted, Rexx assumes that the following instructions are part
of your main program and will execute those instructions. The SAY instruction displays 22 instead of 10
because the caller’s variables are accessible to the routine.
You can return a result to the caller by placing an expression in the RETURN instruction, like this:
myroutine: /* Label */
return i+12 /* Increment I */
The returned result is available to the caller in the special variable RESULT, as previously shown. If
your routine returns a result, you can call it as a function:
myroutine: /* Label */
return i+12 /* Increment I */
You can pass arguments to this sort of routine, but all variables are available to the routine anyway.
You can also write routines that separate the caller’s variables from the routine’s variables. This
eliminates the risk of accidentally writing over a variable used by the caller or by some other unprotected
routine. To get protection, use the PROCEDURE instruction, as follows:
19
Chapter 3. A Quick Tour of Traditional Rexx
end /* do */
exit /* End main program */
In this example, the variable i is used in both the main program and the routine. When the PROCEDURE
instruction is placed after the routine label, the routine’s variables become local variables. They are
isolated from all other variables in the program. Without the PROCEDURE instruction, the program
would loop indefinitely. On each iteration the value of i would be reset to some value less than 100,
which means the loop would never end. If a programming error causes your procedure to loop
indefinitely, use the Ctrl+Break key combination or close the Windows session to end the procedure.
To access variables outside the routine, add an EXPOSE operand to the PROCEDURE instruction. List
the desired variables after the EXPOSE keyword:
In the routine, use the PARSE ARG instruction to retrieve the argument.
20
Chapter 4. Into the Object World
Object Rexx includes features typical of an object-oriented language--features like subclassing,
polymorphism, and data encapsulation. Object Rexx is an extension of the traditional Rexx language,
which has been expanded to include classes, objects, and methods. These extensions do not replace
traditional Rexx functions, or preclude the development or running of traditional Rexx programs. You
can program as before, program with objects, or mix objects with regular Rexx instructions. The Rexx
programming concepts that support the object-oriented features are described in this chapter.
21
Chapter 4. Into the Object World
But with object-oriented programming, it is the data that is modularized. And each data module includes
its own operations for performing actions directly related to its data.
In the case of report, the report object would contain its own built-in PRINT, SEND, ERASE, and FILE
operations.
Object-oriented programming lets you model real-world objects--even very complex ones--precisely and
elegantly. As a result, object manipulation becomes easier and computer instructions become simpler and
can be modified later with minimal effort.
Object-oriented programming hides any information that is not important for acting on an object, thereby
concealing the object’s complexities. Complex tasks can then be initiated simply, at a very high level.
22
Chapter 4. Into the Object World
In object-oriented programming, objects are the basic building blocks--the fundamental units of data.
There are many kinds of objects; for example, character strings, collections, and input and output
streams. An object--such as a character string--always consists of two parts: the possible actions or
operations related to it, and its characteristics or variables. A variable has a variable name, and an
associated data value that can change over time. These actions and characteristics are so closely
associated that they cannot be separated:
To access an object’s data, you must always specify an action. For example, suppose the object is the
number 5. Its actions might include addition, subtraction, multiplication, and division. Each of these
actions is an interface to the object’s data. The data is said to be encapsulated because the only way to
access it is through one of these surrounding actions. The encapsulated internal characteristics of an
object are its variables. Variables are associated with an object and exist for the lifetime of that object:
23
Chapter 4. Into the Object World
Rexx comes with a basic set of classes for creating objects (see The Basics of Classes). Therefore, you
can create objects that exactly match the needs of a particular application.
• A receiving object
• The "message send" symbol, ~, which is called the twiddle
• The action and, optionally in parentheses, any parameters required
So the message format looks like this:
object~action(parameters)
Assume that the object is the string !iH. Sending it a message to use its REVERSE action:
"!iH"~reverse
24
Chapter 4. Into the Object World
4.5. Methods
Sending a message to an object results in performing some action; that is, it results in running some
underlying code. The action-generating code is called a method. When you send a message to an object,
you specify its method name in the message. Method names are character strings like REVERSE. In the
preceding example, sending the reverse message to the !iH object causes it to run the REVERSE
method. Most objects are capable of more than one action, and so have a number of available methods.
The classes Rexx provides include their own predefined methods. The Message class, for example, has
the COMPLETED, INIT, NOTIFY, RESULT, SEND, and START methods. When you create your own
classes, you can write new methods for them in Rexx code. Much of the object programming in Rexx is
writing the code for the methods you create.
4.6. Polymorphism
Rexx lets you send the same message to objects that are different:
As long as each object has its own REVERSE method, REVERSE runs even if the programming
implementation is different for each object. This ability to hide different functions behind a common
interface is called polymorphism. As a result of information hiding, each object in the previous example
knows only its own version of REVERSE. And even though the objects are different, each reverses itself
as dictated by its own code.
Although the !iH object’s REVERSE code is different from the plotter pen’s, the method name can be
the same because Rexx keeps track of the methods each object owns. The ability to reuse the same
method name so that one message can initiate more than one function is another feature of
polymorphism. You do not need to have several message names like REVERSE_STRING,
REVERSE_PEN, REVERSE_BALL. This keeps method-naming schemes simple and makes complex
programs easy to follow and modify.
The ability to hide the various implementations of a method while leaving the interface the same
illustrates polymorphism at its lowest level. On a higher level, polymorphism permits extensive code
reuse.
25
Chapter 4. Into the Object World
All the icon objects might use common methods like DRAW or ERASE. They might contain common
variables like position, color, or size. What makes each icon object different from one another is the data
assigned to its variables. For the Windows system icon, it might be position="20,20" while for the
shredder it is "20,30" and for information it is "20,40"
Objects that belong to a class are called instances of that class. As instances of the Icon class, the
Windows system icon, shredder icon, and information icon acquire the methods and variables of that
class. Instances behave as if they each had their own methods and variables of the same name. All
instances, however, have their own unique properties--the data associated with the variables. Everything
else can be stored at the class level.
26
Chapter 4. Into the Object World
If you must update or change a particular method, you only have to change it at one place, at the class
level. This single update is then acquired by every new instance that uses the method.
A class that can create instances of an object is called an object class. The Icon class is an object class
you can use to create other objects with similar properties, such as an application icon or a drives icon.
An object class is like a factory for producing instances of the objects.
27
Chapter 4. Into the Object World
You can add a class to an existing superclass. For example, you might add the Icon class to the
Screen-Object superclass:
In this way, the subclass inherits additional methods from the superclass. A class can have more than one
superclass, for example, subclass Bitmap might have the superclasses Screen-Object and Art-Object.
Acquiring methods and variables from more than one superclass is known as multiple inheritance:
28
Chapter 5. The Basics of Classes
Similar objects in Rexx are grouped into classes, forming a hierarchy. Rexx gives you a basic class
hierarchy to start with. All of the classes in the hierarchy are described in detail in the Open Object Rexx:
Reference. The following list shows the classes Rexx provides (there may be others in the system). The
classes indented are subclasses. Classes in the list that are described later in this chapter are printed in
bold:
Object
Alarm
Class
Collection classes
Array
List
Queue
Table
Set
Directory
Relation
Bag
Message
Method
Monitor
Stem
Stream
String
Supplier
29
Chapter 5. The Basics of Classes
Rexx includes classes, for example, for arrays, lists, queues, tables, and directories. Each item stored in a
Rexx collection has an associated index that you can use to retrieve the item from the collection with the
AT or [] (left and right bracket) methods, and each collection defines its own acceptable index types:
Array
A sequenced collection of objects ordered by whole-number indexes.
List
A sequenced collection that lets you add new items at any position in the sequence. A list generates
and returns an index value for each item placed in the list. The returned index remains valid until the
item is removed from the list.
Queue
A sequenced collection of items ordered as a queue. You can remove items from the head of the
queue and add items at either its tail or its head. Queues index the items with whole-number
indexes, in the order in which the items would be removed. The current head of the queue has index
1, the item after the head item has index 2, up to the number of items in the queue.
Table
A collection of indexes that can be any object. For example, string objects, array objects, alarm
objects, or any user-created object can be a table index. The Table class determines an index match
by using the == comparison method to test for strict equality. A table contains no duplicate indexes.
Directory
A collection of character string indexes. Indexes are compared using the string == comparison
method to test for strict equality.
Relation
A collection of indexes that can be any object (as with the Table class). A relation can contain
duplicate indexes.
Set
A collection where the indexes are equal to the values. Set indexes can be any object (as with the
Table class) and each index is unique.
Bag
A collection where the index is equal to the value. Bag indexes can be any object (as with the Table
class) and each index can appear more than once.
30
Chapter 5. The Basics of Classes
31
Chapter 5. The Basics of Classes
32
Chapter 5. The Basics of Classes
Figure 5-1. How Subclasses Inherit Instance Methods from the Class Class
As a programmer, you typically create classes by using directives, rather than the methods of the Class
class. In particular, you’ll use the ::CLASS directive, described later in this section. The ::CLASS
directive is a kind of Rexx clause that allows class definitions to be saved permanently, in a file, where
they can be reused by other programs. Creating classes by using Class methods sent as messages is not
recommended if permanency or reuse is required. At any rate, directives have class-creating powers
similar to the Class methods.
+---------------------------------------------------------------------------+
33
Chapter 5. The Basics of Classes
| Object |
+-----------+----------+----------------+----------+----------+-------------+
NEW* | | | | |
= +-------+ +--------+ +-------+ +------+ +-------+
== | Alarm | | Class* | | Array | | List | | Queue |
\= +-------+ +--------+ +-------+ +------+ +-------+
<> CANCEL BASECLASS NEW OF* []
>< INIT DEFAULTNAME OF* [] []=
\== DEFINE [] []= AT
CLASS DELETE []= AT HASINDEX
COPY ENHANCED AT FIRST ITEMS
DEFAULTNAME ID DIMENSION FIRSTITEM MAKEARRAY
HASMETHOD INHERIT FIRST HASINDEX PEEK
INIT INIT HASINDEX INSERT PULL
OBJECTNAME METACLASS ITEMS ITEMS PUSH
OBJECTNAME= METHOD LAST LAST PUT
REQUEST METHODS MAKEARRAY LASTITEM QUEUE
RUN MIXINCLASS NEXT MAKEARRAY REMOVE
SETMETHOD NEW PREVIOUS NEXT SUPPLIER
START QUERYMIXINCLASS PUT PREVIOUS
STRING SUBCLASS REMOVE PUT
UNSETMETHOD SUBCLASSES SECTION REMOVE
SUPERCLASSES SIZE SECTION
UNINHERIT SUPPLIER SUPPLIER
* All of the methods under the Class class are both class and instance
methods.NEW and OF are class methods.
+---------------------------------------------------------------------------+
| Object (continued) |
+---------------+--------------+---------------+------------+---------------+
| | | | |
+-------+ +-----------+ +----------+ +---------+ +--------+
| Table | | Directory | | Relation | | Message | | Method |
+-------+ +-----------+ +----------+ +---------+ +--------+
| [] [] | [] COMPLETED NEW*
| []= []= | []= INIT NEWFILE
| AT DIFFERENCE | ALLAT NOTIFY SETGUARDED
| DIFFERENCE HASINDEX | ALLINDEX RESULT SETPRIVATE
| HASINDEX INTERSECTION | AT SEND SETPROTECTED
| INTERSECTION ITEMS | DIFFERENCE START SETSECURITYMANAGER
| ITEMS MAKEARRAY | HASINDEX SETUNGUARDED
| MAKEARRAY PUT | HASITEM SOURCE
| PUT REMOVE | INDEX
| REMOVE SETENTRY | INTERSECTION
| SUBSET SETMETHOD | ITEMS
| SUPPLIER SUBSET | MAKEARRAY
| UNION SUPPLIER | PUT
34
Chapter 5. The Basics of Classes
* All of the methods under the Class class are both class and instance
methods.NEW and OF are class methods.
+---------------------------------------------------------------------------+
| Object (continued) |
+------------+------------------+----------+--------------------------------+
| | | |
+---------+ +---------------+ +------+ +--------+
| Monitor | | MutableBuffer | | Stem | | Stream |
+---------+ +---------------+ +------+ +--------+
CURRENT APPEND NEW* ARRAYIN
DESTINATION DELETE [] ARRAYOUT
INIT GETBUFFERSIZE []= CHARIN
UNKNOWN INIT MAKEARRAY CHAROUT
INSERT REQUEST CHARS
LENGTH UNKNOWN CLOSE
OVERLAY COMMAND
SETBUFFERSIZE DESCRIPTION
STRING FLUSH
SUBSTR INIT
LINEIN
LINEOUT
LINES
MAKEARRAY
OPEN
POSITION
QUALIFY
QUERY
SEEK
STATE
35
Chapter 5. The Basics of Classes
SUPPLIER
* All of the methods under the Class class are both class and instance
methods.NEW and OF are class methods.
+---------------------------------------------------------------------------+
| Object (continued) |
+-----------------------------+---------------------------------------------+
| |
+--------+ +----------+
| String | | Supplier |
+--------+ +----------+
NEW FORMAT NEW*
"" (abuttal) INSERT AVAILABLE
(arithmetic:) LASTPOS INDEX
+ - * / % // ** LEFT ITEM
’ ’ (blank) LENGTH NEXT
ABBREV (logical:)
ABS & && |
BITAND \
BITOR MAKESTRING
BITXOR MAX
B2X MIN
CENTER OVERLAY
CHANGESTR POS
COMPARE REVERSE
(comparison:) RIGHT
= \= <> >< SIGN
> >= \> SPACE
< <= \< STRING
== \== STRIP
>> \>> >>= SUBSTR
<< \<< <<= SUBWORD
(concatenation:) TRANSLATE
|| TRUNC
COPIES VERIFY
COUNTSTR WORD
C2D WORDINDEX
C2X WORDLENGTH
DATATYPE WORDPOS
DELSTR WORDS
DELWORD X2B
D2C X2C
D2X X2D
* All of the methods under the Class class are both class and instance
36
Chapter 5. The Basics of Classes
• Inheriting instance methods from a specified metaclass as class methods of the new class (the
METACLASS option). For more information on metaclasses, see Metaclasses.
• Making the new class available to programs outside its containing Rexx program (the PUBLIC
option). The outside program must refer to the new class by using a ::REQUIRES directive.
37
Chapter 5. The Basics of Classes
• Subclassing the new class to a mixin class in order to inherit its instance and class methods (the
MIXINCLASS option).
• Adding the instance and class methods of a mixin class to the new class, without subclassing it (the
INHERIT option).
When you create a new class, it is always a subclass of an existing class. If you do not specify the
SUBCLASS or MIXINCLASS option on the ::CLASS directive, the superclass for the new class is the
Object class.
Your class definition can be in a file of its own, with no executable code preceding it. For example, when
you define classes and methods to be shared by several programs, you put the executable code in another
file and refer to the class file using a ::REQUIRES directive.
Rexx processes ::CLASS directives in the order in which they appear, unless there is a dependency on
some later directive’s processing. You cannot create two classes that have the same class name in one
program. If several programs contain classes with the same name, the last ::CLASS directive processed
is used.
• Creating a class method for the most-recent ::CLASS directive (the CLASS option).
• Creating a private method; that is, a method that works like a subroutine and can only be activated by
the object it belongs to--otherwise the method is public by default, and any sender can activate it.
• Creating a method that can be called while other methods are active on the same object, as described
in Activating Methods (the UNGUARDED option).
• Creating the instance methods method_name and method_name= for the preceding ::CLASS directive
(the ATTRIBUTE option).
38
Chapter 5. The Basics of Classes
The ::ROUTINE directive is useful for defining lower-level routines that are called by several methods.
These methods might be in unrelated classes or in different applications. You use ::ROUTINE when you
have a utility that you do not want to appear as a method.
The ::ROUTINE directive includes a PUBLIC option for making the routine available to programs
outside its containing Rexx program. The outside program must reference the routine by using a
::REQUIRES directive.
Only one ::ROUTINE directive can appear for a routine name within a program.
The ::REQUIRES directive must precede all other directives, and the order of the ::REQUIRES
directives determines the search order for the classes and routines defined in the named programs.
Local routine or class definitions within a program override routines or classes of the same name in
programs that are accessed through ::REQUIRES directives. Another directive (or the end of the
program) must follow a ::REQUIRES directive.
1. Processes the directives first, to set up the program’s classes, methods, and routines.
2. Runs any program code preceding the first directive. This code can use any classes, methods, and
routines set up by the directives.
Once Rexx has processed the code preceding the directive, any public classes and objects the
program defines are available to programs having the appropriate ::REQUIRES directive.
39
Chapter 5. The Basics of Classes
::method "TYPE"
return "an account"
::method "NAME="
expose name
use arg name
::method "TYPE"
return "a savings account" /* ... directives end */
The preceding program uses the ::CLASS directive to create two classes, the Account class and its
Savings subclass. In the ::class Account expression, the ::CLASS directive precedes the name of the
new class, Account.
The example program also uses the ::METHOD directive to create TYPE and NAME= methods for
Account. In the ::method "TYPE" expression, the ::METHOD directive precedes the method name, and
is immediately followed by the code for the method. Methods for any new class follow its ::CLASS
directive in the program, and precede the next ::CLASS directive.
In the ::method "NAME=" method, the USE ARG instruction retrieves the argument. The EXPOSE
instruction, which must immediately follow the ::METHOD directive, makes the value (here, "John
Smith") available for use by other methods. A variable in an EXPOSE instruction is called an object
variable.
You do not have to associate object variables with a specific object. Rexx keeps track of object variables
for you. Whenever you send a message to savings account Asav, which points to the Name object, Rexx
knows what internal object value to use. If you assign another value to Asav (such as "Mary Smith"),
Rexx deletes the object that was associated with Asav ("John Smith") as part of its normal
garbage-collection operations.
In the Savings subclass, a second TYPE method is created that supersedes the TYPE method Savings
would otherwise have inherited from Account. Note that the directives appear after the program code.
40
Chapter 5. The Basics of Classes
account = .object~subclass("Account")
41
Chapter 5. The Basics of Classes
Here, .object is a reference to the Rexx Object class. .object is an environment symbol indicating the
intention to create a new class that is a subclass of the Object class. Environment symbols represent
objects in a directory of public objects, called the Environment object. These public objects are available
to all other objects, and include all the classes that Rexx provides. Environment symbols begin with a
period and are followed by the class name. Thus the Object class is represented by .object, the Alarm
class by .alarm, the Array class by .array, and so on.
The twiddle (~) is the "message send" symbol, subclass is a method of Class, and the string identifier in
parentheses is an argument of SUBCLASS that names the new class, Account.
newaccount = savings~new
say newaccount~type
newaccount~name = "John Smith"
• Object classes
• Abstract classes
42
Chapter 5. The Basics of Classes
• Mixin classes
An object class (the default) can create instances of the object in response to receiving a NEW or
ENHANCED message. An abstract class serves mainly to organize other classes in the hierarchy and
define their message interface. A mixin class, through multiple inheritance, is an additional superclass to
a class. The mixin class typically possesses methods useful to the class that inherits it, but these must be
specifically added because they lie outside the class’s normal line of inheritance.
The following sections explain these class types in more detail.
43
Chapter 5. The Basics of Classes
To create a new mixin class, you use the ::CLASS directive with the MIXINCLASS option. A mixin
class is also an object class and can create its own instances.
5.7. Metaclasses
A metaclass is a class you can use to create another class. Rexx provides just one metaclass, the Class
class. A class is a factory for creating instances, and the Class class is a factory for creating factories.
Whenever you create a new factory, or class, the new class is an instance of Class. The instance methods
of Class provide the operations needed to run the new factories. These instance methods are inherited by
the new factory as its class methods.
The classes Rexx provides do not permit changes or additions to their method definitions. As a result, all
new factories inherit these unchangeable actions from the Class class, and thus operate the same way. So
if you want to create a new class--a new factory--that behaves differently from the others, you can do
either of the following:
• Write additional class methods for the new class, using the ::METHOD directive with the CLASS
option
• Use a metaclass
If you plan to create many factories with the same operational changes, you use the metaclass.
Any metaclass you create is a subclass of the Class class. To make your own metaclass, specify class as
a SUBCLASS option in the ::CLASS directive:
The instance methods of your_metaclass becomes the class methods for any new class created using
your_metaclass. For example, you could create a metaclass called InstanceCounter that includes instance
methods for tracking how many instances the class creates:
Instead of having to add instance-counting class methods to other new classes you write, you can make
InstanceCounter their metaclass. When you create the new class, you specify InstanceCounter as a
METACLASS option in the ::CLASS directive. Creating a Point class might look like this:
The instance methods in your new InstanceCounter metaclass become the class methods of the Point
class, and any other classes that you create in the future using a similar directive. Here is a complete
example:
44
Chapter 5. The Basics of Classes
/* A metaclass example */
45
Chapter 5. The Basics of Classes
46
Chapter 6. A Closer Look at Objects
This chapter covers the mechanics of using objects and methods in more detail. First, a quick refresher.
A Rexx object consists of:
47
Chapter 6. A Closer Look at Objects
myarray=.array~new(5)
creates a new instance of the Array class, Myarray. The period precedes a class name in an expression, to
distinguish the class from other variables. The Myarray array object has five elements.
After Myarray is created, you can assign values to it. One way is with the PUT method. PUT has two
arguments, which must be enclosed in parentheses. The first argument is the string to be placed in the
element. The second is the number of the element in which to place the string. Here, the string object
Hello is associated with the third element of Myarray:
myarray~put("Hello",3)
Rexx dynamically adjusts the size of the array to accommodate the new element.
One way to retrieve values from an array object is by sending it an AT message. In the next example, the
SAY instruction displays the third element of Myarray:
say myarray~at(3)
Results:
Hello
The SAY instruction expects the string object as input, which is what AT returns. If you put a nonstring
object in the SAY instruction, SAY sends a STRING message to the object. The STRING method for
Rexx’s built-in objects returns a human-readable string representation for the object. In this example, the
STRING method for Myarray returns the string an array:
Results:
an array
Whenever a method returns a string, you can use it within expressions that require a string. Here, the
element of the array that AT returns is a string, so you can put an expression containing the AT method
inside a string function like COPIES():
say copies(myarray~at(3),4)
Results:
HelloHelloHelloHello
say myarray~at(3)~copies(4)
Notice that the expression is evaluated from left to right. You can also use parentheses to enforce an
order of evaluation.
48
Chapter 6. A Closer Look at Objects
Almost all messages are sent using the twiddle, but there are exceptions. The exceptions are to improve
the reliability of the language. The following example uses the []= (left-bracket right-bracket equal-sign)
and [] methods to set and retrieve array elements:
Although the previous instructions look like an ordinary array assignment and array reference, they are
actually messages to the Myarray object. You can prove this by executing these equivalent instructions,
which use the twiddle to send the messages:
Similarly, expression operators (such as +, -, /, and *) are actually methods, but you do not have to use
the twiddle to send them:
In the second SAY instruction, quotes are needed around the + message because it is a character not
allowed in a Rexx symbol.
49
Chapter 6. A Closer Look at Objects
human-readable string representation for the object. For example, if you instruct Rexx to say a, and a is
an array object, Rexx returns an array. You can take advantage of this automatic use of STRING by
overriding Rexx’s STRING method with your own, and extract the object data itself--in this case, the
actual array data.
The following programs demonstrate STRING and INIT. In the first program, the Part class is created,
and along with it, the two methods under discussion, STRING and INIT:
/* Define the STRING method to return a string with the part name */
::method string
expose name
return "Part name:" name
In the ::CLASS directive, the keyword PUBLIC indicates that the class can be shared with other
programs. The two ::METHOD directives define INIT and STRING. Whenever Rexx creates a new
instance of a class, it calls the INIT method for the class. The sample INIT method uses an EXPOSE
instruction to make the name, description, and number variables available to other methods. These
exposed variables are object variables, and are associated with a particular instance of a class:
50
Chapter 6. A Closer Look at Objects
INIT expects to be passed three arguments. The USE ARG instruction assigns these three arguments to
the name, description, and number variables, respectively. Because those variables are exposed, the
values are available to other methods.
The STRING method returns the string Part name:, followed by the name of a part. The STRING
method does not expect any arguments. It uses the EXPOSE instruction to tap the object variables. The
RETURN instruction returns the result string.
The following example shows how to use the Part class:
The USEPART program creates two parts, which are instances of the Part class. It then displays the
names of the two parts.
Rexx processes all directives before running your program. The ::REQUIRES directive indicates that the
program needs access to public class definitions that are in another program. In this case, the
::REQUIRES directive refers to the PARTDEF program, which contains the Part definition.
The assignment instructions for Mypart A and Mypart B create two objects that are instances of the Part
class. The objects are created by sending a NEW message to the Part class. The NEW message causes
51
Chapter 6. A Closer Look at Objects
the INIT method to be invoked as part of object creation. The INIT method takes the three arguments
you provide and makes them part of the object’s own exclusive set of variables, called a variable pool.
Each object has its own variable pool (name, description, and number).
The SAY instruction sends a STRING message to the object. In the first SAY instruction, the STRING
message is sent to MypartA. The STRING method accesses the Name object variable for MypartA and
returns it as part of a string. In the second SAY instruction, the STRING message is sent again, but to a
different object: MypartB. Because the STRING method is invoked for MypartB, it automatically
accesses the variables for MypartB. You do not need to pass the name of the object to the method in
order to distinguish different sets of object variables; Rexx keeps track of them for you.
Another way to define classes is by using the SUBCLASS method. You can send a SUBCLASS method
to any desired superclass to create a class.
::class scratchpad
::method init
expose text
use arg text
say "Remembering" text
::method uninit
expose text
say "Forgetting" text
return
Whether uninitialization processing is needed depends on the circumstances, for example when a
message object holds an unreported error that should be reported and cleared. If an object requires
uninitialization, define an UNINIT method to specify the processing you want.
52
Chapter 6. A Closer Look at Objects
If UNINIT is defined, Rexx runs it before reclaiming the object’s storage. If an instance has more than
one UNINIT method (for example, UNINIT is defined in several classes), each UNINIT method is
responsible for sending the UNINIT message up the hierarchy, using the SUPERCLASS overrides, to
run the topmost version of UNINIT.
RC
is set to the return code from any executed command, including those submitted with the
ADDRESS instruction. After the trapping of ERROR or FAILURE conditions, it is also set to the
command return code. When the SYNTAX condition is trapped, RC is set to the syntax error
number (1-99). RC is unchanged when any other condition is trapped.
RESULT
is set by a RETURN instruction in a subroutine that has been called, or a method that was activated
by a message instruction, if the RETURN instruction specifies an expression. If the RETURN
instruction has no expression on it, RESULT is dropped (becomes uninitialized). RESULT is also
set by an EXIT or REPLY instruction.
SELF
is set when a method is activated. Its value is the object that forms the execution context for the
method (that is, the receiver object of the activating message).
You can use SELF to:
• Run a method in an object in which a method is already running. For example, a FIND_CLUES
method is running in an object called Mystery_Novel. When FIND_CLUES finds a clue, it sends
a READ_LAST_PAGE message to Mystery_Novel:
self~read_last_page
• Pass references regarding an object to the methods of other objects. For example, a SING method
is running in object Song. The code:
Singer2~duet(self)
53
Chapter 6. A Closer Look at Objects
SIGL
is set to the line number of the last instruction that caused a transfer of control to a label (that is, any
SIGNAL, CALL, internal function call, or trapped condition).
SUPER
is set when a method is activated. Its value is the class object that is the usual starting point for a
superclass method lookup for the SELF object. This is the first immediate superclass of the class
that defined the method currently running.
The special variable SUPER lets you call a method in the superclass of an object. For example, the
following Savings class has INIT methods that the Savings class, Account class, and Object class
define.
::class Account
::method INIT
expose balance
use arg balance
self~init:super /* Forwards to the Object INIT method */
::method TYPE
return "an account"
::method INIT
expose interest_rate
use arg balance, interest_rate
self~init:super(balance) /* Forwards to the Account INIT method */
::method type
return "a savings account"
When the INIT method of the Savings class is called, the variable SUPER is set to the Account
class object. For example:
self~init:super(balance)
This instruction calls the INIT method of the Account class rather than recursively calling the INIT
method of the Savings class. When the INIT method of the Account class is called, the variable
SUPER is assigned to the Object class. For example:
self~init:super
This instruction calls the INIT method the Object class defines.
You can alter these variables, just like any other variable, but Rexx continues to set RC, RESULT, and
SIGL automatically when appropriate. EXPOSE, PROCEDURE, USE, and DROP instructions affect
these variables in their usual way.
Rexx also supplies functions that indirectly affect the execution of a program. An example is the name
that the program was called by and the source of the program (which are available using the PARSE
54
Chapter 6. A Closer Look at Objects
SOURCE instruction). In addition, PARSE VERSION makes available the language version and date of
Rexx implementation that is running. The built-in functions ADDRESS, DIGITS, FUZZ, FORM, and
TRACE return other settings that affect the execution of a program.
.environment~your.object = value
Include a period (.) in any object name you use, to avoid conflicts with current or future Rexx entries to
the Environment directory. To retrieve your object, you use the form:
say .environment~your.object
asav = .savings~new
.Savings is an environment symbol, and refers to the Savings class. The classes you create can be
referenced with an environment symbol. There is an environment symbol for each Rexx-defined class, as
well as for each of the unique objects this section describes, such as the NIL object.
if board[row,column] = .nil
then ...
All the environment objects Rexx provides are single symbols. Use compound symbols when you create
your own, to avoid conflicts with future Rexx-defined entries.
55
Chapter 6. A Closer Look at Objects
.local~your.object = value
Be sure to include a period (.) in any object name you use, to avoid conflicts with current or future Rexx
entries to the Local directory. To retrieve your object, you use the form:
say .local~your.object
.error
is the Error object (the default error stream) to which Rexx writes error messages and trace output
to.
.input
is the Input object (the default input stream), which is the source for the PARSE LINEIN
instruction, the LINEIN method of the Stream class, and (if you do not specify a stream name) the
LINEIN built-in function. It is also the source of the PULL and PARSE PULL instructions if the
external data queue is empty.
.output
is the Output object (the default output stream), which is the destination of output from the SAY
instruction, the LINEOUT method (.OUTPUT~LINEOUT), and (if you do not specify a stream
name) the LINEOUT built-in function. You can replace this object in the environment to direct such
output elsewhere, for example to a transcript window.
.methods
The .methods environment symbol identifies a directory of methods that ::METHOD directives in
the currently running program define. The directory indexes are the method names. The directory
values are the method objects. Only methods that are not preceded by a ::CLASS directive are in the
.methods directory. If there are no such methods, the .methods symbol has the default value of
".METHODS". Here is an example:
use arg class, methname
class~define(methname,.methods["a"])
::method a
use arg text
56
Chapter 6. A Closer Look at Objects
say text
.rs
.rs is set to the return status from any executed command, including those submitted with the
ADDRESS instruction. The .rs environment symbol has a value of -1 when a command returns a
FAILURE condition, a value of 1 when a command returns an ERROR condition, and a value of 0
when a command indicates successful completion. The value of .rs is also available after trapping
the ERROR or FAILURE condition.
Note: Tracing interactively does not change the value of .rs. The initial value of .rs is 0.
1. The directory of classes declared on ::CLASS directives within the current program file.
2. The directory of PUBLIC classes declared on ::CLASS directives of other files included with a
::REQUIRES directive.
3. The program local environment directory, which includes process-specific objects such as the
.INPUT and .OUTPUT objects. You can directly access the local environment directory by using the
.Local environment symbol.
4. The global environment directory, which includes all "permanent" Rexx objects such as the
Rexx-supplied classes (for example, .ARRAY) and constants such as .TRUE and .FALSE. You can
directly access the global environment by using the .environment symbol or using the VALUE
built-in function with a null string for the selector argument.
5. Rexx defined symbols. Other simple environment symbols are reserved for use by Rexx for built-in
objects. The currently defined built-in objects are .RS and .METHODS.
If an entry is not found for an environment symbol, the default character string value is used.
Note: You can place entries in both the .local and .environment directories for programs to use. To
avoid conflicts with future Rexx-defined entries, it is recommended that entries you place in either of
these directories include at least one period in the entry name.
Example:
57
Chapter 6. A Closer Look at Objects
Each class in a class hierarchy has a scope different from any other class. This is what allows a variable
in a subclass to have the same name as a variable in a superclass, even though the methods that use the
variables may be completely different.
58
Chapter 6. A Closer Look at Objects
59
Chapter 6. A Closer Look at Objects
An object acquires the methods of its parent class; that is, the class for which the object was created.
If the class subsequently receives new methods, objects predating the new methods do not acquire
them.
If Rexx does not find a match for the message name, Rexx checks the object for method name
UNKNOWN. If it exists, Rexx calls the UNKNOWN method, and returns whatever the UNKNOWN
method returns. For more information on the UNKNOWN method, see Defining an UNKNOWN
Method. If the object does not have an UNKNOWN method, Rexx raises a NOMETHOD condition. Any
trapped information can then be inspected using Rexx’s CONDITION built-in function.
Rexx searches up the hierarchy so that methods existing in higher levels can be supplemented or
overridden by methods existing in lower levels.
For example, suppose you wrote a program that allows users to look up other users’ phone numbers.
Your program includes a class called Phone_Directory, and all its instances are users’ names with phone
numbers. You have included a method in Phone_Directory called NOTIFY that reports some data to a
file whenever someone looks up a number. All instances of Phone_Directory use the NOTIFY method.
Now you decide you want NOTIFY, in addition to its normal handling, to personally inform you
whenever anyone looks up your number. To accommodate this special case for your name only, you
create your own NOTIFY method that adds the new task and replicates the file-handling task. You save
the new method as part of your own name instance, retaining the same name, NOTIFY.
60
Chapter 6. A Closer Look at Objects
Now, when a NOTIFY message is sent to your name instance, the new version of NOTIFY is found first.
Rexx does not look further up the class hierarchy. The instance-level version overrides the version at the
class level. This technique of overriding lets you change a method used by one instance without
disturbing the common method used by all the other instances. It is very powerful for that reason.
1. Making the receiver object the sender object. You usually do this by specifying the special variable
SELF. SELF holds the value of the object in which a method is running. You can use SELF to run
another method in an object where a method is already running or pass references about an object to
the methods of other objects.
2. Specifying a colon and a class symbol after the message name. The class symbol identifies the class
object to use as the starting point for the search. This class object must be:
• A direct superclass of the class that defines the active method
• The object’s own class, if you used SETMETHOD to define the active method
The class symbol is usually the special variable SUPER, but it can be any environment symbol or
variable name whose value is a valid class.
In A Sample Program Using Directives, an Account subclass of the Object superclass is created. It
defines a TYPE method for Account, and creates the Savings subclass of Account. The example defines
a TYPE method for the Savings subclass, as follows:
::method "TYPE"
return "a savings account"
To change the search order so Rexx searches for TYPE in the Account rather than Savings subclass,
enter this instead:
::method "TYPE"
return self~type:super "(savings)"
When you create an asav instance of the Savings subclass and send a TYPE message to asav:
say asav~type
Rexx displays:
an account
rather than:
a savings account
61
Chapter 6. A Closer Look at Objects
UNKNOWN(message_name,message_args )
6.7. Concurrency
In object-oriented programming, as in the real world, objects interact with each other. Assume, for
example, throngs of people interacting at rush hour in the business district of a big city. A program that
aspires to simulate the real world would have to enable many objects to interact at any given time. That
could mean thousands of objects sending messages to each other, thousands of methods running at once.
In Rexx, this simultaneous activity is called concurrency. To be precise, the concurrency is
object-oriented concurrency because it involves objects, as opposed to, for example, processes or threads.
Rexx objects are inherently concurrent, and this concurrency takes the following forms:
62
Chapter 6. A Closer Look at Objects
• Exposed by methods in the object’s class. This set of variables is called a subpool.
• Inherited from classes elsewhere in the hierarchy (in the form of additional subpools).
All of a class’s variables, together with the methods that expose them, are called a class scope. Rexx
exploits this class scope to achieve concurrency. To explain, the object variable pool is a collection of
variable subpools. Each subpool is at a different scope in the object’s inheritance chain. As long as the
methods running on the object are at different scopes, they can run simultaneously.
Scopes, like objects, hide and protect data from outside manipulation. Methods of the same scope share
the variable subpools of that scope. The scope shields the variable subpools from methods operating at
63
Chapter 6. A Closer Look at Objects
other scopes. Thus, you can reuse variable names from class to class, without the variables being
accessed and possibly corrupted by a method outside their own class. So class scopes divide an object’s
variable pool into subpools that can operate independently of one another. Several methods can use the
same variable pool concurrently, as long as they confine themselves to variables in their own subpools.
• The SETUNGUARDED method of the Method class and the UNGUARDED option of the
::METHOD directive, which provide unconditional intra-object concurrency.
• The GUARD OFF and GUARD ON instructions, which permit switching between intra-object and
default concurrency.
64
Chapter 6. A Closer Look at Objects
When intra-object concurrency at the scope level is needed, you must specifically employ these
mechanisms (see the following section). Otherwise, Rexx sequentially processes the methods when they
are competing for the same object variables.
Note: If expression cannot be met, GUARD ON WHEN puts the program in a continuous wait
condition. This can occur in particular when several activities run concurrently. A second activity can
make expression invalid before GUARD ON WHEN can use it.
65
Chapter 6. A Closer Look at Objects
66
Chapter 7. Commands
From a Rexx program you can pass commands to Windows and Unix/Linux shells or to applications
designed to work with Rexx. When used to run operating system commands, Rexx becomes a powerful
substitute for the Windows Batch Facility or the Unix shell. You can use variables, control structures,
mathematics, and parsing to create procedures that would be impossible to implement with the Windows
Batch Facility.
Applications that are designed to work with Rexx are often referred to as scriptable applications. To
work with Rexx, a scriptable application registers an environment with Rexx. An environment serves as a
kind of workspace shared between Rexx and the application. Environments accept application
subcommands issued from Rexx programs.
For example, many editors provide a command prompt or dialog box from which you can issue
subcommands to set margins or add lines. If the editor is scriptable from Rexx, you can issue editor
subcommands from a Rexx program. These Rexx programs are referred to as macros.
When an application runs a Rexx macro, Rexx directs commands to the application’s environment. If
you issue a subcommand that the application does not recognize, it might pass the command to
Windows, depending on the application.
To let you specify which environment processes a command, Rexx includes an ADDRESS instruction.
Starting your Rexx programs from the Windows command line makes Windows the default environment
for Rexx commands.
• Allow Rexx to evaluate part or all of a clause as an expression. Rexx automatically passes the resulting
string to the default environment.
• Enclose the entire clause in quotation marks. This makes it a literal string for Rexx to pass to the
default environment.
• Send a command explicitly to Windows or Unix/Linux by using the ADDRESS instruction.
Rexx processes your program one clause at a time. It examines each clause to determine if it is:
or
pull input
67
Chapter 7. Commands
• A variable assignment (any valid symbol followed by an equal sign), such as:
price = cost * 1.2
The clause dir is not a Rexx instruction or a label, so Rexx evaluates it and passes the resulting string to
Windows. Windows recognizes the string DIR as one of its commands and processes it.
Letting Rexx evaluate the command as an expression might cause problems, however. Try adding a path
to the DIR command in the above program (such as, dir c:\config.sys). The Windows command in
this case is an incorrect Rexx expression. The program ends with an error.
A safer way to issue commands is by enclosing the command in quotes, which makes the command a
literal string. Rexx does not evaluate the contents of strings. Because the string is not a Rexx instruction
or label, Rexx passes the string to Windows. Here is an example using the PATH command:
The following example, DP.CMD, shows a program using the DIR and PATH commands. The PAUSE
command is added to wait for the user to press a key before issuing the next instruction or command.
Borders are added too.
68
Chapter 7. Commands
/* PATH setting */
[C:\]rexx dp
========================================
========================================
PATH=C:\WINDOWS
[C:\]
Note: Whenever you execute a host command addressed to the Windows or Unix/Linux command
shell, that is, an expression that is passed to the system by address CMD as described above, a new
process is created in which the system command handler is executed. When the host command
returns, any changes to the process environment, such as changing the directory, are not passed
back to the process running the Rexx program. To avoid this potential problem, use a different
function such as directory() instead of the command CD
@echo off
if %1.==. goto msg
69
Chapter 7. Commands
if %1 == on goto yes
if %1 == off goto no
if %1 == ON goto yes
if %1 == OFF goto no
if %1 == On goto yes
if %1 == oN goto yes
if %1 == OFf goto no
if %1 == OfF goto no
if %1 == Off goto no
if %1 == oFF goto no
if %1 == oFf goto no
if %1 == ofF goto no
helpmsg %1
goto exit
:msg
helpmsg
goto exit
:yes
prompt $i[$p]
goto exit
:no
cls
prompt
:exit
call mysub1
70
Chapter 7. Commands
Rexx recognizes the CALL instruction, handles the call, and processes MYSUB1 as a Rexx program.
The Rexx CALL instruction does not call a non-Rexx .CMD file. Instead, you would use the Windows
CALL command. To call a non-Rexx .CMD program named MYSUB2, you could write the CALL
instruction like this:
"call mysub2"
Rexx evaluates the expression and passes it to the Windows command handler for processing. The
command handler recognizes the CALL command and processes MYSUB2 as a .CMD program.
The quotation marks around call mysub2 indicate that this is the Windows CALL command instead of a
Rexx CALL instruction.
You can also execute another Rexx program within a new process by invoking the interpreter followed
by the Rexx program name like this:
"rexx mysub2"
However, remember that running the interpreter concurrently requires additional startup time and system
resources.
Rexx displays the following on the screen when you run the program:
[C:\]rexx shofil
Type a file name:
71
Chapter 7. Commands
demo.txt
[C:\]
Because dir is a variable that contains a string, the string is passed to the system. The DIR command is
not executed. Here are the results:
[C:\]rexx dirrex
DIR command using Rexx:
This is not a directory.
[C:\]
Rexx evaluates a literal string--a string enclosed in matching quotation marks--exactly as it is. To ensure
that a symbol in a command is not evaluated as a variable, enclose it in matching quotation marks as
follows:
extension = "BAK"
72
Chapter 7. Commands
"delete *."||extension
option = "/w"
"dir"||option
For environment specify the destination of the command. To address the Windows environment, use the
symbol CMD. For expression, specify an expression that results in a string that Rexx passes to the
environment. Here are some examples:
Notice that the ADDRESS instruction lets a single Rexx program issue commands to two or more
environments.
/* GETRC.CMD report */
"TYPE nosuch.fil"
say "the return code is" RC
73
Chapter 7. Commands
The special variable RC can be used in expressions like any other variable. In the next example, an error
message is displayed when the TYPE command returns a nonzero value in RC:
This program tells you only that the system could not find a nonexistent file.
A system error does not stop a Rexx program. Without some provision to stop the program, in this case a
trap, Rexx continues running. You might have to press the Ctrl+Break key combination to stop
processing. Rexx includes the following instructions for trapping and controlling system errors:
• CALL ON ERROR
• CALL ON FAILURE
• SIGNAL ON ERROR
• SIGNAL ON FAILURE
• Are easier to read because you can confine error-trapping to a single, common routine
74
Chapter 7. Commands
• Are more flexible because they can respond to errors by clause (SIGL), by return code (RC), or by
other information (CONDITION method or built-in function)
• Can catch problems and react to them before the environment issues an error message
• Are easier to correct because you can turn the traps on and off (SIGNAL OFF and CALL OFF)
For other conditions that can be detected using SIGNAL ON and CALL ON, see the Open Object Rexx:
Reference.
The SIGNAL ON instruction initiates an exit subroutine that ends the program. The CALL ON
instruction initiates a subroutine that returns processing to the clause immediately following the CALL
ON instruction. You use CALL ON to recover from a command error or failure.
The command conditions that can be trapped are:
ERROR
Detects any nonzero error code the default environment issues as the result of a Rexx command.
FAILURE
Detects a severe error, preventing the system from processing the command.
A failure, in this sense, is a particular category of error. If you use SIGNAL ON or CALL ON to set a
trap only for ERROR conditions, then it traps failures as well as other errors. If you also specify a
FAILURE condition, then the ERROR trap ignores failures.
With both the SIGNAL and the CALL instructions, you can specify the name of the trap routine. Add a
NAME keyword followed by the name of the subroutine. If you do not specify the name of the trap
routine, Rexx uses the value of condition as the name (Rexx looks for the label ERROR:, FAILURE:,
and so on).
For more information about other conditions that can be trapped, see the Open Object Rexx: Reference.
75
Chapter 7. Commands
76
Chapter 7. Commands
77
Chapter 7. Commands
78
Chapter 8. Input and Output
Object Rexx supports a stream I/O model. In the stream model, your program reads data from various
devices (such as hard disks, CD-ROMs, and keyboards) as a continuous stream of characters. Your
program also writes data as a continuous stream of characters.
In the stream model, a text file is represented as a stream of characters with special new-line characters
marking the end of each line of text in the stream. A binary file is a stream of characters without an
inherent line structure. Rexx lets you read streams as lines or as characters.
To support the stream model, Object Rexx includes a Stream class and many methods to use on stream
objects. To input or output data, you first create an instance of the Stream class that represents the device
or file you want to use. For example, the following clause creates a stream object for the file
C:\CONFIG.SYS:
Then you send the stream object messages that are appropriate for the device or data. CONFIG.SYS is a
text file, so you would normally use methods that read or write data as lines. Some of these methods are
LINES, LINEIN, and LINEOUT.
If the stream represents a binary file (such as a WAV, GIF, TIF, AVI, or EXE file), you can use methods
that read and write data as characters. Some of these methods are CHARS, CHARIN, and CHAROUT.
The Stream class includes other methods for opening and closing streams, flushing buffers, seeking,
retrieving stream status, and other input/output operations.
Many of the methods of the Stream class are also available as Rexx built-in functions. Although you can
use the functions, it is preferable to use the Stream class.
Note: In any case, do not mix functions and methods on the same stream to avoid unpredictable
results.
79
Chapter 8. Input and Output
on methods such as LINEIN, LINEOUT, CHARIN, and CHAROUT. Rexx also provides SEEK and
POSITION methods for setting the read and write positions.
COUNT uses the String method WORDS to count the words, so COUNT actually counts
blank-delimited tokens:
To read a file, COUNT first creates a stream object for the file by sending the NEW message to the
Stream class. The file name (with or without a path) is specified as an argument on the NEW method.
Within the DO loop, COUNT reads the lines of the file by sending LINEIN messages to the stream
object (pointed to by the variable File). The first LINEIN message causes Rexx to open the file (the
NEW method does not open the file). LINEIN, by default, reads one line from the file, starting at the
current read position.
Rexx returns only the text of the line to your program, but no new-line characters.
The DO loop is controlled by the expression "file~lines<>0". The LINES method returns the number of
lines remaining to be read in the file, so Rexx processes the loop until no lines remain to be read.
In the COUNT program, the LINEIN request forces Rexx to open the file, but you can also open the file
yourself using the OPEN method of the Stream class. By using the OPEN method, you control the mode
in which Rexx opens the file. When Rexx implicitly opens a file because of a LINEIN request, it tries to
open the file for both reading and writing. If that fails, it opens the file for reading. To ensure that the file
is opened only for reading, you can modify COUNT as follows:
80
Chapter 8. Input and Output
The CLOSE method, used near the end of the previous example, closes the file. A CLOSE is not
required. Rexx closes the stream for you when the program ends. However, it is a good idea to CLOSE
streams to make the resource available for other uses.
81
Chapter 8. Input and Output
You do not reduce file I/O by using specific line numbers. Because text files do not have a specific record
length, Rexx must read through the file counting line-end characters to find the line you want.
In TODO, a text string is provided as the only argument on LINEOUT. Rexx writes the line of text to the
file and then writes a new-line character. You do not have to provide a new-line character in the string to
be written.
If you want to overwrite a file, specify a line number as a second argument to position the write pointer:
Rexx does not prevent you from overwriting existing new-line characters in the file. Consequently, if you
want to replace a line of the file without overlaying the following lines, the line you write must have the
same length as the line you are replacing. Writing a line that is shorter than an existing line leaves part of
the old line in the file.
Also, positioning the write pointer to line 1 does not replace the file. Rexx starts writing over the existing
data starting at line 1, but if you happen to write fewer bytes than previously existed in the file, your data
is followed by the remainder of the old file.
To replace a file, use the OPEN method with WRITE REPLACE or BOTH REPLACE as an argument.
In the following example, a file named TEMP.DAT is replaced with a random number of lines.
TEMP.DAT is then read and displayed. You can run the example repeatedly to verify that TEMP.DAT is
replaced on each run.
82
Chapter 8. Input and Output
/*
Now read and display the file. The read pointer is already at the
beginning of the file. MAKEARRAY reads from the read position to
the end of the file and returns an array object containing the
lines.
*/
filedata=testfile~makearray("line")
do i over filedata
say i
end
testfile~close
The REPFILE example also demonstrates that Rexx maintains separate read and write pointers to a
stream. The read pointer is still at the beginning of the file while the write pointer is at the end of it.
The CHARIN method returns a string of characters from the stream, which in this case is CHORD.WAV.
CHARIN accepts two optional arguments. If no arguments are specified, CHARIN reads one character
from the current read position and then advances the read pointer.
The first argument is a start position for reading the file. In the example, 1 is specified so that CHARIN
begins reading with the first character of the file. Omitting the first argument achieves the same result.
The second argument specifies how many characters are to be read. To read all the characters,
infile~chars was specified as the second argument. The CHARS method returns the number of
characters remaining to be read in the input stream receiving the message. CHARIN then returns all the
characters in the stream. CHORD.WAV has about 25000 characters.
83
Chapter 8. Input and Output
Some text-processing programs also write an end-of-file character (ASCII value 26) after the last line.
You can check for that character also when processing text files with character methods. The following
program shows how to handle EOF characters in files.
84
Chapter 8. Input and Output
end /* do */
Rexx does not write end-of-file characters when it closes a file that has been opened for writing.
It is not recommended to use line methods to read binary files. Your binary file might not contain any
new-line characters. And, if it did, the characters probably are not meant to be interpreted as new-line
characters.
Because new-line characters are not added, the text displayed by the TYPE command is concatenated.
CHAROUT writes the string specified and advances the write pointer. If you want to position the write
pointer before writing the string, specify the starting position as a second argument:
In the example, the file is explicitly opened and closed. If you do not open the file, Rexx attempts to open
the file for both reading and writing. If you do not close the file, Rexx closes it when the procedure ends.
If you omit the CLOSE method in the example, the TYPE command does not type the file. To Windows,
the file does not exist yet because it is not closed yet.
85
Chapter 8. Input and Output
DIRECT opens a file for both reading and writing, which is indicated by the BOTH argument of the
OPEN method. The REPLACE argument of the OPEN method causes any existing DIRECT.DAT file to
be replaced.
The OPEN method also has the arguments BINARY and RECLENGTH, which are useful for direct file
access.
The BINARY argument opens the stream in binary mode, which means that line-end characters are
ignored. Binary mode is useful if you want to process binary data using line methods. It is easier to use
line methods for direct access. With line methods, you can search a position in a file using line numbers.
With character methods, you must calculate the character displacement of the file.
The RECLENGTH argument defines a record length of 50 for the file. It enables you to use line methods
in a binary-mode stream. Because Rexx now knows how long each record is, it can calculate the
displacement of the file for a given record number and read the record directly.
86
Chapter 8. Input and Output
After opening the file, DIRECT writes three records using LINEOUT. The records are not padded to 50
characters. Rexx handles that. Because the file is opened in binary mode, Rexx does not write line-end
characters at the end of each line. It only writes the strings one after another to the stream.
In Case 1, the LINEIN method is used to read the file. Because the file is open in binary mode, LINEIN
does not look for line-end characters to mark the end of a line. Instead, it relies on the record length that
you specify on open. In fact, if there were a carriage-return or line-feed sequence of the line, Rexx would
return those characters to your program.
Case 2 demonstrates how to read the file in random order. In this case, the RANDOM function is used to
choose a record to be retrieved. Then the desired record number is specified as an argument on LINEIN.
Note that records are numbered starting from 1, not from 0. Because the file is opened in binary mode,
Rexx does not look for line-end characters. It uses the RECLENGTH to determine where to read. The
LINEIN method can, therefore, retrieve a line directly, without having to scan through the file counting
line-end characters.
Case 3 proves that no line-end characters exist in the file. The CHARIN method reads the entire file.
SAY displays the returned string as one long string. If Rexx inserted line-end characters, each record
would be displayed on a separate line.
Case 4 shows how to read the binary mode file sequentially using CHARIN. But before reading the file,
the read pointer must be reset to the beginning of the file. (Case 3 leaves the read pointer at the end of the
file.) The SEEK method resets the read pointer to character 1, which is the beginning of the file. As with
lines, Rexx numbers characters starting with 1, not 0. Position 1 is the first character of the file.
By default, the number specified with SEEK refers to a character position. You can also search by line
number or by offsets. SEEK allows offsets from the current read or write position, or from the beginning
87
Chapter 8. Input and Output
or ending of the file. If you prefer typing longer method names, you can use POSITION as a synonym
for SEEK.
In the loop of Case 4, the first argument on CHARIN is omitted. The first argument tells where to
position the read pointer. If it is omitted, Rexx automatically advances the read pointer based on the
number of characters you are reading.
Case 5 demonstrates how to read records in random order with CHARIN. In the loop, a random record
number is selected and assigned to variable lineno. This record number is then converted to a character
number, which can be used to specify the read position on CHARIN. Compare Case 5 with Case 2. In
Case 2, which uses line methods, it is not necessary to perform a calculation, you just request the record
you want.
Cases 6 and 7 write records in random order. Case 6 uses LINEOUT, while Case 7 uses CHAROUT.
Because the file is opened in binary mode, LINEOUT does not write line-end characters. You can write
over a line by specifying a line number. With CHAROUT, you need to calculate the character position of
the line to be replaced. Unlike LINEOUT, you need to ensure that the string being written with
CHAROUT is padded to the appropriate record length. Otherwise, part of the record being replaced
remains in the file.
Consequently, for random reading of files with fixed length records, line methods are often the better
choice. However, one limitation of the line methods is that you cannot use them to write sparse records.
That is, if a file already has 200 records, you can use LINEOUT to write record 201, but you cannot use
LINEOUT to write record 300. With CHAROUT, however, you can open a new file and start writing at
character position 5000 if you choose.
In the example, a stream object is created for the file even though it might not exist. This is acceptable
because the file is not opened when the stream object is created.
The QUERY method accepts one argument. To check for the existence of a file, you specify the string
"exists" as previously shown. If the file exists, QUERY returns the full-path specification of the stream
object. Otherwise, QUERY returns a null string.
88
Chapter 8. Input and Output
89
Chapter 8. Input and Output
Reading from STDIN using LINEIN is similar to reading with the PARSE PULL instruction:
Using character methods with STDIN and STDOUT gives you more control over the reading and writing
of line-end characters. In the following example, the prompting string is written to STDOUT using
CHAROUT. Because CHAROUT does not add any line-end characters to the stream, the display cursor
is positioned after the prompt string on the same line.
CHARIN is used to read the user’s response. The user’s keystrokes are not returned to your program
until the user presses the Enter key. In the example, a length of 10 is specified. If fewer characters than
the specified length are available, CHARIN waits until they become available. Otherwise, the characters
are returned to your program. CHARIN does not strip any carriage-return or line-feed characters before
returning the string to your program. You can observe this with INCHAR by typing several strings that
have less than ten characters and pressing Enter after each string:
[C:\]inchar
What is your name? John
Q.
Public
Hi John
Q.
Pu
90
Chapter 8. Input and Output
91
Chapter 8. Input and Output
92
Appendix A. Rexx Application Programming
Interfaces
This appendix describes how to interface applications to Rexx or extend the Rexx language by using
Rexx application programming interfaces (APIs). As used here, the term application refers to programs
written in languages other than Rexx. This is usually the C language. Conventions in this appendix are
based on the C language. Refer to a C programming reference manual if you need a better understanding
of these conventions.
The features described here let an application 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
are 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
are direct extensions of the Rexx language. An application can create functions that extend the
native Rexx function set. Functions can be general-purpose extensions or specific to an application.
System exits
are programmer-defined variations of the operating system. The application programmer can tailor
the Rexx interpreter behavior by replacing Rexx system requests.
Subcommand, function, and system exit handlers have similar coding, compilation, and packaging
characteristics.
In addition, applications can manipulate the variables in Rexx programs (see Variable Pool Interface),
and execute Rexx routines directly from memory (see Macrospace Interface).
• Rexx handlers must use the APIENTRY (_stdcall) linkage convention. Handler functions should be
declared with the appropriate type definition from the Rexx.H include file. Using C++, the functions
must be declared as extern C:
• RexxSubcomHandler
• RexxFunctionHandler
• RexxExitHandler
93
Appendix A. Rexx Application Programming Interfaces
• 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 system; any Rexx program can call them.
• Executable file handlers are local to the registering process; only a Rexx program running in the
same process as an executable module can call a handler packaged within that executable module.
A.2. RXSTRINGs
Many of the Rexx application programming 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:
typedef struct {
ULONG strlength; /* length of string */
PCH strptr; /* pointer to string */
} RXSTRING;
Notes:
1. The Rexx.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.
• If an RXSTRING has a value, the strptr field is not null. The RXSTRING macro
RXVALIDSTRING(string) returns TRUE.
• If an RXSTRING is the Rexx null string (""), the strptr field is not null and the strlength field is 0.
The RXSTRING macro RXZEROLENSTRING(string) returns TRUE.
• If an RXSTRING is empty, the field strptr is null. The RXSTRING macro
RXNULLSTRING(string) returns 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. You can use the C string library functions 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. You use the C string functions only when you do not expect
null characters in the RXSTRINGs, such as file names passed to external functions. The strlength
field in the RXSTRING does not include the terminating null character.
94
Appendix A. Rexx Application Programming Interfaces
4. On calls to subcommand and external functions handlers, as well as to some of the exit handlers, the
Rexx interpreter expects that an RXSTRING value is returned. The Rexx 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
GlobalAlloc(size). The strptr field must point to the new storage and the strlength must be set to
the string length. The Rexx interpreter returns the newly allocated storage to the system for the
handler routine.
A.3.3.1. Parameters
95
Appendix A. Rexx Application Programming Interfaces
Instore[0]
is an RXSTRING describing a memory buffer that contains the Rexx procedure source. The
source must be an exact image of a Rexx procedure disk file, complete with carriage returns,
line feeds, and end-of-file characters.
Instore[1]
is an RXSTRING containing the translated image of the Rexx procedure. If Instore[1] is
empty, the Rexx interpreter returns the translated image in Instore[1] when the Rexx procedure
finishes running. The translated image may be used in Instore[1] on subsequent RexxStart
calls.
If Instore[1] is not empty, the interpreter runs the translated image directly. The program
source provided in Instore[0] is used only if the Rexx procedure uses the SOURCELINE
built-in function. Instore[0] can be empty if SOURCELINE is not used. If Instore[0] is empty
and the procedure uses the SOURCELINE built-in function, SOURCELINE() returns no lines
and any attempt to access the source returns Error 40.
If Instore[1] is not empty, but does not contain a valid Rexx translated image, unpredictable
results can occur. The Rexx interpreter might be able to determine that the translated image is
incorrect and translate the source again.
Instore[1] is both an input and an output parameter.
96
Appendix A. Rexx Application Programming Interfaces
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 performs a
syntax check on the procedure source, but does not execute it and does not store any images.
The program calling RexxStart must release Instore[1] using RexxFreeMemory(ptr) when the
translated image is no longer needed.
Only the interpreter version that created the image can run the translated image. Therefore, neither
change the format of the translated image of a Rexx program, nor move a translated image to other
systems or save it for later use. You can, however, use the translated image several times during a
single application execution.
RXCOMMAND
The Rexx procedure is a system or application command. Rexx commands usually have a
single argument string. The Rexx PARSE SOURCE instruction returns COMMAND as the second
token.
RXSUBROUTINE
The Rexx procedure is a subroutine of another program. The subroutine can have several
arguments and does not need to return a result. The Rexx PARSE SOURCE instruction returns
SUBROUTINE as the second token.
RXFUNCTION
The Rexx procedure is a function called from another program. The subroutine can have
several arguments and must return a result. The Rexx PARSE SOURCE instruction returns
FUNCTION as the second token.
97
Appendix A. Rexx Application Programming Interfaces
The sysexit_name is the address of an ASCII exit handler name registered with
RexxRegisterExitExe or RexxRegisterExitDll. Sysexit_code is a code identifying the handler exit
type. See System Exit Interface for exit code definitions. An RXENDLST entry identifies the
system-exit list end. Exits must be null if exits are not used.
negative
Interpreter errors. See the Appendix in the Open Object Rexx: Reference for the list of Rexx errors.
0
No errors occurred. The Rexx procedure ran normally.
positive
A system return code that indicates problems finding or loading the interpreter. See the return codes
for the Windows functions LoadLibrary and GetProcAddress for details.
When a macrospace Rexx procedure (see Macrospace Interface) is not loaded in the macrospace, the
return code is -3 ("Program is unreadable").
A.3.3.3. Example
98
Appendix A. Rexx Application Programming Interfaces
MAKERXSTRING(argv[0], macro_argument,
strlen(macro_argument));
/* set up default return */
MAKERXSTRING(retstr, return_buffer, sizeof(return_buffer));
When RexxStart is executed within an external program (usually a C program), it runs synchronously
with the main Rexx activity (thread) that it started. That is, when the main activity terminates, RexxStart
returns, and the external program continues running.
To run RexxStart asynchronously, you can start several concurrent activities from the main activity using
START or REPLY (see Concurrency). RexxStart is still synchronous to the main activity, that is, it
returns when the main activity terminates, but it is asynchronous to the concurrent activities. If a
concurrent activity runs longer than the main activity, RexxStart returns when the main activity ends, but
the concurrent activity continues to run.
If, however, a concurrent activity is still running when the external program ends, the activity is
terminated. To ensure that all activities finish executing, use RexxWaitForTermination or a looped
RexxDidRexxTerminate in your external program after RexxStart. The use of RexxWaitForTermination
is recommended also for programs that are not expected to use concurrency.
The following example demonstrates how to call MyCMD.CMD from a Cobol program (Rexx is running
in the same process as the Cobol program).
PROCESS PGMNAME(MIXED)
* You need to specify Rexx.LIB when you link this program,
* for example on the COB2 command.
* Note that the name RexxStart, used later, is case-sensitive,
* and requires the PGMNAME(MIXED) compiler option.
*************************************************************
IDENTIFICATION DIVISION.
*************************************************************
PROGRAM-ID. ’CALLRexx’
AUTHOR. IBM VISUALAGE FOR COBOL.
*************************************************************
*NAME: CALLRexx ***
99
Appendix A. Rexx Application Programming Interfaces
* ***
*FUNCTION: CALL A Rexx PROCEDURE NAME XXXXXXXX, ***
* PASSING ARGUMENT AND GETTING RETURNED DATA. ***
* ***
*EXTERNAL SUBROUTINES: NONE ***
*COPY MEMBERS: NONE ***
* ***
*************************************************************
*************************************************************
ENVIRONMENT DIVISION.
*************************************************************
CONFIGURATION SECTION.
*************************************************************
DATA DIVISION.
*************************************************************
WORKING-STORAGE SECTION.
*************************************************************
* INTERNAL VARIABLES *
*************************************************************
01 WS-WORK-FIELDS.
05 WS-RESULT-AREA PIC X(255) VALUE SPACES.
05 WS-ARGUMENT-AREA PIC X(255) VALUE SPACES.
05 WS-PARM1 PIC X(50) VALUE ’55’.
05 WS-PARM2 PIC X(8) VALUE ’66’.
01 WS-RexxSTART-PARAMETERS.
05 WS-Rexx-ARGUMENT-COUNT PIC S9(9) VALUE +1 COMP-5.
05 WS-Rexx-ARGUMENT-LIST.
10 WS-ARG-LENGTH PIC 9(9) COMP-5.
10 WS-ARG-POINTER POINTER.
05 WS-Rexx-PROGRAM-NAME PIC X(255) VALUE LOW-VALUES.
05 WS-Rexx-ENV-NAME PIC X(20) VALUE LOW-VALUES.
05 WS-Rexx-RETURN-CODE PIC S9(9) VALUE 0 COMP-5.
05 WS-Rexx-RESULT.
10 WS-RESULT-LENGTH PIC 9(9) COMP-5.
10 WS-RESULT-POINTER POINTER.
05 WS-Rexx-INTERPRETER-RC PIC S9(9) COMP-5.
LINKAGE SECTION.
PROCEDURE DIVISION.
SET WS-ARG-POINTER TO ADDRESS OF WS-ARGUMENT-AREA.
MOVE LENGTH OF WS-ARGUMENT-AREA
TO WS-ARG-LENGTH.
STRING WS-PARM1 DELIMITED BY SPACE
’ ’ DELIMITED BY SIZE
WS-PARM2 DELIMITED BY SPACE
INTO WS-ARGUMENT-AREA
END-STRING.
100
Appendix A. Rexx Application Programming Interfaces
RexxWaitForTermination();
retc = RexxDidRexxTerminate();
101
Appendix A. Rexx Application Programming Interfaces
0
Activities are still running.
1
All activities have been terminated.
A.3.5.2. Example
while (!RexxDidRexxTerminate())
{
/* do your processing */
}
where:
102
Appendix A. Rexx Application Programming Interfaces
Command
is the command string created by Rexx.
command is a null-terminated RXSTRING containing the issued command.
Flags
is the subcommand completion status. The subcommand handler can indicate success, error, or
failure status. The subcommand handler can set Flags to one of the following values:
RXSUBCOM_OK
The subcommand completed normally. No errors occurred during subcommand processing and
the Rexx procedure continues 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 raises
an ERROR condition if SIGNAL ON ERROR or CALL ON ERROR traps have been created.
If TRACE ERRORS has been issued, Rexx traces 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 usually return
RXSUBCOM_FAILURE.
If the subcommand handler sets Flags to RXSUBCOM_FAILURE, the Rexx interpreter raises
a FAILURE condition if SIGNAL ON FAILURE or CALL ON FAILURE traps have been
created. If TRACE FAILURES has been issued, Rexx traces the command when the
subcommand handler returns.
Retstr
is the address of an RXSTRING for the return code. It is a character string return code that is
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 be
allocated with GlobalAlloc(size) if the return string is longer than the default RXSTRING. If the
subcommand handler sets Retstr to an empty RXSTRING (a null strptr), Rexx assigns the string 0
to RC.
A.4.1.1.1. Example
103
Appendix A. Rexx Application Programming Interfaces
...
A.4.2.1. RexxRegisterSubcomDll
RexxRegisterSubcomDll registers a subcommand handler that resides in a dynamic-link library routine.
104
Appendix A. Rexx Application Programming Interfaces
A.4.2.1.1. Parameters
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.
105
Appendix A. Rexx Application Programming Interfaces
A.4.2.1.3. Remarks
EntryPoint can only be a 32-bit routine.
A.4.2.2. RexxRegisterSubcomExe
RexxRegisterSubcomExe registers a subcommand handler that resides within the application code.
A.4.2.2.1. Parameters
106
Appendix A. Rexx Application Programming Interfaces
A.4.2.2.3. Remarks
If EnvName is the same as a subcommand handler already registered with RexxRegisterSubcomDll,
RexxRegisterSubcomExe returns RXSUBCOM_DUP. This is not an error condition. It means that
RexxRegisterSubcomExe has successfully registered the new subcommand handler.
A Rexx procedure can register dynamic-link library subcommand handlers with the RXSUBCOM
command. For example:
The RXSUBCOM command registers the Dialog Manager subcommand handler ISPCIR as routine
ISPCIR in the ISPCIR dynamic-link library.
A.4.2.2.4. Example
A.4.2.3. RexxDeregisterSubcom
RexxDeregisterSubcom deregisters a subcommand handler.
A.4.2.3.1. Parameters
107
Appendix A. Rexx Application Programming Interfaces
A.4.2.3.3. Remarks
The handler is removed from the active subcommand handler list.
A.4.2.4. RexxQuerySubcom
RexxQuerySubcom queries a subcommand handler and retrieves saved user information.
A.4.2.4.1. Parameters
108
Appendix A. Rexx Application Programming Interfaces
within the current process. If RexxQuerySubcom does not find a RexxRegisterSubcomExe handler,
it searches the RexxRegisterSubcomDll subcommand handler list.
A.4.2.4.3. Example
109
Appendix A. Rexx Application Programming Interfaces
where:
Name
is the address of an ASCII function name used to call the external function.
Argc
is the number of elements in the Argv array. Argv contains Argc RXSTRINGs.
Argv
is an array of null-terminated RXSTRINGs for the function arguments.
Queuename
is the name of the currently defined external Rexx data queue.
110
Appendix A. Rexx Application Programming Interfaces
Retstr
is the 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 special Rexx variable RESULT. When the Rexx program calls
an external function with a function call, Retstr is used directly within the Rexx expression.
The Rexx interpreter provides a default 256-byte RXSTRING in Retstr. A longer RXSTRING can
be allocated with GlobalAlloc(size) if the returned string is longer than 256 bytes. The Rexx
interpreter releases Retstr with GlobalFree(ptr) when the external function completes.
Returns
is an integer return code from the function. When the external function returns 0, the function
completed successfully. Retstr contains the return value. When the external function returns a
nonzero return code, the Rexx interpreter raises Rexx error 40, "Incorrect 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 empty
RXSTRING (null strptr). When an external function called as a function does not return a value, the
interpreter raises error 44, "Function or message did not return data". When an external function
called with the Rexx CALL instruction does not return a value, the Rexx interpreter drops
(unassigns) the special variable RESULT.
A.5.2.1. Example
ULONG APIENTRY 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 */
111
Appendix A. Rexx Application Programming Interfaces
A.5.3.1. RexxRegisterFunctionDll
RexxRegisterFunctionDll registers an external function that resides in a dynamic-link library routine.
A.5.3.1.1. Parameters
A.5.3.1.3. Remarks
EntryPoint can only be a 32-bit routine.
External functions that reside in a dynamic-link library routine must be exported. You can do this by
specifying a module-definition (.DEF) file that lists the external functions in the EXPORT section. You
must export these functions with both the mixed-case and the uppercase name. For example:
112
Appendix A. Rexx Application Programming Interfaces
EXPORTS
SYSMKDIR = SysMkDir
A Rexx procedure can register dynamic-link library-external functions with the RXFUNCADD built-in
function. For example:
RXFUNCADD registers the external function SysLoadFuncs as routine SysLoadFuncs in the RexxUTIL
dynamic-link library. SysLoadFuncs registers additional functions in RexxUTIL.DLL with
RexxRegisterFunctionDll. See the SysLoadFuncs routine below for a function registration example.
A.5.3.1.4. Example
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; /* Number of entries */
INT j; /* counter */
113
Appendix A. Rexx Application Programming Interfaces
A.5.3.2. RexxRegisterFunctionExe
RexxRegisterFunctionExe registers an external function that resides within the application code.
A.5.3.2.1. Parameters
A.5.3.3. RexxDeregisterFunction
RexxDeregisterFunction deregisters an external function.
retc = RexxDeregisterFunction(FuncName);
A.5.3.3.1. Parameters
114
Appendix A. Rexx Application Programming Interfaces
A.5.3.4. RexxQueryFunction
RexxQueryFunction queries the existence of a registered external function.
retc = RexxQueryFunction(FuncName);
A.5.3.4.1. Parameters
A.5.3.4.3. Remarks
RexxQueryFunction returns RXFUNC_OK only if the requested function is available to the current
process. If not, the RexxQueryFunction searches the external RexxRegisterFunctionDll function list.
115
Appendix A. Rexx Application Programming Interfaces
where:
ExitNumber
is the major function code defining the type of exit call.
Subfunction
is the subfunction code defining the exit event for the call.
ParmBlock
is a pointer to the exit parameter list.
The exit parameter list contains exit-specific information. See the exit descriptions following the
parameter list formats.
Note: Some exit subfunctions do not have parameters. ParmBlock is set to null for exit
subfunctions without parameters.
RXEXIT_HANDLED
The exit handler processed the exit subfunction and updated the subfunction parameter list as
required. The Rexx interpreter continues with processing as usual.
RXEXIT_NOT_HANDLED
The exit handler did not process the exit subfunction. The Rexx interpreter processes the
subfunction as if the exit handler were 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, one of the following happens:
• When the exit handler returns RXEXIT_NOT_HANDLED for an RXSIOSAY subfunction, the Rexx
interpreter writes the output line to STDOUT.
116
Appendix A. Rexx Application Programming Interfaces
• When the exit handler returns RXEXIT_HANDLED for an RXSIOSAY subfunction, the Rexx
interpreter assumes the exit handler has handled all required output. The interpreter does not write the
output line to STDOUT.
• When the exit handler returns RXEXIT_RAISE_ERROR for an RXSIOSAY subfunction, the
interpreter raises Rexx error 48, "Failure in system service".
typedef struct {
PSZ sysexit_name; /* name of exit handler */
LONG sysexit_code; /* system exit function code */
} RXSYSEXIT;
The Rexx interpreter calls the registered exit handler named in sysexit_name for all of the sysexit_code
subfunctions.
A.6.1.3.1. Example
...
{
WORKAREARECORD *user_info[2]; /* saved user information */
RXSYSEXIT exit_list[2]; /* system exit list */
117
Appendix A. Rexx Application Programming Interfaces
exit_list[1].sysexit_code = RXENDLST;
RXFNC
External function call exit.
RXFNCCAL
Call an external function.
118
Appendix A. Rexx Application Programming Interfaces
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 in the external data queue.
RXMSQSIZ
Return the number of lines in the external data queue.
RXMSQNAM
Set the 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 the 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 debugging.
RXHLT
Halt processing exit.
RXHLTTST
Test for a HALT condition.
119
Appendix A. Rexx Application Programming Interfaces
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.
A.6.2.1. RXFNC
Processes calls to external functions.
Note: The variable pool interface is fully enabled during calls to the RXFNC exit handler.
120
Appendix A. Rexx Application Programming Interfaces
RXFNCCAL
Processes calls to external functions.
• When called: When Rexx calls an external subroutine or function.
• Default action: Call the external routine using the usual external function search order.
• Exit action: Call the external routine, if possible.
• Continuation: If necessary, raise Rexx error 40 ("Incorrect call to routine"), 43 ("Routine not
found"), or 44 ("Function or message did not return data").
• Parameter list:
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 ;
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 you call the named external function with the
Rexx CALL instruction (rather than using a function call), the flag rxffsub is TRUE.
The exit handler can set rxfnc_flags to indicate whether the external function call was successful.
If neither rxfferr nor rxffnfnd is TRUE, the exit handler successfully called the external function.
The error flags are checked only when the exit handler handles the request.
The exit handler sets rxffnfnd to TRUE when the exit handler cannot locate the external function.
The interpreter raises Rexx error 43, "Routine not found". The exit handler sets rxfferr to TRUE
when the exit handler locates the external function, but the external function returned an error
return code. The Rexx interpreter raises error 40, "Incorrect call to routine."
The exit handler returns the external function result in the rxfnc_retc RXSTRING. The Rexx
interpreter raises error 44, "Function or method did not return data," when the external routine is
called as a function and the exit handler does not return a result. When the external routine is
called with the Rexx CALL instruction, a result is not required.
121
Appendix A. Rexx Application Programming Interfaces
A.6.2.2. RXCMD
Processes calls to subcommand handlers.
Note: The variable pool interface function is fully enabled during calls to the RXCMD exit handlers.
RXCMDHST
Calls a named subcommand handler.
• When called: When 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.
• Parameter list:
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 ==> */
/* executable file. */
RXSTRING rxcmd_command; /* The command string. */
RXSTRING rxcmd_retc; /* Pointer to return code */
/* buffer. User allocated. */
} RXCMDHST_PARM;
A.6.2.3. RXMSQ
External data queue exit.
122
Appendix A. Rexx Application Programming Interfaces
RXMSQPLL
Pulls 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 data queue that the exit handler provided.
• Parameter list:
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.
RXMSQPSH
Places a line in the external data queue.
• When called: When a Rexx PUSH instruction, QUEUE instruction, or LINEOUT built-in
function adds a line to the data queue.
• Default action: Add the line to the current Rexx data queue.
• Exit action: Add the line to the data queue that the exit handler provided.
• Parameter list:
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).
RXMSQSIZ
Returns 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 of the current Rexx data queue.
• Exit action: Return the size of the data queue that the exit handler provided.
123
Appendix A. Rexx Application Programming Interfaces
• Parameter list:
typedef struct {
ULONG rxmsq_size; /* Number of Lines in Queue */
} RXMSQSIZ_PARM;
RXMSQNAM
Sets 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 data queue that the exit handler provided.
• Parameter list:
typedef struct {
RXSTRING rxmsq_name; /* RXSTRING containing */
/* queue name. */
} RXMSQNAM_PARM;
A.6.2.4. RXSIO
Standard input and output.
Note: The PARSE LINEIN instruction and the LINEIN, LINEOUT, LINES, CHARIN, CHAROUT, and
CHARS built-in functions do not call the RXSIO exit handler.
RXSIOSAY
Writes a line to the standard output stream.
• When called: When the SAY instruction writes a line to the standard output stream.
• Default action: Write a line to the standard output stream (STDOUT).
• Exit action: Write a line to the output stream that the exit handler provided.
• Parameter list:
typedef struct {
RXSTRING rxsio_string; /* String to display. */
} RXSIOSAY_PARM;
124
Appendix A. Rexx Application Programming Interfaces
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.
RXSIOTRC
Writes 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 a line to the standard error stream (.ERROR).
• Exit action: Write a line to the error output stream that the exit handler provided.
• Parameter list:
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.
RXSIOTRD
Reads 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 standard input stream that the exit handler provided.
• Parameter list:
typedef struct {
RXSTRING rxsiotrd_retc; /* RXSTRING for output. */
} RXSIOTRD_PARM;
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 standard debug stream that the exit handler provided.
• Parameter list:
typedef struct {
RXSTRING rxsiodtr_retc; /* RXSTRING for output. */
125
Appendix A. Rexx Application Programming Interfaces
} RXSIODTR_PARM;
A.6.2.5. RXHLT
HALT condition processing.
Because the RXHLT exit handler is called after every Rexx instruction, enabling this exit slows Rexx
program execution. The RexxSetHalt function can halt a Rexx program without between-instruction
polling.
RXHLTTST
Tests the HALT indicator.
• When called: When the interpreter polls externally raises HALT conditions. The exit will be
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.
• Parameter list:
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 is raised in the Rexx program.
The Rexx program can retrieve the reason string using the CONDITION("D") built-in function.
RXHLTCLR
Clears the HALT condition.
• When called: When the interpreter has recognized and raised a HALT condition, to acknowledge
processing of the HALT condition.
• Default action: The interpreter resets the Cntrl-Break signal handlers.
• Exit action: Reset exit handler HALT state to FALSE.
• Parameters: None.
126
Appendix A. Rexx Application Programming Interfaces
A.6.2.6. RXTRC
Tests the external trace indicator.
Note: Because the RXTRC exit is called after every Rexx instruction, enabling this exit slows Rexx
procedure execution. The RexxSetTrace function can turn on Rexx tracing without the
between-instruction polling.
RXTRCTST
Tests the external trace indicator.
• When called: When the interpreter polls 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
the interactive Rexx debug mode using TRACE ?R level of tracing. When the exit handler
switches from TRUE to FALSE, the Rexx interpreter exits the interactive debug mode.
• Parameter list:
typedef struct {
struct {
unsigned rxftrace : 1; /* External trace setting */
} rxtrc_flags;
} RXTRCTST_PARM;
If the exit handler switches rxftrace to TRUE, Rexx switches on the interactive debug mode. If
the exit handler switches rxftrace to FALSE, Rexx switches off the interactive debug mode.
A.6.2.7. RXINI
Initialization processing. This exit is called as the last step of Rexx program initialization.
Note: The variable pool interface is fully enabled for this exit.
RXINIEXT
Initialization exit.
• 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:
127
Appendix A. Rexx Application Programming Interfaces
• Parameters: None.
A.6.2.8. RXTER
Termination processing.
The RXTER exit is called as the first step of Rexx program termination.
Note: The variable pool interface is fully enabled for this exit.
RXTEREXT
Termination exit.
• 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 the Rexx variable values.
• Parameters: None.
A.6.3.1. RexxRegisterExitDll
RexxRegisterExitDll registers an exit handler that resides in a dynamic-link library routine.
A.6.3.1.1. Parameters
128
Appendix A. Rexx Application Programming Interfaces
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.
A.6.3.1.3. Remarks
EntryPoint can be only a 32-bit routine.
129
Appendix A. Rexx Application Programming Interfaces
A.6.3.2. RexxRegisterExitExe
RexxRegisterExitExe registers an exit handler that resides within the application code.
A.6.3.2.1. Parameters
A.6.3.2.3. Remarks
If ExitName has the same name as a handler registered with RexxRegisterExitDll, RexxRegisterExitExe
returns RXEXIT_DUP, which means that the new exit handler has been properly registered.
A.6.3.2.4. Example
130
Appendix A. Rexx Application Programming Interfaces
A.6.3.3. RexxDeregisterExit
RexxDeregisterExit deregisters an exit handler.
A.6.3.3.1. Parameters
A.6.3.3.3. Remarks
The handler is removed from the exit handler list.
131
Appendix A. Rexx Application Programming Interfaces
A.6.3.4. RexxQueryExit
RexxQueryExit queries an exit handler and retrieves saved user information.
A.6.3.4.1. Parameters
A.6.3.4.3. Example
132
Appendix A. Rexx Application Programming Interfaces
133
Appendix A. Rexx Application Programming Interfaces
A.7.3.1. RexxVariablePool
RexxVariablePool accesses variables of a currently active Rexx procedure.
retc = RexxVariablePool(RequestBlockList);
A.7.3.1.1. Parameters
where:
shvnext
is the address of the next SHVBLOCK in the request list. shvnext is null for the last request block.
shvname
is an RXSTRING containing a Rexx variable name. shvname usage varies with the SHVBLOCK
request code:
134
Appendix A. Rexx Application Programming Interfaces
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 that the shared variable
request block accesses.
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 the
shvnamelen characters, the name is truncated and the RXSHV_TRUNC bit of shvret is set. On
return, shvname.strlength contains the length of the variable name; shvnamelen remains
unchanged.
If shvname is an empty RXSTRING (strptr is null), the Rexx interpreter allocates and returns
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 is not allocated for that
request block. The RexxVariablePool caller must release the storage with GlobalFree(ptr).
Note: The RexxVariablePool does not add a terminating null character to the variable
name.
shvvalue
An RXSTRING containing a Rexx variable value. The meaning of shvvalue varies with the
SHVBLOCK request code:
RXSHV_SET
RXSHV_SYSET
shvvalue is the value assigned to the Rexx variable in shvname. shvvaluelen contains the length
of the variable value.
RXSHV_FETCH
RXSHV_SYFET
RXSHV_PRIV
RXSHV_NEXT
shvvalue is a buffer that is used by the Rexx interpreter to return the value of the Rexx variable
shvname. shvvaluelen contains the length of the value buffer. On return, shvvalue.strlength is
set to the length of the returned value but shvvaluelen remains unchanged. If the variable value
135
Appendix A. Rexx Application Programming Interfaces
is longer than the shvvaluelen characters, the value is truncated and the RXSHV_TRUNC bit
of shvret is set. On return, shvvalue.strlength is set to the length of the returned value;
shvvaluelen remains unchanged.
If shvvalue is an empty RXSTRING (strptr is null), the Rexx interpreter allocates and returns
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 is not allocated for that
request block. The RexxVariablePool caller must release the storage with GlobalFree(ptr).
Note: The RexxVariablePool does not add a terminating null character to the variable
value.
RXSHV_DROPV
RXSHV_SYDRO
shvvalue is not used.
shvcode
The shared variable block request code. Valid request codes are:
RXSHV_SET
RXSHV_SYSET
Assign a new value to a Rexx procedure variable.
RXSHV_FETCH
RXSHV_SYFET
Retrieve the value of a Rexx procedure variable.
RXSHV_DROPV
RXSHV_SYDRO
Drop (unassign) a Rexx procedure variable.
RXSHV_PRIV
Fetch the private information of the Rexx procedure. The following information items can be
retrieved by name:
PARM
The number of arguments supplied to the Rexx procedure. The number is formatted as a
character string.
136
Appendix A. Rexx Application Programming Interfaces
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 is
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 the next variable, excluding variables hidden by PROCEDURE instructions. The
variables are not returned in any specified order.
The Rexx interpreter maintains an internal pointer to its list of variables. The variable pointer is
reset to the first Rexx variable whenever:
shvret
The 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 without error (all flag bits are FALSE).
RXSHV_NEWV
The named variable was uninitialized at the time of the call.
RXSHV_LVAR
No more variables are available for an RXSHV_NEXTV operation.
137
Appendix A. Rexx Application Programming Interfaces
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.
The Rexx interpreter processes each request block in the order provided. RexxVariablePool returns to the
caller after the last block is processed or a severe error occurred (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 codes are returned in the shared variable
request blocks.
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 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 when the call was issued.
A.7.3.1.3. Example
/*********************************************************************/
/* */
/* SetRexxVariable - Set the value of a Rexx variable */
/* */
/*********************************************************************/
INT SetRexxVariable(
PSZ name, /* Rexx variable to set */
PSZ value) /* value to assign */
138
Appendix A. Rexx Application Programming Interfaces
{
SHVBLOCK block; /* variable pool control block*/
where:
size
is the number of bytes of requested memory.
Return Codes
Returns a pointer to the newly allocated block of memory, or NULL if no memory could be allocated.
where:
139
Appendix A. Rexx Application Programming Interfaces
MemoryBlock
is a void pointer to the block of memory allocated by the Object REXX interpreter, or allocated by a
previous call to RexxAllocateMemory().
Return Codes
RexxFreeMemory() always returns 0.
A.9.1.1. RexxCreateQueue
RexxCreateQueue creates a new (empty) queue.
A.9.1.1.1. Parameters
140
Appendix A. Rexx Application Programming Interfaces
A.9.1.1.3. Remarks
Queue names must conform to the same syntax rules as Rexx variable names. Lowercase characters in
queue names are translated to uppercase.
The queue name must be a valid Rexx symbol. However, there is no connection between queue names
and variable names. A program can have a variable and a queue with the same name.
A.9.1.2. RexxDeleteQueue
RexxDeleteQueue deletes a queue.
retc = RexxDeleteQueue(QueueName);
A.9.1.2.1. Parameters
141
Appendix A. Rexx Application Programming Interfaces
A.9.1.2.3. Remarks
If a queue is busy (for example, wait is active), it is not deleted.
A.9.1.3. RexxQueryQueue
RexxQueryQueue returns the number of entries remaining in the named queue.
A.9.1.3.1. Parameters
A.9.1.4. RexxAddQueue
RexxAddQueue adds an entry to a queue.
A.9.1.4.1. Parameters
142
Appendix A. Rexx Application Programming Interfaces
A.9.1.5. RexxPullQueue
RexxPullQueue removes the top entry from the queue and returns it to the caller.
A.9.1.5.1. Parameters
143
Appendix A. Rexx Application Programming Interfaces
A.9.1.5.3. Remarks
The caller is responsible for freeing the returned memory that DataBuf points to.
A.10.1.1. RexxSetHalt
RexxSetHalt raises a HALT condition in a running Rexx program.
A.10.1.1.1. Parameters
144
Appendix A. Rexx Application Programming Interfaces
A.10.1.1.3. Remarks
This call is not processed if the target Rexx program is running with the RXHLT exit enabled.
A.10.1.2. RexxSetTrace
RexxSetTrace turns on the interactive debug mode for a Rexx procedure.
A.10.1.2.1. Parameters
A.10.1.2.3. Remarks
A RexxSetTrace call is not processed if the Rexx procedure is using the RXTRC exit.
145
Appendix A. Rexx Application Programming Interfaces
A.10.1.3. RexxResetTrace
RexxResetTrace turns off the interactive debug mode for a Rexx procedure.
retc = RexxResetTrace(ProcessId,ThreadId);
A.10.1.3.1. Parameters
A.10.1.3.3. Remarks
• A RexxResetTrace call is not processed if the Rexx procedure uses the RXTRC exit.
• Interactive debugging is not turned off unless the interactive debug mode was originally started with
RexxSetTrace.
146
Appendix A. Rexx Application Programming Interfaces
Procedures in the macrospace are stored without source code information and therefore cannot be traced.
Rexx procedures in the macrospace can be saved to a disk file. A saved macrospace file can be reloaded
with a single call to RexxLoadMacroSpace. An application, such as an editor, can create its own library
of frequently-used functions and load the entire library into memory for fast access. Several macrospace
libraries can be created and loaded.
Note: The TRACE keyword instruction cannot be used in the Rexx macrospace. Since macrospace
uses the tokenized format, it is not possible to get the source code from macrospace to trace a
function.
RXMACRO_SEARCH_BEFORE
The Rexx interpreter locates a function registered with RXMACRO_SEARCH_BEFORE before
any registered functions or external Rexx files.
RXMACRO_SEARCH_AFTER
The Rexx interpreter locates a function registered with RXMACRO_SEARCH_AFTER after any
registered functions or external Rexx files.
A.11.3.1. RexxAddMacro
RexxAddMacro loads a Rexx procedure into the macrospace.
A.11.3.1.1. Parameters
147
Appendix A. Rexx Application Programming Interfaces
RXMACRO_SEARCH_BEFORE
The Rexx interpreter locates the function before any registered functions or external Rexx files.
RXMACRO_SEARCH_AFTER
The Rexx interpreter locates the function after any registered functions or external Rexx files.
A.11.3.2. RexxDropMacro
RexxDropMacro removes a Rexx procedure from the macrospace.
retc = RexxDropMacro(FuncName);
A.11.3.2.1. Parameter
148
Appendix A. Rexx Application Programming Interfaces
A.11.3.3. RexxClearMacroSpace
RexxClearMacroSpace removes all loaded Rexx procedures from the macrospace.
retc = RexxClearMacroSpace();
A.11.3.3.2. Remarks
RexxClearMacroSpace must be used with care. This function removes all functions from the
macrospace, including functions loaded by other processes.
A.11.3.4. RexxSaveMacroSpace
RexxSaveMacroSpace saves all or part of the macrospace Rexx procedures to a disk file.
A.11.3.4.1. Parameters
149
Appendix A. Rexx Application Programming Interfaces
A.11.3.4.3. Remarks
When FuncCount is 0 or FuncNames is null, RexxSaveMacroSpace saves all functions in the
macrospace.
Saved macrospace files can be used only with the same interpreter version that created the images. If
RexxLoadMacroSpace is called to load a saved macrospace and the release level or service level is
incorrect, RexxLoadMacroSpace fails. The Rexx procedures must then be reloaded individually from the
original source programs.
A.11.3.5. RexxLoadMacroSpace
RexxLoadMacroSpace loads all or part of the Rexx procedures from a saved macrospace file.
A.11.3.5.1. Parameters
150
Appendix A. Rexx Application Programming Interfaces
A.11.3.5.3. Remarks
When FuncCount is 0 or FuncNames is null, RexxLoadMacroSpace loads all Rexx procedures from the
saved file.
If a RexxLoadMacroSpace call replaces an existing macrospace Rexx procedure, the entire load request
is discarded and the macrospace remains unchanged.
A.11.3.6. RexxQueryMacro
RexxQueryMacro searches the macrospace for a specified function.
A.11.3.6.1. Parameters
151
Appendix A. Rexx Application Programming Interfaces
A.11.3.7. RexxReorderMacro
RexxReorderMacro changes the search order position of a loaded macrospace function.
A.11.3.7.1. Parameters
RXMACRO_SEARCH_BEFORE
The Rexx interpreter locates the function before any registered functions or external Rexx files.
RXMACRO_SEARCH_AFTER
The Rexx interpreter locates the function after any registered functions or external Rexx files.
A.12.1. Concurrency
Object Rexx is a multithreaded program. (See Concurrency, in Object Rexx for Windows: Reference.)
152
Appendix A. Rexx Application Programming Interfaces
The closest Windows model is the free-threaded model for dealing with multiple threads. The WSH
controls are typically apartment-threaded. Therefore, since Object Rexx does not restrict its callers to any
particular thread, and it passes on any exterior calls in the thread context in which it was received, then
for all practical purposes it should be treated as an apartment-threaded program.
• IUnknown
• IActiveScriptParse
• IActiveScriptError
• IActiveScriptParseProcedure
• IObjectSafety
While Object Rexx has code for all of the methods of an interface that it supports, all methods may not
be implemented. The methods that are not implemented will return E_NOTIMPL.
The following interfaces are supported:
• IDispatch
• GetIDsOfNames
• Invoke
• IDispatchEx
• GetDispID - but does not support dynamic creation of properties or methods.
• InvokeEx - but does not support dynamic creation of properties or methods.
• GetMemberName
• GetNextDispID
• IActiveScript
• SetScriptSite
• GetScriptState
• SetScriptState
• Close
• AddNamedItem
153
Appendix A. Rexx Application Programming Interfaces
• AddTypeLib
• GetScriptDispatch
A.12.2.3. DCOM
Object Rexx does not support DCOM.
154
Appendix B. Object Rexx Runtime
Object Rexx Runtime is part of the Open Object Rexx distribution. It is a software package that can be
distributed together with your own Rexx applications so that they can run on your client’s computer. The
precondition for using Object Rexx Runtime is that the Rexx scripts have to be tokenized; for further
information on tokenizing, see "Distributing Programs without Source" below. The Object Rexx
Scripting Engine for Windows Scripting Host (WSH) is not available.
Object Rexx also allows you to create tokenized programs that can be used to protect your program
source code.
Note: The installed version must be of the same version number as the one that created the scripts
(or higher) to be able to run the scripts.
1. The SOURCELINE built-in function returns 0 for the number of lines in the program and raises an
error for all attempts to retrieve a line.
2. A sourceless program may not be traced. The TRACE instruction runs without error, but no tracing
of instruction lines, expression results, or intermediate expression values occurs.
The syntax of the REXXC utility is:
>>-RexxC--inputfile--+------------+--+------+------------------><
+-outputfile-+ +- -s -+
If you specify the outputfile, the language processor processes the inputfile and writes the executable
version of the program to the outputfile. If the outputfile already exists, it is replaced.
If the language processor detects a syntax error while processing the program, it reports the error and
stops processing without creating a new output file. If you omit the outputfile, the language processor
performs a syntax check on the program without writing the executable version to a file.
You can use the /s option to suppress the display of the information about the interpreter used.
Note: You can use the in-storage capabilities of the RexxStart programming interface to process the
file image of the output file.
With version 2.1, the tokenized form has changed. All Open Object Rexx for Windows editions contain a
utility called RxMigrate that can be used to change old tokenized forms to the new one. The
recommended procedure is to create a new tokenized file from the original source with the new version
155
Appendix B. Object Rexx Runtime
of Open Object Rexx. However, if the source code is no longer available, RxMigrate can be used to
convert the old tokenized file. The syntax of the RxMigrate utility is:
>>-RxMigrate--inputfile--outputfile----------------------------><
156
Appendix C. Sample Rexx Programs
Rexx supplies the following sample programs as .REX files.
CCREPLY.REX
A concurrent programming example.
This program demonstrates how to use reply to run two methods at the same time.
COMPLEX.REX
A complex number class.
This program demonstrates how to create a complex number class using the ::CLASS and
::METHOD directives. An example of subclassing the complex number class (the Vector subclass)
is also shown. Finally, the Stringlike class demonstrates the use of a mixin to provide to the complex
number class with some string behavior.
DESKICON.REX
A WindowsProgramManager class example.
This sample uses the method AddDesktopIcon of the WindowsProgramManager class to create a
shortcut to a program or an application on the Windows desktop.
DESKTOP.REX
This program demonstrates how you could use the WindowsProgramManager class to manipulate
program groups and program items.
DRIVES.REX
A sample use of the Sys... functions.
This program displays information about drives using the utility functions SysDriveMap,
SysDriveInfo, SysFileSystemType, and SysBootDrive.
EVENTLOG.REX
A sample use of the WindowsEventLog class.
This sample demonstrates how to read from and write to the Windows event log using the methods
of the WindowsEventLog class.
157
Appendix C. Sample Rexx Programs
FACTOR.REX
A factorial program.
This program demonstrates a way to define a factorial class using the subclass method and the
.methods environment symbol.
GREPLY.REX
An example contrasting the GUARDED and UNGUARDED methods.
This program demonstrates the difference between GUARDED and UNGUARDED methods with
respect to their use of the object variable pool.
GUESS.REX
An animal guessing game.
This sample creates a simple node class and uses it to create a logic tree. The logic tree is filled in
by playing a simple guessing game.
KTGUARD.REX
A GUARD instruction example.
This program demonstrates the use of the START method and the GUARD instruction to control the
running of several programs. In this sample, the programs are controlled by one "guarded" variable.
MONTH.REX
An example that displays the days of the month January 1994.
This version demonstrates the use of arrays to replace stems.
OLE\APPS\SAMP01.REX
Starts Internet Explorer and shows the RexxLA homepage. After 10 seconds the RexxLA news
page is displayed.
OLE\APPS\SAMP02.REX
Shows some features of the Windows Scripting Host Shell Object:
• Query environment string
• List special folders
• Create a shortcut on the desktop
158
Appendix C. Sample Rexx Programs
OLE\APPS\SAMP03.REX
Shows some features of the Windows Scripting Host Network object:
• Query computer name, user name
• List network connections for drives and printers
OLE\APPS\SAMP04.REX
Creates a mail message in Lotus Notes® and sends it to a number of recipients automatically.
OLE\APPS\SAMP05.REX
Creates a new document in WordPro 97, enters some text with different attributes, and finally saves
and prints the document.
OLE\APPS\SAMP06.REX
Creates a new document in WordPro 97 with a provided Smartmaster. Fills in some "Click here"
fields with data prompted by the program or queried from the system. Finally the document is saved
to the directory in which this Rexx program is located and is sent to the printer.
OLE\APPS\SAMP07.REX
Creates a new spreadsheet in Lotus 1-2-3® and fills in a table with fictional revenue numbers. The
table also contains a calculated field and different styles. A second sheet is added with a 3D chart
displaying the revenue data.
OLE\APPS\SAMP08.REX
Creates a Microsoft Word document, enters some text, and saves it. The program then loads the
document again and modifies it.
OLE\APPS\SAMP09.REX
Creates a Microsoft Excel sheet, enters some data, and saves it.
OLE\APPS\SAMP10.REX
Uses the Windows Script Host FileSystemObject to obtain information about the drives of the
system.
OLE\APPS\SAMP11.REX
Gets the stock price from the RexxLA internet page with Microsoft Internet Explorer, and stores it
in a Rexx variable.
OLE\APPS\SAMP12.REX
Demonstrates the use of events with Microsoft Internet Explorer:
• Navigate to the RexxLA homepage and disallow the changing of the URL to a page not in that
"address space".
159
Appendix C. Sample Rexx Programs
OLE\APPS\SAMP13.REX
Demonstrates the use of events with Microsoft Internet Explorer:
• Search for the string "Rexx" on the RexxLA Web page, and go randomly to one of the found sites.
OLE\OLEINFO\OLEINFO.REX
This application is a "small" browser for OLE objects.
OLE\ADSI\ADSI1.REX
Retrieves information about a computer with ADSI.
OLE\ADSI\ADSI2.REX
Gets a user’s full name and changes it.
OLE\ADSI\ADSI3.REX
Shows the use of ADSI containers.
OLE\ADSI\ADSI4.REX
Shows the use of filters with ADSI collections.
OLE\ADSI\ADSI5.REX
Displays namespaces and domains.
OLE\ADSI\ADSI6.REX
Enables you to inspect the properties of an object.
OLE\ADSI\ADSI7.REX
Creates a group, and places several users in it.
OLE\ADSI\ADSI8.REX
Removes the users and the group that were created in sample ADSI7.REX.
OLE\METHINFO\MAIN.REX
This application demonstrates the use of the GetKnownMethods method.
OLE\WMI\ACCOUNTS.REX
This is a demo application for displaying all the accounts of the windows system with WMI. It also
shows how to display all the properties of a WMI object in general.
OLE\WMI\SERVICES.REX
This application demonstrates how to list, start, stop, pause, or resume windows services with WMI.
OLE\WMI\PROCESS.REX
This application displays by means of WMI the processes of a windows system that are running.
160
Appendix C. Sample Rexx Programs
OLE\WMI\OSINFO.REX
This sample script uses a Windows Management Instrumentation (WMI) object
("Win32_OperatingSystem") to obtain information about the installed operating system(s).
OLE\WMI\SYSINFO\SYSINFO.REX
This is a demo application for inspecting some system properties using WMI.
PHILFORK.REX
Sample for concurrency with command line output.
PIPE.REX
A pipeline implementation.
This program demonstrates the use of the ::CLASS and ::METHOD directives to create a simple
implementation of a CMS-like pipeline function.
QDATE.REX
An example that types or pushes today’s date and moon phase, in English date format.
QTIME.REX
An example that lays or stacks time in English time format, and also chimes.
REGISTRY.REX
This program demonstrates how you could use the WindowsRegistry class to work with the
Windows registry.
SEMCLS.REX
An Object Rexx semaphore class.
This file implements a semaphore class in Object Rexx.
STACK.REX
A stack class.
This program demonstrates how to implement a stack class using the ::CLASS and ::METHOD
directives. Also included is a short example of the use of a stack.
USECOMP.REX
A simple demonstration of the complex number class.
This program demonstrates the use of the ::REQUIRES directive, using the complex number class
included in the samples.
161
Appendix C. Sample Rexx Programs
USEPIPE.REX
Sample uses of the pipe implementation in PIPE.REX.
This program demonstrates how you could use the pipes implemented in the pipe sample.
162
Appendix D. Notices
Any reference to a non-open source product, program, or service is not intended to state or imply that
only non-open source product, program, or service may be used. Any functionally equivalent product,
program, or service that does not infringe any RexxLA intellectual property right may be used instead.
However, it is the user’s responsibility to evaluate and verify the operation of any non-open source
product, program, or service.
Any performance data contained herein was determined in a controlled environment. Therefore, the
results obtained in other operating environments may vary significantly. Some measurements may have
been made on development-level systems and there is no guarantee that these measurements will be the
same on generally available systems. Furthermore, some measurement may have been estimated through
extrapolation. Actual results may vary. Users of this document should verify the applicable data for their
specific environment.
Information concerning non-open source products was obtained from the suppliers of those products,
their published announcements or other publicly available sources. RexxLA has not tested those products
and cannot confirm the accuracy of performance, compatibility or any other claims related to
non-RexxLA packages. Questions on the capabilities of non-RexxLA packages should be addressed to
the suppliers of those products.
All statements regarding RexxLA’s future direction or intent are subject to change or withdrawal without
notice, and represent goals and objectives only.
This information contains examples of data and reports used in daily business operations. To illustrate
them as completely as possible, the examples include the names of individuals, companies, brands, and
products. All of these names are fictitious and any similarity to the names and addresses used by an
actual business enterprise is entirely coincidental.
D.1. Trademarks
The following terms are trademarks of the IBM Corporation in the United States, other countries, or both:
1-2-3
AIX
IBM
Lotus
Microsoft
OS/2
S/390
VisualAge
Windows NT
Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the Unites States, other
countries, or both.
Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in
the United States, other countries, or both.
Intel, Intel Inside (logos), MMX and Pentium are trademarks of Intel Corporation in the United States,
other countries, or both.
UNIX is a registered trademark of The Open Group in the United States and other countries.
163
Appendix D. Notices
Linux is a trademark of Linus Torvalds in the United States, other countries, or both.
Other company, product, or service names may be trademarks or service marks of others.
The source code for this document is maintained in DocBook SGML/XML format.
164
Appendix E. Common Public License Version
1.0
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON
PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE
PROGRAM CONSTITUTES RECIPIENT’S ACCEPTANCE OF THIS AGREEMENT.
E.1. Definitions
"Contribution" means:
1. in the case of the initial Contributor, the initial code and documentation distributed under this
Agreement, and
2. in the case of each subsequent Contributor:
a. changes to the Program, and
b. additions to the Program;
where such changes and/or additions to the Program originate from and are distributed by that particular
Contributor. A Contribution ’originates’ from a Contributor if it was added to the Program by such
Contributor itself or anyone acting on such Contributor’s behalf. Contributions do not include additions
to the Program which: (i) are separate modules of software distributed in conjunction with the Program
under their own license agreement, and (ii) are not derivative works of the Program.
"Contributor" means any person or entity that distributes the Program.
"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by
the use or sale of its Contribution alone or when combined with the Program.
"Program" means the Contributions distributed in accordance with this Agreement.
"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
1. Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive,
worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly
display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and
such derivative works, in source code and object code form.
2. Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive,
worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import
and otherwise transfer the Contribution of such Contributor, if any, in source code and object code
form. This patent license shall apply to the combination of the Contribution and the Program if, at
the time the Contribution is added by the Contributor, such addition of the Contribution causes such
165
Appendix E. Common Public License Version 1.0
combination to be covered by the Licensed Patents. The patent license shall not apply to any other
combinations which include the Contribution. No hardware per se is licensed hereunder.
3. Recipient understands that although each Contributor grants the licenses to its Contributions set
forth herein, no assurances are provided by any Contributor that the Program does not infringe the
patent or other intellectual property rights of any other entity. Each Contributor disclaims any
liability to Recipient for claims brought by any other entity based on infringement of intellectual
property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder,
each Recipient hereby assumes sole responsibility to secure any other intellectual property rights
needed, if any. For example, if a third party patent license is required to allow Recipient to distribute
the Program, it is Recipient’s responsibility to acquire that license before distributing the Program.
4. Each Contributor represents that to its knowledge it has sufficient copyright rights in its
Contribution, if any, to grant the copyright license set forth in this Agreement.
E.3. Requirements
A Contributor may choose to distribute the Program in object code form under its own license
agreement, provided that:
166
Appendix E. Common Public License Version 1.0
E.5. No Warranty
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED
ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of
using and distributing the Program and assumes all risks associated with its exercise of rights under this
Agreement, including but not limited to the risks and costs of program errors, compliance with applicable
laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
167
Appendix E. Common Public License Version 1.0
E.7. General
If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the
validity or enforceability of the remainder of the terms of this Agreement, and without further action by
the parties hereto, such provision shall be reformed to the minimum extent necessary to make such
provision valid and enforceable.
If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to
software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that
Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed.
In addition, if Recipient institutes patent litigation against any entity (including a cross-claim or
counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with
other software or hardware) infringes such Recipient’s patent(s), then such Recipient’s rights granted
under Section 2(b) shall terminate as of the date such litigation is filed.
All Recipient’s rights under this Agreement shall terminate if it fails to comply with any of the material
terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after
becoming aware of such noncompliance. If all Recipient’s rights under this Agreement terminate,
Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable.
However, Recipient’s obligations under this Agreement and any licenses granted by Recipient relating to
the Program shall continue and survive.
Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency
the Agreement is copyrighted and may only be modified in the following manner. The Agreement
Steward reserves the right to publish new versions (including revisions) of this Agreement from time to
time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the
initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a
suitable separate entity. Each new version of the Agreement will be given a distinguishing version
number. The Program (including Contributions) may always be distributed subject to the version of the
Agreement under which it was received. In addition, after a new version of the Agreement is published,
Contributor may elect to distribute the Program (including its Contributions) under the new version.
Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the
intellectual property of any Contributor under this Agreement, whether expressly, by implication,
estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
This Agreement is governed by the laws of the State of New York and the intellectual property laws of
the United States of America. No party to this Agreement will bring a legal action under this Agreement
more than one year after the cause of action arose. Each party waives its rights to a jury trial in any
resulting litigation.
168
Index RexxWaitForTermination, 101
macrospace interface, 146
RexxAddMacro, 147
RexxClearMacroSpace, 149
Symbols RexxDropMacro, 148
RexxLoadMacroSpace, 150
" (double quotation mark), 12 RexxQueryMacro, 151
’ (single quotation mark), 12 RexxReorderMacro, 152
, (comma), 11 RexxSaveMacroSpace, 149
. (period), 12 queue interface, 140
.NIL object, 55 RexxAddQueue, 142
\ (backslash), 15 RexxCreateQueue, 140
~ (tilde, or twiddle), 6, 24 RexxDeleteQueue, 141
RexxPullQueue, 143
RexxQueryQueue, 142
RXSTRING data structure, 94
A RXSTRING, 94
abstract classes, definition, 43 RXSYSEXIT, 97, 117
access to variables, prioritizing, 64 SHVBLOCK, 134
acquisition, 26 RXSYSEXIT data structure, 97
activities, 63 SHVBLOCK, 134
ADDRESS instruction, 67, 73 subcommand interface, 102
addressing environments by name, 73 RexxDeregisterSubcom, 107
apartment-threading and Windows Scripting RexxQuerySubcom, 108
Host, 152 RexxRegisterSubcomDll, 104
application environments, 74 RexxRegisterSubcomExe, 106
application programming interfaces system memory interface, 139
exit handler, 115 RexxAllocateMemory, 139
exit interface, 115 RexxFreeMemory, 139
RexxDeregisterExit, 131 variable pool interface, 133
RexxQueryExit, 132 RexxVariablePool, 134
RexxRegisterExitDll, 128 ARG instruction, 14
RexxRegisterExitExe, 130 arrays, reading streams into, 81
external function interface, 110 assignments, 13
RexxDeregisterFunction, 114
RexxQueryFunction, 115
RexxRegisterFunctionDll, 112
RexxRegisterFunctionExe, 114
B
halt and trace interface, 144 backslash (\), 15
RexxResetTrace, 146 binary files
RexxSetHalt, 144 closing, 85
RexxSetTrace, 145 direct acess, 85
handler definitions, 102 querying existence, 88
handler interface querying other information, 89
subcommand handler, 102 reading, 84
invoking the Rexx interpreter, 95 writing, 85
RexxDidRexxTerminate, 101 built-in objects, 55, 56
RexxStart, 95
169
C continuing a clause, 11
counting words in a file, 80
CALL command, Windows, 71 CPL, 165
CALL instruction, 19, 70, 74 creating classes, 37, 41
calling .CMD files, 70
calling the Rexx interpreter, 95
changing the search order for methods, 61
checking for the existence of a file, 88 D
class methods, 47
data
class scope, 58
abstraction, 27
classes, 5
encapsulation, 23
abstract, 43
modularizing, 21
Alarm class, 29
default search order for methods, 59
Class class, 29
devices, sending information to, 91
collection classes, 29
direct file access, 85
creating with directives, 37
directives, 37
creating with messages, 41
::CLASS, 37
definition, 25
::METHOD, 38
Message class, 29, 30
::REQUIRES, 39, 51
metaclass, 44
::REQUIRES example, 39
mixin, 43
::ROUTINE, 38
Monitor class, 29, 31
creating classes with, 37
object, 43
definition, 37
provided by Rexx, 29, 33
order of processing, 39
Stem class, 29, 31
sample program, 39, 40, 50
Stream class, 29, 31
DO instruction, 14
String class, 29, 31
double quotation mark ("), 12
subclasses, 27
superclasses, 27
Supplier class, 29, 31
clauses E
and instructions, 10
definition, 10 echoing commands, 69
separating, 11 encapsulation of data, 23
spanning nore than one line, 11 environment for scriptable applications, 67
using object in, 48 Environment objects, 55
closing files, 85 ERROR condition, 75
CMD files, calling, 70 example Rexx programs, included, 157
colection lasses, 29 EXIT instruction, 10
COM interfaces for Windows Scripting Host, exits, 115
153 EXPOSE instruction, 40, 51, 58
comma (,), 11 EXPOSE keyword, 20
commands, 67 external command exit, 122
Common Public License, 165 external function exit, 120
concurrency, 62 external function interface
concurrency and Windows Scripting Host, 152 description, 110
CONDITION built-in function, 74 interface functions, 112
condition traps, 74 returned results, 111
170
RexxDeregisterFunction, 114 instances methods, 26
RexxQueryFunction, 115 instructions
RexxRegisterFunctionDll, 112 ADDRESS, 67, 73
RexxRegisterFunctionExe, 114 ARG, 14
simple function, 111 CALL, 19, 70, 74
simple registration, 114 DO, 14
writing, 110 EXIT, 10
external HALT exit, 126 for program control (DO, IF, SELECT ...),
external I/O exit, 124 14
external queue exit, 122 IF, 14
external trace exit, 127 ITERATE, 18
PARSE, 14
PARSE ARG, 20
F PROCEDURE, 19
PULL, 10, 13
FAILURE condition, 75 RETURN, 19
functions SAY, 10
in expressions, 14 SELECT, 14
nesting, 14 SIGNAL ON, 74
Rexx built-in, 10 inter-object concurrency, 62
intra-object concurrency, 64
invoking the Rexx interpreter, 95
issuing Linux/Unix commands, 9
G issuing Windows commands, 9
GUARD instruction, 64 ITERATE instructions, 18
H L
host command exit, 122 License, Common Public, 165
License, Open Object Rexx, 165
line-end characters, 84
Linix commands, issuing, 9
I Local environment object, 56
I/O model, 79 local objects, 55
I/O, standard (keyboard, displays, and error locking a scope, 64
streams), 89
IF instruction, 14
information hiding, 23 M
inheritance, 27, 33
INIT instruction, 49, 50 macros
INIT method, 40 definition, 67
initialization exit, 127 environments for, 74
instance methods, 47 macrospace interface
instances, 5, 5 description, 146
definition, 27 RexxAddMacro, 147
uninitializing and deleting, 52 RexxClearMacroSpace, 149
171
RexxDropMacro, 148 P
RexxLoadMacroSpace, 150
RexxQueryMacro, 151 PARSE ARG instructions, 20
RexxReorderMacro, 152 PARSE instruction, 14
RexxSaveMacroSpace, 149 period (.), 12
MAKEARRAY method, using, 81 polymorphism, 25
message-send operator (~), 6, 24 prioritizing access to variables, 64
messages, 5, 5, 24 private methods, 62
creating classes with, 41 PROCEDURE instruction, 19
metaclasses, 32, 44 procedures, 18
method names, specifying, 59 programs
methods, 5 definition, 9
definition, 25 running, 9
instance, 26 writing, 11
private, 62 programs without source, 155
public, 62 public methods, 62
scope, 59 public objects, 55
search order for, 59 PULL instruction, 10, 14
selecting, 59
mixin classes, 43
model, stream I/O, 79
Q
modularizing data, 21
multiple clauses on a line, 11 querying a file, 89
multiple inheritance, 27 queue exit, 122
multithreading and Windows Scripting Host, queue interface
152 description, 140, 144
RexxAddQueue, 142
RexxCreateQueue, 140
N RexxDeleteQueue, 141
RexxPullQueue, 143
naming variables, 12 RexxQueryQueue, 142
Notices, 163 RexxResetTrace, 146
RexxSetHalt, 144
RexxSetTrace, 145
O
object classes, 27, 43 R
Object Rexx Runtime, 155
object variable pools, 63 RC special variable, 53, 73
object-oriented programming, 21 reading
objects, 5, 5 a text file, one character at a time, 84
definition, 22 binary files, 83
kinds of, 22 specific lines of text files, 82
ooRexx License, 165 streams into arrays, 81
Open Object Rexx License, 165 text files, 80
operators and operations, partial list of, 15 REPLY instruction, 63
RESULT special variable, 53
172
return code from Windows and Linux, 73 RexxCreateQueue, 140
RETURN instruction, 19 RexxDeleteQueue, 141
Rexx RexxDeregisterExit, 131
ADDRESS instruction, 67, 73 RexxDeregisterFunction, 114
and object-oriented extensions, 5 RexxDeregisterSubcom, 107
and Unix, 4 RexxDidRexxTerminate, 101
and Windows, 4 RexxDropMacro, 148
ARG instruction, 14 RexxFreeMemory, 139
as a macro language, 9 RexxLoadMacroSpace, 150
assignments, 13 RexxPullQueue, 143
built-in functions, 10 RexxQueryExit, 132
built-in objects, 55 RexxQueryFunction, 115
CALL instruction, 19, 70, 74 RexxQueryMacro, 151
default environment, 67 RexxQueryQueue, 142
directives, 37 RexxQuerySubcom, 108
DO instruction, 14 RexxRegisterExitDll, 128
EXIT instruction, 10 RexxRegisterExitExe, 130
EXPOSE instruction, 51, 58 RexxRegisterFunctionDll, 112
features, 3 RexxRegisterFunctionExe, 114
GUARD instruction, 64 RexxRegisterSubcomDll, 104
IF instruction, 14 RexxRegisterSubcomExe, 106
ITERATE instruction, 18 RexxReorderMacro, 152
local objects, 55 RexxResetTrace, 146
PARSE ARG instruction, 20 RexxSaveMacroSpace, 149
PARSE instruction, 14 RexxSetHalt, 144
PROCEDURE instruction, 19 RexxSetTrace, 145
procedures, 18 RexxStart, 95
program samples, included, 157 example using, 98
program, definition, 9 exit example, 107
program, running a, 9 using exits, 97
program, writing a, 11 using in-storage programs, 96
public objects, 55 using macrospace programs, 96
PULL instruction, 10, 14 REXXTRY procedures
REPLY instruction, 63 developing with REXXTRY, 11
RETURN instruction, 19 REXXTRY program, 11
SAY instruction, 10, 48, 49, 52 RexxVariablePool, 134
SELECT instruction, 14 RexxWaitForTermination, 101
SIGNAL instruction, 74 RXCMD exit, 122
subroutines, 18 RXFNC exit, 120
traditional, 5, 9 RXHLT exit, 126
USE ARG instruction, ?? RXINI exit, 127
Rexx interpreter, invoking, 95 RXMSQ exit, 122
Rexx program, definition, 9 RXSIO exit, 124
RexxAddMacro, 147 RXSTRING, 94
RexxAddQueue, 142 definition, 94
RexxAllocateMemory, 139 null terminated, 94
REXXC utility, 155 returning, 95
RexxClearMacroSpace, 149 RXSYSEXIT data structure, 97
173
RXTER exit, 128 subcommand processing, 74
RXTRC exit, 127 subroutines, 18
SUPER special variable, 54
superclasses, 27
S symbols
sample Rexx programs, included, 157 .environment symbol, 55
SAY instruction, 10, 48, 49, 52 .error symbol, 56
scope, 58, 59 .input symbol, 56
scriptable applications, 67
.local symbol, 56
search order
for environment symbols, 57 .methods symbol, 56
for methods, changing, 61, 62 .nil symbol, 55
for methods, default, 59 .output symbol, 56
SELECT instruction, 14 .rs symbol, 57
SELF special variable, 53
SYSEXIT interface
sending messages within an activity, 64
session I/O exit, 124 definition, 115
SHVBLOCK, 134 description, 115
SIGL special variable, 54, 74 exit functions, 128
SIGNAL ON instruction, 74 external function exit, 120
single quotation mark (’), 12
external HALT exit, 126
special variable, 53
splitting clauses, 11 host command exit, 122
standard I/O (keyboard, displays, and error initialization exit, 127
streams), 89 queue exit, 122
starting REXXTRY, 11
registration example, 130
stem, 6
RexxDeregisterExit, 131
stream I/O model, 79
stream object, 79 RexxQueryExit, 132
string, 6 RexxRegisterExitDll, 128
STRING method, 48, 49, 52 RexxRegisterExitExe, 130
strings, 4, 5, 10, 11, 12, 31
RXCMD exit, 119, 122
SUBCLASS method, 52
RXFNC exit, 118, 120
SUBCLASS option, 40, 43, 61
subclasses, 27 RXHLT exit, 119, 126
subcommand interface RXINI exit, 120, 127
definition, 102 RXMSQ exit, 119, 122
description, 102
RXSIO exit, 119, 124
registering, 102
RXSYSEXIT data structure, 117
RexxDeregisterSubcom, 107
RexxQuerySubcom, 108 RXTER exit, 120, 128
RexxRegisterSubcomDll, 104 RXTRC exit, 120, 127
RexxRegisterSubcomExe, 106 sample exit, 117
subcommand errors, 103
termination exit, 128
subcommand failures, 103
subcommand handler example, 103 tracing exit, 127
subcommand return code, 103
174
T variables
acquiring, 26, 28
termination exit, 128 exposing, 20, 40, 51, 63
text files hiding, 18
closing, 85 in objects, 26, 28, 47
direct acess, 85 in variable pools, 63
querying existence, 88 making accessible, 20
querying other information, 89 naming, 12
reading, 80 special, 19, 53, 61, 61
reading a character at a time, 84
reading into an array, 81
reading specific lines, 82
writing, 82
W
thread, 63, 105, 129, 134, 145, 145 Windows batch (CMD) files, 69
tilde (~), 6, 24 Windows CALL command, 70
trapping command errors, 74 Windows commands, issuing, 9
traps, 74 Windows Scripting Host interface, 152
twiddle (~), 6, 24 writing
typeless, 4 binary files, 85
text files, 82
U
UNINIT method, 52
Unix commands, issuing, 9
UNKNOWN method, 60, 62
USE ARG instruction, 40, 51
V
variable pool interface
description, 133
direct interface, 133
dropping a variable, 136
fetching next variable, 135
fetching private information, 135
fetching variables, 135
restrictions, 134
return codes, 136, 137
returning variable names, 134
returning variable value, 135
RexxVariablePool, 134
RexxVariablePool example, 138
setting variables, 135
shared variable pool request block, 134
SHVBLOCK data structure, 134
symbolic interface, 133
175