Using REXX Input/Output Commands
ID: Q99063
|
SUMMARY
This article lists the input/output capabilities of the REXX programming
language and gives examples.
MORE INFORMATION
DISCLAIMER: This article is provided for users capable of developing
programs with the information presented; it is not an extensive treatment
of the language but rather a quick reference to aid someone in writing
simple routines. Microsoft cannot support programming efforts beyond
reproducing and submitting problems with the language implementation
itself. If you need further assistance, consult REXX references such as
"The REXX Language, A Practical Approach to Programming" by M. F.
Cowlishaw, Prentice-Hall, Englewood Cliffs, 1985.
Examples are given at the bottom of the listing. Braces ({}) are used
to indicate comments.
CHARIN(file|input_stream|kbd, start_read, number_to_read) { Returns
number_to_read characters beginning with the file position specified
by start_read (start_read cannot be specified for input_streams such
as COM1). Specifying zero for number_to_read repositions the current
"read point" to start_read. If the number of bytes requested is not
available but may become available (that is, COMn) then CHARIN waits
on them, otherwise a NOTREADY condition results. }
CHAROUT(output_stream|file|screen, data, start_write) { Writes
characters to the specified destination. For files, if the 'data' is
not specified then "write point" is moved to start_write. Normally the
write point is at the end of the file so that data is always appended
to the file by a CHAROUT. If neither 'data' or start_write are given
then the file is closed). Processing stops until CHAROUT completes or
an error condition is returned. }
CHARS(input_stream|file|kbd) { Returns the number of characters
available to read. For STDIN it always returns 1 if data is present
(zero otherwise). It always returns 1 for OS/2 devices. }
LINEIN(from_this_source, top_of_source?, number_of_lines) { returns
either the line read or zero (from_this_source is opened automatically).
If top_of_source is specified as 1 (the only valid value) then the current
read point is reset to the first byte in the source. Number_of_lines is
either zero (to reposition the read point) or 1. }
LINEOUT(to_this_target, this_data, top_of_target?) { returns the number
of lines remaining to be written (usually an error) after this_data is
written to to_this_target, if top_of_target? is set to 1 then the write
position is set to the first byte of the target, if neither this_data or
top_of_target is specified then to_this_target is closed. }
LINES(source) { returns 1 if there is more data available from source,
zero otherwise. }
PULL var1 var2 ... var? { returns input into the variables specified.
If more 'word' than variables are specified, the trailing words on a
line are all placed in the last variable. The effect of PULL, either with
or without variables specified, is to empty the input source. }
PUSH var1 var2 ... var? { places the contents of the variables into the
input source. Each separate PUSH represents a line in the input source.
Example: PUSH a b c creates one line in the input source containing the
contents of a, b and c whereas PUSH a;PUSH b;PUSH c puts three lines in
the input source, one with the contents of a, a second with the contents
of b and a third with the contents of c. }
QUEUE var1 var2 .. . var? { places the variables at the end of the current
queue. Each separate QUEUE puts a separate line in the input source. Using
the above PUSH example, a 'QUEUE xyz' done after the 'PUSH c' would put
xyz's contents in the input source as if a 'PUSH xyz' had been done before
the 'PUSH a'. }
QUEUED() { returns the number of lines in the current REXX queue. }
SAY expression { is like the MS-DOS @echo command but evaluates an
expression before displaying it on the screen. }
SOURCELINE(n) { returns the current program's line number 'n' or, if
'n' is not specified, the total number of program source lines. }
STREAM(I/O_stream, type_of_action, specific_command) { returns
information of a (data) stream based on type_of_action which can be:
'C'ommand (requires a specific_command), 'D'escription (a superset of
'S'tate possibly returning additional information) and 'S'tate (which
returns the current state such as ERROR, NOTREADY, READY, this is
normally on an open file), specific_commands are: OPEN, CLOSE, SEEK
offest, QUERY EXISTS, QUERY SIZE, QUERY DATETIME. The last three
return a stream's path, size and date/time if the stream exists. }
Example (explanation follows):
(You are encouraged to extract the code below and run it. If you do,
remember to include the beginning comment so that OS/2 recognizes it as
a REXX file. In order to do so, you need to create two files: ORDERS and
INSTOCK. Also make sure that you do not have a file named LABELS in the
directory where you run the program. ORDERS has the following record
layout with no carriage-return/line-feeds separating records:
temp_line = STREAM('instock','C','QUERY EXISTS')
IF temp_line = '' THEN
DO
SAY Stock exhausted
EXIT
END
temp_line = STREAM('orders','C','QUERY EXISTS')
IF temp_line = '' THEN
DO
SAY No orders
EXIT
END
temp_line = SOURCELINE(1)
PUSH "Labels produced by " temp_line
PULL temp_line
n = LINEOUT('labels',temp_line)
n = LINEOUT('labels','')
DO WHILE ((CHARS('instock') > 0) & (LINES('orders') > 0))
lname = CHARIN('orders',,8)
fname = CHARIN('orders',,5)
initial = CHARIN('orders',,1)
PUSH fname initial lname
cust_addr = CHARIN('orders',,10)
city_st_zip = CHARIN('orders',,16)
QUEUE cust_addr
QUEUE city_st_zip
part_desc = LINEIN('instock',,1)
PULL first_line
n = CHAROUT('labels',first_line)
n = LINEOUT('labels',part_desc)
DO WHILE queued() > 0
PULL temp_line
n = LINEOUT('labels', temp_line)
END
END
The first twelve lines use the STREAM command to test for the existence
of the files being used and display error messages using the SAY command
if they are not found. Temp_line is used as a working storage string.
Line 13 through 17 use the SOURCELINE command to get the first line of
this program's source. Whatever you place there will be written as the
first line of the LABELS file. The PUSH effectively combines the result
of SOURCELINE with an explanatory prefix which is PULLed back into
temp_line and then written to LABELS with the LINEOUT command. PUSH and
PULL use a built-in REXX internal queue as temporary storage. Each PUSH
creates a carriage-return/line-delimited line in the queue and each PULL
removes a line.
Line 18 uses both the CHARS and LINES commands to cause the loop to
end when the end of either ORDERS or INSTOCK is encountered.
Lines 19-21 read three variables using CHARIN since ORDERS is not a
line-delimited file. The PUSH in line 22 rearranges these three variables
for output.
The variables read in lines 23 and 24 are QUEUEd in lines 25 and 26 in
order to put the address and city/state/zip after the name in the REXX
internal queue. This allows the full address to be put out in the order
desired by simply PULLing off of the top of the internal queue.
LINEIN is used in line 27 because INSTOCK is a line-delimited file. PULL
is then used in line 28 to get the name which is output using CHAROUT in
line 29. CHAROUT is used because it does not add a carriage-return/line-
feed and this is desired in order to put the INSTOCK description next to
the name in the LABELS file. This is followed by the LINEOUT in line 30 to
complete the line.
In line 31 the QUEUED command is used to test for remaining data in the
queue and write it out to LABELS.
Additional query words:
2.10 2.1 .10a 2.1a 2.20 2.2
Keywords :
Version :
Platform :
Issue type :