Appendix 5--ISO I/O Library

A5.1 An Overview of the ISO I/O Library

The modules in this section are taken from ISO/IEC IS 10514, the international standard for Modula-2. See the copyright notice in the acknowledgements section. The chart below shows the modules in the collection and the level at which users employ them.

A5.2 I/O On Standard Channels

A5.2.1 STextIO

DEFINITION MODULE STextIO;

  (* Input and output of character and string types over default channels. The read result is of the type IOConsts.ReadResults. *)

  (* The following procedures do not read past line marks *)

PROCEDURE ReadChar (VAR ch: CHAR);
  (* If possible, removes a character from the default input stream, and assigns the corresponding value to ch.  The read result is set to allRight, endOfLine or endOfInput. *)

PROCEDURE ReadRestLine (VAR s: ARRAY OF CHAR);
  (* Removes any remaining characters from the default input stream before the next line mark, copying to s as many as can be accommodated as a string value.  The read result is set to the value allRight, outOfRange, endOfLine, or endOfInput. *)

PROCEDURE ReadString (VAR s: ARRAY OF CHAR);
  (* Removes only those characters from the default input stream before the next line mark that can be accommodated in s as a string value, and copies them to s.  The read result is set to the value allRight, endOfLine, or endOfInput. *)

PROCEDURE ReadToken (VAR s: ARRAY OF CHAR);
  (* Skips leading spaces, and then removes characters from the default input stream before the next space or line mark, copying to s as many as can be accommodated as a string value.  The read result is set to the value allRight, outOfRange, endOfLine, or endOfInput. *)

  (* The following procedure reads past the next line mark *)

PROCEDURE SkipLine;
  (* Removes successive items from the default input stream up to and including the next line mark or until the end of input is reached. The read result is set to the value allRight, or endOfInput. *)

  (* Output procedures *)

PROCEDURE WriteChar (ch: CHAR);
  (* Writes the value of ch to the default output stream. *)

PROCEDURE WriteLn;
  (* Writes a line mark to the default output stream. *)

PROCEDURE WriteString (s: ARRAY OF CHAR);
  (* Writes the string value of s to the default output stream. *)

END STextIO.

A5.2.2 SWholeIO

DEFINITION MODULE SWholeIO;

(* Input and output of whole numbers in decimal text form over default channels.
  The read result is of the type IOConsts.ReadResults. *)

(* The text form of a signed whole number is ["+" | "-"], decimal digit, {decimal digit}
  The text form of an unsigned whole number is decimal digit, {decimal digit} *)

PROCEDURE ReadInt (VAR int : INTEGER);
(* Skips leading spaces, and removes any remaining characters from the default input channel that form part of a signed whole number.  The value of this number is assigned to int. The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or endOfInput. *)

PROCEDURE WriteInt (int: INTEGER; width: CARDINAL);
  (* Writes the value of int to the default output channel in text form, in a field of the given minimum width. *)

PROCEDURE ReadCard (VAR card: CARDINAL);
  (* Skips leading spaces, and removes any remaining characters from the default input channel that form part of an unsigned whole number.  The value of this  number is assigned to card.  The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or endOfInput. *)

PROCEDURE WriteCard (card: CARDINAL; width: CARDINAL);
  (* Writes the value of card to the default output channel in text form, in a field of the given minimum width. *)

END SWholeIO.

A5.2.3 SRealIO

DEFINITION MODULE SRealIO;

  (* Input and output of real numbers in decimal text form over default
     channels.  The read result is of the type IOConsts.ReadResults.
  *)

  (* The text form of a signed fixed-point real number is
       ["+" | "-"], decimal digit, {decimal digit},
       [".", {decimal digit}]
 
     The text form of a signed floating-point real number is
       signed fixed-point real number,
       "E", ["+" | "-"], decimal digit, {decimal digit}
  *)
 
PROCEDURE ReadReal (VAR real: REAL);
  (* Skips leading spaces, and removes any remaining characters from the default input channel that form part of a signed fixed or floating point number. The value of this number is assigned to real.  The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or endOfInput. *)
 
PROCEDURE WriteFloat (real: REAL; sigFigs: CARDINAL; width: CARDINAL);
  (* Writes the value of real to the default output channel in floating-point text form, with sigFigs significant figures, in a field of the given minimum width.  *)
 
PROCEDURE WriteEng (real: REAL; sigFigs: CARDINAL; width: CARDINAL);
  (* As for WriteFloat, except that the number is scaled with one to three digits in the whole number part, and with an exponent that is a multiple of three.  *)
 
PROCEDURE WriteFixed (real : REAL; place: INTEGER; width : CARDINAL);
(* Writes the value of real to the default output channel in fixed-point text form, rounded to the given place relative to the decimal point, in a field of the given minimum width.  *)
 
PROCEDURE WriteReal (real: REAL; width: CARDINAL);
  (* Writes the value of real to the default output channel, as WriteFixed if the sign and magnitude can be shown in the given width, or otherwise as WriteFloat.  The number of places or significant digits depends on the given width.  *)
 
END SRealIO.

A5.2.4 SLongIO

DEFINITION MODULE SLongIO;

  (* Input and output of real numbers in decimal text form over default
     channels.  The read result is of the type IOConsts.ReadResults.
  *)

  (* The text form of a signed fixed-point real number is
       ["+" | "-"], decimal digit, {decimal digit},
       [".", {decimal digit}]
 
     The text form of a signed floating-point real number is
       signed fixed-point real number,
       "E", ["+" | "-"], decimal digit, {decimal digit}
  *)
 
