Built-in Functions

Rexx provides a set of built-in functions, including character manipulation, conversion, and information functions. The following are general notes on the built-in functions:

ABBREV (Abbreviation)

>>-ABBREV(information,info--+---------+--)---------------------><
                            +-,length-+

Returns 1 if info is equal to the leading characters of information and the length of info is not less than length. It returns 0 if either of these conditions is not met.

If you specify length, it must be a positive whole number or zero. The default for length is the number of characters in info.

Here are some 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 always matches if a length of 0, or the default, is used. This allows a default keyword to be selected automatically if desired; for example:

say "Enter option:";   pull option .
select  /* keyword1 is to be the default */
  when abbrev("keyword1",option) then ...
  when abbrev("keyword2",option) then ...
  ...
  otherwise nop;
end;

ABS (Absolute Value)

>>-ABS(number)-------------------------------------------------><

Returns the absolute value of number. The result has no sign and is formatted according to the current NUMERIC settings.

Here are some examples:

ABS("12.3")       ->    12.3
ABS(" -0.307")    ->    0.307

ADDRESS

>>-ADDRESS()---------------------------------------------------><

Returns the name of the environment to which commands are currently submitted. Trailing whitespace characters are removed from the result.

Here is an example:

ADDRESS()    ->    "CMD"        /* default under Windows */

ADDRESS()    ->    "bash"       /* default under Linux   */

ARG (Argument)

>>-ARG(--+----------------+--)---------------------------------><
         +-n--+---------+-+
              +-,option-+

Returns one or more arguments, or information about the arguments to a program, internal routine, or method.

If you do not specify n, the number of arguments passed to the program or internal routine is returned.

If you specify only n, the nth argument object is returned. If the argument object does not exist, the null string is returned. n must be a positive whole number.

If you specify option, the value returned depends on the value of option. The following are valid options. (Only the capitalized letter is needed; all characters following it are ignored.)

Array

returns a single-index array containing the arguments, starting with the nth argument. The array indexes correspond to the argument positions, so that the nth argument is at index 1, the following argument at index 2, and so on. If any arguments are omitted, their corresponding indexes are absent.

Exists

returns 1 if the nth argument exists; that is, if it was explicitly specified when the routine was called. Otherwise, it returns 0.

Normal

returns the nth argument, if it exists, or a null string.

Omitted

returns 1 if the nth argument was omitted; that is, if it was not explicitly specified when the routine was called. Otherwise, it returns 0.

Here are some examples:

/*  following "Call name;" (no arguments) */
ARG()         ->    0
ARG(1)        ->    ""
ARG(2)        ->    ""
ARG(1,"e")    ->    0
ARG(1,"O")    ->    1
ARG(1,"a")    ->    .array~of()

/*  following "Call name 'a', ,'b';" */
ARG()         ->    3
ARG(1)        ->    "a"
ARG(2)        ->    ""
ARG(3)        ->    "b"
ARG(n)        ->    ""    /* for n>=4 */
ARG(1,"e")    ->    1
ARG(2,"E")    ->    0
ARG(2,"O")    ->    1
ARG(3,"o")    ->    0
ARG(4,"o")    ->    1
ARG(1,"A")    ->    .array~of(a, ,b)
ARG(3,"a")    ->    .array~of(b)

Notes:

  1. The number of argument strings is the largest number n for which ARG(n,"e") returns 1 or 0 if there are no explicit argument strings. That is, it is the position of the last explicitly specified argument string.

  2. Programs called as commands can have only 0 or 1 argument strings. The program has 0 argument strings if it is called with the name only and has 1 argument string if anything else (including whitespace characters) is included in the command.

  3. Programs called by the RexxStart entry point can have several argument strings. (See the Open Object Rexx: Programming Guide for information about RexxStart.)

  4. You can access the argument objects of a program with the USE instruction. See USE for more information.

  5. You can retrieve and directly parse the argument strings of a program or internal routine with the ARG or PARSE ARG instructions.

B2X (Binary to Hexadecimal)

>>-B2X(binary_string)------------------------------------------><

Returns a string, in character format, that represents binary_string converted to hexadecimal.

The binary_string is a string of binary (0 or 1) digits. It can be of any length. You can optionally include whitespace characters in binary_string (at 4-digit boundaries only, not leading or trailing) to improve readability; they are ignored.

The returned string uses uppercase alphabetical characters for the values A-F, and does not include blanks or horizontal tabs.

If binary_string is the null string, B2X returns a null string. If the number of binary digits in binary_string is not a multiple of 4, then up to three 0 digits are added on the left before the conversion to make a total that is a multiple of 4.

Here are some examples:

B2X("11000011")    ->   "C3"
B2X("10111")       ->   "17"
B2X("101")         ->   "5"
B2X("1 1111 0000") ->   "1F0"

You can combine B2X with the functions X2D and X2C to convert a binary number into other forms. For example:

X2D(B2X("10111"))  ->   "23"   /* decimal 23 */

BEEP

>>-BEEP(frequency,duration)------------------------------------><

Sounds the speaker at frequency (Hertz) for duration (milliseconds). The frequency can be any whole number in the range 37 to 32767 Hertz. The duration can be any number in the range 1 to 60000 milliseconds.

This routine is most useful when called as a subroutine. A null string is returned.

Note: Both parameters (frequency, duration) are ignored on Windows 95 and Linux. On computers with multimedia support the function plays the default sound event. On computers without soundcard, the function plays the standard system beep (if activated).

Here is an example for Windows NT:

/* C scale */
note.1 = 262    /* middle C */
note.2 = 294    /*    D     */
note.3 = 330    /*    E     */
note.4 = 349    /*    F     */
note.5 = 392    /*    G     */
note.6 = 440    /*    A     */
note.7 = 494    /*    B     */
note.8 = 523    /*    C     */

do i=1 to 8
call beep note.i,250    /* hold each note for */
/* one-quarter second */
end

BITAND (Bit by Bit AND)

>>-BITAND(string1--+--------------------------+--)-------------><
                   +-,--+---------+--+------+-+
                        +-string2-+  +-,pad-+

Returns a string composed of the two input strings logically ANDed, bit by bit. (The encodings of the strings are used in the logical operation.) The length of the result is the length of the longer of the two strings. If no pad character is provided, the AND operation stops when the shorter of the two strings is exhausted, and the unprocessed portion of the longer string is appended to the partial result. If pad is provided, it extends the shorter of the two strings on the right before carrying out the logical operation. The default for string2 is the zero-length (null) string.

Here are some examples:

BITAND("12"x)                  ->    "12"x
BITAND("73"x,"27"x)            ->    "23"x
BITAND("13"x,"5555"x)          ->    "1155"x
BITAND("13"x,"5555"x,"74"x)    ->    "1154"x
BITAND("pQrS", ,"DF"x)         ->    "PQRS"      /* ASCII   */

BITOR (Bit by Bit OR)

>>-BITOR(string1--+--------------------------+--)--------------><
                  +-,--+---------+--+------+-+
                       +-string2-+  +-,pad-+

Returns a string composed of the two input strings logically inclusive-ORed, bit by bit. (The encodings of the strings are used in the logical operation.) The length of the result is the length of the longer of the two strings. If no pad character is provided, the OR operation stops when the shorter of the two strings is exhausted, and the unprocessed portion of the longer string is appended to the partial result. If pad is provided, it extends the shorter of the two strings on the right before carrying out the logical operation. The default for string2 is the zero-length (null) string.

Here are some examples:

BITOR("12"x)                  ->    "12"x
BITOR("15"x,"24"x)            ->    "35"x
BITOR("15"x,"2456"x)          ->    "3556"x
BITOR("15"x,"2456"x,"F0"x)    ->    "35F6"x
BITOR("1111"x, ,"4D"x)        ->    "5D5D"x
BITOR("pQrS", ,"20"x)         ->    "pqrs" /* ASCII   */

BITXOR (Bit by Bit Exclusive OR)

>>-BITXOR(string1--+--------------------------+--)-------------><
                   +-,--+---------+--+------+-+
                        +-string2-+  +-,pad-+

Returns a string composed of the two input strings logically eXclusive-ORed, bit by bit. (The encodings of the strings are used in the logical operation.) The length of the result is the length of the longer of the two strings. If no pad character is provided, the XOR operation stops when the shorter of the two strings is exhausted, and the unprocessed portion of the longer string is appended to the partial result. If pad is provided, it extends the shorter of the two strings on the right before carrying out the logical operation. The default for string2 is the zero-length (null) string.

Here are some examples:

BITXOR("12"x)                     ->  "12"x
BITXOR("12"x,"22"x)               ->  "30"x
BITXOR("1211"x,"22"x)             ->  "3011"x
BITXOR("1111"x,"444444"x)         ->  "555544"x
BITXOR("1111"x,"444444"x,"40"x)   ->  "555504"x
BITXOR("1111"x, ,"4D"x)           ->  "5C5C"x
BITXOR("C711"x,"222222"x," ")     ->  "E53302"x  /* ASCII  */

C2D (Character to Decimal)

>>-C2D(string--+----+--)---------------------------------------><
               +-,n-+

Returns the decimal value of the binary representation of string. If the result cannot be expressed as a whole number, an error results. That is, the result must not have more digits than the current setting of NUMERIC DIGITS. If you specify n, it is the length of the returned result. If you do not specify n, string is processed as an unsigned binary number.

If string is null, 0 is returned.

Here are some examples:

C2D("09"X)      ->        9
C2D("81"X)      ->      129
C2D("FF81"X)    ->    65409
C2D("")         ->        0
C2D("a")        ->       97     /*  ASCII   */

If you specify n, the string is taken as a signed number expressed in n characters. The number is positive if the leftmost bit is off, and negative if the leftmost bit is on. In both cases, it is converted to a whole number, which can be negative. The string is padded on the left with "00"x characters (not "sign-extended"), or truncated on the left to n characters. This padding or truncation is as though RIGHT(string, n,"00"x) had been processed. If n is 0, C2D always returns 0.

Here are some examples:

C2D("81"X,1)      ->     -127
C2D("81"X,2)      ->      129
C2D("FF81"X,2)    ->     -127
C2D("FF81"X,1)    ->     -127
C2D("FF7F"X,1)    ->      127
C2D("F081"X,2)    ->    -3967
C2D("F081"X,1)    ->     -127
C2D("0031"X,0)    ->        0

C2X (Character to Hexadecimal)

>>-C2X(string)-------------------------------------------------><

Returns a string, in character format, that represents string converted to hexadecimal. The returned string contains twice as many bytes as the input string. On an ASCII system, C2X(1) returns 31 because the ASCII representation of the character 1 is "31"X.

The string returned uses uppercase alphabetical characters for the values A-F and does not include whitespace characters. The string can be of any length. If string is null, a null string is returned.

Here are some examples:

C2X("0123"X)    ->    "0123"   /* "30313233"X     in ASCII */
C2X("ZD8")      ->    "5A4438" /* "354134343338"X in ASCII */

CENTER (or CENTRE)

