TTY Stream

A Prolog stream is a tty stream if the format of the stream is QP_DELIM_TTY. A tty stream is normally associated with a terminal device, a pseudo-terminal device or a terminal emulator. A set of tty streams can be grouped together through a distinct character string key for each group of tty streams. All the tty streams from the same tty device (emulator) should normally be grouped together. A tty stream registers itself to a tty stream group by calling QP_add_tty() with the specific character string key for the group.

There are two services provided automatically by Prolog I/O system to each tty stream group. When a tty stream is closed, it is automatically removed from its tty group.


Prompt Handling
There must be at least one output stream in the tty stream group in order to write out the prompt string of an input stream in the group. When an input tty stream reads at the beginning of a line, the middle layer input function writes out the prompt of the input stream to the latest registered output stream in the tty group before the bottom layer of the read function of the input stream is called.
Stream Position
Character count, line count and line position for each stream in the tty group are automatically adjusted for each tty group. When the buffer of an output stream is written out (such as the output line is terminated, the buffer overflows, or the stream output is flushed), the counts of all the output streams in the tty group are brought up to date. When an input streams reads input to its buffer, the counts of all the streams in its tty group are updated to the current counts. Linking the counts of tty streams in the tty group makes the count of a tty stream correspond to its physical appearance on the tty device.

A sample Prolog session demonstrates the special services performed for tty streams. The default open/[3,4] automatically registers tty streams to the tty group using filename as the key. After writing write\n to Output1, the counts for Output1 and Output2 are brought up to date. The counts in Input1 is not changed since counts in input stream are only updated when reading from the input stream. After reading from Input1, the counts for all the three streams are updated. The prompt INPUT>> is written out either through Output1 or Output2, so it is included in the counts. The count in Input1 is different from Output1 and Output2 since only character r is consumed in the input of read\n.

     | ?- compile(user).
     | write_count(Input, Output1, Output2) :-
          character_count(Input, C0), line_count(Input, L0),
              line_position(Input, P0),
          character_count(Output1, C1), line_count(Output1, L1),
              line_position(Output1, P1),
          character_count(Output2, C2), line_count(Output2, L2),
              line_position(Output2, P2),
          format('input   : ~d, ~d, ~d~n', [C0, L0, P0]),
          format('output1 : ~d, ~d, ~d~n', [C1, L1, P1]),
          format('output2 : ~d, ~d, ~d~n', [C2, L2, P2]).
     | ^D
     % user compiled in module user, 0.216 sec 384 bytes
     
     yes
     | ?- open('/dev/tty', read, Input), prompt(Input, _, 'INPUT>> '),
          open('/dev/tty', write, Output1),
          open('/dev/tty', write, Output2),
          format(Output1, 'write~n', []),
          write_count(Input, Output1, Output2),
          get0(Input, _), write_count(Input, Output1, Output2).
     write
     input   : 0, 1, 0
     output1 : 6, 2, 0
     output2 : 6, 2, 0
     INPUT>> read
     input   : 15, 2, 9
     output1 : 19, 3, 0
     output2 : 19, 3, 0
     

Notice that the I/O in the user_input and user_output are not included in the counts although both streams are connected to the same tty. The three default streams (user_input, user_output and user_error) are put into a different tty group in the embedding initialization function, QU_initio().