PROCEDURE ReadReal (VAR real: LONGREAL);
  (* Skips leading spaces, and removes any remaining characters from the default input channel that form part of a signed fixed or floating point number. The value of this number is assigned to real.  The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or endOfInput.
  *)
 
PROCEDURE WriteFloat (real: LONGREAL; sigFigs: CARDINAL; width: CARDINAL);
  (* Writes the value of real to the default output channel in floating-point text form, with sigFigs significant figures, in a field of the given minimum width. *)
 
PROCEDURE WriteEng (real: LONGREAL; sigFigs: CARDINAL; width: CARDINAL);
  (* As for WriteFloat, except that the number is scaled with one to three digits in the whole number part, and with an exponent that is a multiple of three. *)
 
PROCEDURE WriteFixed (real: LONGREAL; place : INTEGER; width: CARDINAL);
  (* Writes the value of real to the default output channel in fixed-point text form, rounded to the given place relative to the decimal point, in a field of the given minimum width. *)
 
PROCEDURE WriteReal (real: LONGREAL; width: CARDINAL);
  (* Writes the value of real to the default output channel, as WriteFixed if the sign and magnitude can be shown in the given width, or otherwise as WriteFloat.  The number of places or significant digits depends on the given width. *)
 
END SLongIO.

A5.2.5 SRawIO

DEFINITION MODULE SRawIO;

  (* Reading and writing data over default channels using raw operations, that is, with no conversion or interpretation. The read result is of the type IOConsts.ReadResults. *)

IMPORT SYSTEM;
 
PROCEDURE Read (VAR to: ARRAY OF SYSTEM.LOC);
  (* Reads storage units from the default input channel, and assigns them to successive components of to. The read result is set to the value allRight, wrongFormat, or endOfInput. *)
 
PROCEDURE Write (from: ARRAY OF SYSTEM.LOC);
  (* Writes storage units to cid from successive components of from. *)

END SRawIO.

A5.2.6 SIOResult

DEFINITION MODULE SIOResult;

(* Read results for the default input channel *)

IMPORT IOConsts;

TYPE
  ReadResults = IOConsts.ReadResults;

PROCEDURE ReadResult () : ReadResults;
(* Returns the result for the last read operation on the default input channel *)

END SIOResult.

A5.3 Supplied Channels

A5.3.1 StdChans

DEFINITION MODULE StdChans;

  (* Access to standard and default channels *)
 
IMPORT IOChan;
 
TYPE
  ChanId = IOChan.ChanId;
    (* Values of this type are used to identify channels *)
 
  (* The following functions return the standard channel values.
     These channels cannot be closed. *)

PROCEDURE StdInChan (): ChanId;
  (* Returns the identity of the implementation-defined standard source for program input. *)
 
PROCEDURE StdOutChan (): ChanId;
  (* Returns the identity of the implementation-defined standard source for program output. *)
 
PROCEDURE StdErrChan (): ChanId;
  (* Returns the identity of the implementation-defined standard destination for program error messages. *)
 
PROCEDURE NullChan (): ChanId;
  (* Returns the identity of a channel open to the null device. *)
 
  (* The following functions return the default channel values *)
 
PROCEDURE InChan (): ChanId;
  (* Returns the identity of the current default input channel. *)
 
PROCEDURE OutChan (): ChanId;
  (* Returns the identity of the current default output channel. *)
 
PROCEDURE ErrChan (): ChanId;
  (* Returns the identity of the current default error message channel. *)
 
  (* The following procedures allow for redirection of the default channels *)
 
PROCEDURE SetInChan (cid: ChanId);
  (* Sets the current default input channel to that identified by cid. *)
 
PROCEDURE SetOutChan (cid: ChanId);
  (* Sets the current default output channel to that identified by cid. *)
 
PROCEDURE SetErrChan (cid: ChanId);
  (* Sets the current default error channel to that identified by cid. *)
 
END StdChans.

A5.3.2 ProgramArgs

DEFINITION MODULE ProgramArgs;
 
  (* Access to program arguments *)
 
IMPORT IOChan;
 
TYPE
  ChanId = IOChan.ChanId;
 
PROCEDURE ArgChan (): ChanId;
  (* Returns a value that identifies a channel for reading program arguments *)
 
PROCEDURE IsArgPresent (): BOOLEAN;
  (* Tests if there is a current argument to read from. If not, read <= IOChan.CurrentFlags() will be FALSE, and attempting to read from the argument channel will raise the exception notAvailable. *)
 
PROCEDURE NextArg ();
  (* If there is another argument, causes subsequent input from the argument device to come from the start of the next argument.  Otherwise there is no argument to read from, and a call of IsArgPresent will return FALSE. *)

END ProgramArgs.

A5.4 Specified Channels

A5.4.1 TextIO

DEFINITION MODULE TextIO;

  (* Input and output of character and string types over specified channels.
     The read result is of the type IOConsts.ReadResults.
  *)
 
IMPORT IOChan;
 
  (* The following procedures do not read past line marks *)
 
PROCEDURE ReadChar (cid: IOChan.ChanId; VAR ch: CHAR);
  (* If possible, removes a character from the input stream cid and assigns the corresponding value to ch.  The read result is set to the value allRight, endOfLine, or endOfInput.
  *)
 
PROCEDURE ReadRestLine (cid: IOChan.ChanId; VAR s: ARRAY OF CHAR);
  (* Removes any remaining characters from the input stream cid before the next line mark, copying to s as many as can be accommodated as a string value. The read result is set to the value allRight, outOfRange, endOfLine, or endOfInput.  *)
 
