/* StreamTokenizer.java -- parses streams of characters into tokens
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003  Free Software Foundation

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.io;

/**
 * This class parses streams of characters into tokens.  There are a
 * million-zillion flags that can be set to control the parsing, as 
 * described under the various method headings.
 *
 * @author Warren Levy (warrenl@cygnus.com)
 * @date October 25, 1998.  
 */
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
 * "The Java Language Specification", ISBN 0-201-63451-1
 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
 * Status:  Believed complete and correct.
 */
 
public class StreamTokenizer
{
  /** A constant indicating that the end of the stream has been read. */
  public static final int TT_EOF = -1;

  /** A constant indicating that the end of the line has been read. */
  public static final int TT_EOL = '\n';

  /** A constant indicating that a number token has been read. */
  public static final int TT_NUMBER = -2;

  /** A constant indicating that a word token has been read. */
  public static final int TT_WORD = -3;

  /** A constant indicating that no tokens have been read yet. */
  private static final int TT_NONE = -4;

  /**
   * Contains the type of the token read resulting from a call to nextToken
   * The rules are as follows:
   * <ul>
   * <li>For a token consisting of a single ordinary character, this is the 
   *     value of that character.</li>
   * <li>For a quoted string, this is the value of the quote character</li>
   * <li>For a word, this is TT_WORD</li>
   * <li>For a number, this is TT_NUMBER</li>
   * <li>For the end of the line, this is TT_EOL</li>
   * <li>For the end of the stream, this is TT_EOF</li>
   * </ul>
   */
  public int ttype = TT_NONE;

  /** The String associated with word and string tokens. */
  public String sval;

  /** The numeric value associated with number tokens. */
  public double nval;

  /* Indicates whether end-of-line is recognized as a token. */
  private boolean eolSignificant = false;

  /* Indicates whether word tokens are automatically made lower case. */
  private boolean lowerCase = false;

  /* Indicates whether C++ style comments are recognized and skipped. */
  private boolean slashSlash = false;

  /* Indicates whether C style comments are recognized and skipped. */
  private boolean slashStar = false;

  /* Attribute tables of each byte from 0x00 to 0xFF. */
  private boolean[] whitespace = new boolean[256];
  private boolean[] alphabetic = new boolean[256];
  private boolean[] numeric = new boolean[256];
  private boolean[] quote = new boolean[256];
  private boolean[] comment = new boolean[256];

  /* The Reader associated with this class. */
  private PushbackReader in;

  /* Indicates if a token has been pushed back. */
  private boolean pushedBack = false;

  /* Contains the current line number of the reader. */
  private int lineNumber = 1;

  /**
   * This method reads bytes from an <code>InputStream</code> and tokenizes
   * them.  For details on how this method operates by default, see
   * <code>StreamTokenizer(Reader)</code>.
   *
   * @param is The <code>InputStream</code> to read from
   *
   * @deprecated Since JDK 1.1.
   */
  public StreamTokenizer(InputStream is)
  {
    this(new InputStreamReader(is));
  }

  /**
   * This method initializes a new <code>StreamTokenizer</code> to read 
   * characters from a <code>Reader</code> and parse them.  The char values
   * have their hight bits masked so that the value is treated a character
   * in the range of 0x0000 to 0x00FF.
   * <p>
   * This constructor sets up the parsing table to parse the stream in the
   * following manner:
   * <ul>
   * <li>The values 'A' through 'Z', 'a' through 'z' and 0xA0 through 0xFF
   *     are initialized as alphabetic</li>
   * <li>The values 0x00 through 0x20 are initialized as whitespace</li>
   * <li>The values '\'' and '"' are initialized as quote characters</li>
   * <li>'/' is a comment character</li>
   * <li>Numbers will be parsed</li>
   * <li>EOL is not treated as significant</li>
   * <li>C  and C++ (//) comments are not recognized</li>
   * </ul>
   *
   * @param r The <code>Reader</code> to read chars from
   */
  public StreamTokenizer(Reader r)
  {
    in = new PushbackReader(r);

    whitespaceChars(0x00, 0x20);
    wordChars('A', 'Z');
    wordChars('a', 'z');
    wordChars(0xA0, 0xFF);
    commentChar('/');
    quoteChar('\'');
    quoteChar('"');
    parseNumbers();
  }

