// Tom Giordano
// CS 119 Warmup Exercise
// Due 9/24/97

/* 
   Changes made: added three states to the state machine, inClassicComment,
   checkClassicComment, and endClassicComment.  If a '/*' is detected,
   the program goes into inClassicComment.  In this state no characters
   are printed, as in inComment.  If a '*' is detected, the state machine
   proceeds to checkClassicComment, which checks if the next character
   is a '/'.  If so, the comment has terminated, and the state machine
   proceeds to endClassicComment.  Otherwise the state machine returns
   to inClassicComment.  endClassicComment is a pass-through state that
   exists to prevent the final '/' from being printed.  It automatically
   returns to inText.  
*/

						       

import java.io.*;
import javax.swing.*;
public class Warmup
{
  // Possible states for the finite state machine
  static final int start        = 1; // Your compiler might not accept 'final'
  static final int inText       = 2;
  static final int startComment = 3; // We saw a '/'
  static final int inComment    = 4; // We saw '//'

  static final int inClassicComment    = 5; // We saw '/*'
  static final int checkClassicComment = 6; // We saw a '*' after '/*'
  static final int endClassicComment   = 7; // We saw a '*/' after '/*'

  // Takes current char, previous char, current state
  // Returns next state

  public static int process_char( char c, char lastChar, int state )
  {
    switch( state )
    {
      case start:
	if( c == '/' )
	  return startComment;
	else
	  return inText;

      case inText:
	System.out.print( lastChar );
	if( c == '/' )
	  state = startComment;
	return state;

      case startComment:
	if( c == '/' )
	  return inComment;
	else if( c == '*' )
	  return inClassicComment;
	else
	{
	  System.out.print( lastChar );
	  return inText;
	}

      case inComment:
	if( c == '\n' )
	  state = inText;
	return state;

      case inClassicComment:
	if( c == '*' )
	  state = checkClassicComment;
	return state;

      case checkClassicComment:
	if( c == '/' )
	  return endClassicComment;
	else
	  return inClassicComment;

      case endClassicComment:
	return inText;   // Pass through, to get rid of final '/'.

      default:
	System.out.println( "process_char saw state " + state );
    }
    return start;
  }

  public static void main( String[] args )
  {
    if( args.length < 1 ) // Check usage.
    {
      System.err.println( "Usage: WarmUp <file>" );
      return;
    }

    JButton button = new JButton();
    
    try // Part of a "try-catch" block
    {
      // Create a DataInputStream - read a line at a time.
      DataInputStream in =
	new DataInputStream( new FileInputStream( args[0] ) );
      
      String line;

      System.out.println( "File with comments:" );
      while( (line = in.readLine() ) != null)
      {
	// Echo the file
	System.out.println( line );
      }

      // reopen the file
      in = new DataInputStream( new FileInputStream( args[0] ) );

      char lastChar = ' '; char c = ' ';
      int state = start;
      
      System.out.println( "\nFile after removing comments:" );
      while( (line = in.readLine() ) != null )
      {
	// Process one line of the file
	for( int i = 0; i < line.length(); i++ )
	{
	  // Process one character of the file
	  lastChar = c; c = line.charAt( i );
	  state = process_char( c, lastChar, state );
	}

	// <cr> is not included in line; process by hand
	lastChar = c; c = '\n';
	state = process_char( c, lastChar, state );
      }

      // Print the last character
      if( (state == inText) || (state == startComment) )
	System.out.print( c );
    }
    catch( Exception e ) // Catch any problems reading file
    {
      e.printStackTrace();
      return;
    }
  }
}
