[comp.lang.modula2] Number One of Five Mailings of BSI I/O Def Mods

rbh@computer-science.nottingham.ac.UK (Roger Henry) (08/19/87)

**************
This is number one of five mailings of the proposed BSI I/O Library modules.
An earlier message gives the complete list
**************
::::::::::::::
StdIO.def
::::::::::::::
DEFINITION MODULE StdIO;

(* Proposed BSI Standard Modula-2 I/O Library
 * Copyright Roger Henry, University of Nottingham
 * Version WG/2.0, August 17th 1987
 * Permission is given to copy this Definition Module, with the
 * copyright notice intact, for the purposes of evaluation and test.
 * At the stage of a formal draft standard, Copyright will be transferred
 * to BSI (and through BSI to other recognised standards bodies).
 * Status: For review by BSI/IST/5/13
*)


(* Standard channel number variables *)

IMPORT
  Channel;

(*
EXPORT QUALIFIED
  in, out, error;
*)

VAR
  in: Channel.Numbers;		(* standard input *)
  out: Channel.Numbers;		(* standard output *)
  error: Channel.Numbers;	(* standard error *)

(*
These variables shall be initialised by the module to the numbers
of preopened channels.
The numbers shall be selected by Channel.Allocate.
*)

(* notes:
Channel "in" may also be open for output, in which case it may be used
to write prompts for input data.

Other modules may substitute different values for the standard channel
numbers to achieve redirection of standard input and output.
*)

END StdIO.
::::::::::::::
Char.def
::::::::::::::
DEFINITION MODULE Char;

(* Proposed BSI Standard Modula-2 I/O Library
 * Copyright Roger Henry, University of Nottingham
 * Version WG/2.0, August 17th 1987
 * Permission is given to copy this Definition Module, with the
 * copyright notice intact, for the purposes of evaluation and test.
 * At the stage of a formal draft standard, Copyright will be transferred
 * to BSI (and through BSI to other recognised standards bodies).
 * Status: For review by BSI/IST/5/13
*)


(*
I/O of characters
*)

IMPORT
  Channel;
FROM ConvTypes IMPORT
  Justifications;

(*
EXPORT QUALIFIED
  Read, Value, Skip,
  CanRead, CanSkip
  Write, WriteF;
*)

(* Read and consume a character: *)

PROCEDURE Read(cn: Channel.Numbers; VAR char: CHAR);
(* pre	: there is at least one character in the input *)
(* post	: the next character is stored in "char", *)
(*        and has been skipped over in the input. *)

(* The next character may be obtained without consuming the input: *)

PROCEDURE Value(cn: Channel.Numbers): CHAR;
(* pre	: there is at least one character in the input *)
(* post	: the next character is stored in "char". *)

(* If the character is not going to be read it may be skipped: *)

PROCEDURE Skip(cn: Channel.Numbers);
(* pre	: there is at least one character in the input *)
(* post	: the next character has been skipped *)

(*
If the preconditions of Read, Value, or Skip are not satisfied,
a conversion error shall be reported via ConvReports:
  noData: end of input is found before any character.

Initially a handler shall be installed which causes a message to be printed
and the program to be terminated.
A handler may be installed which allows continuation and subsequent
testing for errors.
Any returned value shall be 0C.

Alternatively, predicates can be called to test the precondition in advance:
*)

PROCEDURE CanRead(cn: Channel.Numbers): BOOLEAN;
(* pre  : the channel is open for input operations *)
(* post	: returns TRUE iff there is at least one character in the input *)
(*        The reason for a FALSE result is given by ConvReports.LastReport *)
(* note : this can only be "noData" *)

PROCEDURE CanSkip(cn: Channel.Numbers): BOOLEAN;
(* pre  : the channel is open for input operations *)
(* post	: returns TRUE iff there is at least one character in the input *)
(*        The reason for a FALSE result is given by ConvReports.LastReport *)
(* note : this can only be "noData" *)

(*
*)

PROCEDURE Write(cn: Channel.Numbers; char: CHAR);
(* pre  : the channel is open for output operations *)
(* post : the given character value is written to the Linked device *)

PROCEDURE WriteF(
      cn: Channel.Numbers;
      char: CHAR;
      width: CARDINAL; 
      where: Justifications
  );
(* pre  : the channel is open for output operations *)
(* post	: the given value is written in a field of the given *)
(*        minimum width left, centre, or right justified *)

