//==================================//
//  IO.Get : Simple Input Routines  //
//==================================//
//   Joseph Manning : 2000-Nov-11   //
//==================================//

package IO;

import java.io.*;

public class Get {

   private static final char   EOFchar   = '\u00d7';   // arbitrary magic char
   private static final int    EOFint    = 0xf0e1d2c3; // arbitrary magic number
   private static final double EOFdouble = -0.9182E73; // arbitrary magic number

   //===========================================================================

   public static char Char( ) {

      // Return the next character from 'System.in', or 'EOFchar' at end-of-file

      char c = ' ';
      int i;

      try {
         i = System.in.read( );
         c = ( i == -1 ? EOFchar : (char) i ); }

      catch ( IOException x )
         { }

      return c; }

   //===========================================================================

   public static boolean IsEOF( char c ) {

      // Is 'c' equal to 'EOFchar' ?

      return ( c == EOFchar ); }

   //===========================================================================

   public static boolean Bit( ) {

      char c = ' ';

      do
         c = Char( );
         while ( Character.isWhitespace( c ) );

      Check( c == '0' || c == '1', "Bit", "'0' or '1'", c );

      return ( c == '1' ); }

   //===========================================================================

   public static int Int( ) {

      // Return the next integer from 'System.in', or 'EOFint' at end-of-file

      char c = ' ';
      int i = 0;
      boolean negative;

      do
         c = Char( );
         while ( Character.isWhitespace( c ) );

      if ( c == EOFchar )
         return EOFint;

      negative = ( c == '-' );
      if ( negative )
         c = Char( );

      Check( Character.isDigit( c ), "Int", "a digit", c );

      do {
         i = 10 * i + Character.digit( c, 10 );
         c = Char( ); }
         while ( Character.isDigit( c ) );

      Check( Character.isWhitespace( c ), "Int", "a digit", c );

      if ( negative )
         i = -i;

      return i; }

   //===========================================================================

   public static boolean IsEOF( int i ) {

      // Is 'i' equal to 'EOFint' ?

      return ( i == EOFint ); }

   //===========================================================================

   public static double Double( ) {

      // Return the next double from 'System.in', or 'EOFdouble' at end-of-file
      //
      // Restricted Syntax: <whitespace>* [-] <digit>+ . <digit>+ <whitespace>

      char c = ' ';
      double d = 0.0, p = 0.1;
      boolean negative;

      do
         c = Char( );
         while ( Character.isWhitespace( c ) );

      if ( c == EOFchar )
         return EOFdouble;

      negative = ( c == '-' );
      if ( negative )
         c = Char( );

      Check( Character.isDigit( c ), "Double", "a digit", c );

      do {
         d = 10.0 * d + Character.digit( c, 10 );
         c = Char( ); }
         while ( Character.isDigit( c ) );

      Check( c == '.', "Double", "'.'", c );

      c = Char( );

      Check( Character.isDigit( c ), "Double", "a digit", c );

      do {
         d += Character.digit( c, 10 ) * p;
         c  = Char( );
         p /= 10.0; }
         while ( Character.isDigit( c ) );

      Check( Character.isWhitespace( c ), "Double", "a digit", c );

      if ( negative )
         d = -d;

      return d; }

   //===========================================================================

   public static boolean IsEOF( double d ) {

      // Is 'd' equal to 'EOFdouble' ?

      return ( d == EOFdouble ); }

   //===========================================================================

   private static void Check( boolean p, String m, String e, char f ) {

      // If 'p' is false, issue the error message:
      //    *** IO.Get.'m' : expecting 'e', but found 'f'
      // consume the rest of the current input line, and halt the program

      char c = f;

      if ( ! p ) {
         System.out.print( "\n*** IO.Get." + m + " : expecting " + e +
                           ", but found " +
                           ( f == '\n'    ? "'\\n'"           :
                             f == EOFchar ? "end-of-file"     :
                                            ( "'" + f + "'" )   ) +
                           "\n\n" );

         while ( c != '\n' && c != EOFchar )
            c = Char( );

         System.exit( 0 ); } }

   //===========================================================================

}