PROCEDURE ReadString (cid: IOChan.ChanId; VAR s: ARRAY OF CHAR);
  (* Removes only those characters from the input stream cid before the next line mark that can be accommodated in s as a string value, and copies them to s.  The read result is set to the value allRight, endOfLine, or endOfInput.  *)
 
PROCEDURE ReadToken (cid: IOChan.ChanId; VAR s: ARRAY OF CHAR);
  (* Skips leading spaces, and then removes characters from the input stream cid before the next space or line mark, copying to s as many as can be accommodated as a string value. The read result is set to the value allRight, outOfRange, endOfLine, or endOfInput. *)
 
  (* The following procedure reads past the next line mark *)
 
PROCEDURE SkipLine (cid: IOChan.ChanId);
  (* Removes successive items from the input stream cid up to and including the next line  mark, or until the end of input is reached.  The read result is set to the value allRight, or endOfInput.  *)
 
  (* Output procedures *)
 
PROCEDURE WriteChar (cid: IOChan.ChanId; ch: CHAR);
  (* Writes the value of ch to the output stream cid. *)
 
PROCEDURE WriteLn (cid: IOChan.ChanId);
  (* Writes a line mark to the output stream cid. *)
 
PROCEDURE WriteString (cid: IOChan.ChanId; s: ARRAY OF CHAR);
  (* Writes the string value in s to the output stream cid. *)
 
END TextIO.

A5.4.2 WholeIO

DEFINITION MODULE WholeIO;

  (* Input and output of whole numbers in decimal text form over specified
channels. The read result is of the type IOConsts.ReadResults.
  *)
 
IMPORT IOChan;
 
  (* The text form of a signed whole number is
       ["+" | "-"], decimal digit, {decimal digit}
 
     The text form of an unsigned whole number is
       decimal digit, {decimal digit}
  *)
 
PROCEDURE ReadInt (cid: IOChan.ChanId; VAR int: INTEGER);
  (* Skips leading spaces, and removes any remaining characters from cid that form part of a signed whole number.  The value of this number is assigned to int.  The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or endOfInput. *)
 
PROCEDURE WriteInt (cid: IOChan.ChanId; int: INTEGER; width: CARDINAL);
  (* Writes the value of int to cid in text form, in a field of the given
minimum width. *)
 
PROCEDURE ReadCard (cid: IOChan.ChanId; VAR card: CARDINAL);
  (* Skips leading spaces, and removes any remaining characters from cid that form part of an unsigned whole number.  The value of this number is assigned to card.  The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or endOfInput. *)
 
PROCEDURE WriteCard (cid: IOChan.ChanId; card: CARDINAL; width: CARDINAL);
  (* Writes the value of card to cid in text form, in a field of the given
minimum width. *)
 
END WholeIO.

A5.4.3 RealIO

DEFINITION MODULE RealIO;

  (* Input and output of real numbers in decimal text form over specified
channels. The read result is of the type IOConsts.ReadResults. *)
 
IMPORT IOChan;
 
  (* The text form of a signed fixed-point real number is
       ["+" | "-"], decimal digit, {decimal digit},
       [".", {decimal digit}]
 
     The text form of a signed floating-point real number is
       signed fixed-point real number,
       "E", ["+" | "-"], decimal digit, {decimal digit}
  *)
 
PROCEDURE ReadReal (cid: IOChan.ChanId; VAR real: REAL);
  (* Skips leading spaces, and removes any remaining characters from cid that form part of a signed fixed or floating point number.  The value of this number is assigned to real. The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or  endOfInput. *)
 
PROCEDURE WriteFloat (cid: IOChan.ChanId; real: REAL; sigFigs: CARDINAL; width: CARDINAL);
  (* Writes the value of real to cid in floating-point text form, with sigFigs significant figures, in a field of the given minimum width. *)
 
PROCEDURE WriteEng (cid: IOChan.ChanId; real: REAL; sigFigs: CARDINAL; width: CARDINAL);
  (* As for WriteFloat, except that the number is scaled with one to three
digits in the whole number part, and with an exponent that is a multiple of three. *)
 
PROCEDURE WriteFixed (cid: IOChan.ChanId; real: REAL; place: INTEGER; width: CARDINAL);
  (* Writes the value of real to cid in fixed-point text form, rounded to the
given place relative to the decimal point, in a field of the given minimum width. *)
 
PROCEDURE WriteReal (cid: IOChan.ChanId; real: REAL; width: CARDINAL);
  (* Writes the value of real to cid, as WriteFixed if the sign and magnitude can be shown in the given width, or otherwise as WriteFloat.  The number of places or significant digits depends on the given width.  *)
 
END RealIO.

A5.4.4 LongIO

DEFINITION MODULE LongIO;

  (* Input and output of real numbers in decimal text form over specified
channels. The read result is of the type IOConsts.ReadResults. *)
 
IMPORT IOChan;
 
  (* The text form of a signed fixed-point real number is
       ["+" | "-"], decimal digit, {decimal digit},
       [".", {decimal digit}]
 
     The text form of a signed floating-point real number is
       signed fixed-point real number,
       "E", ["+" | "-"], decimal digit, {decimal digit}
  *)
 
PROCEDURE ReadReal (cid: IOChan.ChanId; VAR real: LONGREAL);
  (* Skips leading spaces, and removes any remaining characters from cid that form part of a signed fixed or floating point number.  The value of this number is assigned to real. The read result is set to the value allRight, outOfRange, wrongFormat, endOfLine, or  endOfInput.
  *)
 