END Char.
::::::::::::::
Line.def
::::::::::::::
DEFINITION MODULE Line;

(* Proposed BSI Standard Modula-2 I/O Library
 * Copyright Roger Henry, University of Nottingham
 * Version WG/2.0, August 17th 1987
 * Permission is given to copy this Definition Module, with the
 * copyright notice intact, for the purposes of evaluation and test.
 * At the stage of a formal draft standard, Copyright will be transferred
 * to BSI (and through BSI to other recognised standards bodies).
 * Status: For review by BSI/IST/5/13
*)


(*
I/O of the contents of lines or parts of lines
*)

IMPORT
  Channel;

(*
EXPORT QUALIFIED
  Read, GetValue, Skip,
  CanRead, CanSkip
  Write;
*)

(* Read and consume characters before a new line: *)

PROCEDURE Read(cn: Channel.Numbers; VAR chars: ARRAY OF CHAR);
(* pre	: there is at least one character before a new line (Nl) *)
(* do   : read characters until the given array fills or Nl found *)
(* post	: the characters are stored in the array, *)
(*        with a 0C terminator if necesary, *)
(*        and have been skipped over in the input. *)
(* note : the Nl character is not stored or consumed *)

(* The characters may be obtained without consuming the input: *)

PROCEDURE GetValue(cn: Channel.Numbers; VAR chars: ARRAY OF CHAR);
(* pre	: there is at least one character before a new line (Nl) *)
(* do   : read characters until the given array fills or Nl found *)
(* post	: the characters are stored in the array, *)
(*        with a 0C terminator if necesary. *)
(* note : the Nl character is not stored *)

(* If the rest of the line is not going to be read it may be skipped: *)

PROCEDURE Skip(cn: Channel.Numbers);
(* pre	: there is at least one character before a new line (Nl) *)
(* post	: all characters upto but excluding the next Nl have been skipped *)

(*
If the preconditions of Read, GetValue, or Skip are not satisfied,
a conversion error shall be reported via ConvReports:
  foundNl: Nl found before any other characters,
  noData: end of input is found before any characters.

Initially a handler shall be installed which causes a message to be printed
and the program to be terminated.
A handler may be installed which allows continuation and subsequent
testing for errors.

Alternatively, predicates can be called to test the precondition in advance:
*)

PROCEDURE CanRead(cn: Channel.Numbers): BOOLEAN;
(* pre  : the channel is open for input operations *)
(* post	: returns TRUE iff there is at least one character *)
(*        before a new line (Nl) *)
(*        The reason for a FALSE result is given by ConvReports.LastReport *)

PROCEDURE CanSkip(cn: Channel.Numbers): BOOLEAN;
(* pre  : the channel is open for input operations *)
(* post	: returns TRUE iff there is at least one character *)
(*        before a new line (Nl) *)
(*        The reason for a FALSE result is given by ConvReports.LastReport *)

(*
*)

PROCEDURE Write(cn: Channel.Numbers; chars: ARRAY OF CHAR);
(* pre  : the channel is open for output operations *)
(* post : the given string value is written to the Linked device *)

END Line.
::::::::::::::
Nl.def
::::::::::::::
DEFINITION MODULE Nl;

(* Proposed BSI Standard Modula-2 I/O Library
 * Copyright Roger Henry, University of Nottingham
 * Version WG/2.0, August 17th 1987
 * Permission is given to copy this Definition Module, with the
 * copyright notice intact, for the purposes of evaluation and test.
 * At the stage of a formal draft standard, Copyright will be transferred
 * to BSI (and through BSI to other recognised standards bodies).
 * Status: For review by BSI/IST/5/13
*)


(*
Skipping and writing of new lines
*)

IMPORT
  Channel;

(*
EXPORT QUALIFIED
  Skip, CanSkip, Write;
*)

PROCEDURE Skip(cn: Channel.Numbers);
(* pre 	: the next significant character is new line (Nl) *)
(* do  	: skip characters until the Nl is passed *)

(*
If the precondition of Skip is not satisfied,
a conversion error shall be reported via ConvReports:
  badFormat: another significant character found before Nl,
  noData: end of input is found before Nl.
  
Initially a handler shall be installed which causes a message to be printed
and the program to be terminated.
A handler may be installed which allows continuation and subsequent
testing for errors.
Significant characters shall not have been consumed.

Alternatively, a predicate can be called to test the precondition in advance:
*)