  /**
   * This method sets the comment attribute on the specified
   * character.  Other attributes for the character are cleared.
   *
   * @param ch The character to set the comment attribute for, passed as an int
   */
  public void commentChar(int ch)
  {
    if (ch >= 0 && ch <= 255)
      {
	comment[ch] = true;
	whitespace[ch] = false;
	alphabetic[ch] = false;
	numeric[ch] = false;
	quote[ch] = false;
      }
  }

  /**
   * This method sets a flag that indicates whether or not the end of line
   * sequence terminates and is a token.  The defaults to <code>false</code>
   *
   * @param flag <code>true</code> if EOF is significant, <code>false</code>
   *             otherwise
   */
  public void eolIsSignificant(boolean flag)
  {
    eolSignificant = flag;
  }

  /**
   * This method returns the current line number.  Note that if the 
   * <code>pushBack()</code> method is called, it has no effect on the
   * line number returned by this method.
   *
   * @return The current line number
   */
  public int lineno()
  {
    return lineNumber;
  }

  /**
   * This method sets a flag that indicates whether or not alphabetic
   * tokens that are returned should be converted to lower case.
   * 
   * @param flag <code>true</code> to convert to lower case,
   *             <code>false</code> otherwise
   */
  public void lowerCaseMode(boolean flag)
  {
    lowerCase = flag;
  }

  private boolean isWhitespace(int ch)
  {
    return (ch >= 0 && ch <= 255 && whitespace[ch]);
  }

  private boolean isAlphabetic(int ch)
  {
    return ((ch > 255) || (ch >= 0 && alphabetic[ch]));
  }

  private boolean isNumeric(int ch)
  {
    return (ch >= 0 && ch <= 255 && numeric[ch]);
  }

  private boolean isQuote(int ch)
  {
    return (ch >= 0 && ch <= 255 && quote[ch]);
  }

  private boolean isComment(int ch)
  {
    return (ch >= 0 && ch <= 255 && comment[ch]);
  }

