home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
rexx
/
dosrexx
/
rexxpc_2.doc
< prev
next >
Wrap
Text File
|
1988-03-16
|
70KB
|
1,772 lines
EXPRESSIONS
An expression is a sequence of terms and operators which is evaluated to
give a final result. The expression is evaluated left to right, except
as modified by operator precedence (see the next section).
TERMS
Terms are the sub-components of an expression. They fall into five
classes.
A term may be a... In which case its value is...
parenthesized expression
the string resulting from evaluating that ex-
pression
constant the string constant itself
word (the name of a variable)
the string currently assigned to that variable
word (not the name of a variable)
the literal word itself
word followed by left paren (function)
the string returned by the function
OPERATORS
Arithmetic operators
REXXPC88 provides the usual arithmetic operators for addition, sub-
traction, multiplication, division, and remainder. The operators are:
+ returns a string representing the sum of its left and right oper-
ands.
- returns a string representing the difference of its left and right
operands.
* returns a string representing the product of its left and right
operands.
% returns a string representing the integer portion of the quotient
of its left and right operands.
// returns a string representing the integer remainder when the left
operand is divided by the right operand.
/ returns a string representing the result when the left operand is
divided by the right operand.
** returns a string representing the result when the left operand is
raised to the right operand whole power.
Comparison operators
REXXPC88 provides thirteen operators for comparing strings. The first
six compare their operands character by character. The others ignore
leading blanks and pad the shorter operand with trailing blanks before
Expressions 27
the comparison. Most of these operators also allow the not symbol in
front of them to mean the opposite.
== returns "1" if left and right operands match character for character
and "0" otherwise.
/== returns "0" if left and right operands match character for character
and "1" otherwise.
<< strictly less than. This operator will not pad either string.
>> strictly greater than. This operator will not pad either string.
<<= strictly less than or equal to. This operator will not pad either
string.
>>= strictly greater than or equal to. This operator will not pad either
string.
= returns "1" if operands match and "0" otherwise.
<> or >< returns "0" if operands match and "1" otherwise.
< returns "1" if left operand is less than right operand and "0"
otherwise. If both of the operands represent numbers, they are
compared as signed integers. Otherwise they are compared alpha-
betically as character strings.
<= returns "1" if left operand is less than or equal to the right op-
erand and "0" otherwise. If both of the the operands represent
numbers, they are compared as signed integers. Otherwise they are
compared alphabetically as character strings.
> returns "1" if left operand is greater than right operand and "0"
otherwise. If both of the the operands represent numbers, they are
compared as signed integers. Otherwise they are compared alpha-
betically as character strings.
>= returns "1" if left operand is greater than or equal to the right
operand and "0" otherwise. If both of the operands represent num-
bers, they are compared as signed integers. Otherwise they are
compared alphabetically as character strings.
Logical operators
REXXPC88 provides four operators for performing logical arithmetic.
│ returns 1 if either operand is 1 and 0 otherwise (logical or)
& returns 1 if both operands are 1 and 0 otherwise (logical and).
\ or ¬ performs the NOT operation on the expression following this op-
erator. The expression must evaluate to 0 or 1. NOT will transform
0 to 1 and 1 to 0.
Note: This character is actually a backslash (from upper left to
lower right). Some printers do not have this character in its print
chain so the actual character seen in this description may vary.
&& xor. returns 0 if both operand expressions are either 1 or 0 (the
same) or 1 otherwise.
If the operands are neither 0 nor 1 an error message is generated.
String operators
REXXPC88 treats string expressions rather differently than most other
languages. Whitespace (a sequence or one or more adjacent blanks and/or
Expressions 28
tabs between two terms) is treated as a concatenate-with-a-blank-in-
between operator. Abuttal (the absence of whitespace between two terms)
is treated as a concatenate operator.
abuttal returns the left term concatenated to the right term.
whitespace returns the left term concatenated to the right term with a
single blank in between.
││ returns the left term concatenated to the right term (same as
abuttal).
OPERATOR PRECEDENCE
Terms appearing between operators of higher precedence are evaluated be-
fore terms appearing between operators of lower precedence, according to
the usual rules of algebra (multiply and divide first, then add and sub-
tract). The operator precedence for REXXPC88 is as follows, listed
highest precedence first:
1. - + \ or ¬ (unary minus, plus, not)
2. ** (power)
3. * / % // (multiply, divide, integer divide, remainder)
4. + - (add, subtract)
5. " " (concatenation with a blank)
││ (concatenation without a blank)
6. == /== (exactly equal/not exactly equal)
<< <<= (exactly less than/exactly less than or equal to)
>> >>= (exactly greater than/exactly greater than or equal to)
= <> >< (equal/not equal)
< >= (less than/not less than)
> <= (greater than/not greater than)
7. & (and)
8. │ or && (or and xor)
NOTES
1. The following instructions...
say This is an ││ expression
say The result is ( 10 * 10 )0
result = 'answer'
say the result is ( 10 * 10 )0
say The 'result' is ( 10 * 10 )0
would produce on the screen...
This is anexpression
The result is 1000
The answer is 1000
The result is 1000
Observations:
a. Note the use of "││" in the first example to force the abuttal of
"an" and "expression".
b. The second example illustrates that numerical and non-numerical
strings can be intermixed in the same expression.
c. The remaining examples show the behavior of initialized vs. un-
initialized variables.
2. In order for a function call to be recognized as such, the opening
parenthesis must immediately follow the function name, with no in-
tervening blank. For example:
say 'Length is' length('abc')
calls the function length with the argument "abc", but
say 'Length is' length ('abc')
treats length as a variable name (or as a constant if there is no
variable by that name).
Expressions 29
COMPOUND VARIABLES
A compound name is a variable name which contains subscripts. It may
appear anywhere a simple variable name would be valid (i.e. within an
expression or as the target of an assignment). The actual variable ref-
erenced at run time is determined by replacing the subscripts with their
current values to form the "actual name" of the variable. The following
example would print "one two three four":
list.1 = 'one'
list.2 = 'two'
x = 3
list.x = 'three'
x = 'mary'
list.x = 'four'
say list.1 list.2 list.3 list.mary
Note that the value of a subscript need not be a number; it may be any
string at all. Thus compound variables allow you to implement arbitrary
types of data collections (i.e., dictionaries, trees, etc.) in addition to
simple arrays.
If a subscript name is currently undefined as a variable, then its value
is the subscript taken as a literal. Thus the following example will
print "list.i list.j list.k" followed by "one two three":
list.1 = 'one'
list.2 = 'two'
list.3 = 'three'
say list.i list.j list.k
i = 1; j = 2; k = 3
say list.i list.j list.k
An entire collection may be initialized by assigning a value to the stem
of the collection. Thus
animals. = 'I don''t know that one'
animals.pig = 'oink oink'
animals.hen = 'cackel'
animals.rooster = 'cockadoodledoo'
say 'Name an animal'
choice = ask()
say animals.choice
would respond "oink oink" to "pig" but "I don't know that one" to
"sparrow".
Compound variables 31
PROCEDURES AND FUNCTIONS
A procedure or function is block of code whose purpose is to accept a list
of arguments and perform some operation using them. We'll refer to pro-
cedures and functions collectively as routines. The inner workings of
routines are generally kept hidden from the rest of the program and serve
as "black boxes" to perform useful operations.
REXXPC88 procedures differ from functions only in the syntax used to in-
voke them and in the fact that functions must return a value whereas
procedures needn't. If desired, the same routine can be called as a
procedure at one time and as a function at some other time.1
A routine may be one of three types:
∙ internal routine
∙ built-in routine
∙ external routine
The first is a labelled entry point you've defined in your program. The
second is a routine that REXXPC88 provides as part of its internal li-
brary. The third is an external REXXPC88 program whose name is the name
of the function and whose filetype is ".BAT". The calling conventions are
exactly the same for each type of routine.
ARGUMENT PASSING AND NAME HIDING
∙ A routine may be called with or without arguments. The same routine
may be called with different numbers of arguments at different times.
If a function is called with zero arguments, the parentheses are still
required.
∙ The number of arguments passed to a routine, as well as their values,
are available thru the arg() built-in routine.
∙ If a procedure instruction is encountered in the body of a routine
then a new symbol table is created at that point. All references to
variables from that point on will be satisfied from the new symbol
table. Variables defined prior to the procedure instruction become
undefined until a return instruction is executed, at which point the
current symbol table is discarded and the preceding symbol table is
re-established.
∙ If a procedure expose instruction is used, then a new symbol table is
still created but in addition some variables in the caller's symbol
table are shared (see the procedure expose instruction).
∙ If no procedure instruction is encountered in a routine, then the
symbol table established by the caller continues to be used.2
RETURN VALUES
The value returned by a routine is handled differently depending on
whether the routine was called as a function or as a subroutine.
1. For a routine called as a subroutine: If the variable returns a value,
that value is stored in the special variable named "result". Other-
wise the current value of "result" (if any) is dropped.
1 A procedure is generally called for its side effects. A function is
generally called for its value and is not supposed to produce side
effects (although no such restriction is imposed by the REXX lan-
guage).
2 Note that there is no way to access "global" variables unless they
are passed explicitly from one routine to the next either as arguments
or as exposed variables.
Procedures and Functions 32
2. For a routine called as a function: If the function returns a value,
that value is substituted into the expression at the position where
the function was called. Otherwise REXXPC88 stops with an error
message.
BUILT-IN ROUTINES
General purpose routines
┌────────────────────────────────────────────────────────────────────────┐
│ ABBREV( information , info [ ,length ] ) │
└────────────────────────────────────────────────────────────────────────┘
returns 1 if info is equal to the leading characters of information and
info is not less than the minimum length, length. Returns 0 if either of
these conditions is not met. The minimum length may be specified as the
third argument; the default is the length of info.
Examples:
ABBREV('Print','Pri') == 1
ABBREV('PRINT','Pri') == 0
ABBREV('PRINT','PRI',4) == 0
ABBREV('PRINT','PRY') == 0
ABBREV('PRINT','') == 1
ABBREV('PRINT','',1) == 0
Note: A null string will always match is a length of 0 (or the default)
is used. This allows a default keyword to be selected automatically if
desired.
┌────────────────────────────────────────────────────────────────────────┐
│ ABS( number ) │
└────────────────────────────────────────────────────────────────────────┘
returns the absolute value of number. The result has no sign and is for-
matted according to the current NUMERIC settings.
Examples:
ABS('12.3') == 12.3
ABS(' -0.307') == 0.307
┌────────────────────────────────────────────────────────────────────────┐
│ ADDRESS() │
└────────────────────────────────────────────────────────────────────────┘
returns the name of the environment to which host commands are currently
being submitted.
┌────────────────────────────────────────────────────────────────────────┐
│ ARG( [ argn0 [ ,option ] ] ) │
└────────────────────────────────────────────────────────────────────────┘
returns an argument string, or information about the argument strings to
a program or internal routine.
If no parameter is given, the number of arguments strings passed to the
program or internal routine is returned.
If only n is specified, n-th argument is returned. If the argument string
does not exist, the null string is returned. n must be positive.
If option is specified, the function tests for the existence of the nth
argument string. Possible values for option (of which only the first
character is significant) are:
Procedures and Functions 33
E (Exists); returns 1 if the nth argument exists; that is, if it
was explicitly specified when the routine was invoked. Returns
0 otherwise.
O (Omitted); returns 1 if the nth argument was omitted; that is,
if it was not explicitly specified when the routine was invoked.
Returns 0 otherwise.
If no routine is currently active, the argument list is that with which
the program was invoked (i.e. the command line). The program fragment
x = 'one'
y = 'two three'
say foo(x, y)
return
foo:
say 'Foo received' arg() 'arguments'
return arg(1) arg(2)
would display the lines:
Foo received 2 arguments
one two three
┌────────────────────────────────────────────────────────────────────────┐
│ CENTER( string, k [ ,pad ] ) / CENTRE( string, k [ ,pad ] ) │
└────────────────────────────────────────────────────────────────────────┘
Returns a string of length k with string centered in it, with pad char-
acters (the default pad character is a blank) added as necessary to make
up the length. If the string is longer than k, then it will be truncated
at both ends to fit. If an odd number of characters are truncated or
added, then the right hand end loses or gains one more character than the
left hand end.
Examples:
CENTRE(abc,7) == ' ABC '
CENTRE(ABC,8,'-') == '--ABC---'
CENTER('The true REX',8) == 'e true R'
CENTER('The true REX',7) == 'e true '
Note: This function may be called either CENTER or CENTRE,
which avoids errors due to the difference between the
British and American spellings.
┌────────────────────────────────────────────────────────────────────────┐
│ COMPARE( string1 , string2 [ , pad ] ) │
└────────────────────────────────────────────────────────────────────────┘
returns 0 if string1 and string2 are identical. If they are not, the re-
turned number is positive and is the position of the first character that
is not the same in both strings. The shorter string is padded on the right
with pad if necessary. The default pad character is a blank.
Examples:
COMPARE('abc','abc') == 0
COMPARE('abc','ak') == 2
COMPARE('ab ','ab') == 0
COMPARE('ab ','ab',' ') == 0
COMPARE('ab ','ab','x') == 3
COMPARE('ab-- ','ab','-') == 5
┌────────────────────────────────────────────────────────────────────────┐
│ COPIES( string, n ) │
└────────────────────────────────────────────────────────────────────────┘
Returns n concatenated copies of string. n must be positive or 0.
Procedures and Functions 34
Examples:
COPIES('abc',3) == 'abcabcabc'
COPIES('abc',0) == ''
┌────────────────────────────────────────────────────────────────────────┐
│ DATATYPE( string [ ,type ] ) │
└────────────────────────────────────────────────────────────────────────┘
If only string is specified, the returned result is 'NUM' if string is a
valid REXXPC88 number, or 'CHAR' otherwise.
If type is specified, the returned result is 1 if string matches the type,
or 0 otherwise. If string is null, 0 is returned (except when type is "X",
which returns 1 for a null string). The valid types (of which only the
first character is significant) are:
A (Alphanumeric); returns 1 if string only contains characters
from the ranges "a-z", "A-Z", and "0-9".
B (Bits); returns 1 if string only contains the characters "0"
and/or "1".
L (Lower case); returns 1 if string only contains characters from
the range "a-z".
M (Mixed case); returns 1 if string contains characters from the
ranges "a-z" and "A-Z".
N (Number); returns 1 if string is a valid REXXPC88 number.
S (Symbol); returns 1 if string only contains characters that are
valid in REXXPC88 symbols. Note that lower case alphabetics are
permitted.
U (Upper case); returns 1 if string only contains characters from
the range "A-Z".
W (Whole number); returns 1 if string is a REXXPC88 whole number.
X (heXidecimal); returns 1 if string only contains characters
from the ranges "a-f", "A-F", "0-9" and blank (so long as blanks
only appear between pairs of hexidecimal characters, as usual).
Also returns 1 if string is a null string, which is a valid
hexidecimal string.
┌────────────────────────────────────────────────────────────────────────┐
│ DATE( [ option ] ) │
└────────────────────────────────────────────────────────────────────────┘
Returns the local date in the format: dd Mmm yyy. e.g. '27 Aug 1982', with
no leading zero on the day. The following formats (first letter signif-
icant) may be supplied to obtain alternative formats:
Century Returns the number of days so far in this century in the
format: ddddd (no leading zeros).
Note: not supported.
Days Returns the number of days so far in this year in the format:
ddd (no leading zeros).
European Returns the date in the format: dd/mm/yy.
Julian-OS Returns the date in "OS" format: yyddd.
Month Returns full name of the current month, e.g. 'August'.
Normal Returns the date in the default format as specified above.
Ordered Returns date in the format: yy/mm/dd (suitable for sorting,
etc.).
Sorted Returns date in the format: yyyymmdd (suitable for sorting,
etc.).
USA Returns date in the format: mm/dd/yy.
Weekday Returns day of week, e.g. 'Tuesday'.
Note: The first call to DATE in one expression causes a time stamp to be
made which is then used for all calls to this function in that expression.
Hence if multiple calls to any of the DATE functions are made in a single
expression, they are guaranteed to be consistent with each other.
┌────────────────────────────────────────────────────────────────────────┐
│ DELSTR( string , n [ ,length ] ) │
└────────────────────────────────────────────────────────────────────────┘
Procedures and Functions 35
deletes the sub-string of string that begins at the nth character, and
is of length length. If length is not specified, the rest of the string
is deleted (including the nth character). length must be non-negative,
and n must be positive. If n is greater than the length of string, the
string is returned unchanged.
Examples:
DELSTR('abcd',3) == 'ab'
DELSTR('abcde',3,2) == 'abe'
DELSTR('abcde',6) == 'abcde'
┌────────────────────────────────────────────────────────────────────────┐
│ DELWORD( string , n [ ,length ] ) │
└────────────────────────────────────────────────────────────────────────┘
deletes the sub-string of string that begins at the nth word, and is of
length length blank-delimited words. If length is omitted it defaults to
be the remaining words in the string (including the nth word). length must
be non-negative, and n must be positive. If n is greater than the number
of words in string, the string is returned unchanged. The string deleted
includes any blanks following the final word involved, but none of the
blanks preceding the first word involved.
Examples:
DELWORD('Now is the time',2,2) == 'Now time'
DELWORD('Now is the time',3) == 'Now is '
DELWORD('Now is time',5) == 'Now is time'
┌────────────────────────────────────────────────────────────────────────┐
│ DIGITS() │
└────────────────────────────────────────────────────────────────────────┘
returns the current setting of NUMERIC DIGITS. See the NUMERIC instruction
for more information.
Example:
DIGITS() == 9 /* if default */
┌────────────────────────────────────────────────────────────────────────┐
│ FORM() │
└────────────────────────────────────────────────────────────────────────┘
returns the current setting of NUMERIC FORM. See the NUMERIC instruction
for more information.
Example:
FORM() == 'SCIENTIFIC' /* if default */
┌────────────────────────────────────────────────────────────────────────┐
│ FORMAT( number [ , [ before ] [ , [ after ] ] ] ) │
└────────────────────────────────────────────────────────────────────────┘
rounds and formats number.
If only number is given, it will be rounded and formatted to standard
REXXPC88 rules, just as though the operation "number+0" had been carried
out. The arguments before and after describe how many characters are to
be used for the integer and decimal parts of the result respectively. If
either of these is omitted, the number of characters used will be as many
as are needed for that part.
If before is not large enough to contain the integer part of the number,
an error results. If after is not the same size as the decimal part of
the number, the number will be rounded (or extended with zeros) to fit.
Specifying 0 will cause the number to be rounded to an integer (that is,
it will have no decimal part).
Procedures and Functions 36
Examples:
FORMAT('3',4) == ' 3'
FORMAT('1.73'4,0) == ' 2'
FORMAT('1.73',4,3) == ' 1.730'
FORMAT('-.76',4,1) == ' -0.8'
FORMAT('3.03',4) == ' 3.03'
FORMAT(' - 12.73',,4) == '-12.7300'
FORMAT(' - 12.73') == '-12.73'
FORMAT('0.000') == '0'
A further two arguments may be passed to the FORMAT function to control
the use of exponential notation. The full syntax of the function is
therefore:
┌────────────────────────────────────────────────────────────────────────┐
│ FORMAT( number [ , [ before ] [ , [ after ] [ , [ expp ] [ , expt ] │
│ ] ] ) │
└────────────────────────────────────────────────────────────────────────┘
The first three arguments are as described above, and in addition expp
and expt control the exponent part of the result, which by default is
formatted according to the current NUMERIC settings of DIGIT and FORM.
expp sets the number of places (digits) to be used for the exponent part,
the default being to use as many as needed. expt sets the trigger point
for use of exponential notation. If the number of places needed for the
integer or decimal part exceeds expt or twice expt respectively, expo-
nential notation will be used. The default is the current setting of NU-
MERIC DIGITS. If 0 is specified for expt, exponential notation is always
used unless the exponent would be zero.
If 0 is specified for the expp field, no exponent will be supplied, and
the number will be expressed in "simple" form with added zeros as neces-
sary (this overrides a 0 value of expt if necessary). Otherwise, if expp
is not large enough to contain the exponent, an error results. If the
exponent will be 0 in this case (a non-zero expp), then expp+2 blanks are
supplied for the exponent part of the result.
Examples:
FORMAT('12345.73',,,2,2) == '1.234573E+04'
FORMAT('12345.73',,3,,0) == '1.235E+4'
FORMAT('1.234573',,3,,0) == '1.235'
FORMAT('123.45',,3,2,0) == '1.235E+02'
FORMAT('1.2345',,3,2,0) == '1.235'
FORMAT('12345.73',,,3,6) == '12345.73'
FORMAT('1234567e5',,3,0) == '123456700000.000'
Note: If NUMERIC FORM ENGINEERING is in effect, up to three digits may be
needed for the integer part of the result (before).
┌────────────────────────────────────────────────────────────────────────┐
│ FUZZ() │
└────────────────────────────────────────────────────────────────────────┘
returns the current setting of NUMERIC FUZZ. See the NUMERIC instruction
for more information.
Example:
FUZZ() == 0 /* if default */
┌────────────────────────────────────────────────────────────────────────┐
│ INSERT( new , target [ , [ n ] [ , [ length ] [ , pad ] ] ] ) │
└────────────────────────────────────────────────────────────────────────┘
inserts the string new, padded to the length length, into the string target
after the nth character. length and n must be non-negative. If n is
greater than the length of the target string, padding is added before the
new string also. The default value fr n is 0, which means insert before
the beginning of the string. The default value for length is the length
of new. The default pad character is a blank.
Procedures and Functions 37
Examples:
INSERT(' ','abcdef',3) == 'abc def'
INSERT('123','abc',5,6) == 'abc 123 '
INSERT('123','abc',5,6,'+') == 'abc++123+++'
INSERT('123','abc') == '123abc'
INSERT('123','abc',5,,'-') == '123--abc'
┌────────────────────────────────────────────────────────────────────────┐
│ LASTPOS( needle , haystack [ , start ] ) │
└────────────────────────────────────────────────────────────────────────┘
Returns the position of the last occurrence of one string in another. (see
also POS). If the string needle is not found, then '0' is returned. By
default the search starts at the last character of haystack (i.e.,
start=LENGTH(string)) and scans backwards. This may be overridden by
specifying start, the point at which to start the backwards scan. start
must be a positive whole number.
Examples:
LASTPOS(' ','abc def ghi') == 8
LASTPOS(' ','abcdefghi') == 0
LASTPOS(' ','abc def ghi',7) == 4
┌────────────────────────────────────────────────────────────────────────┐
│ LEFT( string , k [ , pad ] ) │
└────────────────────────────────────────────────────────────────────────┘
Returns a string of length k containing the left-most k characters of
string that is padded with pad characters (or truncated) on the right as
needed. The default pad character is a blank. k must be non-negative.
Exactly equivalent to SUBSTR(string,l,k,[,pad]).
Examples:
LEFT('abc d',8) == 'abc d '
LEFT('abc d',8,'.') == 'abc d...'
LEFT('abc def',7) == 'abc de'
┌────────────────────────────────────────────────────────────────────────┐
│ LENGTH( string ) │
└────────────────────────────────────────────────────────────────────────┘
Length returns the length of the string expression passed as an argument.
For example, the following expressions all evaluate to "7":
LENGTH('abc def')
4 + LENGTH(123)
7 + LENGTH('')
┌────────────────────────────────────────────────────────────────────────┐
│ LINEIN( [ name ] [ , [ line ] [ , count ] ] ) │
└────────────────────────────────────────────────────────────────────────┘
Returns count (0 or 1) lines read from the character input stream name.
The default count is 1. The form of name is implementation-dependent. If
name is omitted, then the line will be read from the default input stream.
For PC/DOS the standard input stream is the keyboard if no name is given
or name is "KEYBOARD". If no line is available from the keyboard (using
DOS function x'0a'), the program will wait until enter is pressed. A "?"
prompt will be displayed for this option to indicate console read active.
If name is "EXQUE" the next line (if any) from the external interrupt
queue is returned. If no line exists in the external interrupt queue, the
null string is returned.
For this release the line and count options are not supported. Also LINEIN
does not support files at this time. Use the READ function instead.
Procedures and Functions 38
┌────────────────────────────────────────────────────────────────────────┐
│ LINEOUT( [ name ] [ , [ string ] [ , line ] ] ) │
└────────────────────────────────────────────────────────────────────────┘
LINEOUT is not supported at this time. Use the WRITE function instead.
┌────────────────────────────────────────────────────────────────────────┐
│ LINES( [ name ] ) │
└────────────────────────────────────────────────────────────────────────┘
returns the number of complete lines remaining in the character input
stream name. If the stream has already been read with the CHARIN function,
this may include an initial partial line. In the case of persistent
streams (files) the count starts at the current read position.
The form of name is implementation-dependent. If name is omitted, then
the number of complete lines available in the default input stream is
returned.
If an implementation cannot determine the count accurately or effi-
ciently, then it may return 1 for any non-zero result. An actual line
count may therefore be used only in programs specific to a particular
environment in which LINES is fully supported.
For PC/DOS only two names are supported: "KEYBOARD" and "EXQUE". If name
is not supplied, the count of lines remaining in the "KEYBOARD" will be
returned. As no accurate count can be established, '1' is returned if any
keystrokes are detected via the INT 16h status call (AH=1).
"EXQUE" refers to the count of lines queued in the external interrupt
queue. This queue will only contain lines if the queue interface to the
resident REXXPC88 version specified the external queue as the destination
for the message.
┌────────────────────────────────────────────────────────────────────────┐
│ MAX( number , [ number ]...) │
└────────────────────────────────────────────────────────────────────────┘
returns the largest number from the given list of numbers - that is, the
number in the list which can be derived by adding a positive number or
zero to any of the other numbers in the list. The result is formatted
according to the current NUMERIC settings.
Examples:
MAX(12,6,7,9) == 12
MAX(17.3,3,19,17.03) == 19
MAX(-7,-3,-4.3) == -3
┌────────────────────────────────────────────────────────────────────────┐
│ MIN( number , [ number ]...) │
└────────────────────────────────────────────────────────────────────────┘
returns the smallest number from the given list of numbers - that is, the
number in the list which can be derived by subtracting a positive number
or zero from any of the other numbers in the list. The result is for-
matted according to the current NUMERIC settings.
Examples:
MIN(12,6,7,9) == 6
MIN(17.3,19,17.03) == 17.03
MIN(-7,-3,-4.3) == -7
┌────────────────────────────────────────────────────────────────────────┐
│ OVERLAY( new , target [ , [ n ] [ length ] [ , pad ] ] ] ) │
└────────────────────────────────────────────────────────────────────────┘
overlays the string new, padded or truncated to length length, onto the
string target starting at the nth character. If length is specified it
must be positive or zero. If n is greater than the length of the target
string, padding is added before the new string also. The default pad
character is a blank, and the default value for n is 1. n must be greater
than 0. The default value for length is the length of new.
Procedures and Functions 39
Examples:
OVERLAY(' ','abcdef',3) == 'ab def'
OVERLAY('.','abcdef',3,2) == 'ab. ef'
OVERLAY('qq','abcd') == 'qqcd'
OVERLAY('qq',abcd',4) == 'abcqq'
OVERLAY('123','abc',5,6,'+') == 'abc+123+++'
┌────────────────────────────────────────────────────────────────────────┐
│ POS( needle , haystack [ , start ] ) │
└────────────────────────────────────────────────────────────────────────┘
Returns the position of the one string in another. See also the LASTPOS
function. If the string needle is not found, then '0' is returned. By
default the search starts at the first character of haystack (i.e.,
start=1). This may be overridden by specifying start (which must be a
positive whole number), the point at which to start the search.
Examples:
POS(' ','abc def ghi') == 4
POS('x','abc def ghi') == 0
POS(' ','abc def ghi',5) == 8
┌────────────────────────────────────────────────────────────────────────┐
│ QUEUED() │
└────────────────────────────────────────────────────────────────────────┘
Returns the number of lines remaining in the data queue at the time when
the function is invoked. If QUEUED()=0 then a PULL or PARSE PULL will read
from the console input buffer. If there is no user input waiting the will
cause a console read ("?").
Example:
QUEUED() == '5' /* parhaps */
┌────────────────────────────────────────────────────────────────────────┐
│ RANDOM( [ min ] [ , [ max ] ] [ , seed ] ) │
└────────────────────────────────────────────────────────────────────────┘
returns a quasi-random non-negative whole number in the range min to max
inclusive. If only one argument is specified, the range will be from 0
to that number. Otherwise the default values for min and max are 0 and
999 respectively. A specific seed (which must be a whole number) for the
random number may be specified as the third argument to start a repeatable
sequence of results.
The magnitude of the range (that is, max minus min) may not exceed 100000.
Examples:
RANDOM() == 305 /* possible */
RANDOM(5,8) == 7 /* possible */
RANDOM(,,1985) == 663 /* possible but constant answer */
RANDOM(2) == 0 /* possible */
Notes:
1. To obtain a predictable sequence of quasi-random numbers, call RANDOM
a number of times, but only specify seed on the first call. For ex-
ample, to simulate ten throws of a six sided dice:
say random(1,6,12345)
do 9
say random(1,6)
end
The numbers are generated mathematically, using the initial seed, so
that as far as possible they appear to be random. Running the program
again will produce the same sequence; using a different initial seed
will almost always produce a difference sequence. If you do not provide
Procedures and Functions 40
a seed, then the first time RANDOM is called an arbitrary seed will
be used. (The seed used will be the timer tick count from BIOS).
2. The random number generator is global for the entire program - the
current seed is not saved across routine calls.
3. The actual implementation differs from VM and so will not produce
indentical results in a ported VM REXX program.
┌────────────────────────────────────────────────────────────────────────┐
│ REVERSE( string ) │
└────────────────────────────────────────────────────────────────────────┘
Returns string, swapped end for end.
Example:
reverse('ABc.') == '.cBA'
┌────────────────────────────────────────────────────────────────────────┐
│ RIGHT( string , k [ , pad ] ) │
└────────────────────────────────────────────────────────────────────────┘
Returns a string of length k containing the right-most k characters of
string. That is, padded with pad characters (or truncated) on the left
as needed. The default pad character is a blank. k must be non-negative.
Example:
RIGHT('abc d',8) == ' abc d'
RIGHT('abc def',5) == 'c def'
RIGHT('12',5,'0') == '00012'
┌────────────────────────────────────────────────────────────────────────┐
│ SIGN( number ) │
└────────────────────────────────────────────────────────────────────────┘
number is rounded according to the current setting of NUMERIC DIGITS. If
the number is then less than 0 then '-1' is returned; if it is 0 then '0'
is returned; and if it is greater than 0 then '1' is returned.
Examples:
SIGN('12.3') == 1
SIGN(0.0) == 0
SIGN('-0.307') == -1
┌────────────────────────────────────────────────────────────────────────┐
│ SPACE( string [ , [ n ] [ , pad ] ] ) │
└────────────────────────────────────────────────────────────────────────┘
Formats the blank-delimited words in string with n pad characters between
each word. n must be non-negative. if n is 0, then all blanks are removed.
Leading and trailing blanks are always removed. The default for n is 1,
and the default pad character is a blank.
Examples:
SPACE('abc def ') == 'abc def'
SPACE(' abc def',3) == 'abc def'
SPACE('abc def ',1) == 'abc def'
SPACE('abc def ',0) == 'abcdef'
SPACE('abc def ',2,'+') == 'abc++def'
┌────────────────────────────────────────────────────────────────────────┐
│ STRIP( string [ , [ option ] [ , char ] ] ) │
└────────────────────────────────────────────────────────────────────────┘
Removes Leading, Trailing, or Both leading and trailing characters from
string when the first character of option is 'L', 'T', or 'B' respectively
(these may be given in upper or lower case). The default is 'B'. The third
argument, char specifies the character to be removed, with the default
being a blank. If given, char must be exactly one character long.
Procedures and Functions 41
Examples:
STRIP(' ab c ') == 'ab c'
STRIP(' ab c ','L') == 'ab c '
STRIP(' ab c ','t') == ' ab c'
STRIP('12.7000',,'0') == '12.7'
STRIP('0012.700',,'0') == '12.7'
┌────────────────────────────────────────────────────────────────────────┐
│ SUBSTR( string , pos [ , length [ , pad ] ] ) │
└────────────────────────────────────────────────────────────────────────┘
substr extracts a substring of specified length, starting at pos. If
length would exceed the remainder of string then characters of value pad
are appended as required. If length is omitted it defaults to the length
of the remaining string. If pad is omitted it defaults to a blank.
For example, the following expressions all evaluate to "abc$$$":
SUBSTR('abc$$$', 1)
SUBSTR('xyzabc$$$', 4)
SUBSTR('xyzabc', 4, 6, '$')
┌────────────────────────────────────────────────────────────────────────┐
│ SUBWORD( string , n [ , k ] ) │
└────────────────────────────────────────────────────────────────────────┘
Returns the substring of string that starts at the nth word, and is of
length k blank-delimited words. n must be positive. If k is omitted it
defaults to the remaining words in the string. The returned string will
never have leading or trailing blanks, but will include all blanks between
selected words.
Example:
SUBWORD('Now is the time',2,2) == 'is the'
SUBWORD('Now is the time',3) == 'the time'
SUBWORD('Now is the time',5) == ''
┌────────────────────────────────────────────────────────────────────────┐
│ SYMBOL( name ) │
└────────────────────────────────────────────────────────────────────────┘
If name is not a valid REXXPC88 symbol, 'BAD' is returned. If it is the
name of a variable (that is, a symbol that has been assigned a value),
'VAR' is returned. Otherwise 'LIT' is returned, which indicates that it
is either a constant symbol or a symbol that has not yet been assigned a
value (that is a Literal).
┌────────────────────────────────────────────────────────────────────────┐
│ TIME( [ option ] ) │
└────────────────────────────────────────────────────────────────────────┘
by default returns the local time in the 24-hour clock format 'hh:mm:ss'
(hours, minutes, and seconds). e.g., '04:41:37'.
The following options (first letter significant) may be supplied to obtain
alternative formats:
Civil returns 'hh:mmxx', the time in Civil format, in which the hours
may take values from 1 thru 12, and the minutes the values 00
through 59. The minutes are immediately followed by the letters
"am" or "pm" to distinguish times in the morning (midnight 12:00
am through 11:59am) from noon and afternoon (noon 12:00pm
through 11:59pm). The hour will not have a leading zero. The
minute field shows the current minute (rather than the nearest
minute) for consistency with other TIME results.
Normal Returns the time in the default format described above.
Long Returns time in the format: hh:mm:ss.uuuuuu (uuuuuu is the
fraction of seconds, in hundredths).
Procedures and Functions 42
Hours returns the number of Hours since midnight in the format: hh
(no leading zero).
Minutes returns the number of minutes since midnight in the format: mmmm
(no leading zeros).
Seconds returns the number of seconds since midnight in the format:
sssss (no leading zeros).
Elapsed returns 'sssssssss.uuuuuu', the number of seconds (and hun-
dredths) since the elapsed time clock was started or reset. The
number will have no leading zeros or blanks, and is not
affected by the setting of NUMERIC DIGITS.
Reset returns 'sssssssss.uuuuuu', the number of seconds (and hun-
dredths) since the elapsed time clock was started or reset, and
simultaneously resets the elapsed time clock to zero. The num-
ber will have no leading zeros or blanks, and is not affected
by the setting of NUMERIC DIGITS.
Examples:
TIME('L') == '16:54:22.123456'
TIME() == '16:54:22'
TIME('H') == '16'
TIME('M') == '1014' /* 54 + 60*16 */
TIME('S') == '60862' /* 22 + 60*(54+60*16) */
The elapsed time clock
The time function may be used for measuring real (elapsed) time intervals.
On the first call in a program to the TIME('E') or TIME('R'), the elapsed
time clock is started and either call would return 0. From then on, calls
to TIME('E') or TIME('R') will return the elapsed time since that first
call or since the last call to TIME('R').
Examples:
TIME('E') == 0 /* first call in program */`
TIME('E') == 1.120000 /* approx 1 second */
TIME('R') == 2.220000 /* approx 1 more second */
TIME('R') == 1.120000 /* approx 1 second since last time(r) */
The clock is saved across internal routine calls, which is to say that an
internal routine will inherit the time clock started by its caller,
but if it should reset the clock, then any timing being done by the caller
will not be affected.
Note: The first call to TIME in one expression causes a time stamp to be
made which is then used for all calls to this function in that expression.
Hence if multiple calls to any of the TIME functions are made in a single
expression, they are guaranteed to be consistent with each other.
┌────────────────────────────────────────────────────────────────────────┐
│ TRACE( [ setting ] ) │
└────────────────────────────────────────────────────────────────────────┘
returns the trace setting currently in effect, and optionally alters the
trace setting.
If setting is supplied, it is used to select the trace setting. The set-
ting must be a valid prefix("?") and/or one of the alphabetic character
settings (A,C,E,F,I,L,N or R) associated with the TRACE instruction.
┌────────────────────────────────────────────────────────────────────────┐
│ TRANSLATE( string [ , [ tableo ] [ , [ tablei ] [ , pad ] ] ] ) │
└────────────────────────────────────────────────────────────────────────┘
Translates characters in string to other characters, or may be used to
reorder characters in a string. The input translate table is tablei (the
default is XRANGE('00'x,'FFx)), and tableo is the output table. If nei-
ther translate table is given, string is simply translated to upper case.
The output table defaults to the null string, and is padded with pad
characters or truncated as necessary. The default pad is a blank.
The tables may be of any length; the first occurrence of a character in
the input table is the one that is used if there are any duplicates. If a
Procedures and Functions 43
character in string does not appear in tablei then it will appear in the
result string unchanged.
Examples:
TRANSLATE('abcdef') == 'ABCDEF'
TRANSLATE('abbc','&','b') == 'a&&c'
TRANSLATE('abcdef','12','ec') == 'ab2d1f'
TRANSLATE('abcdef','12','abcd','.') == '12..ef'
TRANSLATE('4123','abcd','1234') == 'dabc'
┌────────────────────────────────────────────────────────────────────────┐
│ TRUNC( number [ , n ] ) │
└────────────────────────────────────────────────────────────────────────┘
returns the integer part of the number, and n decimal places (digits after
the decimal point). n must be non-negative and defaults to zero. The
number is truncated to n decimal places (or trailing zeros are added if
needed to make up the specified length). If n is 0 (the default) than an
integer with no decimal point is returned. The result will never be in
exponential form.
Examples:
TRUNC(12.3) == 12
TRUNC(127.09782,3) == 127.097
TRUNC(127.1,3) == 127.100
TRUNC(127,2) == 127.00
Note: The number will be rounded according to the current setting of NU-
MERIC DIGITS, if necessary, before being processed by the function.
┌────────────────────────────────────────────────────────────────────────┐
│ VALUE( name ) │
└────────────────────────────────────────────────────────────────────────┘
returns the value of the symbol name. As with symbols appearing normally
in REXXPC88 expressions, lower case characters in the name will be
translated to upper case and substitution in a compound name will occur
if possible. name must be a valid REXXPC88 symbol, or an error results.
┌────────────────────────────────────────────────────────────────────────┐
│ VERIFY( string , reference [ , [ option ] [ start ] ] ) │
└────────────────────────────────────────────────────────────────────────┘
verifies that the string is composed only of characters from reference,
by returning the position of the first character in string that is not
also in reference. If all the characters were found in reference, 0 is
returned.
The option may be either 'Nomatch' (the default) or 'Match'. Only the
first character of option is significant and it may be in upper case or
lower case, as usual. If 'Match' is specified, the position of the first
character in string that is in reference is returned, or 0 if none of the
characters were found.
The default for start is 1, i.e., the search starts at the first character
of string. This can be overridden by giving a different start point,
which must be positive.
If string is null, the function returns 0, regardless of the value of the
third argument (option). Similiarly, if start is greater than
LENGTH(string), 0 is returned
Examples:
VERIFY('123','1234567890') == 0
VERIFY('1Z3','1234567890') == 2
VERIFY('AB4T','1234567890','M') == 3
VERIFY('1P3Q4','1234567890',,3) == 4
VERIFY('AB3CD5','1234567890','M',4) == 6
Procedures and Functions 44
┌────────────────────────────────────────────────────────────────────────┐
│ WORD( string , n ) │
└────────────────────────────────────────────────────────────────────────┘
Returns the nth blank-delimited word in string. n must be positive. If
there are less than n words in string, then the null string is returned.
Exactly equivalent to SUBWORD(string,n,1).
Examples:
WORD('Now is the time',3) == 'the'
WORD('Now is the time',5) == ''
┌────────────────────────────────────────────────────────────────────────┐
│ WORDINDEX( string , n ) │
└────────────────────────────────────────────────────────────────────────┘
Returns the character position of the nth blank-delimited word in
string. n must be positive. If there are not n words in string, then 0
is returned.
Examples:
WORDINDEX('Now is the time',3) == 8
WORDINDEX('Now is the time',6) == 0
┌────────────────────────────────────────────────────────────────────────┐
│ WORDLENGTH( string , n ) │
└────────────────────────────────────────────────────────────────────────┘
Returns the length of the nth blank-delimited word in string. n must be
positive. If there are not n words in string, then 0 is returned.
Examples:
WORDLENGTH('Now is the time',2) == 2
WORDLENGTH('Now comes the time',2) == 5
WORDLENGTH('Now is the time',6) == 0
┌────────────────────────────────────────────────────────────────────────┐
│ WORDPOS( phrase , string [ , start ] ) │
└────────────────────────────────────────────────────────────────────────┘
searches string for the first occurrence of the sequence of blank-
delimited words phrase, and returns the word number of the first word of
phrase in string. Multiple blanks between words in either phrase or string
are treated as a single blank for comparison, but otherwise the words
must match exactly. Returns 0 if phrase is not found.
By default the search starts at the first word in string. This may be
overridden by specifying start (which must be positive), the word at which
to start the search.
* Note: The function FIND is replaced with this function. See the differ-
* ences section for more info.
Examples:
WORDPOS('the','now is the time') == 3
WORDPOS('The','now is the time') == 0
WORDPOS('is the','now is the time') == 2
WORDPOS('is the','now is the time') == 2
WORDPOS('is time ','now is the time') == 0
WORDPOS('be','To be or not to be') == 2
WORDPOS('be','To be or not to be',3') == 6
┌────────────────────────────────────────────────────────────────────────┐
│ WORDS( string ) │
└────────────────────────────────────────────────────────────────────────┘
Returns the number of blank-delimited words in string.
Procedures and Functions 45
Examples:
WORDS('Now is the time') == 4
WORDS(' ') == 0
┌────────────────────────────────────────────────────────────────────────┐
│ ASK( [ 'noecho' ] ) │
└────────────────────────────────────────────────────────────────────────┘
Ask returns a line read from standard input. As characters are typed by
the user, they are echoed unless the string "noecho" is supplied as an
argument to ask, in which case they are not echoed. The backspace key
may be used to edit the input line. Characters are read until the ENTER
key is typed. The ENTER key is not included as part of the returned
string. Example:
/* prompt for a response */
say 'Enter your name'
/* get it (echo the response) */
name = ask()
/* prompt for another response */
say 'Enter your password'
/* get it (don't echo the response) */
pword = ask(noecho)
┌────────────────────────────────────────────────────────────────────────┐
│ VER() │
└────────────────────────────────────────────────────────────────────────┘
returns the current DOS version number in the format m.nn, where m is the
major version number and nn is the minor version number.
Examples:
VER() == 2.00 /* for dos 2.0 */
VER() == 2.10 /* for dos 2.1 */
VER() == 3.00 /* for dos 3.0 */
VER() == 3.10 /* for dos 3.1 */
VER() == 3.20 /* for dos 3.2 */
Note: I intend to add another word identifying the language currently
active.
┌────────────────────────────────────────────────────────────────────────┐
│ GETENV( string ) │
└────────────────────────────────────────────────────────────────────────┘
returns the contents of the environment variable string. If string is not
found, the null string is returned.
The name of the environment variable string does NOT include the equal
('=') sign.
Examples:
GETENV('PATH') == 'C:\;' /* perhaps */
GETENV('xyz') == '' /* perhaps */
Note:
The string may be in either upper or lower case.
For PC/DOS this function searches the environment area of the master
copy of COMMAND.COM or the process that this REXXPC88 program is
running under. If it is COMMAND.COM and the environment area moves
from its default location (either resident version or standalone
version) then changes to the environment will not be found until the
next REXXPC88 program is run.
┌────────────────────────────────────────────────────────────────────────┐
│ EXTLOADED( funcname ) │
└────────────────────────────────────────────────────────────────────────┘
Procedures and Functions 46
returns either "0" or "1" depending on whether the resident extension
named funcname answered the loaded call.
Note: This function uses the new AX=7 loaded function to determine the
value to be returned. The extension must be coded to respond to the call
properly.
Examples:
EXTLOADED('HSAY') == '0' /* probably, rex2host function */
EXTLOADED('DISPLAY') == '0' /* for sure, rexxezvu function */
┌────────────────────────────────────────────────────────────────────────┐
│ LISTFILE( [ filespec ] [ , [ attributes ] ] [ , [ option ] ] ) │
└────────────────────────────────────────────────────────────────────────┘
Listfile provides a file listing capability like that of the listfile
command on VM.
Filespec is the optional parameter that is the file name string to search
for. This spec may include the global file name characters * and ?. If
not specified the filespec defaults to "*.*".
Attributes is the optional decimal numeric value of the file attributes
to search for.
If attribute is a positive number, the search will take place according
to the standard DOS rules concerning inclusive and exclusive searches
(i.e., you will get files on all searches, even if you ask for directories
only).
If attribute is a negative number, the search will return ONLY those files
which match exactly the option specified. The absolute value of attribute
is used in all cases.
Note: See the DOS Technical Reference manual for a description of the
values for this field. If not specified the attribute defaults to 55, all
attributes.
If option is supplied as the third argument, it must evaluate to one of
the following strings:
FIFO The result of the listfile command is to be placed on the data
queue in First-in, First-out order.
LIFO The result of the listfile command is to be placed on the data
queue in Last-in, First-out order.
any other The result of the listfile command is to be displayed on the
users console.
The data returned by listfile consists of the following info:
fn File name including dot between filename and extension with NO
imbedded spaces.
fsize File size in bytes, directories are 0.
fattr File attributes in decimal. See the DOS Technical Reference
under file attributes for the values.
wdate Last file write date
ftime Last file write time
[<DIR>] If the file is a directory this string will be the last field
This allows a quich check without having to know the attribute
of a directory entry (16).
[<VOL>] If the file is a volume label this string will be the last field
This allows a quick check without having to know the attribute
of a volume label (8).
* ┌────────────────────────────────────────────────────────────────────────┐
* │ REXXRES() │
* └────────────────────────────────────────────────────────────────────────┘
* This function will provide an indicator for whether the RESIDENT or
* STANDALONE version is running the REXXIBM program. The result of the
* function is '1' if resident version, or '0' if standalone version.
Procedures and Functions 47
* Examples:
*
* REXXRES() == '0' /* if STANDALONE version executing */
* REXXRES() == '1' /* if RESIDENT version executing */
*
File management routines
┌────────────────────────────────────────────────────────────────────────┐
│ DIRECTORY( [ newdirectory ] ) │
└────────────────────────────────────────────────────────────────────────┘
This function returns the "current working directory", first changing it
to newdirectory if an argument is supplied and the new directory exists.
Under MSDOS, directory() returns a drive letter prefix as the first two
characters of the directory name. Specifying a drive letter prefix as
part of the newdirectory string causes that drive to become the "current
drive". If a directory is specified, then in addition that directory
becomes the "current directory". If no drive letter is specified, then
the "current drive" remains unchanged.
The following program fragment saves the current directory, switches to
a new directory, performs an operation there, and then returns to the
former directory.
/* get current directory */
curdir = directory()
/* go play a game */
newdir = directory("d:/usr/games")
if newdir = "d:/usr/games" then
do
fortune /* tell a fortune */
/* return to former directory */
call directory curdir
end
else
say 'Can''t find /usr/games'
┌────────────────────────────────────────────────────────────────────────┐
│ READ( filename [ , position ] ) │
└────────────────────────────────────────────────────────────────────────┘
Read returns one line from the file named in its first argument, starting
at the current read/write position (which is the beginning of the file
if the file has never been read or written). The read/write position is
advanced by the size of the line read. A carriage return, followed by a
linefeed is expected to terminate the line, but it and the linefeed is
thrown away and not included in the returned string.
If the end of file is encountered, '' (an empty string) is returned.
A line consisting of 0 characters followed by a carriage return (and
perhaps a linefeed) is returned as ' ' (a string containing a single
blank) so that it can't be misinterpreted as indicating the end of the
file. Example:
/* display a file */
say 'Enter filename' /* ask user for a name */
fname = ask () /* get his response */
do forever
fline = read(fname) /* next line of file */
say fline /* display it */
if fline == '' then /* is it empty? */
do /* yes... we're done */
say 'END-OF-FILE'
return
end
end
Procedures and Functions 48
there is a limit on the length of the longest line that can be read (See
"Appendix G. Bugs and Limitations" on page 73).
┌────────────────────────────────────────────────────────────────────────┐
│ SEEK( filename [ , position ] ) │
└────────────────────────────────────────────────────────────────────────┘
Seek may be used to find out, or to set, the byte offset within filename
at which subsequent reading or writing will take place. If the second
argument is omitted, seek returns the current read/write position. If
the second argument is supplied, REXXPC88 will reset its read/write po-
sition to that offset within the file. The second argument must be a
number and must be positive or zero. Examples:
/* point read/write position to the first
* character of a file
*/
myfile = 'd:/tmp/junk.jnk'
call seek myfile, 0
/* find out current read/write position */
curpos = seek(myfile)
/* point read/write position to the EOF character
* at the end of a standard DOS text file, so
* subsequent write()'s will append to the file
*/
call seek myfile, size(myfile) - 1
┌────────────────────────────────────────────────────────────────────────┐
│ SIZE( FILENAME ) │
└────────────────────────────────────────────────────────────────────────┘
If filename exists, its size (in bytes) is returned. Otherwise '' (an
empty string) is returned.
┌────────────────────────────────────────────────────────────────────────┐
│ WRITE( filename , string [ , option ] ) │
└────────────────────────────────────────────────────────────────────────┘
Write writes the string supplied as its second argument to the file named
by its first argument. The string is written at the current read/write
position (which is the beginning of the file if the file has never been
read or written). The read/write position is advanced by the length of
the string written.
Write returns '' (an empty string) if the write failed to a disk-full
condition or a read-only file. Otherwise it returns the string that was
written.
If option is supplied as the third argument, it must evaluate to one of
the following strings:
eol a carriage return and line feed ('0D'x and '0A'x, respectively)
are written to the file following the string. The read/write
position is advanced by 2, in addition to the length of the
string.
eof an end-of-file mark ('1A'x) is written to the file following
the string. The read/write position is advanced by 1, in ad-
dition to the length of the string.
a number the number is used as a screen writing attribute (this applies
only to the special file named "screen"; see "Appendix B. Spe-
cial files" on page 56).
Procedures and Functions 49
Example 1:
/* create a new file and write 2 lines to it */
myfile = 'd:/tmp/junk.jnk'
if size(myfile) <> '' then /* file exists... */
erase myfile /* ...erase it */
call write myfile, 'Hello world', eol /*line 1*/
call write myfile, 'Whats ' /*line 2, part 1 */
call write myfile, 'new', eol /*line 2, part 2*/
call write myfile, '', eof /* empty line + EOF*/
/* the file now contains the following data:
* Hello world<CR><LF>Whats new<CR><LF><EOF>
*/
/* read back the first line and display it */
call seek myfile, 0 /* point to the first line */
say read(myfile) /* read and display */
/* change the second line */
call seek myfile, 19 /* point to 'new' */
/* change 'new' to 'old' */
call write myfile, 'old'
/* re-display second line */
call seek myfile, 13 /* point to 2nd line */
say read(myfile) /* read and display */
Example 2:
/* write with error detection */
if write(myfile, 'abc', eol) == '' then
do
say 'Write failed'
exit
end
┌────────────────────────────────────────────────────────────────────────┐
│ FINISH( filename ) │
└────────────────────────────────────────────────────────────────────────┘
Finish forces any pending output to be written to the named file and
then frees REXXPC88's internal file tables for future use. The finish
function need only be called explicitly if you will be manipulating a
large number of files (the exact number depends on how REXXPC88 was in-
voked: see "Executing A Rexx Program") with the read, write, or seek
functions. REXXPC88 will automatically finish all active files for
you before terminating your program. Example:
/* Write 20 files */
do i = 1 to 20
/* write next file... */
say write(testfile.i, 'This is' testfile.i, eol)
/* we're done with this file for now... */
call finish testfile.i
end
Procedures and Functions 50