>>-+-CENTER(-+--string,length--+------+--)---------------------><
   +-CENTRE(-+                 +-,pad-+

Returns a string of length length with string centered in it and with pad characters added as necessary to make up length. The length must be a positive whole number or zero. The default pad character is blank. If the string is longer than length, it is truncated at both ends to fit. If an odd number of characters is truncated or added, the right-hand end loses or gains one more character than the left-hand end.

Here are some examples:

CENTER(abc,7)               ->    "  ABC  "
CENTER(abc,8,"-")           ->    "--ABC---"
CENTRE("The blue sky",8)    ->    "e blue s"
CENTRE("The blue sky",7)    ->    "e blue "

Note: To avoid errors because of the difference between British and American spellings, this function can be called either CENTRE or CENTER.

CHANGESTR

>>-CHANGESTR(needle,haystack,newneedle--+--------+--)------------------------><
                                        +-,count-+

Returns a copy of haystack in which newneedle replaces occurrences of needle. If count is not specified, all occurrences of needle are replaced. If count is specified, it must be a positive, whole number that gives the maximum number of occurrences to be replaced. The following defines the effect:

result = ""
$tempx = 1
do forever
   $tempy = pos(needle, haystack, $tempx)
   if $tempy = 0 then leave
   result = result || substr(haystack, $tempx, $tempy - $tempx) || newneedle
   $tempx = $tempy + length(needle)
end
result = result || substr(haystack, $tempx)

Here are some examples:

CHANGESTR("1","101100","")     ->    "000"
CHANGESTR("1","101100","X")    ->    "X0XX00"
CHANGESTR("1","101100","X", 1) ->    "X01100"

CHARIN (Character Input)

>>-CHARIN(--+------+--+---------------------------+--)---------><
            +-name-+  +-,--+-------+--+---------+-+
                           +-start-+  +-,length-+

Returns a string of up to length characters read from the character input stream name. (To understand the input and output functions, see Input and Output Streams.) If you omit name, characters are read from STDIN, which is the default input stream. The default length is 1.

For persistent streams, a read position is maintained for each stream. Any read from the stream starts at the current read position by default. When the language processor completes reading, the read position is increased by the number of characters read. You can give a start value to specify an explicit read position. This read position must be a positive whole number and within the bounds of the stream, and must not be specified for a transient stream. A value of 1 for start refers to the first character in the stream. If start is not a positive whole number the appropriate syntax condition is raised. When the read position is past the bounds of the stream, the empty string is returned and the NOTREADY condition is raised.

If you specify a length of 0, then the read position is set to the value of start, but no characters are read and the null string is returned.

In a transient stream, if there are fewer than length characters available, the execution of the program generally stops until sufficient characters become available. If, however, it is impossible for those characters to become available because of an error or another problem, the NOTREADY condition is raised (see Errors during Input and Output) and CHARIN returns with fewer than the requested number of characters.

Here are some examples:

CHARIN(myfile,1,3)   ->   "MFC"    /* the first 3        */
                                   /* characters         */
CHARIN(myfile,1,0)   ->   ""       /* now at start       */
CHARIN(myfile)       ->   "M"      /* after last call    */
CHARIN(myfile, ,2)   ->   "FC"     /* after last call    */

/* Reading from the default input (here, the keyboard)   */
/* User types "abcd efg"                                 */
CHARIN()             ->   "a"      /* default is         */
                                   /* 1 character        */
CHARIN(, ,5)         ->   "bcd e"

Notes:

  1. CHARIN returns all characters that appear in the stream, including control characters such as line feed, carriage return, and end of file.

  2. When CHARIN reads from the keyboard, program execution stops until you press the Enter key.

CHAROUT (Character Output)

>>-CHAROUT(--+------+--+---------------------------+--)--------><
             +-name-+  +-,--+--------+--+--------+-+
                            +-string-+  +-,start-+

Returns the count of characters remaining after attempting to write string to the character output stream name. (To understand the input and output functions, see Input and Output Streams.) If you omit name, characters in string are written to STDOUT (generally the display), which is the default output stream. The string can be a null string, in which case no characters are written to the stream, and 0 is always returned.

For persistent streams, a write position is maintained for each stream. Any write to the stream starts at the current write position by default. When the language processor completes writing, the write position is increased by the number of characters written. When the stream is first opened, the write position is at the end of the stream so that calls to CHAROUT append characters to the end of the stream.

You can give a start value to specify an explicit write position for a persistent stream. This write position must be a positive whole number. A value of 1 for start refers to the first character in the stream.

You can omit the string for persistent streams. In this case, the write position is set to the value of start that was given, no characters are written to the stream, and 0 is returned. If you do not specify start or string, the stream is closed and 0 is returned.

Execution of the program usually stops until the output operation is complete.

For example, when data is sent to a printer, the system accepts the data and returns control to Rexx, even though the output data might not have been printed. Rexx considers this to be complete, even though the data has not been printed. If, however, it is impossible for all the characters to be written, the NOTREADY condition is raised (see Errors during Input and Output) and CHAROUT returns with the number of characters that could not be written (the residual count).

Here are some examples:

CHAROUT(myfile,"Hi")     ->   0   /* typically        */
CHAROUT(myfile,"Hi",5)   ->   0   /* typically        */
CHAROUT(myfile, ,6)      ->   0   /* now at char 6    */
CHAROUT(myfile)          ->   0   /* at end of stream */
CHAROUT(,"Hi")           ->   0   /* typically        */
CHAROUT(,"Hello")        ->   2   /* maybe            */

Note: This routine is often best called as a subroutine. The residual count is then available in the variable RESULT.

For example:

Call CHAROUT myfile,"Hello"
Call CHAROUT myfile,"Hi",6
Call CHAROUT myfile

CHARS (Characters Remaining)

>>-CHARS(--+------+--)-----------------------------------------><
           +-name-+

Returns the total number of characters remaining in the character input stream name. The count includes any line separator characters, if these are defined for the stream. In the case of persistent streams, it is the count of characters from the current read position. (See Input and Output Streams for a discussion of Rexx input and output.) If you omit name, the number of characters available in the default input stream (STDIN) is returned.

The total number of characters remaining cannot be determined for some streams (for example, STDIN). For these streams, the CHARS function returns 1 to indicate that data is present, or 0 if no data is present. For windows devices, CHARS always returns 1.

Here are some examples:

CHARS(myfile)     ->   42   /* perhaps */
CHARS(nonfile)    ->   0
CHARS()           ->   1    /* perhaps */

COMPARE

>>-COMPARE(string1,string2--+------+--)------------------------><
                            +-,pad-+

Returns 0 if the strings string1 and string2 are identical. Otherwise, it returns the position of the first character that does not match. The shorter string is padded on the right with pad if necessary. The default pad character is a blank.

Here are some 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

CONDITION

>>-CONDITION(--+--------+--)-----------------------------------><
               +-option-+

Returns the condition information associated with the current trapped condition. (See Conditions and Condition Traps for a description of condition traps.) You can request the following pieces of information:

In addition, you can request a condition object containing all of the preceding information.

To select the information to be returned, use the following options. (Only the capitalized letter is needed; all characters following it are ignored.)

Additional

returns any additional object information associated with the current trapped condition. See Additional Object Information for a list of possible values. If no additional object information is available or no condition has been trapped, the language processor returns the Nil object.

Condition name

returns the name of the current trapped condition. For user conditions, the returned string is a concatenation of the word USER and the user condition name, separated by a whitespace character.

Description

returns any descriptive string associated with the current trapped condition. See Descriptive Strings for the list of possible values. If no description is available or no condition has been trapped, it returns a null string.

Instruction

returns either CALL or SIGNAL, the keyword for the instruction processed when the current condition was trapped. This is the default if you omit option. If no condition has been trapped, it returns a null string.

Object

returns an object that contains all the information about the current trapped condition. See Conditions and Condition Traps for more information. If no condition has been trapped, it returns the Nil object.

Status

returns the status of the current trapped condition. This can change during processing, and is one of the following:

  • ON - the condition is enabled

  • OFF - the condition is disabled

  • DELAY - any new occurrence of the condition is delayed or ignored

If no condition has been trapped, a null string is returned.

Here are some examples:

CONDITION()            ->    "CALL"        /* perhaps */
CONDITION("C")         ->    "FAILURE"
CONDITION("I")         ->    "CALL"
CONDITION("D")         ->    "FailureTest"
CONDITION("S")         ->    "OFF"        /* perhaps */

Note: The CONDITION function returns condition information that is saved and restored across subroutine calls (including those a CALL ON condition trap causes). Therefore, after a subroutine called with CALL ON trapname has returned, the current trapped condition reverts to the condition that was current before the CALL took place (which can be none). CONDITION returns the values it returned before the condition was trapped.

COPIES

>>-COPIES(string,n)--------------------------------------------><

Returns n concatenated copies of string. The n must be a positive whole number or zero.

Here are some examples:

COPIES("abc",3)    ->    "abcabcabc"
COPIES("abc",0)    ->    ""

COUNTSTR

>>-COUNTSTR(needle,haystack)-----------------------------------><

Returns a count of the occurrences of needle in haystack that do not overlap. The following defines the effect:

result=0
$tempx=pos(needle,haystack)
do while $temp > 0
result=result+1
$temp=pos(needle,haystack,$temp+length(needle))
end

Here are some examples:

COUNTSTR("1","101101")        ->    4
COUNTSTR("KK","J0KKK0")       ->    1

D2C (Decimal to Character)

>>-D2C(wholenumber--+----+--)----------------------------------><
                    +-,n-+

Returns a string, in character format, that is the ASCII representation of the decimal number. If you specify n, it is the length of the final result in characters; leading "00"x (for a positive wholenumber) or "FF"x (for a negative wholenumber) characters are added to the result string as necessary. n must be a positive whole number or zero.

Wholenumber must not have more digits than the current setting of NUMERIC DIGITS.

If you omit n, wholenumber must be a positive whole number or zero, and the result length is as needed. Therefore, the returned result has no leading "00"x characters.

Here are some examples:

D2C(65)      ->   "A"      /* "41"x is an ASCII "A"               */
D2C(65,1)    ->   "A"
D2C(65,2)    ->   " A"     /* the leading character is a "00"x    */
D2C(65,5)    ->   "    A"  /* the leading characters are "00"x    */
D2C(109)     ->   "m"      /* "6D"x  is an ASCII "m"              */
D2C(-109,1)  ->   "ô"      /* "93"x is an ASCII "ô"   */
D2C(76,2)    ->   " L"     /* "4C"x  is an ASCII "L"              */
D2C(-180,2)  ->   " L"     /* the leading character is a "FF"x    */

Implementation maximum: The output string must not have more than 250 significant characters, although it can be longer if it contains leading sign characters ("00"x and "FF"x).

D2X (Decimal to Hexadecimal)

>>-D2X(wholenumber--+----+--)----------------------------------><
                    +-,n-+

Returns a string, in character format, that represents wholenumber, a decimal number, converted to hexadecimal. The returned string uses uppercase alphabetics for the values A-F and does not include whitespace characters.

Wholenumber must not have more digits than the current setting of NUMERIC DIGITS.

If you specify n, it is the length of the final result in characters. After conversion the input string is sign-extended to the required length. If the number is too big to fit n characters, it is truncated on the left. n must be a positive whole number or zero.

If you omit n, wholenumber must be a positive whole number or zero, and the returned result has no leading zeros.

Here are some examples:

D2X(9)         ->    "9"
D2X(129)       ->    "81"
D2X(129,1)     ->    "1"
D2X(129,2)     ->    "81"
D2X(129,4)     ->    "0081"
D2X(257,2)     ->    "01"
D2X(-127,2)    ->    "81"
D2X(-127,4)    ->    "FF81"
D2X(12,0)      ->    ""

Implementation maximum: The output string must not have more than 500 significant hexadecimal characters, although it can be longer if it contains leading sign characters (0 and F).

DATATYPE

>>-DATATYPE(string--+-------+--)-------------------------------><
                    +-,type-+

Returns NUM if you specify only string and if string is a valid Rexx number that can be added to 0 without error; returns CHAR if string is not a valid number.

If you specify type, it returns 1 if string matches the type. Otherwise, it returns 0. If string is null, the function returns 0 (except when the type is X or B, for which DATATYPE returns 1 for a null string). The following are valid types. (Only the capitalized letter, or the number of the last type listed, is needed; all characters surrounding it are ignored. Note that for the hexadecimal option, you must start your string specifying the name of the option with x rather than h.)

Alphanumeric

returns 1 if string contains only characters from the ranges a-z, A-Z, and 0-9.

Binary

returns 1 if string contains only the characters 0 or 1, or whitespace. Whitespace characters can appear only between groups of 4 binary characters. It also returns 1 if string is a null string, which is a valid binary string.

Lowercase

returns 1 if string contains only characters from the range a-z.

Mixed case

returns 1 if string contains only characters from the ranges a-z and A-Z.

Number

returns 1 if DATATYPE(string) returns NUM.

lOgical

returns 1 if the string is exactly "0" or "1". Otherwise it returns 0.

Symbol

returns 1 if string is a valid symbol, that is, if SYMBOL(string) does not return BAD. (See Symbols.) Note that both uppercase and lowercase alphabetics are permitted.

Uppercase

returns 1 if string contains only characters from the range A-Z.

Variable

returns 1 if string could appear on the left-hand side of an assignment without causing a SYNTAX condition.

Whole number

returns 1 if string is a Rexx whole number under the current setting of NUMERIC DIGITS.

heXadecimal

returns 1 if string contains only characters from the ranges a-f, A-F, 0-9, and whitespace (as long as the whitespace characters appear only between pairs of hexadecimal characters). It also returns 1 if string is a null string, which is a valid hexadecimal string.

9 digits

returns 1 if DATATYPE(string,"W") returns 1 when NUMERIC DIGITS is set to 9.

Here are some examples:

DATATYPE(" 12 ")         ->   "NUM"
DATATYPE("")             ->   "CHAR"
DATATYPE("123*")         ->   "CHAR"
DATATYPE("12.3","N")     ->    1
DATATYPE("12.3","W")     ->    0
DATATYPE("Fred","M")     ->    1
DATATYPE("Fred","U")     ->    0
DATATYPE("Fred","L")     ->    0
DATATYPE("?20K","s")     ->    1
DATATYPE("BCd3","X")     ->    1
DATATYPE("BC d3","X")    ->    1
DATATYPE("1","O")        ->    1
DATATYPE("11,"O")        ->    0

Note: The DATATYPE function tests the meaning or type of characters in a string, independent of the encoding of those characters (for example, ASCII or EBCDIC).

DATE

>>-DATE(-------------------------------------------------------->

>--+-------------------------------------------------------------+-->
   +-option--+-------------------------------------------------+-+
             +-,string--+----------+---------------------------+
             |          +-,option2-+                           |
             +-+-,--,------------------+--+-,osep------------+-+
               +-,string--+-,option2-+-+  +-+-,osep-+--,isep-+
                          +-,--------+      +-,-----+

>--)-----------------------------------------------------------><

Returns, by default, the local date in the format: dd mon yyyy (day month year--for example, 13 Nov 1998), with no leading zero or blank on the day. The first three characters of the English name of the month are used.

You can use the following options to obtain specific formats. (Only the capitalized letter is needed; all characters following it are ignored.)

Base

returns the number of complete days (that is, not including the current day) since and including the base date, 1 January 0001, in the format: dddddd (no leading zeros or whitespace). The expression DATE("B")//7 returns a number in the range 0-6 that corresponds to the current day of the week, where 0 is Monday and 6 is Sunday.

Note: The base date of 1 January 0001 is determined by extending the current Gregorian calendar backward (365 days each year, with an extra day every year that is divisible by 4 except century years that are not divisible by 400. It does not take into account any errors in the calendar system that created the Gregorian calendar originally.

Days

returns the number of days, including the current day, that have passed this year in the format ddd (no leading zeros or whitespace).

European

returns the date in the format dd/mm/yy.

Full

returns the number of microseconds since 00:00:00.000000 on 1 January 0001, in the format: dddddddddddddddddd (no leading zeros or whitespace).

Notes: The base date of 1 January 0001 is determined by extending the current Gregorian calendar backward (365 days each year, with an extra day every year that is divisible by 4 except century years that are not divisible by 400. It does not take into account any errors in the calendar system that created the Gregorian calendar originally.

The value returned by Date('F') can be used to calculate the interval between any two dates. Note, however, that values returned generally contain more digits that the default NUMERIC DIGITS setting. The NUMERIC DIGITS setting should be increased to a minimum value of 18 when performing timestamp arithmetic.

Language

returns the date in an implementation- and language-dependent, or local, date format. The format is dd month yyyy. The name of the month is according to the national language installed on the system. If no local date format is available, the default format is returned.

Note: This format is intended to be used as a whole; Rexx programs must not make any assumptions about the form or content of the returned string.

Month

returns the full English name of the current month, for example, August.

Normal

returns the date in the format dd mon yyyy. This is the default.

Ordered

returns the date in the format yy/mm/dd (suitable for sorting, for example).

Standard

returns the date in the format yyyymmdd (suitable for sorting, for example).

Ticks

returns the number of seconds since 00:00:00.000000 on 1 January 1970, in the format: dddddddddddd (no leading zeros or whitespace).

Notes: The base date of 1 January 1970 is determined by extending the current Gregorian calendar backward (365 days each year, with an extra day every year that is divisible by 4 except century years that are not divisible by 400. It does not take into account any errors in the calendar system that created the Gregorian calendar originally.

The value returned by Date('T') can be used to calculate the interval between any two dates. Note, however, that values returned generally contain more digits that the default NUMERIC DIGITS setting. The NUMERIC DIGITS setting should be increased to a minimum value of 12 when performing timestamp arithmetic.

Date('T') will return a negative number for dates prior to 1 January 1970.

Usa

returns the date in the format mm/dd/yy.

Weekday

returns the English name for the day of the week, in mixed case, for example, Tuesday.

Here are some examples, assuming today is 13 November 1996:

DATE()         ->    "13 Nov 1996"
DATE("B")      ->    728975
DATE("D")      ->    318
DATE("E")      ->    "13/11/96"
DATE("L")      ->    "13 November 1996"
DATE("M")      ->    "November"
DATE("N")      ->    "13 Nov 1996"
DATE("O")      ->    "96/11/13"
DATE("S")      ->    "19961113"
DATE("U")      ->    "11/13/96"
DATE("W")      ->    "Wednesday"

Note: The first call to DATE or TIME in one clause causes a time stamp to be made that is then used for all calls to these functions in that clause. Therefore, several calls to any of the DATE or TIME functions, or both, in a single expression or clause are consistent with each other.

If you specify string, DATE returns the date corresponding to string in the format option. The string must be supplied in the format option2. The option2 format must specify day, month, and year (that is, not "D", "L", "M", or "W"). The default for option2 is "N", so you need to specify option2 if string is not in the Normal format. Here are some examples:

DATE("O","13 Feb 1923")     ->    "23/02/13"
DATE("O","06/01/50","U")    ->    "50/06/01"
DATE("N", "63326132161828000", "f")   -> "23 Sep 2007"

If you specify an output separator character osep, the days, month, and year returned are separated by this character. Any nonalphanumeric character or an empty string can be used. A separator character is only valid for the formats "E", "N", "O", "S", and "U". Here are some examples:

DATE("S","13 Feb 1996","N","-")     ->    "1996-02-13"
DATE("N","13 Feb 1996","N","")      ->    "13Feb1996"
DATE("N","13 Feb 1996","N","-")     ->    "13-Feb-1996"
DATE("O","06/01/50","U","")         ->    "500601"
DATE("E","02/13/96","U",".")        ->    "13.02.96"
DATE("N", , ,"_")                   ->    "26_Mar_1998"  (today)

In this way, formats can be created that are derived from their respective default format, which is the format associated with option using its default separator character. The default separator character for each of these formats is:

Option       Default separator

European     "/"
Normal       " "
Ordered      "/"
Standard     ""  (empty string)
Usa          "/"

If you specify a string containing a separator that is different from the default separator character of option2, you must also specify isep to indicate which separator character is valid for string. Basically, any date format that can be generated with any valid separator character can be used as input date string as long as its format has the generalized form specified by option2 and its separator character matches the character specified by isep.

Here are some examples:

DATE("S","1996-11-13","S","","-")      ->    "19961113"
DATE("S","13-Nov-1996","N","","-")     ->    "19961113"
DATE("O","06*01*50","U","","*")        ->    "500601"
DATE("U","13.Feb.1996","N", ,".")      ->    "02/13/96"

You can determine the number of days between two dates; for example:

say date("B","12/25/96","U")-date("B") " shopping days till Christmas!"

If string does not include the century but option defines that the century be returned as part of the date, the century is determined depending on whether the year to be returned is within the past 50 years or the next 49 years. Assume, for example, that you specify 10/15/43 for string and today's date is 10/27/1998. In this case, 1943 would be 55 years ago and 2043 would be 45 years in the future. So, 10/15/2043 would be the returned date.

Note: This rule is suitable for dates that are close to today's date. However, when working with birth dates, it is recommended that you explicitly provide the century.

When requesting dates to be converted to Full format or Ticks format, a time value of "00:00:00.000000" is used for the conversion. A time stamp for a time and date combination can be created by combining a value from Time() for the time of day.

    numeric digits 18  -- needed to add the timestamps
    timestamp = date('f, '20072301', 'S') + time('f', '08:14:22', 'N')

DELSTR (Delete String)

>>-DELSTR(string,n--+---------+--)-----------------------------><
                    +-,length-+

Returns string after deleting the substring that begins at the nth character and is of length characters. If you omit length, or if length is greater than the number of characters from n to the end of string, the function deletes the rest of string (including the nth character). The length must be a positive whole number or zero. n must be a positive whole number. If n is greater than the length of string, the function returns string unchanged.

Here are some examples:

DELSTR("abcd",3)       ->    "ab"
DELSTR("abcde",3,2)    ->    "abe"
DELSTR("abcde",6)      ->    "abcde"

DELWORD (Delete Word)

>>-DELWORD(string,n--+---------+--)----------------------------><
                     +-,length-+

Returns string after deleting the substring that starts at the nth word and is of length whitespace-delimited words. If you omit length, or if length is greater than the number of words from n to the end of string, the function deletes the remaining words in string (including the nth word). The length must be a positive whole number or zero. n must be a positive whole number. If n is greater than the number of words in string, the function returns string unchanged. The string deleted includes any whitespace characters following the final word involved but none of the whitespace preceding the first word involved.

Here are some examples:

DELWORD("Now is the  time",2,2)  ->  "Now time"
DELWORD("Now is the time ",3)    ->  "Now is "
DELWORD("Now is the  time",5)    ->  "Now is the  time"
DELWORD("Now is   the time",3,1) ->  "Now is   time"
DELWORD("Now is the  time",2,2)  ->  "Now time"

DIGITS

>>-DIGITS()----------------------------------------------------><

Returns the current setting of NUMERIC DIGITS. See NUMERIC for more information.

Here is an example:

DIGITS()    ->    9      /* by default */

DIRECTORY

>>-DIRECTORY(--+--------------+--)-----------------------------><
               +-newdirectory-+

Returns the current directory, changing it to newdirectory if an argument is supplied and the named directory exists. If newdirectory is not specified, the name of the current directory is returned. Otherwise, an attempt is made to change to the specified newdirectory. If successful, the name of the newdirectory is returned; if an error occurred, null is returned.

For example, the following program fragment saves the current directory and switches to a new directory; it performs an operation there, and then returns to the former directory.

/* get current directory      */
curdir = directory()
/* go play a game             */
newdir = directory("/usr/games")    /* Linux type subdirectory */
if newdir = "/usr/games" then
  do
  fortune   /* tell a fortune */
/* return to former directory */
  call directory curdir
end
else
  say "Can't find /usr/games"

ENDLOCAL (Linux only)

>>-ENDLOCAL()--------------------------------------------------><

Restores the directory and environment variables in effect before the last SETLOCAL function was run. If ENDLOCAL is not included in a procedure, the initial environment saved by SETLOCAL is restored upon exiting the procedure.

ENDLOCAL returns a value of 1 if the initial environment is successfully restored and a value of 0 if no SETLOCAL was issued or the action is otherwise unsuccessful.

Here is an example:

n = SETLOCAL()                   /* saves the current environment */
          /*
          The program can now change environment variables
          (with the VALUE function) and then work in the
          changed environment.
          */
n = ENDLOCAL()                   /* restores the initial environment */

For additional examples, see SETLOCAL.

ERRORTEXT

>>-ERRORTEXT(n)------------------------------------------------><

Returns the Rexx error message associated with error number n. n must be in the range 0-99. It returns the null string if n is in the allowed range but is not a defined Rexx error number. See Error Numbers and Messages for a complete description of error numbers and messages.

Here are some examples:

ERRORTEXT(16)    ->    "Label not found"
ERRORTEXT(60)    ->    ""

FILESPEC

>>-FILESPEC(option,filespec)-----------------------------------><

Returns a selected element of filespec, given file specification, identified by one of the following option strings:

Drive

The drive letter of the given filespec. Only available on Windows

Path

The directory path of the given filespec.

Location

The full location portion of the given filespec. On Windows, this will include both the Drive and Path information. On other platforms, this returns the same result as the Path option.

Name

The file name of the given filespec.

Extension

The extension portion of the filespec file name.

If filespec the requested information, then the FILESPEC function returns a null string ("").

Note: Only the initial letter of option is needed.

Here are some Windows examples:

thisfile = "C:\WINDOWS\UTIL\SYSTEM.INI"
say FILESPEC("drive",thisfile)     /* says "C:"              */
say FILESPEC("path",thisfile)      /* says "\WINDOWS\UTIL\"  */
say FILESPEC("location",thisfile)  /* says "C:\WINDOWS\UTIL\"  */
say FILESPEC("name",thisfile)      /* says "SYSTEM.INI"      */
say FILESPEC("extension",thisfile) /* says "INI"      */
part = "name"
say FILESPEC(part,thisfile)        /* says "SYSTEM.INI"      */

FORM

>>-FORM()------------------------------------------------------><

Returns the current setting of NUMERIC FORM. See NUMERIC for more information.

Here is an example:

FORM()    ->    "SCIENTIFIC"  /* by default */

FORMAT

>>-FORMAT(number------------------------------------------------>

>--+-------------------------------------------------------------+-->
   +-,--+--------+--+------------------------------------------+-+
        +-before-+  +-,--+-------+--+------------------------+-+
                         +-after-+  +-,--+------+--+-------+-+
                                         +-expp-+  +-,expt-+

>--)-----------------------------------------------------------><

Returns number, rounded and formatted.

The number is first rounded according to standard Rexx rules, as though the operation number+0 had been carried out. The result is precisely that of this operation if you specify only number. If you specify any other options, the number is formatted as described in the following.

The before and after options describe how many characters are used for the integer and decimal parts of the result, respectively. If you omit either or both of them, the number of characters used for that part is as needed.

If before is not large enough to contain the integer part of the number (plus the sign for a negative number), an error results. If before is larger than needed for that part, the number is padded on the left with blanks. If after is not the same size as the decimal part of the number, the number is rounded (or extended with zeros) to fit. Specifying 0 causes the number to be rounded to an integer.

Here are some 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"

The first three arguments are as described previously. In addition, expp and expt control the exponent part of the result, which, by default, is formatted according to the current NUMERIC settings of DIGITS and FORM. expp sets the number of places for the exponent part; the default is to use as many as needed (which can be zero). expt specifies when the exponential expression is used. The default is the current setting of NUMERIC DIGITS.

If expp is 0, the number is not in exponential notation. If expp is not large enough to contain the exponent, an error results.

If the number of places needed for the integer or decimal part exceeds expt or twice expt, respectively, the exponential notation is used. If expt is 0, the exponential notation is always used unless the exponent would be 0. (If expp is 0, this overrides a 0 value of expt.) If the exponent would be 0 when a nonzero expp is specified, then expp+2 blanks are supplied for the exponent part of the result. If the exponent would be 0 and expp is not specified, the number is not an exponential expression.

Here are some 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("12345.73", , ,3,6)  ->    "12345.73"
FORMAT("1234567e5", ,3,0)   ->    "123456700000.000"

FUZZ

>>-FUZZ()------------------------------------------------------><

Returns the current setting of NUMERIC FUZZ. See NUMERIC for more information.

Here is an example:

FUZZ()    ->    0     /* by default */

INSERT

>>-INSERT(new,target-------------------------------------------->

>--+---------------------------------------+--)----------------><
   +-,--+---+--+-------------------------+-+
        +-n-+  +-,--+--------+--+------+-+
                    +-length-+  +-,pad-+

Inserts the string new, padded or truncated to length length, into the string target after the nth character. The default value for n is 0, which means insertion before the beginning of the string. If specified, n and length must be positive whole numbers or zero. If n is greater than the length of the target string, the string new is padded at the beginning. The default value for length is the length of new. If length is less than the length of the string new, then INSERT truncates new to length length. The default pad character is a blank.

Here are some 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 (Last Position)

>>-LASTPOS(needle,haystack-+---------------------------+--)----------------------><
                           +-,--+-------+--+---------+-+
                                +-start-+  +-,length-+

Returns the position of the last occurrence of one string, needle, in another, haystack. (See also POS (Position).) It returns 0 if needle is a null string or not found. By default, the search starts at the last character of haystack and scans backward to the beginning of the string. You can override this by specifying start, the point at which the backward scan starts and length, the range of characters to scan. The start must be a positive whole number and defaults to receiving_string~length if larger than that value or omitted. The length must be a non-negative whole number and defaults to start.

Here are some examples:

LASTPOS(" ","abc def ghi")      ->    8
LASTPOS(" ","abcdefghi")        ->    0
LASTPOS("xy","efgxyz")          ->    4
LASTPOS(" ","abc def ghi",7)    ->    4
LASTPOS(" ","abc def ghi",7,3)  ->    0

LEFT

>>-LEFT(string,length--+------+--)-----------------------------><
                       +-,pad-+

Returns a string of length length, containing the leftmost length characters of string. The string returned is padded with pad characters, or truncated, on the right as needed. The default pad character is a blank. length must be a positive whole number or zero. The LEFT function is exactly equivalent to:

>>-SUBSTR(string,1,length--+------+--)-------------------------><
                           +-,pad-+

Here are some examples:

LEFT("abc d",8)        ->    "abc d   "
LEFT("abc d",8,".")    ->    "abc d..."
LEFT("abc  def",7)     ->    "abc  de"

LENGTH

>>-LENGTH(string)----------------------------------------------><

Returns the length of string.

Here are some examples:

LENGTH("abcdefgh")    ->    8
LENGTH("abc defg")    ->    8
LENGTH("")            ->    0

LINEIN (Line Input)

>>-LINEIN(--+------+--+-------------------------+--)-----------><
            +-name-+  +-,--+------+--+--------+-+
                           +-line-+  +-,count-+

Returns count lines read from the character input stream name. The count must be 1 or 0 (To understand the input and output functions, see Input and Output Streams.) If you omit name, the line is read from the default input stream, STDIN. The default count is 1.

For persistent streams, a read position is maintained for each stream. Any read from the stream starts at the current read position by default. Under certain circumstances, a call to LINEIN returns a partial line. This can happen if the stream has already been read with the CHARIN function, and part but not all of a line (and its termination, if any) has already been read. When the language processor completes reading, the read position is moved to the beginning of the next line.

A line number may be given to set the read position to the start of a specified line. This line number must be positive and within the bounds of the stream, and must not be specified for a transient stream. The read position can be set to the beginning of the stream by giving line a value of 1.

If you give a count of 0, then no characters are read and a null string is returned.

For transient streams, if a complete line is not available in the stream, then execution of the program usually stops until the line is complete. If, however, it is impossible for a line to be completed because of an error or another problem, the NOTREADY condition is raised (see Errors during Input and Output) and LINEIN returns whatever characters are available.

Here are some examples:

LINEIN()                             /* Reads one line from the    */
                                     /* default input stream;      */
                                     /* usually this is an entry   */
                                     /* typed at the keyboard      */
myfile = "ANYFILE.TXT"
LINEIN(myfile)     -> "Current line" /* Reads one line from        */
                                     /* ANYFILE.TXT, beginning     */
                                     /* at the current read        */
                                     /* position. (If first call,  */
                                     /* file is opened and the     */
                                     /* first line is read.)       */

LINEIN(myfile,1,1) ->  "first line"  /* Opens and reads the first  */
                                     /* line of ANYFILE.TXT (if    */
                                     /* the file is already open,  */
                                     /* reads first line); sets    */
                                     /* read position on the       */
                                     /* second line.               */

LINEIN(myfile,1,0) ->  ""            /* No read; opens ANYFILE.TXT */
                                     /* (if file is already open,  */
                                     /* sets the read position to  */
                                     /* the first line).           */

LINEIN(myfile, ,0)  ->  ""           /* No read; opens ANYFILE.TXT */
                                     /* (no action if the file is  */
                                     /* already open).             */

LINEIN("QUEUE:")   ->  "Queue line" /* Read a line from the queue. */
                                    /* If the queue is empty, the  */
                                    /* program waits until a line  */
                                    /* is put on the queue.        */

Note: If you want to read complete lines from the default input stream, as in a dialog with a user, use the PULL or PARSE PULL instruction.

The PARSE LINEIN instruction is also useful in certain cases. (See PARSE LINEIN.)

LINEOUT (Line Output)

>>-LINEOUT(--+------+--+--------------------------+--)---------><
             +-name-+  +-,--+--------+--+-------+-+
                            +-string-+  +-,line-+

Returns 0 if successful in writing string to the character output stream name, or 1 if an error occurs while writing the line. (To understand the input and output functions, see Input and Output Streams.) If you omit string but include line, only the write position is repositioned. If string is a null string, LINEOUT repositions the write position (if you include line) and does a carriage return. Otherwise, the stream is closed. LINEOUT adds a line-feed and a carriage-return character to the end of string.

If you omit name, the line is written to the default output stream STDOUT (usually the display).

For persistent streams, a write position is maintained for each stream. Any write to the stream starts at the current write position by default. (Under certain circumstances the characters written by a call to LINEOUT can be added to a partial line previously written to the stream with the CHAROUT routine. LINEOUT stops a line at the end of each call.) When the language processor completes writing, the write position is set to the beginning of the line following the one just written. When the stream is first opened, the write position is at the end of the stream, so that calls to LINEOUT append lines to the end of the stream.

You can specify a line number to set the write position to the start of a particular line in a persistent stream. This line number must be positive and within the bounds of the stream unless it is a binary stream (though it can specify the line number immediately after the end of the stream). A value of 1 for line refers to the first line in the stream. Note that, unlike CHAROUT, you cannot specify a position beyond the end of the stream for non-binary streams.

You can omit the string for persistent streams. If you specify line, the write position is set to the start of the line that was given, nothing is written to the stream, and the function returns 0. If you specify neither line nor string, the stream is closed. Again, the function returns 0.

Execution of the program usually stops until the output operation is effectively complete. For example, when data is sent to a printer, the system accepts the data and returns control to Rexx, even though the output data might not have been printed. Rexx considers this to be complete, even though the data has not been printed. If, however, it is impossible for a line to be written, the NOTREADY condition is raised (see Errors during Input and Output), and LINEOUT returns a result of 1, that is, the residual count of lines written.

Here are some examples:

LINEOUT(,"Display this")          /* Writes string to the default   */
                                  /* output stream (usually, the    */
                                  /* display); returns 0 if         */
                                  /* successful                     */

myfile = "ANYFILE.TXT"
LINEOUT(myfile,"A new line")      /* Opens the file ANYFILE.TXT and */
                                  /* appends the string to the end. */
                                  /* If the file is already open,   */
                                  /* the string is written at the   */
                                  /* current write position.        */
                                  /* Returns 0 if successful.       */

LINEOUT(myfile,"A new start",1)   /* Opens the file (if not already */
                                  /* open); overwrites first line   */
                                  /* with a new line.               */
                                  /* Returns 0 if successful.       */

LINEOUT(myfile, ,1)               /* Opens the file (if not already */
                                  /* open). No write; sets write    */
                                  /* position at first character.   */

LINEOUT(myfile)                   /* Closes ANYFILE.TXT             */

LINEOUT is often most useful when called as a subroutine. The return value is then available in the variable RESULT. For example:

Call LINEOUT "A:rexx.bat","Shell",1
Call LINEOUT ,"Hello"

Note: If the lines are to be written to the default output stream without the possibility of error, use the SAY instruction instead.

LINES (Lines Remaining)

                        +-, Normal-+
>>-LINES(--+------+-----+----------+---)-----------------------><
           +-name-+     +-, Count--+

Returns 1 if any data remains between the current read position and the end of the character input stream name. It returns 0 if no data remains. In effect, LINES reports whether a read action that CHARIN (see CHARIN (Character Input)) or LINEIN (see LINEIN (Line Input)) performs will succeed. (To understand the input and output functions, see Input and Output Streams.)

The ANSI Standard has extended this function to allow an option: "Count". If this option is used, LINES returns the actual number of complete lines remaining in the stream, irrespective of how long this operation takes.

The option "Normal" returns 1 if there is at least one complete line remaining in the file or 0 if no lines remain.

The default is "Normal".

Here are some examples:

LINES(myfile)    ->    0    /* at end of the file   */
LINES()          ->    1    /* data remains in the  */
                            /* default input stream */
                            /* STDIN:               */

Note: The CHARS function returns the number of characters in a persistent stream or the presence of data in a transient stream.

LOWER

>>-LOWER(string-+----------------------------+--)--------------><
                +--,--+-----+--+-----------+-+
                      +--n--+  +--,length--+

Returns a new string with the characters of string beginning with character n for length characters converted to lowercase. If n is specified, it must be a positive whole number. If n is not specified, the case conversion will start with the first character. If length is specified, it must be a non-negative whole number. If length the default is to convert the remainder of the string.

Examples:

lower("Albert Einstein")      ->    "albert einstein"
lower("ABCDEF", 4)            ->    "ABCdef"
lower("ABCDEF", 3, 2)         ->    "ABcdEF"

MAX (Maximum)

         +-,------+
         V        |
>>-MAX(----number-+--)-----------------------------------------><

Returns the largest number of the list specified, formatted according to the current NUMERIC settings. You can specify any number of numbers.

Here are some examples:

MAX(12,6,7,9)                                                ->    12
MAX(17.3,19,17.03)                                           ->    19
MAX(-7,-3,-4.3)                                              ->    -3
MAX(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)   ->    21

MIN (Minimum)

         +-,------+
         V        |
>>-MIN(----number-+--)-----------------------------------------><

Returns the smallest number of the list specified, formatted according to the current NUMERIC settings. You can specify any number of numbers.

Here are some examples:

MIN(12,6,7,9)                                                ->   6
MIN(17.3,19,17.03)                                           ->  17.03
MIN(-7,-3,-4.3)                                              ->  -7
MIN(21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)   ->   1

OVERLAY

>>-OVERLAY(new,target------------------------------------------->

>--+---------------------------------------+--)----------------><
   +-,--+---+--+-------------------------+-+
        +-n-+  +-,--+--------+--+------+-+
                    +-length-+  +-,pad-+

Returns the string target, which, starting at the nth character, is overlaid with the string new, padded or truncated to length length. The overlay may extend beyond the end of the original target string. If you specify length, it must be a positive whole number or zero. The default value for length is the length of new. If n is greater than the length of the target string, the string new is padded at the beginning. The default pad character is a blank, and the default value for n is 1. If you specify n, it must be a positive whole number.

Here are some 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 (Position)

>>-POS(needle,haystack--+---------------------------+--)--------------------------><
                        +-,--+-------+--+---------+-+
                             +-start-+  +-,length-+

Returns the position of one string, needle, in another, haystack. (See also LASTPOS (Last Position).) It returns 0 if needle is a null string or not found or if start is greater than the length of haystack. By default, the search starts at the first character of the receiving string (that is, the value of start is 1), and continues to the end of the string. You can override this by specifying start, the point at which the search starts, and length, the bounding limit for the search. If specified, start must be a positive whole number and length must be a non-negative whole number.

Here are some examples:

POS("day","Saturday")       ->    6
POS("x","abc def ghi")      ->    0
POS(" ","abc def ghi")      ->    4
POS(" ","abc def ghi",5)    ->    8
POS(" ","abc def ghi",5,3)  ->    0

QUALIFY

>>-QUALIFY(name)-----------------------------------------------><

Returns the a fully qualified file name for name. Qualifying merely expands the file name into a name that includes directory information. The file does not need to exist to generate the full name.

QUEUED

>>-QUEUED()----------------------------------------------------><

Returns the number of lines remaining in the external data queue when the function is called. (See Input and Output Streams for a discussion of Rexx input and output.)

Here is an example:

QUEUED()    ->    5    /* Perhaps */

RANDOM

>>-RANDOM(--+------------------------------------+--)----------><
            +--max-------------------------------+
            +-+--------+-,-+-------+--+--------+-+
              +--min--+    +--max--+  +--,seed-+

Returns a quasi-random whole number in the range min to max inclusive. If you specify max or min,max, then max minus min cannot exceed 999999999. min and max default to 0 and 999, respectively. To start a repeatable sequence of results, use a specific seed as the third argument, as described in Note 1. This seed must be a positive whole number from 0 to 999999999.

Here are some examples:

RANDOM()          ->    305
RANDOM(5,8)       ->      7
RANDOM(2)         ->      0  /*  0  to  2    */
RANDOM(, ,1983)   ->    123  /* reproducible */
RANDOM(-5, 5)     ->    -3

Notes:

  1. To obtain a predictable sequence of quasi-random numbers, use RANDOM a number of times, but specify a seed only the first time. For example, to simulate 40 throws of a 6-sided, unbiased die:

    sequence = RANDOM(1,6,12345)  /* any number would */
                                  /* do for a seed    */
    do 39
    sequence = sequence RANDOM(1,6)
    end
    say sequence
    The numbers are generated mathematically, using the initial seed, so that as far as possible they appear to be random. Running the program again produces the same sequence; using a different initial seed almost certainly produces a different sequence. If you do not supply a seed, the first time RANDOM is called, an arbitrary seed is used. Hence, your program usually gives different results each time it is run.

  2. The random number generator is global for an entire program; the current seed is not saved across internal routine calls.

REVERSE

>>-REVERSE(string)---------------------------------------------><

Returns string reversed.

Here are some examples:

REVERSE("ABc.")    ->    ".cBA"
REVERSE("XYZ ")    ->    " ZYX"

RIGHT

>>-RIGHT(string,length--+------+--)----------------------------><
                        +-,pad-+

Returns a string of length length containing the rightmost length characters of string. The string returned is padded with pad character, or truncated, on the left as needed. The default pad character is a blank. The length must be a positive whole number or zero.

Here are some examples:

RIGHT("abc  d",8)     ->    "  abc  d"
RIGHT("abc def",5)    ->    "c def"
RIGHT("12",5,"0")     ->    "00012"

RXFUNCADD

>>-RXFUNCADD(name,module-+------------+-)----------------------><
                         +-,procedure-+

Registers the function , making it available to Rexx procedures. The module is the name of an external library where the native function is located. In some environments, such as Unix-based systems, the library name is case sensitive. The procedure is the name of the exported prodcure inside of module. If procedure is not specified, it defaults to name. The procedure is generally case-sensitive. RxFuncAdd will attempt to resolve the procedure address using the name as specified and if that attempt fails, will retry using an uppercased name.

A return value 0 signifies successful registration and that the registered function has been located in the specified module. A return value 1 signifies that the function could not be resolved.

rxfuncadd("SysCls","rexxutil", "SysCls") -> 0 /* if SysCls can be located */
                                         -> 1 /* if SysCls can not be located */

RXFUNCDROP

>>-RXFUNCDROP(name)--------------------------------------------><

Removes (deregisters) the function name from the list of available functions. A zero return value signifies successful removal.

rxfuncdrop("SysLoadFuncs")         -> 0 /* if successfully removed   */

RXFUNCQUERY

>>-RXFUNCQUERY(name)-------------------------------------------><

Queries the list of available functions for the function name. It returns a value of 0 if the function is registered, and a value of 1 if it is not.

rxfuncquery("SysLoadFuncs")        -> 0 /* if registered             */

RXQUEUE

>>-RXQUEUE(-+-"Create"-+------------+-+-)----------------------><
            |          +-,queuename-+ |
            +-"Delete",queuename------+
            +-"Get"-------------------+
            +-"Set",newqueuename------+

Creates and deletes external data queues. It also sets and queries their names.

"Create"

creates a queue with the name queuename if you specify queuename and if no queue of that name exists already. You must not use SESSION as a queuename. If you specify no queuename, then the language processor provides a name. The name of the queue is returned in either case.

The maximum length of queuename can be 1024 characters.

Many queues can exist at the same time, and most systems have sufficient resources available to support several hundred queues at a time. If a queue with the specified name exists already, a queue is still created with a name assigned by the language processor. The assigned name is then returned to you.

"Delete"

deletes the named queue. It returns 0 if successful or a nonzero number if an error occurs. Possible return values are:

0

Queue has been deleted.

5

Not a valid queue name or tried to delete queue named "SESSION".

9

Specified queue does not exist.

10

Queue is busy; wait is active.

12

A memory failure has occurred.

1002

Failure in memory manager.

"Get"

returns the name of the queue currently in use.

"Set"

sets the name of the current queue to newqueuename and returns the previously active queue name.

The first parameter determines the function. Only the first character of the first parameter is significant. The parameter can be entered in any case. The syntax for a valid queue name is the same as for a valid Rexx symbol.

The second parameter specified for Create, Set, and Delete must follow the same syntax rules as the Rexx variable names. There is no connection, however, between queue names and variable names. A program can have a variable and a queue with the same name. The actual name of the queue is the uppercase value of the name requested.

Named queues prevent different Rexx programs that are running in a single session from interfering with each other. They allow Rexx programs running in different sessions to synchronize execution and pass data. LINEIN("QUEUE:") is especially useful because the calling program stops running until another program places a line on the queue.

/* default queue                                    */
rxqueue("Get")             -> "SESSION"
/* assuming FRED does not already exist             */
rxqueue("Create", "Fred")  -> "FRED"
/* assuming SESSION had been active                 */
rxqueue("Set", "Fred")     -> "SESSION"
/* assuming FRED exists                             */
rxqueue("delete", "Fred")  -> "0"

SETLOCAL (Linux only)

>>-SETLOCAL()--------------------------------------------------><

Saves the current working directory and the current values of the environment variables that are local to the current process.

For example, SETLOCAL can be used to save the current environment before changing selected settings with the VALUE function (see VALUE. To restore the directory and environment, use the ENDLOCAL function (see ENDLOCAL.

SETLOCAL returns a value of 1 if the initial directory and environment are successfully saved and a value of 0 if unsuccessful. If SETLOCAL is not followed by an ENDLOCAL function in a procedure, the initial environment saved by SETLOCAL is restored upon exiting the procedure.

Here is an example:

/* Current path is "user/bin" */
n = SETLOCAL()           /* saves all environment settings */
/* Now use the VALUE function to change the PATH variable */
p = VALUE("Path","home/user/bin"."ENVIRONMENT")
/* Programs in directory home/user/bin can now be run */
n = ENDLOCAL()           /* restores initial environment including */
                         /* the changed PATH variable, which is    */
                         /* "user/bin"                             */

SIGN

>>-SIGN(number)------------------------------------------------><

Returns a number that indicates the sign of number. The number is first rounded according to standard Rexx rules, as though the operation number+0 had been carried out. It returns -1 if number is less than 0, 0 if it is 0, and 1 if it is greater than 0.

Here are some examples:

SIGN("12.3")       ->     1
SIGN(" -0.307")    ->    -1
SIGN(0.0)          ->     0

SOURCELINE

>>-SOURCELINE(--+---+--)---------------------------------------><
                +-n-+

Returns the line number of the final line in the program if you omit n. If you specify n, returns the nth line in the program if available at the time of execution. Otherwise, it returns a null string. If specified, n must be a positive whole number and must not exceed the number that a call to SOURCELINE with no arguments returns.

If the Rexx program is in tokenized form the this function raises an error for all attempts to retrieve a line of the program.

Here are some examples:

SOURCELINE()    ->   10
SOURCELINE(1)   ->   "/* This is a 10-line Rexx program */"

SPACE

>>-SPACE(string--+--------------------+--)---------------------><
                 +-,--+---+--+------+-+
                      +-n-+  +-,pad-+

Returns the whitespace-delimited words in string with n pad characters between each word. If you specify n, it must be a positive whole number or zero. If it is 0, all whitespace characters are removed. Leading and trailing whitespace characters are always removed. The default for n is 1, and the default pad character is a blank.

Here are some 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"

STREAM

>>-STREAM(name--+-----------------------------------+--)-------><
                |    +-State----------------------+ |
                +-,--+----------------------------+-+
                     +-Command--,--stream_command-+
                     +-Description----------------+

Returns a string describing the state of, or the result of an operation upon, the character stream name. The result may depend on characteristics of the stream that you have specified in other uses of the STREAM function. (To understand the input and output functions, see Input and Output Streams.) This function requests information on the state of an input or output stream or carries out some specific operation on the stream.

The first argument, name, specifies the stream to be accessed. The second argument can be one of the following strings that describe the action to be carried out. (Only the capitalized letter is needed; all characters following it are ignored.)

Command

an operation (specified by the stream_command given as the third argument) is applied to the selected input or output stream. The string that is returned depends on the command performed and can be a null string. The possible input strings for the stream_command argument are described later.

Description

returns any descriptive string associated with the current state of the specified stream. It is identical to the State operation, except that the returned string is followed by a colon and, if available, additional information about the ERROR or NOTREADY states.

State

returns a string that indicates the current state of the specified stream. This is the default operation.

The returned strings are as described in STATE.

Note: The state (and operation) of an input or output stream is global to a Rexx program; it is not saved and restored across internal function and subroutine calls (including those calls that a CALL ON condition trap causes).

Stream Commands

The following stream commands are used to:

  • Open a stream for reading, writing, or both.

  • Close a stream at the end of an operation.

  • Position the read or write position within a persistent stream (for example, a file).

  • Get information about a stream (its existence, size, and last edit date).

The streamcommand argument must be used when--and only when--you select the operation C (command). The syntax is:

>>-STREAM(name,"C",streamcommand)------------------------------><

In this form, the STREAM function itself returns a string corresponding to the given streamcommand if the command is successful. If the command is unsuccessful, STREAM returns an error message string in the same form as the D (Description) operation supplies.

For most error conditions, the additional information is in the form of a numeric return code. This return code is the value of ERRNO that is set whenever one of the file system primitives returns with a -1.

Command Strings

The argument streamcommand can be any expression that the language processor evaluates to a command string that corresponds to the following diagram:

           +-BOTH--| Write Options |--+
>>-+-OPEN--+--------------------------+--+-------------+-+-----><
   |       +-READ---------------------+  +-| Options |-+ |
   |       +-WRITE--| Write Options |-+                  |
   +-CLOSE-----------------------------------------------+
   +-FLUSH-----------------------------------------------+
   |               +- = -+                    +-CHAR-+   |
   +-+-SEEK-----+--+-----+-offset--+-------+--+------+---+
   | +-POSITION-+  +- < -+         +-READ--+  +-LINE-+   |
   |               +- + -+         +-WRITE-+             |
   |               +- ; -+                               |
   +-QUERY--+-DATETIME--------------------------+--------+
            +-EXISTS----------------------------+
            +-HANDLE----------------------------+
            |                       +-CHAR-+    |
            +-+-SEEK-----+--+-READ--+------+--+-+
            | +-POSITION-+  |       +-LINE-+  | |
            |               |        +-CHAR-+ | |
            |               +-WRITE--+------+-+ |
            |               |        +-LINE-+ | |
            |               +-SYS-------------+ |
            +-SIZE------------------------------+
            +-STREAMTYPE------------------------+
            +-TIMESTAMP-------------------------+

Write Options:

|--+---------+--------------------------------------------------|
   +-APPEND--+
   +-REPLACE-+

Options:

                   +-----------------------------------+
                   V                                   |
|--+------------+----+-NOBUFFER----------------------+-+--------|
   +-SHARED-----+    +-BINARY--+-------------------+-+
   +-SHAREREAD--+              +-RECLENGTH--length-+
   +-SHAREWRITE-+

OPEN

opens the named stream. The default for OPEN is to open the stream for both reading and writing data, for example, "OPEN BOTH".

The STREAM function itself returns a description string similar to the one that the D option provides, for example, "READY:" if the named stream is successfully opened, or "ERROR:2" if the named stream is not found.

The following is a description of the options for OPEN:

READ

opens the stream for reading only.

WRITE

opens the stream for writing only.

BOTH

opens the stream for both reading and writing. (This is the default.) Separate read and write pointers are maintained.

APPEND

positions the write pointer at the end of the stream. The write pointer cannot be moved anywhere within the extent of the file as it existed when the file was opened.

REPLACE

sets the write pointer to the beginning of the stream and truncates the file. In other words, this option deletes all data that was in the stream when opened.

SHARED

Enables another process to work with the stream in a shared mode. This mode must be compatible with the shared mode (SHARED, SHAREREAD, or SHAREWRITE) used by the process that opened the stream.

SHAREREAD

Enables another process to read the stream in a shared mode.

SHAREWRITE

Enables another process to write the stream in a shared mode.

NOBUFFER

turns off buffering of the stream. Thus, all data written to the stream is flushed immediately to the operating system for writing. This option can severely affect output performance. Therefore, use it only when data integrity is a concern, or to force interleaved output to a stream to appear in the exact order in which it was written.

BINARY

causes the stream to be opened in binary mode. This means that line end characters are ignored and treated as another byte of data. This is intended to force file operations that are compatible with other Rexx language processors that run on record-based systems, or to process binary data using the line operations.

Note: Specifying the BINARY option for a stream that does not exist but is opened for writing also requires the RECLENGTH option to be specified. Omitting the RECLENGTH option in this case raises an error condition.

RECLENGTH length

allows the specification of an exact length for each line in a stream. This allows line operations on binary-mode streams to operate on individual fixed-length records. Without this option, line operations on binary-mode files operate on the entire file (for example, as if the RECLENGTH option were specified with a length equal to that of the file). length must be 1 or greater.

Examples:

stream(strout,"c","open")
stream(strout,"c","open write")
stream(strinp,"c","open read")
stream(strinp,"c","open read shared")
CLOSE

closes the named stream. The STREAM function itself returns READY: if the named stream is successfully closed, or an appropriate error message. If an attempt is made to close an unopened file, STREAM returns a null string ("").

Example:

stream("STRM.TXT","c","close")
FLUSH

forces any data currently buffered for writing to be written to this stream.

SEEK offset

sets the read or write position within a persistent stream. If the stream is opened for both reading and writing and no SEEK option is specified, both the read and write positions are set.

Note: See Input and Output Streams for a discussion of read and write positions in a persistent stream.

To use this command, the named stream must first be opened with the OPEN stream command or implicitly with an input or output operation. One of the following characters can precede the offset number:

=

explicitly specifies the offset from the beginning of the stream. This is the default if no prefix is supplied. Line Offset=1 means the beginning of stream.

<

specifies offset from the end of the stream.

+

specifies offset forward from the current read or write position.

-

specifies offset backward from the current read or write position.

The STREAM function itself returns the new position in the stream if the read or write position is successfully located or an appropriate error message otherwise.

The following is a description of the options for SEEK:

READ

specifies that the read position is to be set by this command.

WRITE

specifies that the write position is to be set by this command.

CHAR

specifies that the positioning is to be done in terms of characters. This is the default.

LINE

specifies that the positioning is to be done in terms of lines. For non-binary streams, this is an operation that can take a long time to complete, because, in most cases, the file must be scanned from the top to count line-end characters. However, for binary streams with a specified record length, this results in a simple multiplication of the new resulting line number by the record length, and then a simple character positioning. See Line versus Character Positioning for a detailed discussion of this issue.

Note: If you do line positioning in a file open only for writing, you receive an error message.

Examples:

stream(name,"c","seek =2 read")
stream(name,"c","seek +15 read")
stream(name,"c","seek -7 write line")
fromend  = 125
stream(name,"c","seek <"fromend read)
POSITION

is a synonym for SEEK.

QUERY Stream Commands

Used with these stream commands, the STREAM function returns specific information about a stream. Except for QUERY HANDLE and QUERY POSITION, the language processor returns the query information even if the stream is not open. The language processor returns UNKNOWN for QUERY STREAMTYPE and the null string for nonexistent streams.

Note that technically although a directory is persistent, it is not a stream. If the directory exists, the date / time queries return the time stamp of the directory, QUERY SIZE returns 0, and QUERY STREAMTYPE returns UNKNOWN. The other commands return the null string.

QUERY DATETIME

returns the date and time stamps of a stream in US format. This is included for compatibility with OS/2®.

stream("..\file.txt","c","query datetime")

A sample output might be:

11-12-98 03:29:12
QUERY EXISTS

returns the full path specification of the named stream, if it exists, or a null string.

stream("..\file.txt","c","query exists")

A sample output might be:

c:\data\file.txt
QUERY HANDLE

returns the handle associated with the open stream.

stream("..\file.txt","c","query handle")

A sample output might be:

3
QUERY POSITION

returns the current read or write position for the stream, as qualified by the following options:

READ

returns the current read position.

WRITE

returns the current write position.

Note: If the stream is open for both reading and writing, the default is to return the read position. Otherwise, it returns the appropriate position by default.

CHAR

returns the position in terms of characters. This is the default.

LINE

returns the position in terms of lines. For non-binary streams, this operation can take a long time to complete, because the language processor starts tracking the current line number if not already doing so. Thus, it might require a scan of the stream from the top to count line-end characters. See Line versus Character Positioning for a detailed discussion of this issue.

stream("myfile","c","query position write")

A sample output might be:

247
SYS

returns the operating-system stream position in terms of characters.

QUERY SIZE

returns the size, in bytes, of a persistent stream.

stream("..\file.txt","c","query size")

A sample output might be:

1305
QUERY STREAMTYPE

returns a string indicating whether the stream is PERSISTENT, TRANSIENT, or UNKNOWN.

QUERY TIMESTAMP

returns the date and time stamps of a stream in an international format. This is the preferred method of getting the date and time because it provides the full 4-digit year.

stream("..\file.txt","c","query timestamp")

A sample output might be:

1998-11-12 03:29:12

STRIP

>>-STRIP(string--+--------------------------+--)---------------><
                 +-,--+--------+--+-------+-+
                      +-option-+  +-,char-+

Returns string with leading characters, trailing characters, or both, removed, based on the option you specify. The following are valid options. (Only the capitalized letter is needed; all characters following it are ignored.)

Both

removes both leading and trailing characters from string. This is the default.

Leading

removes leading characters from string.

Trailing

removes trailing characters from string.

The third argument, char, specifies the character to be removed, and the default is to remove all whitespace characters. If you specify char, it must be exactly one character long.

Here are some 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 (Substring)

>>-SUBSTR(string,n--+-------------------------+--)-------------><
                    +-,--+--------+--+------+-+
                         +-length-+  +-,pad-+

Returns the substring of string that begins at the nth character and is of length length, padded with pad if necessary. n must be a positive whole number. If n is greater than LENGTH(string), only pad characters are returned.

If you omit length, the rest of the string is returned. The default pad character is a blank.

Here are some examples:

SUBSTR("abc",2)          ->    "bc"
SUBSTR("abc",2,4)        ->    "bc  "
SUBSTR("abc",2,6,".")    ->    "bc...."

Note: In some situations the positional (numeric) patterns of parsing templates are more convenient for selecting substrings, especially if more than one substring is to be extracted from a string. See also LEFT and RIGHT.

SUBWORD

>>-SUBWORD(string,n--+---------+--)----------------------------><
                     +-,length-+

Returns the substring of string that starts at the nth word, and is up to length whitespace-delimited words. n must be a positive whole number. If you omit length, it defaults to the number of remaining words in string. The returned string never has leading or trailing whitespace, but includes all whitespace characters between the selected words.

Here are some examples:

SUBWORD("Now is the  time",2,2)    ->    "is the"
SUBWORD("Now is the  time",3)      ->    "the  time"
SUBWORD("Now is the  time",5)      ->    ""

SYMBOL

>>-SYMBOL(name)------------------------------------------------><

Returns the state of the symbol named by name. It returns BAD if name is not a valid Rexx symbol. It returns VAR if it is the name of a variable, that is, a symbol that has been assigned a value. Otherwise, it returns LIT, indicating that it is either a constant symbol or a symbol that has not yet been assigned a value, that is, a literal.

As with symbols in Rexx expressions, lowercase characters in name are translated to uppercase and substitution in a compound name occurs if possible.

Note: You should specify name as a literal string, or it should be derived from an expression, to prevent substitution before it is passed to the function.

Here are some examples:

/* following: Drop A.3;  J=3 */
SYMBOL("J")      ->   "VAR"
SYMBOL(J)        ->   "LIT" /* has tested "3"     */
SYMBOL("a.j")    ->   "LIT" /* has tested A.3     */
SYMBOL(2)        ->   "LIT" /* a constant symbol  */
SYMBOL("*")      ->   "BAD" /* not a valid symbol */

TIME

>>-TIME(--+-----------------------------------+--)-------------><
          +-option--+-----------------------+-+
                    +-,string--+----------+-+
                               +-,option2-+

Returns the local time in the 24-hour clock format hh:mm:ss (hours, minutes, and seconds) by default, for example, 04:41:37.

You can use the following options to obtain alternative formats, or to gain access to the elapsed-time clock. (Only the capitalized letter is needed; all characters following it are ignored.)

Civil

returns the time in Civil format hh:mmxx. The hours can take the values 1 through 12, and the minutes the values 00 through 59. The minutes are followed immediately by the letters am or pm. This distinguishes times in the morning (12 midnight through 11:59 a.m.--appearing as 12:00am through 11:59am) from noon and afternoon (12 noon through 11:59 p.m.--appearing as 12:00pm through 11:59pm). The hour has no leading zero. The minute field shows the current minute (rather than the nearest minute) for consistency with other TIME results.

Elapsed

returns sssssssss.uuuuuu, the number of seconds and microseconds since the elapsed-time clock (described later) was started or reset. The returned number has no leading zeros or whitespace, and the setting of NUMERIC DIGITS does not affect it. The number has always four trailing zeros in the decimal portion.

The language processor calculates elapsed time by subtracting the time at which the elapsed-time clock was started or reset from the current time. It is possible to change the system time clock while the system is running. This means that the calculated elapsed time value might not be a true elapsed time. If the time is changed so that the system time is earlier than when the Rexx elapsed-time clock was started (so that the elapsed time would appear negative), the language processor raises an error and disables the elapsed-time clock. To restart the elapsed-time clock, trap the error through SIGNAL ON SYNTAX.

The clock can also be changed by programs on the system. Many LAN-attached programs synchronize the system time clock with the system time clock of the server during startup. This causes the Rexx elapsed time function to be unreliable during LAN initialization.

Full

returns the number of microseconds since 00:00:00.000000 on 1 January 0001, in the format: dddddddddddddddddd (no leading zeros or whitespace).

Notes: The base date of 1 January 0001 is determined by extending the current Gregorian calendar backward (365 days each year, with an extra day every year that is divisible by 4 except century years that are not divisible by 400. It does not take into account any errors in the calendar system that created the Gregorian calendar originally.

The value returned by Time('F') can be used to calculate the interval between any two times. Note, however, that values returned generally contain more digits that the default NUMERIC DIGITS setting. The NUMERIC DIGITS setting should be increased to a minimum value of 18 when performing timestamp arithmetic.

Hours

returns up to two characters giving the number of hours since midnight in the format hh (no leading zeros or whitespace, except for a result of 0).

Long

returns time in the format hh:mm:ss.uuuuuu (where uuuuuu are microseconds).

Minutes

returns up to four characters giving the number of minutes since midnight in the format mmmm (no leading zeros or whitespace, except for a result of 0).

Normal

returns the time in the default format hh:mm:ss. The hours can have the values 00 through 23, and minutes and seconds, 00 through 59. There are always two digits. Any fractions of seconds are ignored (times are never rounded). This is the default.

Offset

returns the offset of the local time from UTC in microseconds. The offset value will be negative for timezones west of the Prime Meridian and positive for timezones east of Prime Meridian. The local time('F') value can be converted to UTC by adding the time('O') value.

Reset

returns sssssssss.uuuuuu, the number of seconds and microseconds since the elapsed-time clock (described later) was started or reset and also resets the elapsed-time clock to zero. The returned number has no leading zeros or whitespace, and the setting of NUMERIC DIGITS does not affect it. The number always has four trailing zeros in the decimal portion.

See the Elapsed option for more information on resetting the system time clock.

Seconds

returns up to five characters giving the number of seconds since midnight in the format sssss (no leading zeros or whitespace, except for a result of 0).

Ticks

returns the number of seconds since 00:00:00.000000 on 1 January 1970, in the format: dddddddddddd (no leading zeros or whitespace).

Notes: The base date of 1 January 1970 is determined by extending the current Gregorian calendar backward (365 days each year, with an extra day every year that is divisible by 4 except century years that are not divisible by 400. It does not take into account any errors in the calendar system that created the Gregorian calendar originally.

The value returned by Time('T') can be used to calculate the interval between any two times. Note, however, that values returned generally contain more digits that the default NUMERIC DIGITS setting. The NUMERIC DIGITS setting should be increased to a minimum value of 12 when performing timestamp arithmetic.

Time('T') will return a negative number for dates prior to 1 January 1970.

Here are some examples, assuming that the time is 4:54 p.m.:

TIME()       ->   "16:54:22"
TIME("C")    ->   "4:54pm"
TIME("H")    ->   "16"
TIME("L")    ->   "16:54:22.120000"   /* Perhaps */
TIME("M")    ->   "1014"           /* 54 + 60*16 */
TIME("N")    ->   "16:54:22"
TIME("S")    ->   "60862"  /* 22 + 60*(54+60*16) */

The elapsed-time clock:

You can use the TIME function to measure real (elapsed) time intervals. On the first call in a program to TIME("E") or TIME("R"), the elapsed-time clock is started, and either call returns 0. From then on, calls to TIME("E") and TIME("R") return the elapsed time since that first call or since the last call to TIME("R").

The clock is saved across internal routine calls, which means that an internal routine inherits the time clock that its caller started. Any timing the caller is doing is not affected, even if an internal routine resets the clock. An example of the elapsed-time clock:

time("E")    ->    0          /* The first call */
                  /* pause of one second here */
time("E")    ->    1.020000   /* or thereabouts */
                  /* pause of one second here */
time("R")    ->    2.030000   /* or thereabouts */
                  /* pause of one second here */
time("R")    ->    1.050000   /* or thereabouts */

Note: The elapsed-time clock is synchronized with the other calls to TIME and DATE, so several calls to the elapsed-time clock in a single clause always return the same result. For this reason, the interval between two usual TIME/DATE results can be calculated exactly using the elapsed-time clock.

If you specify string, TIME returns the time corresponding to string in the format option. The string must be supplied in the format option2. The default for option2 is "N". So you need to specify option2 only if string is not in the Normal format. option2 must specify the current time, for example, not "E" or "R". Here are some examples:

time("C","11:27:21")    ->    11:27am
time("N","11:27am","C") ->    11:27:00
time("N", "63326132161828000", "F")   ->   08:16:01

You can determine the difference between two times; for example:

If TIME("M","5:00pm","C")-TIME("M")<=0
then say "Time to go home"
else say "Keep working"

The TIME returned is the earliest time consistent with string. For example, if the result requires components that are not specified in the source format, then those components of the result are zero. If the source has components that the result does not need, then those components of the source are ignored.

When requesting times be converted to Full or Ticks format, a date value of 1 January 0001 is used for the conversion. A time stamp for a time and date combination can be created by combining a value from Date('F') for the time of day.

    numeric digits 18  -- needed to add the timestamps
    timestamp = date('f, '20072301', 'S') + time('f', '08:14:22', 'N')

Implementation maximum: If the number of seconds in the elapsed time exceeds nine digits (equivalent to over 31.6 years), an error results.

TRACE

>>-TRACE(--+--------+--)---------------------------------------><
           +-option-+

Returns trace actions currently in effect and, optionally, alters the setting.

If you specify option, it selects the trace setting. It must be the valid prefix ?, one of the alphabetic character options associated with the TRACE instruction (that is, starting with A, C, E, F, I, L, N, O, or R), or both. (See the TRACE instruction in Alphabetic Character (Word) Options for full details.)

Unlike the TRACE instruction, the TRACE function alters the trace action even if interactive debugging is active. Also unlike the TRACE instruction, option cannot be a number.

Here are some examples:

TRACE()       ->   "?R" /* maybe */
TRACE("O")    ->   "?R" /* also sets tracing off */
TRACE("?I")   ->   "O"  /* now in interactive debugging */

TRANSLATE

>>-TRANSLATE(string--------------------------------------------->

>--+--------------------------------------------+--)--------------------------------+-><
   +-,--+--------+--+-------------------------+-+     +-------------------------+-)-+
        +-tableo-+  +-,--+--------+--+------+-+       +-,--+-----+--+---------+-+
                         +-tablei-+  +-,pad-+              +-pos-+  +-,length-+

Returns string with each character translated to another character or unchanged. You can also use this function to reorder the characters in string.

The output table is tableo and the input translation table is tablei. TRANSLATE searches tablei for each character in string. If the character is found, the corresponding character in tableo is used in the result string; if there are duplicates in tablei, the first (leftmost) occurrence is used. If the character is not found, the original character in string is used. The result string is always the same length as string.

The tables can be of any length. If you specify neither table and omit pad, string is simply translated to uppercase (that is, lowercase a-z to uppercase A-Z), but, if you include pad, the language processor translates the entire string to pad characters. tablei defaults to XRANGE("00"x,"FF"x), and tableo defaults to the null string and is padded with pad or truncated as necessary. The default pad is a blank.

pos is the position of the first character of the translated range. The default starting position is 1. length is the range of characters to be translated. If omitted, length remainder of the string from the starting position to the end is used.

Here are some examples:

TRANSLATE("abcdef")                        ->    "ABCDEF"
TRANSLATE("abcdef", , , , 2, 3)            ->    "aBCDef"
TRANSLATE("abcdef", "12", "ec")            ->    "ab2d1f"
TRANSLATE("abcdef", "12", "abcd", ".")     ->    "12..ef"
TRANSLATE("APQRV", , "PR")                 ->    "A Q V"
TRANSLATE("APQRV", XRANGE("00"X, "Q"))     ->    "APQ  "
TRANSLATE("4123", "abcd", "1234")          ->    "dabc"
TRANSLATE("4123", "abcd", "1234", , 2, 2)  ->    "4ab1"

Note: The last example shows how to use the TRANSLATE function to reorder the characters in a string. The last character of any four-character string specified as the second argument is moved to the beginning of the string.

TRUNC (Truncate)

>>-TRUNC(number--+----+--)-------------------------------------><
                 +-,n-+

Returns the integer part of number and n decimal places. The default n is 0 and returns an integer with no decimal point. If you specify n, it must be a positive whole number or zero. The number is rounded according to standard Rexx rules, as though the operation number+0 had been carried out. Then it is truncated to n decimal places or trailing zeros are added to reach the specified length. The result is never in exponential form. If there are no nonzero digits in the result, any minus sign is removed.

Here are some 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 is rounded according to the current setting of NUMERIC DIGITS, if necessary, before the function processes it.

UPPER

>>-UPPER(string-+----------------------------+--)--------------><
                +--,--+-----+--+-----------+-+
                      +--n--+  +--,length--+

Returns a new string with the characters of string beginning with character n for length characters converted to uppercase. If n is specified, it must be a positive whole number. If n is not specified, the case conversion will start with the first character. If length is specified, it must be a non-negative whole number. If length the default is to convert the remainder of the string.

Examples:

upper("Albert Einstein")      ->    "ALBERT EINSTEIN"
upper("abcdef", 4)            ->    "abcDEF"
upper("abcdef", 3, 2)         ->    "abCDef"

USERID

>>-USERID()----------------------------------------------------><

The return value is the active user identification.

VALUE

>>-VALUE(name--+--------------------------------+--)-----------><
               +-,--+----------+--+-----------+-+
                    +-newvalue-+  +-,selector-+

Returns the value of the symbol that name (often constructed dynamically) represents and optionally assigns a new value to it. By default, VALUE refers to the current Rexx-variables environment, but other, external collections of variables can be selected. If you use the function to refer to Rexx variables, name must be a valid Rexx symbol. (You can confirm this by using the SYMBOL function.) Lowercase characters in name are translated to uppercase for the local environment. For the global environment lowercase characters are not translated because the global environment supports mixed-case identifiers. Substitution in a compound name (see Compound Symbols) occurs if possible.

If you specify newvalue, the named variable is assigned this new value. This does not affect the result returned; that is, the function returns the value of name as it was before the new assignment.

Here are some examples:

/* After: Drop A3; A33=7; K=3; fred="K"; list.5="Hi" */
VALUE("a"k)     ->  "A3" /* looks up A3                */
VALUE("a"k||k)  ->  "7"
VALUE("fred")   ->  "K"  /* looks up FRED              */
VALUE(fred)     ->  "3"  /* looks up K                 */
VALUE(fred,5)   ->  "3"  /* looks up K and             */
                         /* then sets K=5              */
VALUE(fred)     ->  "5"  /* looks up K                 */
VALUE("LIST."k) ->  "Hi" /* looks up LIST.5            */

To use VALUE to manipulate environment variables, selector must be the string "ENVIRONMENT" or an expression that evaluates to "ENVIRONMENT". In this case, the variable name need not be a valid Rexx symbol. Environment variables set by VALUE are not kept after program termination.

Restriction: The values assigned to the variables must not contain any character that is a hexadecimal zero ("00"X). For example:

Call VALUE "MYVAR", "FIRST" || "00"X || "SECOND", "ENVIRONMENT"

sets MYVAR to "FIRST", truncating "00"x and "SECOND".

Here are some more examples:

/* Given that an external variable FRED has a value of 4         */
share = "ENVIRONMENT"
say VALUE("fred",7,share)      /* says "4" and assigns           */
                               /* FRED a new value of 7          */

say VALUE("fred", ,share)      /* says "7"                       */

/* Accessing and changing Windows environment entries given that */
                               /* PATH=C:\EDIT\DOCS;             */
env = "ENVIRONMENT"
new = "C:\EDIT\DOCS;"
say value("PATH",new,env)   /* says "C:\WINDOWS" (perhaps)       */
                            /* and sets PATH = "C:\EDIT\DOCS;"   */

say value("PATH", ,env)     /* says "C:\EDIT\DOCS;"              */

To delete an environment variable use the Nil object as the newvalue. To delete the environment variable "MYVAR" specify: value("MYVAR", .NIL, "ENVIRONMENT"). If you specify an empty string as the newvalue like in value("MYVAR", ", "ENVIRONMENT") the value of the external environment variable is set to an empty string which on Windows and *nix is not the same as deleting the environment variable.

A selector called "WSHENGINE" is also available to the VALUE function when a Rexx script is run in a Windows Script Host scripting context (running via cscript, wscript or as embedded code in HTML for the Microsoft Internet Explorer). The only currently supported value is "NAMEDITEMS". Calling VALUE with these parameters returns an array with the names of the named items that were added at script start.

Example:

myArray = VALUE("NAMEDITEMS", ,"WSHENGINE")

The value NAMEDITEMS is read-only, writing to it is prohibited.

Object Rexx scripts running via the scripting engine (in WSH context) can now call the default method of an object as a function call with the object name.

Example:

The SESSION object of ASP (Active Server Pages) has the default method VALUE. The usual (and recommended) way of using the SESSION object would be to use

SESSION~VALUE("key","value").

Because VALUE is the default method, a function call

SESSION("key","value")
SESSION~VALUE("key","value").
causes an invocation of VALUE with the given arguments. For objects that have the name of a Rexx function, an explicit call to the default method must be made, because Rexx functions have priority over this implicit method invocation mechanism.

Note: In contrast to OS/2, the Windows and *nix environments are unchanged after program termination.

You can use the VALUE function to return a value to the global environment directory. To do so, omit newvalue and specify selector as the null string. The language processor sends the message name (without arguments) to the current environment object. The environment returns the object identified by name. If there is no such object, it returns, by default, the string name with an added initial period (an environment symbol--see Environment Symbols).

Here are some examples:

/* Assume the environment name MYNAME identifies the string "Simon"    */
name = value("MYNAME", ,"") /* Sends MYNAME message to the environment */
name = .myname              /* Same as previous instruction            */
say "Hello," name           /* Produces: "Hello, Simon"                */
/* Assume the environment name NONAME does not exist.                  */
name = value("NONAME", ,"") /* Sends NONAME message to the environment */
say "Hello," name           /* Produces:  "Hello, .NONAME"             */

You can use the VALUE function to change a value in the Rexx environment directory. Include a newvalue and specify selector as the null string. The language processor sends the message name (with = appended) and the single argument newvalue to the current environment object. After receiving this message, the environment identifies the object newvalue by the name name.

Here is an example:

name = value("MYNAME","David","") /* Sends "MYNAME=("David") message  */
/* to the environment.                                                */
/* You could also use:                                                */
/*   call value "MYNAME","David",""                                   */
say "Hello," .myname              /* Produces:  "Hello, David"        */

Notes:

  1. If the VALUE function refers to an uninitialized Rexx variable, the default value of the variable is always returned. The NOVALUE condition is not raised because a reference to an external collection of variables never raises NOVALUE.

  2. The VALUE function is used when a variable contains the name of another variable, or when a name is constructed dynamically. If you specify name as a single literal string and omit newvalue and selector, the symbol is a constant and the string between the quotation marks can usually replace the whole function call. For example, fred=VALUE("k"); is identical with the assignment fred=k;, unless the NOVALUE condition is trapped. See Conditions and Condition Traps.

VAR

>>-VAR(name)---------------------------------------------------><

Returns 1 if name is the name of a variable, that is, a symbol that has been assigned a value), or 0.

Here are some examples:

/* Following: DROP A.3; J=3  */
VAR("J")       -> 1
VAR(J)         -> 0  /* has tested "3"    */
VAR("a.j")     -> 0  /* has tested "A.3"  */
VAR(2)         -> 0  /* a constant symbol */
VAR("*")       -> 0  /* an invalid symbol */

VERIFY

>>-VERIFY(string,reference--+----------------------------------------------+--)---><
                            +-,--+--------+--+---------------------------+-+
                                 +-option-+  +-,--+-------+--+---------+-+
                                                  +-start-+  +-,length-+

Returns a number that, by default, indicates whether string is composed only of characters from reference. It returns 0 if all characters in string are in reference, or returns the position of the first character in string that is not in reference.

The option can be either Nomatch (the default) or Match. (Only the capitalized and highlighted letter is needed. All characters following it are ignored, and it can be in uppercase or lowercase characters.) If you specify Match, the function returns the position of the first character in the string that is in reference, or returns 0 if none of the characters are found.

The default for start is 1; thus, the search starts at the first character of string. You can override this by specifying a different start point, which must be a positive whole number.

The default for length is the length of the string from start to the end of the string. Thus, the search proceeds to the end of the receiving string. You can override this by specifying a different length, which must be a non-negative whole number.

If string is null, the function returns 0, regardless of the value of the third argument. Similarly, if start is greater than LENGTH(string), the function returns 0. If reference is null, the function returns 0 if you specify Match; otherwise, the function returns the start value.

Here are some examples:

VERIFY("123","1234567890")             ->    0
VERIFY("1Z3","1234567890")             ->    2
VERIFY("AB4T","1234567890")            ->    1
VERIFY("AB4T","1234567890","M")        ->    3
VERIFY("AB4T","1234567890","N")        ->    1
VERIFY("1P3Q4","1234567890", ,3)       ->    4
VERIFY("123","",N,2)                   ->    2
VERIFY("ABCDE","", ,3)                 ->    3
VERIFY("AB3CD5","1234567890","M",4)    ->    6
VERIFY("ABCDEF","ABC","N",2,3)         ->    4
VERIFY("ABCDEF","ADEF","M",2,3)        ->    4

WORD

>>-WORD(string,n)----------------------------------------------><

Returns the nth whitespace-delimited word in string or returns the null string if less than n words are in string. n must be a positive whole number. This function is equal to SUBWORD(string, n,1).

Here are some examples:

WORD("Now is the time",3)    ->    "the"
WORD("Now is the time",5)    ->    ""

WORDINDEX

>>-WORDINDEX(string,n)-----------------------------------------><

Returns the position of the first character in the nth whitespace-delimited word in string or returns 0 if less than n words are in string. n must be a positive whole number.

Here are some examples:

WORDINDEX("Now is the time",3)    ->    8
WORDINDEX("Now is the time",6)    ->    0

WORDLENGTH

>>-WORDLENGTH(string,n)----------------------------------------><

Returns the length of the nth whitespace-delimited word in the string or returns 0 if less than n words are in the string. n must be a positive whole number.

Here are some examples:

WORDLENGTH("Now is the time",2)       ->    2
WORDLENGTH("Now comes the time",2)    ->    5
WORDLENGTH("Now is the time",6)       ->    0

WORDPOS (Word Position)

>>-WORDPOS(phrase,string--+--------+--)------------------------><
                          +-,start-+

Returns the word number of the first word of phrase found in string or returns 0 if phrase contains no words or if phrase is not found. Several whitespace characters between words in either phrase or string are treated as a single blank for the comparison, but otherwise the words must match exactly.

By default, the search starts at the first word in string. You can override this by specifying start (which must be positive), the word at which to start the search.

Here are some 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

>>-WORDS(string)-----------------------------------------------><

Returns the number of whitespace-delimited words in string.

Here are some examples:

WORDS("Now is the time")    ->    4
WORDS(" ")                  ->    0

X2B (Hexadecimal to Binary)

>>-X2B(hexstring)----------------------------------------------><

Returns a string, in character format, that represents hexstring converted to binary. The hexstring is a string of hexadecimal characters. It can be of any length. Each hexadecimal character is converted to a string of 4 binary digits. You can optionally include whitespace characters in hexstring (at byte boundaries only, not leading or trailing) to improve readability; they are ignored.

The returned string has a length that is a multiple of 4, and does not include any whitespace.

If hexstring is null, the function returns a null string.

Here are some examples:

X2B("C3")        ->  "11000011"
X2B("7")         ->  "0111"
X2B("1 C1")      ->  "000111000001"

You can combine X2B with the functions D2X and C2X to convert numbers or character strings into binary form.

Here are some examples:

X2B(C2X("C3"x))  ->  "11000011"
X2B(D2X("129"))  ->  "10000001"
X2B(D2X("12"))   ->  "1100"

X2C (Hexadecimal to Character)

>>-X2C(hexstring)----------------------------------------------><

Returns a string, in character format, that represents hexstring converted to character. The returned string has half as many bytes as the original hexstring. hexstring can be of any length. If necessary, it is padded with a leading zero to make an even number of hexadecimal digits.

You can optionally include whitespace characters in hexstring (at byte boundaries only, not leading or trailing) to improve readability; they are ignored.

If hexstring is null, the function returns a null string.

Here are some examples:

X2C("4865 6c6c 6f") ->  "Hello"     /*  ASCII             */
X2C("3732 73")      ->  "72s"       /*  ASCII             */

X2D (Hexadecimal to Decimal)

>>-X2D(hexstring--+----+--)------------------------------------><
                  +-,n-+

Returns the decimal representation of hexstring. The hexstring is a string of hexadecimal characters. If the result cannot be expressed as a whole number, an error occurs. That is, the result must not have more digits than the current setting of NUMERIC DIGITS.

You can optionally include whitespace characters in hexstring (at byte boundaries only, not leading or trailing) to aid readability; they are ignored.

If hexstring is null, the function returns 0.

If you do not specify n, the hexstring is processed as an unsigned binary number.

Here are some examples:

X2D("0E")        ->    14
X2D("81")        ->    129
X2D("F81")       ->    3969
X2D("FF81")      ->    65409
X2D("46 30"X)    ->    240          /*  ASCII   */
X2D("66 30"X)    ->    240          /*  ASCII   */

If you specify n, the string is taken as a signed number expressed in n hexadecimal digits. If the leftmost bit is off, then the number is positive; otherwise, it is a negative number. In both cases it is converted to a whole number, which can be negative. If n is 0, the function returns 0.

If necessary, hexstring is padded on the left with 0 characters (not "sign-extended"), or truncated on the left to n characters.

Here are some examples:

X2D("81",2)      ->    -127
X2D("81",4)      ->    129
X2D("F081",4)    ->    -3967
X2D("F081",3)    ->    129
X2D("F081",2)    ->    -127
X2D("F081",1)    ->    1
X2D("0031",0)    ->    0

XRANGE (Hexadecimal Range)

>>-XRANGE(--+-------+--+------+--)-----------------------------><
            +-start-+  +-,end-+

Returns a string of all valid 1-byte encodings (in ascending order) between and including the values start and end. The default value for start is "00"x, and the default value for end is "FF"x. If start is greater than end, the values wrap from "FF"x to "00"x. If specified, start and end must be single characters.

Here are some examples:

XRANGE("a","f")      ->   "abcdef"
XRANGE("03"x,"07"x)  ->   "0304050607"x
XRANGE(,"04"x)       ->   "0001020304"x
XRANGE("FE"x,"02"x)  ->   "FEFF000102"x
XRANGE("i","j")      ->   "ij"                   /* ASCII  */