PROCEDURE CanSkip(cn: Channel.Numbers): BOOLEAN;
(* pre  : the channel is open for input operations *)
(* post	: returns TRUE iff Nl is the next significant character *)
(*        The reason for a FALSE result is given by ConvReports.LastReport *)

(*
*)

PROCEDURE Write(cn: Channel.Numbers);
(* pre  : the channel is open for output operations *)
(* do   : write the Nl character to the Linked device *)

END Nl.
::::::::::::::
Int.def
::::::::::::::
DEFINITION MODULE Int;

(* Proposed BSI Standard Modula-2 I/O Library
 * Copyright Roger Henry, University of Nottingham
 * Version WG/2.0, August 17th 1987
 * Permission is given to copy this Definition Module, with the
 * copyright notice intact, for the purposes of evaluation and test.
 * At the stage of a formal draft standard, Copyright will be transferred
 * to BSI (and through BSI to other recognised standards bodies).
 * Status: For review by BSI/IST/5/13
*)


(*
INTEGER IO with conversion from and to character sequences
*)

IMPORT
  Channel;
FROM ConvTypes IMPORT
  Justifications;

(*
EXPORT QUALIFIED
  Read, Value, Skip,
  CanRead, CanSkip
  Write, WriteF;
*)

(* Input:
leading white-space (Space and Tab) ignored,
optional +/- sign,
followed immediately by a sequence of decimal digits,
terminated by the first non-digit.
The terminating character is not consumed.
*)

(* Read and consume a legible integer value *)

PROCEDURE Read(cn: Channel.Numbers; VAR int: INTEGER);
(* pre	: there is a well-formed integer next in the input data *)
(*        which can be represented as an INTEGER value *)
(* post	: value of "int" = what was the next data value and this has been *)
(*        skipped over in the input *)

(* The value of the integer can be obtained without consuming the input: *)

PROCEDURE Value(cn: Channel.Numbers): INTEGER;
(* pre	: there is a well-formed integer next in the input data *)
(*        which can be represented as an INTEGER value *)
(* post	: returns the value of the next item of data *)

(* If the integer is not going to be read it may be skipped: *)

PROCEDURE Skip(cn: Channel.Numbers);
(* pre 	: there is a well-formed integer next in the input data *)
(* post	: what was the next data value has been skipped over *)

(*
If the preconditions of Read, Value, or Skip are not satisfied,
a conversion error shall be reported via ConvReports:
  badValue: the value is too large to be represented,
  badFormat: next characters within line do not give a well-formed integer,
  foundNl: unexpected new line character found,
  noData: end of input is found before any significant characters.

Initially a handler shall be installed which causes a message to be printed
and the program to be terminated.
A handler may be installed which allows continuation and subsequent
testing for errors.
Significant characters shall not have been consumed,
and any returned value shall be MAX(INTEGER).

Alternatively, predicates can be called to test the precondition in advance:
*)

PROCEDURE CanRead(cn: Channel.Numbers): BOOLEAN;
(* pre  : the channel is open for input operations *)
(* post	: returns TRUE iff there is a well-formed integer next in the input *)
(*        data which can be represented as an INTEGER value. *)
(*        The reason for a FALSE result is given by ConvReports.LastReport *)

(*
Skipping does not strictly require the value to be representable:
*)

PROCEDURE CanSkip(cn: Channel.Numbers): BOOLEAN;
(* pre  : the channel is open for input operations *)
(* post	: returns TRUE iff there is a well-formed integer next in the input *)
(*        The reason for a FALSE result is given by ConvReports.LastReport *)

(* Output:
no specified field width:
  leading sign for negative integers, space for non-negative.
with specified field width:
  leading sign for negative integers, space for non-negative,
  left, centre, or right justified within the given minimum field width. 
  In the special case of a specified field width of 0, the leading space
  for non-negative values shall be suppressed.
*)

PROCEDURE Write(cn: Channel.Numbers; int: INTEGER);
(* pre  : the channel is open for output operations *)
(* post : the given integer value is written with no field *)
(* note : successive values written in this format can be distinguished *)
(*        on input *)

PROCEDURE WriteF(
      cn: Channel.Numbers;
      int: INTEGER;
      width: CARDINAL; 
      where: Justifications
  );
(* pre  : the channel is open for output operations *)
(* post	: the given value is written in a field of the given *)
(*        minimum width left, centre, or right justified *)

