REF CHARIO John Gibson Jul 1993
COPYRIGHT University of Sussex 1993. All Rights Reserved.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<< CHARACTER STREAM >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<< INPUT AND OUTPUT >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Character stream input and output is the simplest form of I/O in Poplog.
This REF file details the procedures, etc, associated with standard
character repeaters and consumers, and the creation of new repeaters and
consumers.
CONTENTS - (Use <ENTER> g to access required sections)
1 Introduction
2 Standard Character Repeaters
3 Standard Character Consumers
4 Raw Mode Repeaters/Consumers
5 Creating New Repeaters/Consumers
---------------
1 Introduction
---------------
Character streams are the simplest form of input/output in Poplog. They
are used by many parts of the system, including the Pop-11 compiler and
printing utilities. For more complex I/O facilities using device
records, see REF * SYSIO
Character stream I/O is performed using character repeater and
consumer procedures. A character repeater is a procedure which each time
it is called returns the next character from an input stream; a
character consumer takes a character as argument and writes it to an
output stream. Character streams are terminated by the special item
<termin> (the value of the constant termin); a character repeater will
return <termin> when an input stream is exhausted, and giving <termin>
to a character consumer will close its output stream.
See also REF * ITEMISE, which describes the procedure incharitem for
turning character repeaters into item repeaters. REF * POPCOMPILE
explains how a text item stream is created from a character stream for
the Pop11 compilation process.
-------------------------------
2 Standard Character Repeaters
-------------------------------
charin() -> char [procedure]
This is a character repeater for the current standard input
channel, i.e. it reads characters from the device
pop_charin_device (normally in interactive mode this is a system
device that inputs from the user's terminal/window etc, but when
in Ved interactive mode, it is a pseudo `user' device which
reads input from the current Ved input buffer).
The prompt string output by charin is determined by popprompt
(see REF * popprompt).
If the character read in is `\^G` (CTRL-G) then charin invokes
setpop (This mechanism may be withdrawn, as it is a relic of
earlier versions of Pop-2).
If the last character read in was a newline character
(poplastchar == `\n`), and the next character read in is char,
charin checks to see whether char is in the list
pop_charin_escapes, in which case it will spawn a DCL process
(in VMS) or Shell process (in Unix) and hand the rest of the
line as a command to be run by that process, using sysobey. The
character char is given to sysobey as its second argument. When
sysobey returns, charin assigns the newline character to char.
Before finally returning, charin assigns char to poplastchar
then checks whether poplogfile is a procedure, in which case it
is applied to char. This provides a simple logging mechanism.
REF * ITEMISE explains how an "item-repeater" can be created
from a character repeater like charin, and REF * POPCOMPILE
explains how program text read in from the standard input is
compiled. HELP * IM explains how charin is made to read from the
Ved buffer.
The character returned by charin is normally an ASCII character
code, but if the "end of file" character was typed at the
terminal, or if the device has been "emptied" then it returns
the special object <termin>, as explained in the Overview,
above.
(Note that before reading a character from pop_charin_device,
charin first calls the trap procedure pop_chario_trap with the
device and true as arguments, i.e.
pop_chario_trap(pop_charin_device, true)
See pop_chario_trap below.)
pop_charin_escapes -> list [variable]
list -> pop_charin_escapes
This list is examined by charin as explained above, whenever a
character is read in immediately after a newline character. If
the new character is a member of pop_charin_escapes then charin
uses sysobey to spawn a sub-process given the rest of the input
line as a command.
In VMS the list pop_charin_escapes defaults to [`$`] and on Unix
to [ `%` `$` `!`], i.e. the characters that can be given as
second argument to sysobey. The procedure vedsetpop sets
pop_charin_escapes locally to [], so that the mechanism will not
be triggered accidentially in Ved immediate in mode (See
HELP * IM) or in processes that compile from the Ved buffer (See
HELP * LMR). (Ved allows an alternative mechanism for spawning
sub-processes from the command line, as described in HELP
VEDCOMMS)
poplastchar -> char [variable]
char -> poplastchar
Always contains the last character read by charin.
poplinenum -> int [protected variable]
This integer variable is incremented whenever a newline
character is read by charin or a character repeater created by
discin. poplinenum is local to pop11_compile where it is
initialised to 1: hence it records the number of newline
characters read in since the beginning of the call of
pop11_compile (and is used by * sys_pr_message in printing
mishap and warning messages).
poplogfile -> char_cons_or_false [variable]
false_or_char_cons -> poplogfile
This variable may contain a character consumer procedure or
false. In the former case every character read by charin, or
output by charout is also given to poplogfile (including
prompts). This can be used to record terminal interactions (for
an example of which, see LIB * RECORD). (Default value false)
termin -> <termin> [constant]
termin_key -> key [constant]
The value of termin is the unique item <termin>, used as an
end-of-file marker for character/item stream I/O (and also for
dynamic list streams, see REF * LISTS). termin_key is a constant
holding the key structure of the unique item <termin> (see
REF * KEYS).
pop_chario_trap(dev, is_input) [protected procedure variable]
The procedure in this variable is called by charin, charout and
charerr before doing anything; it is redefined in various
contexts, e.g. in Ved, and is intended for system use only.
(If a new trap procedure trap_p is to be added, it must be
concatenated onto the existing value, i.e.
trap_p <> pop_chario_trap -> pop_chario_trap;
where trap_p is defined as
trap_p(dev, is_input) -> (dev, is_input);
that is, passes on the arguments given to it to the next
procedure in the chain.)
-------------------------------
3 Standard Character Consumers
-------------------------------
charout(char) [procedure]
charerr(char) [procedure]
These are character consumers for the current standard output
and error output channels respectively, i.e. characters are
output via the devices pop_charout_device and pop_charerr_device
respectively (normally in interactive mode these are system
devices that output to the user's terminal/window etc, but when
in Ved interactive mode, they are pseudo `user' devices which
output to the current Ved output buffer).
(Note that before writing a character to pop_charX_device, these
procedures first call the trap procedure pop_chario_trap with
the device and false as arguments, i.e.
pop_chario_trap(pop_charX_device, false)
See pop_chario_trap above.)
pop_charout_col -> int [variable]
int -> pop_charout_col
pop_charerr_col -> int [variable]
int -> pop_charerr_col
These variables contain integers representing the number of
columns filled by charout and charerr respectively in their
current lines, where tab characters count as vedindentstep
columns if in Ved or 8 otherwise, control characters (i.e. ASCII
value < 32) count as none, and all other characters count as 1.
These values are reset to 0 on outputting a newline character.
poplinewidth -> int [variable]
int -> poplinewidth
poplinemax -> int [variable]
int -> poplinemax
When poplinewidth is an integer, these two variables together
control the breaking of long lines by charout and charerr.
If on outputting a character with charX, pop_charX_col is
greater than or equal to poplinewidth, and either the current
character for output is a space or tab, OR the column count is
already greater than or equal to poplinemax, then an automatic
linebreak is inserted before printing the character.
(In other words, lines are broken at the next whitespace
character after poplinewidth columns, or failing that after
poplinemax columns. Note that if a line is broken at a space or
tab, that character is NOT output.)
A linebreak consists of a newline followed by any
continuation-line prefix characters specified by * poplineprefix
(qv).
If poplinewidth is not an integer, linebreaks are not inserted.
poplinewidth defaults to 70, and poplinemax to 78.
poplineprefix -> pair_or_false [variable]
pair_or_false -> poplineprefix
This variable enables automatic prefixing of lines output via
charout and charerr. It may be false, or a pair whose front or
back are each either a string or false.
If poplineprefix is a pair whose front is a string, that string
is output at the beginning of every line (that is, when charX is
called with pop_charX_col = 0).
If poplineprefix is a pair whose back is a string, that string
is output instead at the beginning of every continuation line,
i.e. after an automatic newline inserted by the poplinewidth
mechanism.
If poplineprefix is not a pair, or the back is not a string,
automatic newlines are followed by any 'every-line' prefix
specified, plus a single tab character.
cucharout(char) [procedure variable]
cucharerr(char) [procedure variable]
These procedure variables contain the current character
consumers for standard output and error output. All printing
utilities in Poplog use cucharout to produce output, and all
error printing is done via cucharerr. The standard values of
these variables are charout and charerr respectively.
cuchartrace -> char_cons [variable]
char_cons -> cuchartrace
If this variable is false then cucharout is used for tracing
output. Otherwise the character consumer cuchartrace contains is
used instead. Assigning a character consumer to this variable
enables trace printing to be separated from normal printout.
pop_buffer_charout -> bool [variable]
bool -> pop_buffer_charout
This boolean variable controls whether normal-mode character
output to terminals is buffered within each line; if false, each
character is output immediately (it therefore affects charout
and charerr when these reference terminals). See REF * SYSIO
-------------------------------
4 Raw Mode Repeaters/Consumers
-------------------------------
rawcharin() -> char [procedure]
This repeater reads characters from the device poprawdevin
(giving 'raw mode' input from the terminal). See REF * SYSIO
rawcharout(char_or_string) [procedure]
This consumer writes characters to the device poprawdevout
(giving buffered 'raw mode' output to the terminal). It can take
either a single character or a byte vector. See REF * SYSIO
rawsubstringout(string, index, num); [procedure]
Just like rawcharout, but outputs num characters, starting at
index, from string. See REF * SYSIO
rawoutflush() [procedure]
Flushes poprawdevout, i.e. writes out any outstanding characters
in the buffer. Same as sysflush(poprawdevout).
charin_timeout(hsecs) -> char [procedure]
Returns the first character read from the terminal with
rawcharin during the time-span hsecs, or false if none were
available. hsecs is measured in hundredths of a second (but
rounded to the nearest whole second). (This procedure is
implemented in terms of pop_timeout_secs and pop_timeout, see
REF * SYSIO).
-----------------------------------
5 Creating New Repeaters/Consumers
-----------------------------------
bits_out(filename, n, signed) -> int_consumer [procedure]
bits_in(filename, n, signed) -> int_repeater [procedure]
The bits_in/bits_out mechanism facilitates compact storage of a
series of integers. For example, the data for a binary array
could be stored using 1/8 the space used by simply printing the
numbers to disk.
For both procedures, the argument filename may be a file name
string, or a device.
The n argument specifies the bitsize of the integers; if the
boolean argument signed is true, the integers are signed,
otherwise unsigned.
bits_out returns an 'integer consumer' procedure int_consumer
for the specified file. Successive calls of int_consumer write
n-bit integers to the file, i.e.
int_consumer(int_or_termin);
bits_in returns an 'integer repeater' procedure int_repeater
linked to the specified file (normally, one created with
bits_out). Successive calls of int_repeater read n-bit integers
from the file, i.e.
int_repeater() -> int_or_termin
discin(filename) -> char_rep [procedure]
Returns a character repeater for the filename filename, which
may be a string or word -- if a word then pop_default_type is
appended to the name (see below).
Note that, despite the name of this procedure, filename is not
restricted to being a disk file; it may be any suitable
operating system device. (The device is opened using
sysopen(filename, 0, false, `N`) -> dev;
i.e. a disk file is assumed to be a text file. See the
description of the third argument to sysopen in REF * SYSIO.) A
mishap will result if the specified file cannot be opened.
filename may also be a device record open for reading, e.g. a
device created by sysopen or syspipe (in Unix) or sysmailbox (in
VMS). In that case a character repeater for the device is
returned. This technique can be used for 'binary' disk files,
e.g.
sysopen(filename, 0, true, `N`) -> dev;
discin(dev) -> char_rep;
discout(filename) -> char_cons [procedure]
Returns a character consumer for the filename filename (which is
as for discin). If filename is a disk file, then a new file is
created, otherwise the file is simply opened. (The device is
created using
syscreate(filename, 1, false) -> dev;
i.e. a disk file is assumed to be a text file. See the
description of the third argument to syscreate in REF * SYSIO.)
A mishap will result if the specified file cannot be created or
opened.
filename may also be a device record open for writing, in which
case a character consumer for that device is returned. As with
discin, this technique can be used for 'binary' disk files, e.g.
syscreate(filename, 1, true) -> dev;
discout(dev) -> char_cons;
discappend(filename) -> char_cons [procedure]
Opens an existing file, and returns a character consumer
char_cons that will append characters to the file (i.e. will
actually update an existing disk file). filename is as for
discin.
discin_device(char_rep) -> dev [procedure]
discin_device(char_rep, mishap) -> dev_or_false
Given a character repeater procedure char_rep, returns the
device record dev associated with it. If char_rep was not
created by discin, a mishap occurs unless the optional boolean
argument mishap is supplied and is false (in which case false is
returned).
discout_device(char_cons) -> dev [procedure]
Returns the device record dev associated with the character
consumer procedure char_cons. An error is signalled if char_cons
was not created by discout.
pop_default_type -> string [variable]
string -> pop_default_type
The string in this variable (default value '.p') is used as the
default file type/extension by discin, discout and discappend,
and is concatenated onto a word argument given to these
procedures (but not onto a string argument).
sysisprogfile(filename) -> bool [procedure]
Where filename is a string, returns true if filename has the
file type/extension given by pop_default_type, false otherwise.
stringin(string) -> char_rep [procedure]
Returns a character repeater for the string string, i.e. a
procedure which each time it is called produces the next
character from the string, and <termin> when the string is
exhausted.
isclosed(item, mishap) -> bool [procedure]
isclosed(item) -> bool
For item a device, this procedure returns true if the device is
closed, false if it is still open.
For item a character repeater produced by discin or stringin, it
returns true if the repeater is exhausted (i.e. would return
<termin> if called), or false if it still has characters
available.
For a character consumer produced by discout, it returns true
if <termin> has been given to the consumer.
The mishap argument is a boolean controlling what happens if
item is not one of the above: if false, the procedure returns
"undef", otherwise a mishap occurs. The mishap argument defaults
to true if omitted.
+-+ C.all/ref/chario
+-+ Copyright University of Sussex 1993. All rights reserved.