From Wirth to ISO - for those used to gpm's 'Wirth' I/O library (InOut, etc),
an introduction to the ISO Standard Modula-2 I/O libraries.
=============================================================================



Simple I/O from stdin and to stdout
-----------------------------------

InOut is replaced by
- STextIO for ReadChar, WriteChar, ReadString, WriteString and WriteLn;
  it adds SkipLine, ReadRestLine, ReadToken.
- SWholeIO for ReadCard, ReadInt, WriteCard, WriteInt.
- SIOResult for ReadResult.
RealInOut is replaced by
- SRealIO

So the changes are:
- minor name changes (the modules, and ReadChar/WriteChar)

- no Done; instead check for SIOResult.ReadResult() = allRight;
  the full SIOResult.ReadResults enumeration is:
	notKnown,     (* no read result is set *)
	allRight,     (* data is as expected or as required *)
	outOfRange,   (* data cannot be represented *)
	wrongFormat,  (* data not in expected form *)
	endOfLine,    (* end of line seen before expected data *)
	endOfInput    (* end of input seen before expected data *)
  examples are:
  outOfRange: a string too long to fit the array supplied,
    negative value for cardinal, numberic value too largeo;
  wrongFormat: non-numeric input to ReadCard/Int;
  endOfLine: see below
  
- no TermCh; thus Read procedures consume only what they were intended to, and
  the 'terminating character' is still to be read; it can be checked without
  consuming it by IOChan.Look, which returns a ReadResults and a CHAR
  
- the endOfLine value of ReadResults highlights a significant (unfortunate?)
  change: Read procedures will not read through an end-of-line; in particular,
  ReadChar will return endOfLine, and an undefined ch parameter, and will
  continue to do so on successive calls; ReadCard/Int, though they skip through
  leading spaces (and tabs) will similarly fail repeatedly if they encounter
  an end-of-line before a valid number is found.
  To consume an end-of-line, you must use SkipLine, which discards all
  characters up to and including the next end-of-line (cf Pascal Readln()).
  This slightly complicates processing loops; for examples see USINGISO.
  It does mean that a common bug will be an infinite loop due to omitting the
  endOfLine handling, causing a Read loop to block at an end-of-line.



I/O from/to files.
-----------------

The simplest way is to redirect stdin and stdout using command-line
redirection (<, >); all the SxxxxIO facilities still  apply.
For access to multiple files:

UxFiles is replaced by
- StreamFile for Open and Close
TextInOut is replaced by
- TextIO, WholeIO, IOResult
- RealIO

Open takes a file name and an open mode flag set, and returns an opaque ChanId
(cf UxFiles FILE) and an OpenResults enumeration value.

Streamfile exports various singleton values of FlagSet, to allow for example,
read+write:
CONST
  read  = FlagSet{readFlag};  (* input operations are requested/available *)
  write = FlagSet{writeFlag}; (* output operations are requested/available *)
  old   = FlagSet{oldFlag};   (* a file may/must/did exist before the channel
                                 was opened *)
  text  = FlagSet{textFlag};  (* text operations are requested/available *)
  raw   = FlagSet{rawFlag};   (* raw operations are requested/available *)

with some useful defaults: unless binary is set, text is implied, and if read
is set, old is implied. Again, some examples such as those in USINGISO help.

The OpenResults values are:
TYPE
  OpenResults = (
    opened,
    wrongNameFormat,
    wrongFlags,
    tooManyOpen,
    outOfChans,
    wrongPermissions,
    noRoomOnDevice,
    noSuchFile,
    fileExists,
    wrongFileType,
    noTextOperations,
    noRawOperations,
    noMixedOperations,
    alreadyOpen,
    otherProblem
  );
see the DEF file for details; usually just a check for "opened" suffices.

The TextIO, WholeIO, IOResult and RealIO modules export exactly the same
facilities as their "S" versions, but take an additional first ChanId
parameter.

StdError is replaced by TextIO/WholeIO/RealIO using the channel id
StdChans.StdErrChan().



Other data streams
------------------
StreamFile makes files (and standard channels such as stdin, stdout,  stderr,
null and bad) accessible as "sequential data streams"; other libraries
offering similar interfaces are:

RndFile	"random access files" - OpenOld, OpenClean, StartPos, CurrentPos,
				EndpOs, NewPos, SetPos, Close
SeqFile "rewindable sequential files" - OpenWrite/OpenAppend/OpenRead, Reread,
					Rewrite, Close
TermFile "the single terminal device" - echo flag - see below


Terminal I/O
------------

Terminal is replaced by
- TermFile plus normal I/O modules

The Standard treats terminal I/O by the TermFile device module; having opened
the implied device it returns a ChanId for use in TextIO, WholeIO, etc calls.

The Open call allows an extra flag: echo. If echo is set, "single character
mode" is used for all calls - input is not buffered, and echoing is controlled
by the user: a Read will echo the character as it is read, but a Look, Skip
pair will remove it without echo.
If echo is not set, "line mode" is used - input is buffered and echoed, just
as for StreamFile input.

Thus, the functionality of Terminal.GetKeyStroke is provided by opening the
terminal in single-sharacter mode and using Look/Skip.

Since the current implementation buffers StreamFile and TermFile line mode
input, care should be exercised when mixing these with single character mode.
Recommendations: if single character mode is to be used, use only TermFile;
multiple channels can be opened with TermFile at one time, allowing mixed
line and single character input; however the user should ensure that an entire
line is read in line mode (ie the buffer is empty) before using single
character mode.

There is no equivalent of Terminal.WasKeyPressed - we are currently looking at
implementing it as an extension in TermDevice - see below.


Additions/Omissions
-------------------

The Standard includes no provision for deleting a file (Open procedures will
create a file if it does not exist and old is not required).
We have provided Delete in StdDevice - one of the implementation-dependant
modules which also provide the low-level implementation of the facilities of
StreamFile, TextIO, etc; apart from Delete, users should have no need for
StdDevice procedures. Users should stick to the StreamFile/TextIO/... level,
with the occasional need to use the IOChan level.



Raw (binary) I/O
----------------
to come