END Int.
::::::::::::::
ConvTypes.def
::::::::::::::
DEFINITION MODULE ConvTypes;

(* Proposed BSI Standard Modula-2 I/O Library
 * Copyright Roger Henry, University of Nottingham
 * Version WG/2.0, August 17th 1987
 * Permission is given to copy this Definition Module, with the
 * copyright notice intact, for the purposes of evaluation and test.
 * At the stage of a formal draft standard, Copyright will be transferred
 * to BSI (and through BSI to other recognised standards bodies).
 * Status: For review by BSI/IST/5/13
*)


(* Types used in conversions from and to character sequences *)

(*
EXPORT QUALIFIED
  ConvResults, BadConvResults, Justifications;
*)

TYPE
  ConvResults = (
    goodValue,		(* good format and value *)
    badValue,		(* good format but value cannot be represented *)
    badFormat,		(* bad format of data within line *)
    foundNl,		(* unexpected new line character found *)
    noData		(* no significant characters to convert *)
    );
  BadConvResults = [badValue .. noData];
  Justifications = (left, centre, right);

END ConvTypes.
::::::::::::::
ConvReports.def
::::::::::::::
DEFINITION MODULE ConvReports;

(* Proposed BSI Standard Modula-2 I/O Library
 * Copyright Roger Henry, University of Nottingham
 * Version WG/2.0, August 17th 1987
 * Permission is given to copy this Definition Module, with the
 * copyright notice intact, for the purposes of evaluation and test.
 * At the stage of a formal draft standard, Copyright will be transferred
 * to BSI (and through BSI to other recognised standards bodies).
 * Status: For review by BSI/IST/5/13
*)


(*
Handling of input conversion reports
*)

IMPORT
  Channel;
FROM ConvTypes IMPORT
  ConvResults, BadConvResults;

(*
EXPORT QUALIFIED
  NoteGood, NoteBad, NoteError,
  Handlers,
  Abort, Continue, GetHandler, SetHandler,
  LastReport;
*)

(* An <Object>IO input procedure - Read, Value, or Skip - reports when *)
(* it has a good result on a channel: *)

PROCEDURE NoteGood(cn: Channel.Numbers);
(* post: the result of the last input procedure is noted as good *)

(* An <Object>IO input predicate - CanRead, or CanSkip - reports the *)
(* reason when it returns FALSE: *)

PROCEDURE NoteBad(cn: Channel.Numbers; badRes: BadConvResults);
(* post: the result of the last input test is noted as bad *)

(* The <Object>IO input procedures report when an incorrect format or  *)
(* out of range value condition arises on input. *)
(* When reported, a per-channel handler routine is called: *)

PROCEDURE NoteError(
      cn: Channel.Numbers;
      badRes: BadConvResults;
      msg: ARRAY OF CHAR);
(* pre : badRes conveys the problem. *)
(*       msg gives further information such as calling procedure name *)
(* post: the condition has been noted and a per-channel handler called *)

TYPE
  Handlers =
    PROCEDURE(Channel.Numbers, BadConvResults, VAR ARRAY OF CHAR);

(* The reported message shall be passed unchanged to the handler. *)
(* Initially a handler is installed which composes a message *)
(* and terminates the program. *)

(* The standard handlers: *)
  
PROCEDURE Abort(
      cn: Channel.Numbers;
      res: BadConvResults;
  VAR msg: ARRAY OF CHAR
  );
(* default handler *)
(* print message from res and msg and terminate the program *)

PROCEDURE Continue(
      cn: Channel.Numbers;
      res: BadConvResults;
  VAR msg: ARRAY OF CHAR
  );
(* alternative standard handler *)
(* do nothing *)

(*
Get and set the input conversion error handler for a channel
*)

PROCEDURE GetHandler(cn: Channel.Numbers; VAR h: Handlers);
(* post: the current handler is assigned to h *)

PROCEDURE SetHandler(cn: Channel.Numbers; h: Handlers);
(* post: the current handler is set to h *)

(*
Allow the user to test if a call for legible input was successful,
in cases where the handler has continued.
Determine the reason for a FALSE result from an input predicate
*)

PROCEDURE LastReport(cn: Channel.Numbers): ConvResults;
(* pre  : there has been a call of an <Object>IO input routine *)
(*        or a call of a predicate which returned FALSE *)
(* post : returns the report made on the last such call on the channel *)

END ConvReports.