DEFINITION MODULE PascalIO;
(* 
   Module:	Pascal-like Input/Output
   Author:	Ceriel J.H. Jacobs
   Version:	$Id$

   This module provides for I/O that is essentially equivalent to the I/O
   provided by Pascal with "text", or "file of char".
   Output buffers are automatically flushed at program termination.
   The CloseOutput routine is just there for compatibility with earlier
   versions of this module.
*)

  CONST	Eos = 0C;		(* End of string character *)

  TYPE	Text;

  VAR	Input, Output: Text;	(* standard input and standard output available
				   immediately.
				   Standard output is not buffered when
				   connected to a terminal.
				*)
  VAR	Notext: Text;		(* Initialize your Text variables with this *)

  PROCEDURE Reset(VAR InputText: Text; Filename: ARRAY OF CHAR);
  (* When InputText indicates an open textfile, it is first flushed
     and closed. Then, the file indicated by "Filename" is opened for reading.
     If this fails, a runtime error results. Otherwise, InputText is
     associated with the new input file.
  *)

  PROCEDURE Rewrite(VAR OutputText: Text; Filename: ARRAY OF CHAR);
  (* When OutputText indicates an open textfile, it is first flushed
     and closed. Then, the file indicated by "Filename" is opened for writing.
     If this fails, a runtime error results. Otherwise, OutputText is
     associated with the new output file.
  *)

  PROCEDURE CloseOutput();
  (* To be called at the end of the program, to flush all output buffers. *)

  (***************************************************************************
     Input routines;
     All these routines result in a runtime error when not called with either
     "Input", or a "Text" value obtained by Reset.
     Also, the routines that actually advance the "read pointer", result in a
     runtime error when end of file is reached prematurely.
  ****************************************************************************)

  PROCEDURE NextChar(InputText: Text): CHAR;
  (* Returns the next character from the InputText, 0C on end of file.
     Does not advance the "read pointer", so behaves much like "input^"
     in Pascal. However, unlike Pascal, if Eoln(InputText) is TRUE, it
     returns the newline character, rather than a space.
  *)

  PROCEDURE Get(InputText: Text);
  (* Advances the "read pointer" by one character. *)

  PROCEDURE Eoln(InputText: Text): BOOLEAN;
  (* Returns TRUE if the next character from the InputText is a linefeed.
     Unlike Pascal however, it does not produce a runtime error when
     called when Eof(InputText) is TRUE.
  *)

  PROCEDURE Eof(InputText: Text): BOOLEAN;
  (* Returns TRUE if the end of the InputText is reached. *)

  PROCEDURE ReadChar(InputText: Text; VAR Char: CHAR);
  (* Read a character from the InputText, and leave the result in "Char".
     Unlike Pascal, if Eoln(InputText) is TRUE, the newline character
     is put in "Char".
  *)

  PROCEDURE ReadLn(InputText: Text);
  (* Skip the rest of the current line from the InputText,
     including the linefeed.
  *)

  PROCEDURE ReadInteger(InputText: Text; VAR Integer: INTEGER);
  (* Skip leading blanks, read an optionally signed integer from the
     InputText, and leave the result in "Integer".
     If no integer is read, or when overflow occurs, a runtime error results.
     Input stops at the character following the integer.
  *)

  PROCEDURE ReadCardinal(InputText: Text; VAR Cardinal: CARDINAL);
  (* Skip leading blanks, read a cardinal from the InputText, and leave the
     result in "Cardinal".
     If no cardinal is read, or when overflow occurs, a runtime error results.
     Input stops at the character following the cardinal.
  *)

  PROCEDURE ReadReal(InputText: Text; VAR Real: REAL);
  (* Skip leading blanks, read a real from the InputText, and leave the
     result in "Real".
     Syntax:
      real -->	[(+|-)] digit {digit} [. digit {digit}]
		[ E [(+|-)] digit {digit} ]
     If no real is read, or when overflow/underflow occurs, a runtime error
     results.
     Input stops at the character following the real.
  *)

  PROCEDURE ReadLongReal(InputText: Text; VAR Real: LONGREAL);
  (* Like ReadReal, but for LONGREAL *)

  (***************************************************************************
     Output routines;
     All these routines result in a runtime error when not called with either
     "Output", or a "Text" value obtained by Rewrite.
  ****************************************************************************)

  PROCEDURE WriteChar(OutputText: Text; Char: CHAR);
  (* Writes the character "Char" to the OutputText. *)

  PROCEDURE WriteLn(OutputText: Text);
  (* Writes a linefeed to the OutputText. *)

  PROCEDURE Page(OutputText: Text);
  (* Writes a form-feed to the OutputText *)

  PROCEDURE WriteInteger(OutputText: Text; Integer: INTEGER; Width: CARDINAL);
  (* Write integer "Integer" to the OutputText, using at least "Width" places,
     blank-padding to the left if needed.
  *)

  PROCEDURE WriteCardinal(OutputText: Text; Cardinal, Width: CARDINAL);
  (* Write cardinal "Cardinal" to the OutputText, using at least
     "Width" places, blank-padding to the left if needed.
  *)

  PROCEDURE WriteBoolean(OutputText: Text; Boolean: BOOLEAN; Width: CARDINAL);
  (* Write boolean "Boolean" to the OutputText, using at least "Width" places,
     blank-padding to the left if needed.
     Equivalent to WriteString(OutputText, " TRUE", Width), or
		   WriteString(OutputText, "FALSE", Width).
  *)

  PROCEDURE WriteString(OutputText: Text;
			String: ARRAY OF CHAR; Width: CARDINAL);
  (* Write string "String" to the OutputText, using at least "Width" places,
     blank-padding to the left if needed.
     The string is terminated either by the character Eos, or by the upperbound
     of the array "String".
  *)

  PROCEDURE WriteReal(OutputText: Text; Real: REAL; Width, Nfrac: CARDINAL);
  (* Write real "Real" to the OutputText. If "Nfrac" = 0, use scientific
     notation, otherwise use fixed-point notation with "Nfrac" digits behind
     the dot.
     Always use at least "Width" places, blank-padding to the left if needed.
  *)

  PROCEDURE WriteLongReal(OutputText: Text; Real: LONGREAL;
			  Width, Nfrac: CARDINAL);
  (* Like WriteReal, but for LONGREAL *)
END PascalIO.
