DEFINITION MODULE InOut;

(*       Input/output facilities as defined by N.Wirth          

         Original material Copyright 1984 ETH Zurich            
         with some extensions.                                *)

  CONST EOL = 15C;

  VAR Done:  BOOLEAN;
      termCH:  CHAR;  (*terminating character in
                        ReadString, ReadInt, and ReadCard
                        (but not in ReadLine) *)

  PROCEDURE OpenInput ( name : ARRAY OF CHAR );
     (*closes the input stream "In" and opens a new input stream *)

  PROCEDURE OpenOutput ( name : ARRAY OF CHAR );
     (*closes the output stream "Out" and opens a new output stream. *)

     (*If name is a valid file-name or one of the special
       streamnames:
       
                "CON:"    the Terminal.
                "AUX:"    the seriel port (RS 232).
                "PRN:"    the parallel port (the printer)
                
       that file or stream is opened immedially if possible.
       (In OpenInput "PRN:" causes Done=FALSE.)
       
       Valid examples of file names include:
       
          .DAT (the Modula-2 standard), *.DAT, DATA.*, *A.D*, DATA.D??,
          B:DATA.DAT, G:\*.D?T, C:\FOLDER\?ATA.D?T, etc
          
       If the name is a valid and complete file name (ie contains a name
       but no wildcards ( * or ? )) then this file is opened immediately.
       Else a standard GEM File Selector reflecting as much as possible
       of the given name shows up on the screen offering the user the
       possibility to select the wantet file. A click on Cancel causes 
       Done= FALSE.
       
       If the file or stream is successfully opened subsequent in- or 
       output will be from (to) that file or stream and Done is returned
       TRUE. Else subsequent in- or output will be to the Terminal and
       Done is returned FALSE.
       
       If an already existing file is opened by OpenOutput, that file is 
       first deleted and a new file with the same name is created. *)
       

  PROCEDURE CloseInput;
     (* closes input stream "In"; returns input to the keyboard *)

  PROCEDURE CloseOutput;
     (* closes output stream "Out"; returns output to screen *)

  PROCEDURE Read ( VAR ch : CHAR );
     (* Done := ch was successfully read 
        ie the last char of the stream was not allready read *)

  PROCEDURE ReadString ( VAR s : ARRAY OF CHAR );
     (*read a string, i.e. sequence of characters not containing
       blanks nor control characters, from stream "In";
       leading blanks are ignored.
       Input is terminated by any character <= " ";
       this character is assigned to termCH.
       Done:="all characters were read, and assigned 
       to the elements of s".*)

  PROCEDURE ReadLine ( VAR s : ARRAY OF CHAR );
     (*read a line, i.e. sequence of characters not containing
       control characters, from stream "In".
       Input is terminated by any character < " ";
       ASCII.NUL (CHR(0)) is assigned to termCH
       and to the first character of S not read into.
       Done:="all characters were read, and assigned 
       to the elements of s".*)

  PROCEDURE ReadInt ( VAR x : INTEGER );
     (*read string from stream "In" using ReadString 
       and convert to integer.
       Syntax:
         integer = ["+"|"-"] digit {digit} ["B"|"C"|"H"].
           "B"|"C"   : interpreted as an octal number.
           "H"       : interpreted as a hexadecimal number.
           No letter : interpreted as a decimal number.
       Leading blanks are ignored.
       Done := "integer was read"*)

  PROCEDURE ReadCard ( VAR x : CARDINAL );
     (*read string from stream "In" using ReadString
       and convert to cardinal. 
       Syntax:
         cardinal = digit {digit} ["B"|"C"|"H"]. 
           "B"|"C"   : interpreted as an octal number.
           "H"       : interpreted as a hexadecimal number.
           No letter : interpreted as a decimal number.
       Leading blanks are ignored.
       Done := "cardinal was read"*)

  PROCEDURE Write ( ch : CHAR );
     (* Writes any 8 bit character on stream "Out" *)

  PROCEDURE WriteLn;
     (* terminate line by writing ASCII.CR and ASCII.LF on stream "Out" *)

  PROCEDURE WriteString ( s : ARRAY OF CHAR );
     (* the string is a sequence of characters ending with ASCII.NUL,
        it is writen on stream "Out" *)

  PROCEDURE WriteStringRight ( s : ARRAY OF CHAR; n : INTEGER );
     (* The string is writen on stream "Out".
        If n is greater than the number of character needed,
        blanks are added preceding the string to make the total 
        number of characters equal to n *)

  PROCEDURE WriteInt ( x : INTEGER ; n : CARDINAL );
     (* write integer x with (at least) n characters on stream "Out",
        using WriteStringRight *)
        
  PROCEDURE WriteCard ( x, n : CARDINAL);
  PROCEDURE WriteOct  ( x, n : CARDINAL);
  PROCEDURE WriteHex  ( x, n : CARDINAL);
     (*write cardinal x decimal, octal, or hexadecimal,
       analog to WriteInt *)

  PROCEDURE ConvFromStr(T : ARRAY OF CHAR;
                  VAR res : LONGCARD;
                      max : LONGCARD;
                      neg : BOOLEAN;
                 VAR done : BOOLEAN);

END (* Of DEFINITION MODULE *) InOut.
