Oberon/V5/Out.Mod

From Wikibooks, open books for an open world
< Oberon‎ | V5
Jump to navigation Jump to search
(* Oberon, Copyright 2001 ETH Zuerich Institut fuer Computersysteme, ETH Zentrum, CH-8092 Zuerich.
Refer to the "General ETH Oberon System Source License" contract available at: http://www.oberon.ethz.ch/ *)

MODULE Out (* IN V5 *); (** portable *)	(* based on module from "Programming in Oberon" *)

(** Simple output routines for writing text into the Oberon log or a separate viewer. *)

IMPORT Texts, Viewers, Oberon, MenuViewers, TextFrames;

CONST
  StandardMenu = "System.Close System.Copy System.Grow Edit.Search Edit.Store";

VAR T: Texts.Text; W: Texts.Writer; epoch: CHAR; (*
  epoch = "i" denoting "append immediately",
  epoch = "e" denoting "append at end of line". *)

PROCEDURE SetEpoch*(c: CHAR); BEGIN epoch := c END SetEpoch;

PROCEDURE Append();
BEGIN 
  IF epoch = "i" THEN
    Texts.Append(T, W.buf)
  ELSIF epoch = "e" THEN (* Postpone *)
  ELSE
    Texts.WriteString(W, "Character "); Texts.Write(W, epoch);
    Texts.WriteString(W, " in epoch not recognizable."); Texts.WriteLn(W);
    Texts.Append(T, W.buf)
  END
END Append;

(** Write character. *)
PROCEDURE Char*(ch: CHAR);
BEGIN
	Texts.Write(W, ch); Append()
END Char;

(** Write a string. *)
PROCEDURE String*(str: ARRAY OF CHAR);
BEGIN
	Texts.WriteString(W, str); Append()
END String;

(** Write the integer i in n field positions. *)
PROCEDURE Int*(i, n: LONGINT);
BEGIN
	Texts.WriteInt(W, i, n); Append()
END Int;

(** Write the integer i in hexadecimal with a leading space. *)
PROCEDURE Hex*(i: LONGINT);
BEGIN
	Texts.WriteHex(W, i); Append()
END Hex;

(** Write the real x in n field positions. *)
PROCEDURE Real*(x: REAL; n: INTEGER);
BEGIN
	Texts.WriteReal(W, x, n); Append()
END Real;

(** Write the real x in n field positions in fixed point notation with f fraction digits. *)
PROCEDURE RealFix*(x: REAL; n, f: INTEGER);
BEGIN
	Texts.WriteRealFix(W, x, n, f); Append()
END RealFix;

(** Write the longreal x in n field positions. *)
PROCEDURE LongReal*(x: LONGREAL; n: INTEGER);
BEGIN
	Texts.WriteReal(W, x, n); Append()
END LongReal;

(** Write the longreal x in n field positions in fixed point notation with f fraction digits. *)
PROCEDURE LongRealFix*(x: LONGREAL; n, f: INTEGER);
BEGIN
	Texts.WriteRealFix(W, x, n, f); Append()
END LongRealFix;

(** Write a carriage return (CR or end-of-line). *)
PROCEDURE Ln*;
BEGIN
	Texts.WriteLn(W); Texts.Append(T, W.buf)
END Ln;

(** Open a separate viewer for output. *)
PROCEDURE Open*;
  VAR V: Viewers.Viewer;
    X, Y: INTEGER;
BEGIN
	IF T = Oberon.Log THEN NEW(T); Texts.Open(T, "") END;
	Oberon.AllocateUserViewer(400, X, Y);
	(*
	Oberon.OpenText("Out.Text", T, 400, 200)
	*)
	V := MenuViewers.New(
		TextFrames.NewMenu("Out.Text", StandardMenu),
		TextFrames.NewText(T, 0),
		TextFrames.menuH, X, Y)
END Open;

(** Revert output to the system log. *)
PROCEDURE Close*;
BEGIN
	T := Oberon.Log
END Close;

BEGIN
	Texts.OpenWriter(W);  T := Oberon.Log; epoch := "e"
END Out.

(** Remarks:

1. Out uses a Writer from module Texts to write output to the log. 
When epoch = "i" Out is slow because the log is updated after every 
procedure call.  When epoch = "e" performance is better.  Best 
performance is when Texts is used directly.  SetEpoch() is exported 
to allow programmatical change of epoch.

2. Out.Open creates a new text and viewer for output.  Once this is 
done, output can be sent to the system log again by executing Close.
*)