  /**
   * This method reads the next token from the stream.  It sets the 
   * <code>ttype</code> variable to the appropriate token type and 
   * returns it.  It also can set <code>sval</code> or <code>nval</code>
   * as described below.  The parsing strategy is as follows:
   * <ul>
   * <li>Skip any whitespace characters.</li>
   * <li>If a numeric character is encountered, attempt to parse a numeric
   * value.  Leading '-' characters indicate a numeric only if followed by
   * another non-'-' numeric.  The value of the numeric token is terminated
   * by either the first non-numeric encountered, or the second occurrence of
   * '-' or '.'.  The token type returned is TT_NUMBER and <code>nval</code>
   * is set to the value parsed.</li>
   * <li>If an alphabetic character is parsed, all subsequent characters
   * are read until the first non-alphabetic or non-numeric character is
   * encountered.  The token type returned is TT_WORD and the value parsed
   * is stored in <code>sval</code>.  If lower case mode is set, the token
   * stored in <code>sval</code> is converted to lower case.  The end of line
   * sequence terminates a word only if EOL signficance has been turned on.
   * The start of a comment also terminates a word.  Any character with a 
   * non-alphabetic and non-numeric attribute (such as white space, a quote,
   * or a commet) are treated as non-alphabetic and terminate the word.</li>
   * <li>If a comment character is parsed, then all remaining characters on
   * the current line are skipped and another token is parsed.  Any EOL or
   * EOF's encountered are not discarded, but rather terminate the comment.</li>
   * <li>If a quote character is parsed, then all characters up to the 
   * second occurrence of the same quote character are parsed into a
   * <code>String</code>.  This <code>String</code> is stored as
   * <code>sval</code>, but is not converted to lower case, even if lower case
   * mode is enabled.  The token type returned is the value of the quote
   * character encountered.  Any escape sequences
   * (\b (backspace), \t (HTAB), \n (linefeed), \f (form feed), \r
   * (carriage return), \" (double quote), \' (single quote), \\
   * (backslash), \XXX (octal esacpe)) are converted to the appropriate
   * char values.  Invalid esacape sequences are left in untranslated.  
   * Unicode characters like ('\ u0000') are not recognized. </li>
   * <li>If the C++ comment sequence "//" is encountered, and the parser
   * is configured to handle that sequence, then the remainder of the line
   * is skipped and another token is read exactly as if a character with
   * the comment attribute was encountered.</li>
   * <li>If the C comment sequence "/*" is encountered, and the parser
   * is configured to handle that sequence, then all characters up to and
   * including the comment terminator sequence are discarded and another
   * token is parsed.</li>
   * <li>If all cases above are not met, then the character is an ordinary
   * character that is parsed as a token by itself.  The char encountered
   * is returned as the token type.</li>
   * </ul>
   *
   * @return The token type
   * @exception IOException If an I/O error occurs
   */
  public int nextToken() throws IOException
  {
    if (pushedBack)
      {
	pushedBack = false;
	if (ttype != TT_NONE)
	  return ttype;
      }

    sval = null;
    int ch;

    // Skip whitespace.  Deal with EOL along the way.
    while (isWhitespace(ch = in.read()))
      if (ch == '\n' || ch == '\r')
	{
	  lineNumber++;

	  // Throw away \n if in combination with \r.
	  if (ch == '\r' && (ch = in.read()) != '\n')
	    {
	      if (ch != TT_EOF)
		in.unread(ch);
	    }
	  if (eolSignificant)
	    return (ttype = TT_EOL);
	}

    if (ch == '/')
      if ((ch = in.read()) == '/' && slashSlash)
	{
	  while ((ch = in.read()) != '\n' && ch != '\r' && ch != TT_EOF)
	    ;
	  if (ch != TT_EOF)
	    in.unread(ch);
	  return nextToken(); // Recursive, but not too deep in normal cases
	}
      else if (ch == '*' && slashStar) 
	{
	  while (true)
	    {
	      ch = in.read();
	      if (ch == '*')
		{
		  if ((ch = in.read()) == '/')
		    break;
		  else if (ch != TT_EOF)
		    in.unread(ch);
		}
	      else if (ch == '\n' || ch == '\r')
		{
		  lineNumber++;
		  if (ch == '\r' && (ch = in.read()) != '\n')
		    {
		      if (ch != TT_EOF)
			in.unread(ch);
		    }
		}
	      else if (ch == TT_EOF)
		{
		  break;
		}
	    }
	  return nextToken(); // Recursive, but not too deep in normal cases
	}
      else
	{
	  if (ch != TT_EOF)
	    in.unread(ch);
	  ch = '/';
	}

    if (ch == TT_EOF)
      ttype = TT_EOF;
    else if (isNumeric(ch))
      {
	boolean isNegative = false;
	if (ch == '-')
	  {
	    // Read ahead to see if this is an ordinary '-' rather than numeric.
	    ch = in.read();
	    if (isNumeric(ch) && ch != '-')
	      {
		isNegative = true;
	      }
	    else
	      {
		if (ch != TT_EOF)
		  in.unread(ch);
		return (ttype = '-');
	      }
	  }

	StringBuffer tokbuf = new StringBuffer();
	tokbuf.append((char) ch);

	int decCount = 0;
	while (isNumeric(ch = in.read()) && ch != '-')
	  if (ch == '.' && decCount++ > 0)
	    break;
	  else
	    tokbuf.append((char) ch);

	if (ch != TT_EOF)
	  in.unread(ch);
	ttype = TT_NUMBER;
	try
	  {
	    nval = Double.valueOf(tokbuf.toString()).doubleValue();
	  }
	catch (NumberFormatException _)
	  {
	    nval = 0.0;
	  }
	if (isNegative)
	  nval = -nval;
      }
    else if (isAlphabetic(ch))
      {
	StringBuffer tokbuf = new StringBuffer();
	tokbuf.append((char) ch);
	while (isAlphabetic(ch = in.read()) || isNumeric(ch))
	  tokbuf.append((char) ch);
	if (ch != TT_EOF)
	  in.unread(ch);
	ttype = TT_WORD;
	sval = tokbuf.toString();
	if (lowerCase)
	  sval = sval.toLowerCase();
      }
    else if (isComment(ch))
      {
	while ((ch = in.read()) != '\n' && ch != '\r' && ch != TT_EOF)
	  ;
	if (ch != TT_EOF)
	  in.unread(ch);
	return nextToken();	// Recursive, but not too deep in normal cases.
      }
    else if (isQuote(ch))
      {
	ttype = ch;
	StringBuffer tokbuf = new StringBuffer();
	while ((ch = in.read()) != ttype && ch != '\n' && ch != '\r' &&
	       ch != TT_EOF)
	  {
	    if (ch == '\\')
	      switch (ch = in.read())
		{
		  case 'a':	ch = 0x7;
		    break;
		  case 'b':	ch = '\b';
		    break;
		  case 'f':	ch = 0xC;
		    break;
		  case 'n':	ch = '\n';
		    break;
		  case 'r':	ch = '\r';
		    break;
		  case 't':	ch = '\t';
		    break;
		  case 'v':	ch = 0xB;
		    break;
		  case '\n':    ch = '\n';
		    break;
                  case '\r':    ch = '\r';
		    break;
		  case '\"':
		  case '\'':
		  case '\\':
		    break;
		  default:
		    int ch1, nextch;
		    if ((nextch = ch1 = ch) >= '0' && ch <= '7')
		      {
		        ch -= '0';
		        if ((nextch = in.read()) >= '0' && nextch <= '7')
			  {
			    ch = ch * 8 + nextch - '0';
			    if ((nextch = in.read()) >= '0' && nextch <= '7' &&
				ch1 >= '0' && ch1 <= '3')
			      {
				ch = ch * 8 + nextch - '0';
				nextch = in.read();
			      }
			  }
		      }

		    if (nextch != TT_EOF)
		      in.unread(nextch);
		}

	    tokbuf.append((char) ch);
	  }

	// Throw away matching quote char.
	if (ch != ttype && ch != TT_EOF)
	  in.unread(ch);

	sval = tokbuf.toString();
      }
    else
      {
	ttype = ch;
      }

    return ttype;
  }

