MODULE PromptFor; (***************************************************************************) (* Copyright (C) Olivetti 1989 *) (* All Rights reserved *) (* *) (* Use and copy of this software and preparation of derivative works based *) (* upon this software are permitted to any person, provided this same *) (* copyright notice and the following Olivetti warranty disclaimer are *) (* included in any copy of the software or any modification thereof or *) (* derivative work therefrom made by any person. *) (* *) (* This software is made available AS IS and Olivetti disclaims all *) (* warranties with respect to this software, whether expressed or implied *) (* under any law, including all implied warranties of merchantibility and *) (* fitness for any purpose. In no event shall Olivetti be liable for any *) (* damages whatsoever resulting from loss of use, data or profits or *) (* otherwise arising out of or in connection with the use or performance *) (* of this software. *) (***************************************************************************) IMPORT IO, Text, CharType, StdIO, TextTo; IMPORT TextExtras; <*INLINE*> PROCEDURE SetupStreams(VAR in, out: IO.Stream) RAISES {}= BEGIN IF in = NIL THEN in := StdIO.In() END; IF out = NIL THEN out := StdIO.Out() END; END SetupStreams; PROCEDURE GetLine( in, out: IO.Stream; prompt: Text.T) : Text.T RAISES {IO.Error, IO.EndOfStream}= BEGIN IO.PutText(out, prompt); IO.Flush(out); VAR text := IO.GetText(in, CharType.SpaceOrTab, CharType.EndOfLine, FALSE); length := Text.Length(text); pos := length; BEGIN WHILE pos > 0 AND Text.GetChar(text, pos-1) IN CharType.SpaceOrTab DO DEC(pos); END; IF pos # length THEN RETURN Text.Sub(text, 0, pos) ELSE RETURN text END; END; END GetLine; PROCEDURE Int( prompt: Text.T; default := 0; min, max := 0; in, out: IO.Stream := NIL) : INTEGER RAISES {IO.Error, IO.EndOfStream}= (* simple routine to get an integer from standard input stream, prompting on the standard output stream *) BEGIN SetupStreams(in, out); LOOP VAR text := GetLine(in, out, prompt); value: INTEGER; BEGIN IF TextTo.BigInt(text, value) AND (min = max OR value <= max AND value >= min) THEN RETURN value; ELSIF Text.Length(text) = 0 THEN RETURN default; ELSE IO.PutF(out, "\'%s\' is invalid or out of range; try again\n", text); (* loop *) END; END; END; END Int; PROCEDURE Card( prompt: Text.T; default: CARDINAL := 0; min, max: CARDINAL := 0; in, out: IO.Stream := NIL) : CARDINAL RAISES {IO.Error, IO.EndOfStream}= (* simple routine to get a positive number from standard input stream, prompting on the standard output stream *) BEGIN RETURN Int(prompt, default, min, max, in, out); END Card; PROCEDURE Real( prompt: Text.T; default := 0.0; min, max := 0.0; in, out: IO.Stream := NIL) : REAL RAISES {IO.Error, IO.EndOfStream}= BEGIN SetupStreams(in, out); LOOP VAR text := GetLine(in, out, prompt); value: REAL; BEGIN IF TextTo.Real(text, value) AND (min = max OR value <= max AND value >= min) THEN RETURN value; ELSIF Text.Length(text) = 0 THEN RETURN default; ELSE IO.PutF(out, "\'%s\' is invalid or out of range; try again\n", text); (* loop *) END; END; END; END Real; PROCEDURE LongReal( prompt: Text.T; default := 0.0D0; min, max := 0.0D0; in, out: IO.Stream := NIL) : LONGREAL RAISES {IO.Error, IO.EndOfStream}= BEGIN SetupStreams(in, out); LOOP VAR text := GetLine(in, out, prompt); value: LONGREAL; BEGIN IF TextTo.LongReal(text, value) AND (min = max OR value <= max AND value >= min) THEN RETURN value; ELSIF Text.Length(text) = 0 THEN RETURN default; ELSE IO.PutF(out, "\'%s\' is invalid or out of range; try again\n", text); (* loop *) END; END; END; END LongReal; PROCEDURE IsAnswer(t: Text.T; VAR value: BOOLEAN): BOOLEAN RAISES {}= VAR length := Text.Length(t); BEGIN IF length > 0 THEN CASE Text.GetChar(t, 0) OF | 'Y', 'y' => IF length = 1 OR TextExtras.CIEqual(t, "yes") THEN value := TRUE; RETURN TRUE; END; | 'N', 'n' => IF length = 1 OR TextExtras.CIEqual(t, "no") THEN value := FALSE; RETURN TRUE; END; ELSE END; END; RETURN FALSE; END IsAnswer; PROCEDURE Answer( prompt: Text.T; default := FALSE; in, out: IO.Stream := NIL) : BOOLEAN RAISES {IO.Error, IO.EndOfStream}= BEGIN SetupStreams(in, out); LOOP VAR text := GetLine(in, out, prompt); value: BOOLEAN; BEGIN IF IsAnswer(text, value) THEN RETURN value; ELSIF Text.Length(text) = 0 THEN RETURN default; ELSE IO.PutF(out, "\'%s\' is not a valid answer; try again\n", text); (* loop *) END; END; END; END Answer; BEGIN END PromptFor.