Added unit tests (also demonstrate how to use the new Packages' options method), revision changes
logged at: <https://sourceforge.net/p/oorexx/feature-requests/857/>.
---rony
On 09.10.2025 14:09, Rony G. Flatscher wrote:
A few minutes ago RFE # 857 (https://sourceforge.net/p/oorexx/feature-requests/857/) was created,
and the code committed with [r13017] for testing.
The code adds a protected method named 'options' to the Package class.
Here a few ooRexx samples demonstrating the intended usage, here about numeric form and numeric
digits:
pkg=.context~package say "---" say "pkg~name :" pkg~name say "pkg~options:"
pkg~options say
call showOptions .context say "---" say call calc say say "---" say
"changing form to
'Engineering'" pkg~options("form","E") say call showOptions .context say say
"calling routine
calc..." call calc say say "---" newDigits=33 say "changing digits to
'"newDigits"'"
pkg~options("digits",33) say call showOptions .context say say "calling routine
calc..." call
calc say ::routine calc say "***" .line":" .context~name pkg=.context~package say "#"
.line":"
"calc: digits():" digits() "form():" form() "trace():" trace() say "#" .line":"
"1/17 :" 1/17
"(form:" pkg~options("form")")" say "#" .line":" "2**327:" 2**37 "(form:"
pkg~options("form")")" say say "--- "~copies(5) ::routine showOptions say "***"
.line":"
.context~name use strict arg context say .line":" .context~name say
pkg=context~package say
.line":" context~name "context~package~name:" pkg~name say .line":"
"pkg~options="pp(pkg~options) say do counter c1 opt over
"digits","error","failure","form","fuzz","lostdigits","nostring","notready","novalue","prolog","trace"
say c1~right(2)":" pp(opt)~left(14,'.') pp(pkg~options(opt)) end ::routine pp return
"["arg(1)"]"
Running it yields:
--- pkg~name : G:\test\orx\options\test5.rex pkg~options: ::OPTIONS DIGITS
9 FORM SCIENTIFIC
FUZZ 0 ERROR CONDITION FAILURE CONDITION LOSTDIGITS CONDITION NOSTRING
CONDITION NOTREADY
CONDITION NOVALUE CONDITION PROLOG TRACE NORMAL *** 41: SHOWOPTIONS 43:
SHOWOPTIONS 46:
G:\test\orx\options\test5.rex context~package~name:
G:\test\orx\options\test5.rex 47:
pkg~options=[::OPTIONS DIGITS 9 FORM SCIENTIFIC FUZZ 0 ERROR CONDITION
FAILURE CONDITION
LOSTDIGITS CONDITION NOSTRING CONDITION NOTREADY CONDITION NOVALUE
CONDITION PROLOG TRACE
NORMAL] 1: [digits]...... [9] 2: [error]....... [CONDITION] 3:
[failure]..... [CONDITION] 4:
[form]........ [SCIENTIFIC] 5: [fuzz]........ [0] 6: [lostdigits]..
[CONDITION] 7:
[nostring].... [CONDITION] 8: [notready].... [CONDITION] 9: [novalue].....
[CONDITION] 10:
[prolog]...... [PROLOG] 11: [trace]....... [NORMAL] --- *** 32: CALC # 34:
calc: digits(): 9
form(): SCIENTIFIC trace(): N # 35: 1/17 : 0.0588235294 (form: SCIENTIFIC)
# 36: 2**327:
1.37438953E+11 (form: SCIENTIFIC) --- --- --- --- --- --- changing form to
'Engineering' ***
41: SHOWOPTIONS 43: SHOWOPTIONS 46: G:\test\orx\options\test5.rex
context~package~name:
G:\test\orx\options\test5.rex 47: pkg~options=[::OPTIONS DIGITS 9 FORM
ENGINEERING FUZZ 0
ERROR CONDITION FAILURE CONDITION LOSTDIGITS CONDITION NOSTRING CONDITION
NOTREADY CONDITION
NOVALUE CONDITION PROLOG TRACE NORMAL] 1: [digits]...... [9] 2:
[error]....... [CONDITION] 3:
[failure]..... [CONDITION] 4: [form]........ [ENGINEERING] 5:
[fuzz]........ [0] 6:
[lostdigits].. [CONDITION] 7: [nostring].... [CONDITION] 8: [notready]....
[CONDITION] 9:
[novalue]..... [CONDITION] 10: [prolog]...... [PROLOG] 11: [trace].......
[NORMAL] calling
routine calc... *** 32: CALC # 34: calc: digits(): 9 form(): ENGINEERING
trace(): N # 35: 1/17
: 0.0588235294 (form: ENGINEERING) # 36: 2**327: 137.438953E+9 (form:
ENGINEERING) --- --- ---
--- --- --- changing digits to '33' *** 41: SHOWOPTIONS 43: SHOWOPTIONS 46:
G:\test\orx\options\test5.rex context~package~name:
G:\test\orx\options\test5.rex 47:
pkg~options=[::OPTIONS DIGITS 33 FORM ENGINEERING FUZZ 0 ERROR CONDITION
FAILURE CONDITION
LOSTDIGITS CONDITION NOSTRING CONDITION NOTREADY CONDITION NOVALUE
CONDITION PROLOG TRACE
NORMAL] 1: [digits]...... [33] 2: [error]....... [CONDITION] 3:
[failure]..... [CONDITION] 4:
[form]........ [ENGINEERING] 5: [fuzz]........ [0] 6: [lostdigits]..
[CONDITION] 7:
[nostring].... [CONDITION] 8: [notready].... [CONDITION] 9: [novalue].....
[CONDITION] 10:
[prolog]...... [PROLOG] 11: [trace]....... [NORMAL] calling routine calc...
*** 32: CALC # 34:
calc: digits(): 33 form(): ENGINEERING trace(): N # 35: 1/17 :
0.0588235294117647058823529411764706 (form: ENGINEERING) # 36: 2**327:
137438953472 (form:
ENGINEERING) --- --- --- --- ---
Here about tracing:
ruler="-"~copies(79) pkg=.context~package say "1. main: pkg~options:"
pp(pkg~options) say say
"testing all trace options, one by one:" do counter c1 opt over "A", "Res", "I", "c",
"er",
"fa", "la", "of", "n" say "-->" c1":" "opt=["opt"] |
pkg~options('trace',opt) returns previous
value ["pkg~options('trace',opt)"]" - "now:
pkg~options('trace')="pkg~options('trace') say "
pkg~options=[".context~package~options"]" say "about to : call
test_trace..." call test_trace
say "back from: call test_trace" say ruler say end say say "2. main:
pkg~options:"
pp(pkg~options) ::routine test_trace a=1 say "a+3:" pp(a+3) ::routine pp return
"["arg(1)"]"
Running it yields:
1. main: pkg~options: [::OPTIONS DIGITS 9 FORM SCIENTIFIC FUZZ 0 ERROR
CONDITION FAILURE
CONDITION LOSTDIGITS CONDITION NOSTRING CONDITION NOTREADY CONDITION
NOVALUE CONDITION PROLOG
TRACE NORMAL] testing all trace options, one by one: --> 1: opt=[A] |
pkg~options('trace',opt)
returns previous value [NORMAL] now: pkg~options('trace')=ALL
pkg~options=[::OPTIONS DIGITS 9
FORM SCIENTIFIC FUZZ 0 ERROR CONDITION FAILURE CONDITION LOSTDIGITS
CONDITION NOSTRING
CONDITION NOTREADY CONDITION NOVALUE CONDITION PROLOG TRACE ALL] about to :
call test_trace...
>I> Routine "TEST_TRACE" in package "G:\test\orx\options\test4.rex". 22 *-*
a=1 23 *-* say
"a+3:" pp(a+3) >I> Routine "PP" in package "G:\test\orx\options\test4.rex".
26 *-* return
"["arg(1)"]" <I< Routine "PP" in package "G:\test\orx\options\test4.rex". a+3:
[4] <I< Routine
"TEST_TRACE" in package "G:\test\orx\options\test4.rex". back from: call
test_trace
-------------------------------------------------------------------------------
--> 2:
opt=[Res] | pkg~options('trace',opt) returns previous value [ALL] now:
pkg~options('trace')=RESULTS pkg~options=[::OPTIONS DIGITS 9 FORM
SCIENTIFIC FUZZ 0 ERROR
CONDITION FAILURE CONDITION LOSTDIGITS CONDITION NOSTRING CONDITION
NOTREADY CONDITION NOVALUE
CONDITION PROLOG TRACE RESULTS] about to : call test_trace... >I> Routine
"TEST_TRACE" in
package "G:\test\orx\options\test4.rex". 22 *-* a=1 >>> "1" 23 *-* say "a+3:"
pp(a+3) >I>
Routine "PP" in package "G:\test\orx\options\test4.rex". 26 *-* return "["arg(1)"]"
>>> "[4]"
<I< Routine "PP" in package "G:\test\orx\options\test4.rex". >>> "a+3: [4]" a+3:
[4] <I<
Routine "TEST_TRACE" in package "G:\test\orx\options\test4.rex". back from:
call test_trace
-------------------------------------------------------------------------------
--> 3: opt=[I]
| pkg~options('trace',opt) returns previous value [RESULTS] now:
pkg~options('trace')=INTERMEDIATES pkg~options=[::OPTIONS DIGITS 9 FORM
SCIENTIFIC FUZZ 0
ERROR CONDITION FAILURE CONDITION LOSTDIGITS CONDITION NOSTRING CONDITION
NOTREADY CONDITION
NOVALUE CONDITION PROLOG TRACE INTERMEDIATES] about to : call test_trace...
>I> Routine
"TEST_TRACE" in package "G:\test\orx\options\test4.rex". 22 *-* a=1 >L> "1" >>> "1"
>=> A <=
"1" 23 *-* say "a+3:" pp(a+3) >L> "a+3:" >V> A => "1" >L> "3" >O> "+" => "4" >A>
"4" >I>
Routine "PP" in package "G:\test\orx\options\test4.rex". 26 *-* return "["arg(1)"]"
>L> "["
>L> "1" >A> "1" >F> ARG => "4" >O> "" => "[4" >L> "]" >O> "" => "[4]" >>> "[4]"
<I< Routine
"PP" in package "G:\test\orx\options\test4.rex". >F> PP => "[4]" >O> " " => "a+3:
[4]" >>>
"a+3: [4]" a+3: [4] <I< Routine "TEST_TRACE" in package
"G:\test\orx\options\test4.rex". back
from: call test_trace
-------------------------------------------------------------------------------
--> 4: opt=[c]
| pkg~options('trace',opt) returns previous value [INTERMEDIATES] now:
pkg~options('trace')=COMMANDS pkg~options=[::OPTIONS DIGITS 9 FORM
SCIENTIFIC FUZZ 0 ERROR
CONDITION FAILURE CONDITION LOSTDIGITS CONDITION NOSTRING CONDITION
NOTREADY CONDITION NOVALUE
CONDITION PROLOG TRACE COMMANDS] about to : call test_trace... a+3: [4]
back from: call
test_trace
-------------------------------------------------------------------------------
-->
5: opt=[er] | pkg~options('trace',opt) returns previous value [COMMANDS]
now:
pkg~options('trace')=ERROR pkg~options=[::OPTIONS DIGITS 9 FORM SCIENTIFIC
FUZZ 0 ERROR
CONDITION FAILURE CONDITION LOSTDIGITS CONDITION NOSTRING CONDITION
NOTREADY CONDITION NOVALUE
CONDITION PROLOG TRACE ERROR] about to : call test_trace... a+3: [4] back
from: call
test_trace
-------------------------------------------------------------------------------
-->
6: opt=[fa] | pkg~options('trace',opt) returns previous value [ERROR] now:
pkg~options('trace')=FAILURE pkg~options=[::OPTIONS DIGITS 9 FORM
SCIENTIFIC FUZZ 0 ERROR
CONDITION FAILURE CONDITION LOSTDIGITS CONDITION NOSTRING CONDITION
NOTREADY CONDITION NOVALUE
CONDITION PROLOG TRACE FAILURE] about to : call test_trace... a+3: [4] back
from: call
test_trace
-------------------------------------------------------------------------------
-->
7: opt=[la] | pkg~options('trace',opt) returns previous value [FAILURE] now:
pkg~options('trace')=LABELS pkg~options=[::OPTIONS DIGITS 9 FORM SCIENTIFIC
FUZZ 0 ERROR
CONDITION FAILURE CONDITION LOSTDIGITS CONDITION NOSTRING CONDITION
NOTREADY CONDITION NOVALUE
CONDITION PROLOG TRACE LABELS] about to : call test_trace... >I> Routine
"TEST_TRACE" in
package "G:\test\orx\options\test4.rex". >I> Routine "PP" in package
"G:\test\orx\options\test4.rex". <I< Routine "PP" in package
"G:\test\orx\options\test4.rex".
a+3: [4] <I< Routine "TEST_TRACE" in package
"G:\test\orx\options\test4.rex". back from: call
test_trace
-------------------------------------------------------------------------------
-->
8: opt=[of] | pkg~options('trace',opt) returns previous value [LABELS] now:
pkg~options('trace')=OFF pkg~options=[::OPTIONS DIGITS 9 FORM SCIENTIFIC
FUZZ 0 ERROR
CONDITION FAILURE CONDITION LOSTDIGITS CONDITION NOSTRING CONDITION
NOTREADY CONDITION NOVALUE
CONDITION PROLOG TRACE OFF] about to : call test_trace... a+3: [4] back
from: call test_trace
-------------------------------------------------------------------------------
--> 9: opt=[n]
| pkg~options('trace',opt) returns previous value [OFF] now:
pkg~options('trace')=NORMAL
pkg~options=[::OPTIONS DIGITS 9 FORM SCIENTIFIC FUZZ 0 ERROR CONDITION
FAILURE CONDITION
LOSTDIGITS CONDITION NOSTRING CONDITION NOTREADY CONDITION NOVALUE
CONDITION PROLOG TRACE
NORMAL] about to : call test_trace... a+3: [4] back from: call test_trace
-------------------------------------------------------------------------------
2. main:
pkg~options: [::OPTIONS DIGITS 9 FORM SCIENTIFIC FUZZ 0 ERROR CONDITION
FAILURE CONDITION
LOSTDIGITS CONDITION NOSTRING CONDITION NOTREADY CONDITION NOVALUE
CONDITION PROLOG TRACE NORMAL]
Here about turning a condition into a syntax condition:
pkg=.context~package say "---" say "pkg~name :" pkg~name say "pkg~options:"
pkg~options say
call showOptions .context say "---" say say "calling routine
testNovalue..." call testNovalue
say say "---" say "changing NOVALUE condition to a syntax condition"
pkg~options("novalue","syntax") call showOptions .context say say "---" say say
"calling
routine testNovalue..." call testNovalue say ::routine testNoValue say "#"
.line":"
ThisIsAVariableWithoutValue "..." ::routine showOptions say "***" .line":"
.context~name use
strict arg context say .line":" .context~name say pkg=context~package say
.line":"
context~name "context~package~name:" pkg~name say .line":"
"pkg~options="pp(pkg~options) say
do counter c1 opt over
"digits","error","failure","form","fuzz","lostdigits","nostring","notready","novalue","prolog","trace"
say c1~right(2)":" pp(opt)~left(14,'.') pp(pkg~options(opt)) end ::routine pp return
"["arg(1)"]"
Running it yields:
--- pkg~name : G:\test\orx\options\test6.rex pkg~options: ::OPTIONS DIGITS
9 FORM SCIENTIFIC
FUZZ 0 ERROR CONDITION FAILURE CONDITION LOSTDIGITS CONDITION NOSTRING
CONDITION NOTREA DY
CONDITION NOVALUE CONDITION PROLOG TRACE NORMAL *** 27: SHOWOPTIONS 29:
SHOWOPTIONS 32:
G:\test\orx\options\test6.rex context~package~name:
G:\test\orx\options\test6.rex 33:
pkg~options=[::OPTIONS DIGITS 9 FORM SCIENTIFIC FUZZ 0 ERROR CONDITION
FAILURE CONDITION
LOSTDIGITS CONDITION NOSTRING CONDITION NO TREADY CONDITION NOVALUE
CONDITION PROLOG TRACE
NORMAL] 1: [digits]...... [9] 2: [error]....... [CONDITION] 3:
[failure]..... [CONDITION] 4:
[form]........ [SCIENTIFIC] 5: [fuzz]........ [0] 6: [lostdigits]..
[CONDITION] 7:
[nostring].... [CONDITION] 8: [notready].... [CONDITION] 9: [novalue].....
[CONDITION] 10:
[prolog]...... [PROLOG] 11: [trace]....... [NORMAL] --- calling routine
testNovalue... # 24:
THISISAVARIABLEWITHOUTVALUE ... --- changing NOVALUE condition to a syntax
condition *** 27:
SHOWOPTIONS 29: SHOWOPTIONS 32: G:\test\orx\options\test6.rex
context~package~name:
G:\test\orx\options\test6.rex 33: pkg~options=[::OPTIONS DIGITS 9 FORM
SCIENTIFIC FUZZ 0 ERROR
CONDITION FAILURE CONDITION LOSTDIGITS CONDITION NOSTRING CONDITION NO
TREADY CONDITION
NOVALUE SYNTAX PROLOG TRACE NORMAL] 1: [digits]...... [9] 2: [error].......
[CONDITION] 3:
[failure]..... [CONDITION] 4: [form]........ [SCIENTIFIC] 5: [fuzz]........
[0] 6:
[lostdigits].. [CONDITION] 7: [nostring].... [CONDITION] 8: [notready]....
[CONDITION] 9:
[novalue]..... [SYNTAX] 10: [prolog]...... [PROLOG] 11: [trace].......
[NORMAL] --- calling
routine testNovalue... 24 *-* say "#" .line":" ThisIsAVariableWithoutValue
"..." 20 *-* call
testNovalue Error 98 running G:\test\orx\options\test6.rex line 24:
Execution error. Error
98.986: Reference to unassigned variable "THISISAVARIABLEWITHOUTVALUE".
You should be able to get the beta version from Sourceforge in a while, cf.
<https://sourceforge.net/projects/oorexx/files/oorexx/5.2.0beta/>, or the portable vesion from
<https://sourceforge.net/projects/oorexx/files/oorexx/5.2.0beta/portable/>. The release should be
at least "13017".
---rony
On 04.10.2025 12:03, Rony G. Flatscher wrote:
The idea of first implementing the options method (as an instance method) is to become able to
experiment with changing options at runtime.
Then the step of allowing an environment variable or a command line option would enter the field
Gil has brought up with PROLOG/NOPROLOG, with Josep Maria's idea of a class method. As Gil
writes, if a program/package is loaded, the prolog code block gets run by default, unless the
program/package contains an "::option noprolog" option. If allowing overrides at startup or
globally for all loaded programs/packages, then it is necessary to a) record the override
options, b) find the location where to add them to the loading program/package (before the prolog
code block gets run). The override options for loading programs/packages need to be defined at
the class level, allowing defining, querying, and removing these override options at runtime as
well, to keep everything truly dynamic, which would allow for testing that feature before making
it available via the environment or startup option.
An indication that an option is to be fetched from a file, one additional thought: in Java, it is
possible to configure the JVM at startup, for which, over time, there has been a wealth of
options defined, which sometimes gets out of hand. So the Java people introduced the ability to
define any number of startup options in a file which gets marked/indicated with an at character
(@) followed by the file name, e.g., "my_options" would be indicated as "@my_options", cf.
<https://docs.oracle.com/en/java/javase/17/docs/specs/man/java.html>. So, going this route
instead of "file:<filespec>", we could use "@<filespec>".
Ad format of the environment, command line, or file: here I would suggest using the ::options
directive itself. The reason being that programmers dealing with options are aware of the
::options directive and can formulate and understand therefore ::options definition. In case
multiple ::options are desired, the programmer can do so by delimiting the ::options directives
with semi-colons (end-of-clause), such that the options string would be a proper, testable ooRexx
program.
Ad short and long option names: from the Unix world, options start by convention with a dash and
used to be as short as possible to save programmers typing. Sometimes the option names being
single characters would not indicate well enough their intent, so over time an optional
(self-describing) long format for options became customary (introduced with two dashes, --),
which the Java world also has embraced. Hence, suggesting for "-o" a long format "--options", for
"-go" a long format "--global-options".
What do you think?
---rony
On 04.10.2025 08:57, Josep Maria Blasco wrote:
I don't have strong opinions about whether this should be or not a method of
the package class. Indeed, and since what it will be governing is how packages
are loaded, it might be the nucleus of a possible future loader class, and that
would most probably deserve its own separate class, which most probably
should be a singleton, by the way.
Josep Maria
Missatge de Gilbert Barmwater via Oorexx-devel <[email protected]> del dia dv.,
3 d’oct. 2025 a les 20:53:
That's an interesting thought although I can't think of another class that
has such a concept.
Gil
On 10/3/2025 2:45 PM, Josep Maria Blasco wrote:
Maybe the "options" method Rony is suggesting has to be a class method,
i.e.,
an instance method of the Package class, not of the package class instances?
That way, one would be able to say "from now on, package loading will be
governed by the following rules", which is the original goal of the whole
discussion.
If "options" is a class method and I understand things correctly, the
problems
you mention should disappear.
Josep Maria
Missatge de Gilbert Barmwater via Oorexx-devel
<[email protected]> del dia
dv., 3 d’oct. 2025 a les 18:49:
Just a heads up based on my experience w/ the Package class. Creating
an instance of
.package ALWAYS* causes the code in it to execute immediately. This
includes both the
New method and the LoadPackage method (and probably LoadLibrary). *If
the target file
or source array has an ::option noprolog, then the prolog code, if any,
is NOT
immediately executed but all directives are immediately processed. So
it seems
problematic to me to define an Options method on that class to change
how the package
is going to behave since it will be "after the fact" so to speak.
This behavior was a bit of a surprise to me initially but it makes
sense in the context
of being able to dynamically ::requires other packages at runtime.
You'll notice the
.package class has NO method similar to the Call method of .Routine.
(One can create a
.routine from the prolog via the Prolog method which can then be
executed.)
Gil
On 10/3/2025 5:49 AM, Rony G. Flatscher wrote:
In order to systematically try to implement this feature, I would
suggest implementing
the method "options" for Package first and then analyzing whether
everything works as
expected. If that works out, the next step would be to define the specs
for the
environment variable and command line switches (this includes whether,
and if so, how
to define options/fileContent that should be used for the initial
program/package, or
globally from that moment on for all programs/packages that get loaded).
So here is a suggestion for the description of the suggested OPTIONS
method for the
Package class:
OPTIONS( [optionName [, newValue]])
Returns a directory with the values of all currently set options
for the package.
If the optional argument "optionName" is supplied, it returns the
current setting.
If the optional argument "newValue" is supplied for "optionName", then
"newValue"
replaces the current value for the package.
"optionName" can be one of (only the first signifcant letters need
to be supplied
as argument, depicted in uppercase):
* Digits
returns the current number of digits (default: 9)
* FOrm
returns "ENGINEERING" or "SCIENTIFIC" (default:
"SCIENTIFIC")
* FUzz
returns the current number of FUZZ digits (default: 0)
* Handlecondition (default: "ERROR CONDITION FAILURE
CONDITION LOSTDIGITS
CONDITION NOSTRING CONDITION NOTREADY CONDITION NOVALUE
CONDITION")
returns a string denoting how conditions get handled
* Prolog (default: "PROLOG")
returns "PROLOG" or "NOPROLOG"
* Trace (default: "NORMAL")
returns "NORMAL | ALL | COMMANDS | ERROR | FAILURE |
INTERMEDIATES |
LABELS | OFF | RESULTS"
Changing "optionName" to "newValue" (only the first significant
letters need to be
supplied as argument, depicted in uppercase)
* Digits, nrDigits
nrDigits>0
* FOrm, "Engineering" | "Scientific"
* FUzz, nrDigigs
nrDigits>=0
* Handlecondition, (All | Error | Failure | Lostdigits |
NOString | NOTReady
| NOValue "Condition" | "Syntax")+
Note 1: using ALL will set ERROR, FAILURE, LOSTDIGITS,
NOSTRING, NOTREADY,
NOVALUE to "CONDITION" | "SYNTAX"
Note 2: it is possible to have multiple definitions such
that one could
use ALL for the default handling, and define specific
handling options for
ERROR, FAILURE, LOSTDIGITS, NOSTRING, NOTREADY, NOVALUE if
need be; in
case of conflict, the last definition prevails
Note 3: the settings of the conditions HALT, NOMETHOD,
SYNTAX, and USE
cannot be changed
* Prolog, "Prolog" | "Noprolog"
* Trace, Normal | All | Commands | Error | Failure |
Intermediates | Labels
| Off | Results
How about protecting this method such that a security manager can be
used to protect
access to this method, if need be?
Are there any stumbling blocks, side effects one needs to be aware of?
Any thoughts, comments, ideas?
---rony
--
Gil Barmwater
_
_______________________________________________
Oorexx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/oorexx-devel