  private void resetChar(int ch)
  {
    whitespace[ch] = alphabetic[ch] = numeric[ch] = quote[ch] = comment[ch] =
      false;
  }

  /**
   * This method makes the specified character an ordinary character.  This
   * means that none of the attributes (whitespace, alphabetic, numeric,
   * quote, or comment) will be set on this character.  This character will
   * parse as its own token.
   *
   * @param ch The character to make ordinary, passed as an int
   */
  public void ordinaryChar(int ch)
  {
    if (ch >= 0 && ch <= 255)
      resetChar(ch);
  }

  /**
   * This method makes all the characters in the specified range, range
   * terminators included, ordinary.  This means the none of the attributes
   * (whitespace, alphabetic, numeric, quote, or comment) will be set on
   * any of the characters in the range.  This makes each character in this
   * range parse as its own token.
   *
   * @param low The low end of the range of values to set the whitespace
   * attribute for
   * @param hi The high end of the range of values to set the whitespace
   * attribute for
   */
  public void ordinaryChars(int low, int hi)
  {
    if (low < 0)
      low = 0;
    if (hi > 255)
      hi = 255;
    for (int i = low; i <= hi; i++)
      resetChar(i);
  }

  /**
   * This method sets the numeric attribute on the characters '0' - '9' and
   * the characters '.' and '-'.
   * When this method is used, the result of giving other attributes
   * (whitespace, quote, or comment) to the numeric characters may
   * vary depending on the implementation. For example, if
   * parseNumbers() and then whitespaceChars('1', '1') are called,
   * this implementation reads "121" as 2, while some other implementation
   * will read it as 21.
   */
  public void parseNumbers()
  {
    for (int i = 0; i <= 9; i++)
      numeric['0' + i] = true;

    numeric['.'] = true;
    numeric['-'] = true;
  }

  /**
   * Puts the current token back into the StreamTokenizer so
   * <code>nextToken</code> will return the same value on the next call.
   * May cause the lineno method to return an incorrect value
   * if lineno is called before the next call to nextToken.
   */
  public void pushBack()
  {
    pushedBack = true;
  }

