Copyright (c) 2012-2016 Hyperion Entertainment and contributors.
AmigaOS Manual: ARexx Input and Output
ARexx's input and output model consists of three parts: character input streams, character output streams, and an external data stack. The input and output streams can be manipulated character-by-character or line-by-line, while the data stack can be accessed only by line operations.
- 1 The External Data Stack
- 2 The Character Input and Output Streams
The External Data Stack
The external data stack is ARexx's queue service. An ARexx program can store character strings (lines) to the stack and pull strings out of the stack. The external data stack is connected to the command line interface which is the standard input/output stream. The external data stack provides an alternative way for inter-process-communication, since a parent program can pull lines from the stack which where pushed there by a child program and a child program can pull lines from the stack which were pushed there by a parent program.
There are two instructions for adding lines of text to the external data stack. PUSH will add one line at the top of the stack while QUEUE will add the line at the bottom of the stack. Despite of the stack's connection to the standard input/output stream, lines stored in the external data stack will not be visible to the user until an ARexx script exits. Only after then the whole content of the stack will be emptied to the standard output stream.
PULL instruction is used for reading and removing the top-most line from the external data stack. If the stack is empty, PULL will read a line from the standard input stream, i.e. from the console window.
Program 17. ReadLine.rexx
/* ** Read a line from the console window. */ SAY 'Type anything and press enter.' /* ** PULL will read a line from the standard input since ** the external data stack is empty. */ PULL line SAY 'You typed:' line
When a PUSH instruction is used for adding a line to the stack, the line will be added at the top of the stack. Together with a PULL instruction this forms a stack data structure where last inserted line is pulled out first – last-in-first-out (LIFO).
Program 18. Stack.rexx
/* ** Stack example */ /* Put 3 lines to the stack */ PUSH 'Item 1' PUSH 'Item 2' PUSH 'Item 3' /* Pop 3 lines from the stack */ PARSE PULL first PARSE PULL second PARSE PULL third SAY '1st' first SAY '2nd' second SAY '3rd' third
If a QUEUE instruction is used for adding a line to the stack, the line will be added at the bottom of the stack. Together with a PULL instruction this forms a queue data structure where the first inserted line is pulled out first – first-in-first-out (FIFO).
Program 19. Queue.rexx
/* ** Queue example */ /* Put 3 lines to the stack */ QUEUE 'Item 1' QUEUE 'Item 2' QUEUE 'Item 3' /* Pop 3 lines from the stack */ PARSE PULL first PARSE PULL second PARSE PULL third SAY '1st' first SAY '2nd' second SAY '3rd' third
If the number of stacked items is unknown, you can use LINES function to find out how many lines there currently are in the stack. The program below demonstrates how to empty the stack by utilising the LINES function.
Program 20. EmptyStack.rexx
/* ** Empty the external data stack */ /* Add 4 lines to the external stack */ QUEUE 'Tinker, Tailor,' QUEUE 'Soldier, Sailor,' QUEUE 'Rich Man, Poor Man,' QUEUE 'Beggar Man, Thief.' /* Pull all lines from the stack */ DO LINES( STDIN ) PARSE PULL line SAY line END
An example of inter-process-communication through the external data stack.
Program 21. Parent.rexx
/* ** This program adds data to the external stack, then ** executes the child program 'Child.rexx', which reads the data ** from the stack, and finally reads child's reply from the stack. */ /* Add two lines to the stack */ SAY 'Parent: sending data to child...' QUEUE 'Item 1' QUEUE 'Item 2' /* Execute child */ ADDRESS command 'RX Child.rexx' /* Get child's reply */ PARSE PULL message SAY 'Parent: Got the following reply:' message
Program 22. Child.rexx
/* ** Child program */ /* Get data */ PARSE PULL first PARSE PULL second SAY 'Child: Received the following data:' SAY ' ' first SAY ' ' second /* Reply through the external stack */ PUSH 'Thanks!'
The Character Input and Output Streams
The character input and output streams are used for reading and writing to files. The following functions are available for the streams:
|CLOSE||Close an input/output stream.|
|EOF||Check if the read/write position of the stream is at the end of the stream.|
|OPEN||Open an input/output stream.|
|READCH||Reads specified number of characters from a previously opened input stream at the current stream position.|
|READLN||Reads a line from a previously opened input stream at the current stream position.|
|SEEK||Moves the stream's read/write position.|
|WRITECH||Writes a string to a previously opened output stream at the current stream position.|
|WRITELN||Writes a line to a previously opened output stream at the current stream position.|
The general procedure of writing to a file is as follows:
- Open an output stream using OPEN function.
- Write to the stream using WRITECH or WRITELN function.
- Close the stream using CLOSE function.
Example 23. CreateFile.rexx
/* Create a file */ file = 'RAM:myfile.txt' /* Open a file for writing */ IF ~OPEN( 'MYFILE', file, 'W' ) THEN DO SAY 'Failed to create file "' || file || '".' EXIT 10 END /* Write to the file */ CALL WRITELN( 'MYFILE', 'It goes in the morning on four feet,' ) CALL WRITELN( 'MYFILE', 'at lunch-time on two,' ) CALL WRITELN( 'MYFILE', 'in the evening on three.' ) CALL WRITELN( 'MYFILE', '' ) CALL WRITELN( 'MYFILE', 'What is it?' ) /* Close the file */ CALL CLOSE( 'MYFILE' )
The general procedure of reading from a file is as follows:
- Open an input stream using OPEN function.
- Read characters or lines from the stream using READCH or READLN function.
- Close the stream using CLOSE function.
Example 24. ReadFile.rexx
/* Read a file */ file = 'RAM:myfile.txt' /* Open a file for reading */ IF ~OPEN( 'MYFILE', file, 'R' ) THEN DO SAY 'Failed to open file "' || file || '".' EXIT 10 END /* Read the whole file content or maximum of 65535 characters */ content = READCH( 'MYFILE', 65535 ) /* Close the file */ CALL CLOSE( 'MYFILE' ) /* Print file content */ SAY content
The character input and output stream functions can also be used for reading and writing to the standard input and output stream – to the console window. ARexx opens and closes the input and output streams to the standard input and output automatically and provides a common logical name for accessing the standard input/output stream: STDIN.
Reading and writing to the console window is simpler than reading and writing to a file because you do not have to open and close the stream – ARexx will do that for you. To read a line from the console window you just call the READLN function with the logical name of STDIN:
line = READLN( STDIN )
Writing to the console window is equally easy:
CALL WRITELN( STDIN, 'Hello world!' )
Example 25. ReadCharacters.rexx
/* Read 3 characters from the standard input */ characters = READCH( STDIN, 3 ) SAY characters /* Any extra characters are stored in the */ /* external data stack and can be pulled out. */ PARSE PULL extraChars SAY extraChars
The following program shows how to print text without changing a line.
Example 26. WriteCharacters.rexx
/* Print prompt using WRITECH */ CALL WRITECH( STDIN, "Hi! I'm Amiza. What is your problem? " ) PARSE PULL line SAY 'I see.'