PROCEDURE WriteFloat (cid: IOChan.ChanId; real: LONGREAL; sigFigs: CARDINAL; width: CARDINAL);
  (* Writes the value of real to cid in floating-point text form, with sigFigs significant figures, in a field of the given minimum width. *)
 
PROCEDURE WriteEng (cid: IOChan.ChanId; real: LONGREAL; sigFigs: CARDINAL; width: CARDINAL);
  (* As for WriteFloat, except that the number is scaled with one to three
digits in the whole number part, and with an exponent that is a multiple of three. *)
 
PROCEDURE WriteFixed (cid: IOChan.ChanId; real: LONGREAL; place: INTEGER; width:
CARDINAL);
  (* Writes the value of real to cid in fixed-point text form, rounded to the
given place relative to the decimal point, in a field of the given minimum width. *)
 
PROCEDURE WriteReal (cid: IOChan.ChanId; real: LONGREAL; width: CARDINAL);
  (* Writes the value of real to cid, as WriteFixed if the sign and magnitude can be shown in the given width, or otherwise as WriteFloat.  The number of places or significant digits depends on the given width.  *)
 
END LongIO.

A5.4.5 RawIO

DEFINITION MODULE RawIO;

  (* Reading and writing data over specified channels using raw operations, that is, with no conversion or interpretation. The read result is of the type IOConsts.ReadResults. *)

IMPORT IOChan, SYSTEM;
 
PROCEDURE Read (cid: IOChan.ChanId; VAR to: ARRAY OF SYSTEM.LOC);
  (* Reads storage units from cid, and assigns them to successive components of to. The read result is set to the value allRight, wrongFormat, or endOfInput. *)
 
PROCEDURE Write (cid: IOChan.ChanId; from: ARRAY OF SYSTEM.LOC);
  (* Writes storage units to cid from successive components of from. *)
 
END RawIO.

A5.4.6 IOResult

DEFINITION MODULE IOResult;

  (* Read results for specified channels *)
 
IMPORT IOConsts, IOChan;

TYPE
  ReadResults = IOConsts.ReadResults;

PROCEDURE ReadResult (cid: IOChan.ChanId): ReadResults;
  (* Returns the result for the last read operation on the channel cid. *)

END IOResult.

A5.5 Channel Constants--IOConsts

DEFINITION MODULE IOConsts;

(* Types and constants for input/output modules *)

TYPE
  ReadResults =
  (* This type is used to classify the result of an input operation *)
  (        notKnown,      (* no data read result is set *)
    allRight,      (* data is as expected or as required *)
    outOfRange,    (* data cannot be represented *)
    wrongFormat,  (* data not in expected format *)
    endOfLine,    (* end of line seen before expected data *)
    endOfInput    (* end of input seen before expected data *)
  );

END IOConsts.

A5.6 Device Independent Channel I/O--IOChan

DEFINITION MODULE IOChan;

  (* Types and procedures forming the interface to channels for
device-independent data transfer modules *)
 
IMPORT IOConsts, ChanConsts, SYSTEM;
 
TYPE
  ChanId; (* Values of this type are used to identify channels *)
 
  (* There is one pre-defined value identifying an invalid channel on which no data transfer operations are available.  It may be used to initialize variables of type ChanId. *)
 
PROCEDURE InvalidChan (): ChanId;
  (* Returns the value identifying the invalid channel. *)
 
  (* For each of the following operations, if the device supports the operation on the channel, the behaviour of the procedure conforms with the description below.  The full behaviour is defined for each device module.  If the device does not support the operation on the channel, the behaviour of the procedure is to raise the exception notAvailable. *)
  
  (* Text operations - these perform any required translation between the internal and external representation of text. *)
 
PROCEDURE Look (cid: ChanId; VAR ch: CHAR; VAR res: IOConsts.ReadResults);
  (* If there is a character as the next item in the input stream cid, assigns its value to ch without removing it from the stream; otherwise the value of ch is not defined.  res (and the stored read result) are set to the value allRight, endOfLine, or endOfInput. *)
 
PROCEDURE Skip (cid: ChanId);
  (* If the input stream cid has ended, the exception skipAtEnd is raised; otherwise the next character or line mark in cid is removed, and the stored read result is set to the value allRight. *)
 
PROCEDURE SkipLook (cid: ChanId; VAR ch: CHAR; VAR res: IOConsts.ReadResults);
  (* If the input stream cid has ended, the exception skipAtEnd is raised; otherwise the next character or line mark in cid is removed.  If there is a character as the next item in cid stream, assigns its value to ch without removing it from the stream.
     Otherwise, the value of ch is not defined.  res (and the stored read result) are set to the value allRight, endOfLine, or endOfInput. *)

PROCEDURE WriteLn (cid: ChanId);
  (* Writes a line mark over the channel cid. *)
 
PROCEDURE TextRead (cid: ChanId; to: SYSTEM.ADDRESS; maxChars: CARDINAL; VAR charsRead: CARDINAL);
  (* Reads at most maxChars characters from the current line in cid, and assigns corresponding values to successive components of an ARRAY OF CHAR variable for which the address of the first component is to. The number of characters read is assigned to charsRead. The stored read result is set to allRight, endOfLine, or endOfInput. *)

PROCEDURE TextWrite (cid: ChanId; from: SYSTEM.ADDRESS; charsToWrite:
CARDINAL);
  (* Writes a number of characters given by the value of charsToWrite, from successive components of an ARRAY OF CHAR variable for which the address of the first component is from, to the channel cid. *)
 
  (* Direct raw operations  - these do not effect translation between the internal and external representation of data  *)
 