  /**
   * This method sets the quote attribute on the specified character.
   * Other attributes for the character are cleared.
   *
   * @param ch The character to set the quote attribute for, passed as an int.
   */
  public void quoteChar(int ch)
  {
    if (ch >= 0 && ch <= 255)
      {
	quote[ch] = true;
	comment[ch] = false;
	whitespace[ch] = false;
	alphabetic[ch] = false;
	numeric[ch] = false;
      }
  }

  /**
   * This method removes all attributes (whitespace, alphabetic, numeric,
   * quote, and comment) from all characters.  It is equivalent to calling
   * <code>ordinaryChars(0x00, 0xFF)</code>.
   *
   * @see #ordinaryChars(int, int)
   */
  public void resetSyntax()
  {
    ordinaryChars(0x00, 0xFF);
  }

  /**
   * This method sets a flag that indicates whether or not "C++" language style
   * comments ("//" comments through EOL ) are handled by the parser.
   * If this is <code>true</code> commented out sequences are skipped and
   * ignored by the parser.  This defaults to <code>false</code>.
   *
   * @param flag <code>true</code> to recognized and handle "C++" style
   *             comments, <code>false</code> otherwise
   */
  public void slashSlashComments(boolean flag)
  {
    slashSlash = flag;
  }

  /**
   * This method sets a flag that indicates whether or not "C" language style
   * comments (with nesting not allowed) are handled by the parser.
   * If this is <code>true</code> commented out sequences are skipped and
   * ignored by the parser.  This defaults to <code>false</code>.
   *
   * @param flag <code>true</code> to recognized and handle "C" style comments,
   *             <code>false</code> otherwise
   */
  public void slashStarComments(boolean flag)
  {
    slashStar = flag;
  }

  /**
   * This method returns the current token value as a <code>String</code> in
   * the form "Token[x], line n", where 'n' is the current line numbers and
   * 'x' is determined as follows.
   * <p>
   * <ul>
   * <li>If no token has been read, then 'x' is "NOTHING" and 'n' is 0</li>
   * <li>If <code>ttype</code> is TT_EOF, then 'x' is "EOF"</li>
   * <li>If <code>ttype</code> is TT_EOL, then 'x' is "EOL"</li>
   * <li>If <code>ttype</code> is TT_WORD, then 'x' is <code>sval</code></li>
   * <li>If <code>ttype</code> is TT_NUMBER, then 'x' is "n=strnval" where
   * 'strnval' is <code>String.valueOf(nval)</code>.</li>
   * <li>If <code>ttype</code> is a quote character, then 'x' is
   * <code>sval</code></li>
   * <li>For all other cases, 'x' is <code>ttype</code></li>
   * </ul>
   */
  public String toString()
  {
    String tempstr;
    if (ttype == TT_EOF)
      tempstr = "EOF";
    else if (ttype == TT_EOL)
      tempstr = "EOL";
    else if (ttype == TT_WORD)
      tempstr = sval;
    else if (ttype == TT_NUMBER)
      tempstr = "n=" + nval;
    else if (ttype == TT_NONE)
      tempstr = "NOTHING";
    else // must be an ordinary char.
      tempstr = "\'" + (char) ttype + "\'";

    return "Token[" + tempstr + "], line " + lineno();
  }

  /**
   * This method sets the whitespace attribute for all characters in the
   * specified range, range terminators included.
   *
   * @param low The low end of the range of values to set the whitespace
   * attribute for
   * @param hi The high end of the range of values to set the whitespace
   * attribute for
   */
  public void whitespaceChars(int low, int hi)
  {
    if (low < 0)
      low = 0;
    if (hi > 255)
      hi = 255;
    for (int i = low; i <= hi; i++)
      {
	resetChar(i);
	whitespace[i] = true;
      }
  }

  /**
   * This method sets the alphabetic attribute for all characters in the
   * specified range, range terminators included.
   *
   * @param low The low end of the range of values to set the alphabetic
   * attribute for
   * @param hi The high end of the range of values to set the alphabetic
   * attribute for
   */
  public void wordChars(int low, int hi)
  {
    if (low < 0)
      low = 0;
    if (hi > 255)
      hi = 255;
    for (int i = low; i <= hi; i++)
      alphabetic[i] = true;
  }
}
