diff options
Diffstat (limited to 'libjava/java/io/StreamTokenizer.java')
-rw-r--r-- | libjava/java/io/StreamTokenizer.java | 433 |
1 files changed, 433 insertions, 0 deletions
diff --git a/libjava/java/io/StreamTokenizer.java b/libjava/java/io/StreamTokenizer.java new file mode 100644 index 00000000000..d518f83b98d --- /dev/null +++ b/libjava/java/io/StreamTokenizer.java @@ -0,0 +1,433 @@ +/* Copyright (C) 1998, 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +package java.io; + +/** + * @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; + + /* Contains the type of the token read resulting from a call to nextToken. */ + public int ttype; + + /* 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; + private boolean[] alphabetic; + private boolean[] numeric; + private boolean[] quote; + private boolean[] comment; + + /* 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; + + // Deprecated in JDK 1.1. + public StreamTokenizer(InputStream is) + { + this(new InputStreamReader(is)); + } + + public StreamTokenizer(Reader r) + { + in = new PushbackReader(r); + + whitespace = new boolean[256]; + alphabetic = new boolean[256]; + numeric = new boolean[256]; + quote = new boolean[256]; + comment = new boolean[256]; + for (int i = 0; i < 256; i++) + resetChar(i); + + whitespaceChars(0x00, 0x20); + wordChars('A', 'Z'); + wordChars('a', 'z'); + wordChars(0xA0, 0xFF); + commentChar('/'); + quoteChar('\''); + quoteChar('"'); + parseNumbers(); + } + + public void commentChar(int ch) + { + if (ch >= 0 && ch <= 255) + comment[ch] = true; + } + + public void eolIsSignificant(boolean flag) + { + eolSignificant = flag; + } + + public int lineno() + { + return lineNumber; + } + + public void lowerCaseMode(boolean flag) + { + lowerCase = flag; + } + + private boolean isWhitespace(int ch) + { + if (ch >= 0 && ch <= 255) + return whitespace[ch]; + + return false; + } + + private boolean isAlphabetic(int ch) + { + if (ch >= 0 && ch <= 255) + return alphabetic[ch]; + else if (ch > 255) + return true; + + return false; + } + + private boolean isNumeric(int ch) + { + if (ch >= 0 && ch <= 255) + return numeric[ch]; + + return false; + } + + private boolean isQuote(int ch) + { + if (ch >= 0 && ch <= 255) + return quote[ch]; + + return false; + } + + private boolean isComment(int ch) + { + if (ch >= 0 && ch <= 255) + return comment[ch]; + + return false; + } + + public int nextToken() throws IOException + { + if (pushedBack) + { + pushedBack = false; + 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') + in.unread(ch); + if (eolSignificant) + return (ttype = TT_EOL); + } + + if (ch == TT_EOF) + ttype = TT_EOF; + else if (isNumeric(ch)) + { + if (ch == '-') + { + // Read ahead to see if this is an ordinary '-' rather than numeric. + ch = in.read(); + in.unread(ch); + if (isNumeric(ch) && ch != '-') + ch = '-'; + else + 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); + + in.unread(ch); + ttype = TT_NUMBER; + nval = Double.valueOf(tokbuf.toString()).doubleValue(); + } + else if (isAlphabetic(ch)) + { + StringBuffer tokbuf = new StringBuffer(); + tokbuf.append((char) ch); + while (isAlphabetic(ch = in.read()) || isNumeric(ch)) + tokbuf.append((char) ch); + in.unread(ch); + ttype = TT_WORD; + sval = tokbuf.toString(); + if (lowerCase) + sval.toLowerCase(); + } + else if (isComment(ch)) + { + while ((ch = in.read()) != '\n' && ch != '\r' && 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 '\"': + 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(); + } + } + } + + in.unread(nextch); + } + + tokbuf.append((char) ch); + } + + // Throw away matching quote char. + if (ch != ttype) + in.unread(ch); + + sval = tokbuf.toString(); + } + else + { + if (ch == '/') + if ((ch = in.read()) == '/' && slashSlash) + { + while ((ch = in.read()) != '\n' && ch != '\r' && 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 + in.unread(ch); + else if (ch == '\n' || ch == '\r') + { + lineNumber++; + if (ch == '\r' && (ch = in.read()) != '\n') + in.unread(ch); + } + else if (ch == TT_EOF) + { + in.unread(ch); + break; + } + } + return nextToken(); // Recursive, but not too deep in normal cases + } + else + { + in.unread(ch); + ch = '/'; + } + + ttype = ch; + } + + return ttype; + } + + private void resetChar(int ch) + { + whitespace[ch] = alphabetic[ch] = numeric[ch] = quote[ch] = comment[ch] = + false; + } + + public void ordinaryChar(int ch) + { + if (ch >= 0 && ch <= 255) + resetChar(ch); + } + + 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); + } + + public void parseNumbers() + { + for (int i = 0; i <= 9; i++) + numeric['0' + i] = true; + + numeric['.'] = true; + numeric['-'] = true; + } + + public void pushBack() + { + // pushBack may cause the lineno method to return an incorrect value + // if lineno is called before the next call to nextToken. + pushedBack = true; + } + + public void quoteChar(int ch) + { + if (ch >= 0 && ch <= 255) + quote[ch] = true; + } + + public void resetSyntax() + { + ordinaryChars(0x00, 0xFF); + } + + public void slashSlashComments(boolean flag) + { + slashSlash = flag; + } + + public void slashStarComments(boolean flag) + { + slashStar = flag; + } + + 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=" + Double.toString(nval); + else // must be an ordinary char. + tempstr = "\'" + (new Character((char) ttype)).toString() + "\'"; + + return "Token[" + tempstr + "], line " + Integer.toString(lineno()); + } + + public void whitespaceChars(int low, int hi) + { + if (low < 0) + low = 0; + if (hi > 255) + hi = 255; + for (int i = low; i <= hi; i++) + whitespace[i] = true; + } + + 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; + } +} |