PROCEDURE RawRead (cid: ChanId; to: SYSTEM.ADDRESS; maxLocs: CARDINAL; VAR locsRead: CARDINAL);
  (* Reads at most maxLocs items from cid, and assigns corresponding values to successive components of an ARRAY OF LOC variable for which the address of the first component is to. The number of characters read is assigned to charsRead. The stored read result is set to the value allRight, or endOfInput. *)
 
PROCEDURE RawWrite (cid: ChanId; from: SYSTEM.ADDRESS; locsToWrite: CARDINAL);
  (* Writes a number of items given by the value of charsToWrite, from successive components of an ARRAY OF LOC variable for which the address of the first component is from, to the channel cid. *)
 
  (* Common operations *)
 
PROCEDURE GetName (cid: ChanId; VAR s: ARRAY OF CHAR);
  (* Copies to s a name associated with the channel cid, possibly truncated (depending on the capacity of s).  *)
 
PROCEDURE Reset (cid: ChanId);
  (* Resets the channel cid to a state defined by the device module. *)
 
PROCEDURE Flush (cid: ChanId);
  (* Flushes any data buffered by the device module out to the channel cid. *)
 
  (* Access to read results *)
 
PROCEDURE SetReadResult (cid: ChanId; res: IOConsts.ReadResults);
  (* Sets the read result value for the channel cid to the value res. *)
 
PROCEDURE ReadResult (cid: ChanId): IOConsts.ReadResults;
  (* Returns the stored read result value for the channel cid. (This is initially the value notKnown). *)

  (* Users can discover which flags actually apply to a channel *)
 
PROCEDURE CurrentFlags (cid: ChanId): ChanConsts.FlagSet;
  (* Returns the set of flags that currently apply to the channel cid. *)

  (* The following exceptions are defined for this module and its clients *)
 
TYPE
  ChanExceptions =
    (wrongDevice,      (* device specific operation on wrong device *)
     notAvailable,     (* operation attempted that is not available on that
channel *)
     skipAtEnd,        (* attempt to skip data from a stream that has ended *)
     softDeviceError,  (* device specific recoverable error *)
     hardDeviceError,  (* device specific non-recoverable error *)
     textParseError,   (* input data does not correspond to a character or line mark - optional detection *)
     notAChannel       (* given value does not identify a channel - optional detection *)
    );
 
PROCEDURE IsChanException (): BOOLEAN;
  (* Returns TRUE if the current coroutine is in the exceptional execution state because of the raising of an exception from ChanExceptions;
     otherwise returns FALSE. *)

PROCEDURE ChanException (): ChanExceptions;
  (* If the current coroutine is in the exceptional execution state because of the raising of an exception from ChanExceptions, returns the corresponding enumeration value, and otherwise raises an exception. *)

  (* When a device procedure detects a device error, it raises the exception softDeviceError or hardDeviceError.  If these exceptions are handled, the following facilities may be used to discover an implementation-defined error number for the channel. *)
 
TYPE
  DeviceErrNum = INTEGER;
 
PROCEDURE DeviceError (cid: ChanId): DeviceErrNum;
  (* If a device error exception has been raised for the channel cid, returns the error number stored by the device module. *)

END IOChan.

A5.7 Device Drivers

A5.7.1 StreamFile

DEFINITION MODULE StreamFile;

  (* Independent sequential data streams *)
 
IMPORT IOChan, ChanConsts;
 
TYPE
  ChanId = IOChan.ChanId;
  FlagSet = ChanConsts.FlagSet;
  OpenResults = ChanConsts.OpenResults;
 
  (* Accepted singleton values of FlagSet *)
 
CONST
  read = FlagSet{ChanConsts.readFlag};   (* input operations are requested/available *)
  write = FlagSet{ChanConsts.writeFlag}; (* output operations are requested/available *)
  old = FlagSet{ChanConsts.oldFlag};     (* a file may/must/did exist before the channel is opened *)
  text = FlagSet{ChanConsts.textFlag};   (* text operations are requested/available *)
  raw = FlagSet{ChanConsts.rawFlag};     (* raw operations are requested/available *)

PROCEDURE Open (VAR cid: ChanId; name: ARRAY OF CHAR; flags: FlagSet; VAR res: OpenResults);
  (* Attempts to obtain and open a channel connected to a sequential stream of the given name. The read flag implies old; without the raw flag, text is implied. If successful, assigns to cid the identity of the opened channel, and assigns the value opened to res. If a channel cannot be opened as required, the value of res indicates the reason, and cid identifies the invalid channel.   *)
 
PROCEDURE IsStreamFile (cid: ChanId): BOOLEAN;
  (* Tests if the channel identified by cid is open to a sequential stream. *)
 
PROCEDURE Close (VAR cid: ChanId);
  (* If the channel identified by cid is not open to a sequential stream, the exception wrongDevice is raised; otherwise closes the channel, and assigns the value identifying the invalid channel to cid.   *)
 
END StreamFile.

A5.7.2 SeqFile

DEFINITION MODULE SeqFile;

  (* Rewindable sequential files *)

IMPORT IOChan, ChanConsts;
 
TYPE
  ChanId = IOChan.ChanId;
  FlagSet = ChanConsts.FlagSet;
  OpenResults = ChanConsts.OpenResults;
 
  (* Accepted singleton values of FlagSet *)
 
CONST
  read = FlagSet{ChanConsts.readFlag};   (* input operations are
requested/available *)
  write = FlagSet{ChanConsts.writeFlag}; (* output operations are
requested/available *)
  old = FlagSet{ChanConsts.oldFlag};     (* a file may/must/did exist before the channel is opened *)
  text = FlagSet{ChanConsts.textFlag};   (* text operations are
requested/available *)
  raw = FlagSet{ChanConsts.rawFlag};     (* raw operations are
requested/available *)
 
PROCEDURE OpenWrite (VAR cid: ChanId; name: ARRAY OF CHAR; flags: FlagSet; VAR res: OpenResults);
  (* Attempts to obtain and open a channel connected to a stored rewindable file of the given name.
     The write flag is implied; without the raw flag, text is implied.
     If successful, assigns to cid the identity of the opened channel, assigns
the value opened to res, and selects output mode, with the write position at the start of the file (i.e. the file is of zero length).
     If a channel cannot be opened as required, the value of res indicates the
reason, and cid identifies the invalid channel.
  *)
 
PROCEDURE OpenAppend (VAR cid: ChanId; name: ARRAY OF CHAR; flags: FlagSet; VAR res: OpenResults);
  (* Attempts to obtain and open a channel connected to a stored rewindable file of the given name.
     The write and old flags are implied; without the raw flag, text is
implied. If successful, assigns to cid the identity of the opened channel, assigns the value opened to res, and selects output mode, with the write position corresponding to the length of the file.
     If a channel cannot be opened as required, the value of res indicates the
reason, and cid identifies the invalid channel.
  *)
 
PROCEDURE OpenRead (VAR cid: ChanId; name: ARRAY OF CHAR; flags: FlagSet; VAR res: OpenResults);
  (* Attempts to obtain and open a channel connected to a stored rewindable file of the given name.
     The read and old flags are implied; without the raw flag, text is implied.
     If successful, assigns to cid the identity of the opened channel, assigns
the value opened to res, and selects input mode, with the read position corresponding to the start of the file.
     If a channel cannot be opened as required, the value of res indicates the
reason, and cid identifies the invalid channel.
  *)
 
PROCEDURE IsSeqFile (cid: ChanId): BOOLEAN;
  (* Tests if the channel identified by cid is open to a rewindable sequential
file. *)
 
PROCEDURE Reread (cid: ChanId);
  (* If the channel identified by cid is not open to a rewindable sequential
file, the exception wrongDevice is raised; otherwise attempts to set the read position to the start of the file, and to select input mode.
     If the operation cannot be performed (perhaps because of insufficient
permissions) neither input mode nor output mode is selected.
  *)
 
PROCEDURE Rewrite (cid: ChanId);
  (* If the channel identified by cid is not open to a rewindable sequential
file, the exception wrongDevice is raised; otherwise, attempts to truncate the file to zero length, and to select output mode.
     If the operation cannot be performed (perhaps because of insufficient
permissions) neither input mode nor output mode is selected.
  *)
 
PROCEDURE Close (VAR cid: ChanId);
  (* If the channel identified by cid is not open to a rewindable sequential
file, the exception wrongDevice is raised; otherwise closes the channel, and assigns the value identifying the invalid channel to cid.
  *)
 
END SeqFile.

A5.7.3 RndFile

DEFINITION MODULE RndFile;

  (* Random access files *)

IMPORT IOChan, ChanConsts, SYSTEM;
 
TYPE
  ChanId = IOChan.ChanId;
  FlagSet = ChanConsts.FlagSet;
  OpenResults = ChanConsts.OpenResults;
 
  (* Accepted singleton values of FlagSet *)
 
CONST
  read = FlagSet{ChanConsts.readFlag};   (* input operations are
requested/available *)
  write = FlagSet{ChanConsts.writeFlag}; (* output operations are
requested/available *)
  old = FlagSet{ChanConsts.oldFlag};     (* a file may/must/did exist before the channel is opened *)
  text = FlagSet{ChanConsts.textFlag};   (* text operations are
requested/available *)
  raw = FlagSet{ChanConsts.rawFlag};     (* raw operations are
requested/available *)

PROCEDURE OpenOld (VAR cid: ChanId; name: ARRAY OF CHAR; flags: FlagSet; VAR res: OpenResults);
  (* Attempts to obtain and open a channel connected to a stored random access file of the given name.
     The old flag is implied; without the write flag, read is implied; without the text flag, raw is implied.
     If successful, assigns to cid the identity of the opened channel, assigns
the value opened to res, and sets the read/write position to the start of the file.
     If a channel cannot be opened as required, the value of res indicates the
reason, and cid identifies the invalid channel.  *)
 
PROCEDURE OpenClean (VAR cid: ChanId; name: ARRAY OF CHAR; flags: FlagSet; VAR res: OpenResults);
  (* Attempts to obtain and open a channel connected to a stored random access file of the given name.
     The write flag is implied; without the text flag, raw is implied.
     If successful, assigns to cid the identity of the opened channel, assigns
the value opened to res, and truncates the file to zero length.
     If a channel cannot be opened as required, the value of res indicates the
reason, and cid identifies the invalid channel.  *)
 
PROCEDURE IsRndFile (cid: ChanId): BOOLEAN;
  (* Tests if the channel identified by cid is open to a random access file. *)

PROCEDURE IsRndFileException (): BOOLEAN;
  (* Returns TRUE if the current coroutine is in the exceptional execution state because of the raising of a RndFile exception; otherwise returns FALSE.  *)
 
CONST
  FilePosSize = 4;  (***** version defined****)
 
TYPE
  FilePos = ARRAY [1 .. FilePosSize] OF SYSTEM.LOC;  
 
PROCEDURE StartPos (cid: ChanId): FilePos;
  (* If the channel identified by cid is not open to a random access file, the exception wrongDevice is raised; otherwise returns the position of the start of the file.   *)
 
PROCEDURE CurrentPos (cid: ChanId): FilePos;
  (* If the channel identified by cid is not open to a random access file, the
exception wrongDevice is raised; otherwise returns the position of the current read/write position.  *)

PROCEDURE EndPos (cid: ChanId): FilePos;
  (* If the channel identified by cid is not open to a random access file, the
exception wrongDevice is raised; otherwise returns the first position after which there have been no writes.  *)

PROCEDURE NewPos (cid: ChanId; chunks: INTEGER; chunkSize: CARDINAL; from: FilePos): FilePos;
  (* If the channel identified by cid is not open to a random access file, the
exception wrongDevice is raised; otherwise returns the position (chunks * chunkSize) relative to the position given by from, or raises the exception posRange if the required position cannot be represented as a value of type FilePos.  *)

PROCEDURE SetPos (cid: ChanId; pos: FilePos);
  (* If the channel identified by cid is not open to a random access file, the
exception wrongDevice is raised; otherwise sets the read/write position to the value given by pos.  *)

PROCEDURE Close (VAR cid: ChanId);
  (* If the channel identified by cid is not open to a random access file, the
exception wrongDevice is raised; otherwise closes the channel, and assigns the value identifying the invalid channel to cid.  *)

END RndFile.

A5.7.4 TermFile

DEFINITION MODULE TermFile;

  (* Access to the terminal device *)

  (* Channels opened by this module are connected to a single terminal device; typed characters are distributed between channels according to the sequence of read requests. *)

IMPORT IOChan, ChanConsts;

TYPE
  ChanId = IOChan.ChanId;
  FlagSet = ChanConsts.FlagSet;
  OpenResults = ChanConsts.OpenResults;

  (* Accepted singleton values of FlagSet *)

CONST
  read = FlagSet{ChanConsts.readFlag};   (* input operations are
requested/available *)
  write = FlagSet{ChanConsts.writeFlag}; (* output operations are
requested/available *)
  text = FlagSet{ChanConsts.textFlag};   (* text operations are
requested/available *)
  raw = FlagSet{ChanConsts.rawFlag};     (* raw operations are
requested/available *)
  echo = FlagSet{ChanConsts.echoFlag};   (* echoing by interactive device on reading of characters from input stream requested/applies *)

PROCEDURE Open (VAR cid: ChanId; flags: FlagSet; VAR res: OpenResults);
  (* Attempts to obtain and open a channel connected to the terminal.
     Without the raw flag, text is implied.
     Without the echo flag, line mode is requested, otherwise single character mode is requested.
     If successful, assigns to cid the identity of the opened channel, and
assigns the value opened to res.
     If a channel cannot be opened as required, the value of res indicates the
reason, and cid identifies the invalid channel. *)

PROCEDURE IsTermFile (cid: ChanId): BOOLEAN;
  (* Tests if the channel identified by cid is open to the terminal. *)

PROCEDURE Close (VAR cid: ChanId);
  (* If the channel identified by cid is not open to the terminal, the exception wrongDevice is raised; otherwise closes the channel and assigns the value identifying the invalid channel to cid. *)

END TermFile.

A5.8 Device Module Constants--ChanConsts

DEFINITION MODULE ChanConsts;

  (* Common types and values for channel open requests and results *)
 
TYPE
  ChanFlags =      (* Request flags possibly given when a channel is opened *)
  ( readFlag,        (* input operations are requested/available *)
    writeFlag,       (* output operations are requested/available *)
    oldFlag,         (* a file may/must/did exist before the channel is opened *)
    textFlag,        (* text operations are requested/available *)
    rawFlag,         (* raw operations are requested/available *)
    interactiveFlag, (* interactive use is requested/applies *)
    echoFlag         (* echoing by interactive device on removal of characters from input stream requested/applies *)
  );
 
  FlagSet = SET OF ChanFlags;
 
  (* 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 is
opened *)
  text = FlagSet{textFlag};   (* text operations are requested/available *)
  raw = FlagSet{rawFlag};     (* raw operations are requested/available *)
  interactive = FlagSet{interactiveFlag}; (* interactive use is
requested/applies *)
  echo = FlagSet{echoFlag};   (* echoing by interactive device on removal of
characters from input stream requested/applies *)
 
TYPE
  OpenResults =        (* Possible results of open requests *)
    (opened,           (* the open succeeded as requested *)
     wrongNameFormat,  (* given name is in the wrong format for the
implementation *)
     wrongFlags,       (* given flags include a value that does not apply to the device *)
     tooManyOpen,      (* this device cannot support any more open channels *)
     outOfChans,       (* no more channels can be allocated *)
     wrongPermissions, (* file or directory permissions do not allow request *)
     noRoomOnDevice,   (* storage limits on the device prevent the open *)
     noSuchFile,       (* a needed file does not exist *)
     fileExists,       (* a file of the given name already exists when a new one is required *)
     wrongFileType,    (* the file is of the wrong type to support the required operations *)
     noTextOperations, (* text operations have been requested, but are not supported *)
     noRawOperations,  (* raw operations have been requested, but are not supported *)
     noMixedOperations,(* text and raw operations have been requested, but they are not supported in combination *)
     alreadyOpen,      (* the source/destination is already open for operations not supported in combination with the requested operations *)
     otherProblem      (* open failed for some other reason *)
    );
 
END ChanConsts.

A5.9 Linking Drivers To Channels--IOLink

DEFINITION MODULE IOLink;

  (* Types and procedures for the standard implementation of channels *)
 
IMPORT IOChan, IOConsts, ChanConsts, SYSTEM;
 
TYPE
  DeviceId;
    (* Values of this type are used to identify new device modules, and are normally obtained by them during their initialization.
    *)
 
PROCEDURE AllocateDeviceId (VAR did: DeviceId);
  (* Allocates a unique value of type DeviceId, and assigns this value to did. *)
 
PROCEDURE MakeChan (did: DeviceId; VAR cid: IOChan.ChanId);
  (* Attempts to make a new channel for the device module identified by did.  If no more channels can be made, the identity of the invalid channel is assigned to cid. Otherwise, the identity of a new channel is assigned to cid.  *)
 
PROCEDURE UnMakeChan (did: DeviceId; VAR cid: IOChan.ChanId);
  (* If the device module identified by did is not the module that made the channel identified by cid, the exception wrongDevice is raised; otherwise the channel is deallocated, and the value identifying the invalid channel is assigned to cid. *)
 
TYPE
  DeviceTablePtr = POINTER TO DeviceTable;
    (* Values of this type are used to refer to device tables *)
 
TYPE
  LookProc =      PROCEDURE (DeviceTablePtr, VAR CHAR, VAR IOConsts.ReadResults);
  SkipProc =      PROCEDURE (DeviceTablePtr);
  SkipLookProc =  PROCEDURE (DeviceTablePtr, VAR CHAR, VAR IOConsts.ReadResults);
  WriteLnProc =   PROCEDURE (DeviceTablePtr);
  TextReadProc =  PROCEDURE (DeviceTablePtr, SYSTEM.ADDRESS, CARDINAL, VAR CARDINAL);
  TextWriteProc = PROCEDURE (DeviceTablePtr, SYSTEM.ADDRESS, CARDINAL);
  RawReadProc =   PROCEDURE (DeviceTablePtr, SYSTEM.ADDRESS, CARDINAL, VAR CARDINAL);
  RawWriteProc =  PROCEDURE (DeviceTablePtr, SYSTEM.ADDRESS, CARDINAL);
  GetNameProc =   PROCEDURE (DeviceTablePtr, VAR ARRAY OF CHAR);
  ResetProc =     PROCEDURE (DeviceTablePtr);
  FlushProc =     PROCEDURE (DeviceTablePtr);
  FreeProc =      PROCEDURE (DeviceTablePtr);
      (* Carry out the operations involved in closing the corresponding channel, including flushing buffers, but do not unmake the channel. *)
 
TYPE
  DeviceData = SYSTEM.ADDRESS;
 
  DeviceTable =
    RECORD                         (* Initialized by MakeChan to: *)
      cd: DeviceData;              (* the value NIL *)
      did: DeviceId;               (* the value given in the call of MakeChan *)
      cid: IOChan.ChanId;          (* the identity of the channel *)
      result: IOConsts.ReadResults;(* the value notKnown *)
      errNum: IOChan.DeviceErrNum; (* undefined *)
      flags: ChanConsts.FlagSet;   (* ChanConsts.FlagSet{} *)
      doLook: LookProc;            (* raise exception notAvailable *)
      doSkip: SkipProc;            (* raise exception notAvailable *)
      doSkipLook: SkipLookProc;    (* raise exception notAvailable *)
      doLnWrite: WriteLnProc;      (* raise exception notAvailable *)
      doTextRead: TextReadProc;    (* raise exception notAvailable *)
      doTextWrite: TextWriteProc;  (* raise exception notAvailable *)
      doRawRead: RawReadProc;      (* raise exception notAvailable *)
      doRawWrite: RawWriteProc;    (* raise exception notAvailable *)
      doGetName: GetNameProc;      (* return the empty string *)
      doReset: ResetProc;          (* do nothing *)
      doFlush: FlushProc;          (* do nothing *)
      doFree: FreeProc;            (* do nothing *)
    END;
 
  (* The pointer to the device table for a channel is obtained using the following procedure: *)
 
PROCEDURE DeviceTablePtrValue (cid: IOChan.ChanId; did: DeviceId): DeviceTablePtr;
  (* If the device module identified by did is not the module that made the channel identified by cid, the exception wrongDevice is raised; otherwise returns a pointer to the device table for the channel.  *)
 
PROCEDURE IsDevice (cid: IOChan.ChanId; did: DeviceId): BOOLEAN;
  (* Tests if the device module identified by did is the module that made the channel dentified by cid. *)
 
TYPE
  DevExceptionRange = [IOChan. notAvailable .. IOChan. textParseError];

PROCEDURE RAISEdevException (cid: IOChan.ChanId; did: DeviceId;
                             x: DevExceptionRange; s: ARRAY OF CHAR);
  (* If the device module identified by did is not the module that made the channel identified by cid, the exception wrongDevice is raised; otherwise the given exception is raised, and the string value in s is included in the exception message. *)
 
PROCEDURE IsIOException (): BOOLEAN;
  (* If the current coroutine is in the exceptional execution state
     because of the raising of an exception from ChanExceptions;
   otherwise returns FALSE. *)
 
PROCEDURE IOException (): IOChan.ChanExceptions;
  (* Returns TRUE if the current coroutine is in the exceptional execution state because of the raising of an exception from ChanExceptions, returns the corresponding enumeration value, and otherwise raises an exception. *)

END IOLink.

Contents