1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/* 2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification 3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * of Java bytecode. 4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59f606f95f03a75961498803e24bee6799a7c0885Ying Wang * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) 6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it 8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free 9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option) 10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version. 11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT 13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details. 16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along 18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc., 19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard; 22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport java.io.*; 24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/** 27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * An abstract reader of words, with the possibility to include other readers. 28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Words are separated by spaces or broken off at delimiters. Words containing 29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * spaces or delimiters can be quoted with single or double quotes. 30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Comments (everything starting with '#' on a single line) are ignored. 31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune 33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @noinspection TailRecursion 34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic abstract class WordReader 36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{ 37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private static final char COMMENT_CHARACTER = '#'; 38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private File baseDir; 41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private WordReader includeWordReader; 42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private String currentLine; 43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private int currentLineLength; 44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private int currentIndex; 45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private String currentWord; 46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private String currentComments; 47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates a new WordReader with the given base directory. 51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato protected WordReader(File baseDir) 53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.baseDir = baseDir; 55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Sets the base directory of this reader. 60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void setBaseDir(File baseDir) 62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (includeWordReader != null) 64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato includeWordReader.setBaseDir(baseDir); 66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato else 68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.baseDir = baseDir; 70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns the base directory of this reader, if any. 76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public File getBaseDir() 78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return includeWordReader != null ? 80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato includeWordReader.getBaseDir() : 81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato baseDir; 82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Specifies to start reading words from the given WordReader. When it is 87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * exhausted, this WordReader will continue to provide its own words. 88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param newIncludeWordReader the WordReader that will start reading words. 90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void includeWordReader(WordReader newIncludeWordReader) 92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (includeWordReader == null) 94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato includeWordReader = newIncludeWordReader; 96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato else 98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato includeWordReader.includeWordReader(newIncludeWordReader); 100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Reads a word from this WordReader, or from one of its active included 106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * WordReader objects. 107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @return the read word. 109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 1109f606f95f03a75961498803e24bee6799a7c0885Ying Wang public String nextWord() throws IOException 111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato currentWord = null; 113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // See if we have an included reader to produce a word. 115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (includeWordReader != null) 116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Does the included word reader still produce a word? 1189f606f95f03a75961498803e24bee6799a7c0885Ying Wang currentWord = includeWordReader.nextWord(); 119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (currentWord != null) 120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Return it if so. 122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return currentWord; 123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Otherwise close and ditch the word reader. 126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato includeWordReader.close(); 127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato includeWordReader = null; 128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Get a word from this reader. 131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 1329f606f95f03a75961498803e24bee6799a7c0885Ying Wang // Skip leading whitespace. 1339f606f95f03a75961498803e24bee6799a7c0885Ying Wang while (currentLine != null && 1349f606f95f03a75961498803e24bee6799a7c0885Ying Wang currentIndex < currentLineLength && 1359f606f95f03a75961498803e24bee6799a7c0885Ying Wang Character.isWhitespace(currentLine.charAt(currentIndex))) 136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 1379f606f95f03a75961498803e24bee6799a7c0885Ying Wang currentIndex++; 138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Make sure we have a non-blank line. 141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato while (currentLine == null || currentIndex == currentLineLength) 142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato currentLine = nextLine(); 144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (currentLine == null) 145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return null; 147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 1499f606f95f03a75961498803e24bee6799a7c0885Ying Wang // Trim off any comments. 1509f606f95f03a75961498803e24bee6799a7c0885Ying Wang int comments_start = currentLine.indexOf(COMMENT_CHARACTER); 1519f606f95f03a75961498803e24bee6799a7c0885Ying Wang if (comments_start >= 0) 152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 1539f606f95f03a75961498803e24bee6799a7c0885Ying Wang currentLineLength = comments_start; 154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Remember the comments. 1569f606f95f03a75961498803e24bee6799a7c0885Ying Wang String comment = currentLine.substring(comments_start + 1); 157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato currentComments = currentComments == null ? 158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato comment : 159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato currentComments + '\n' + comment; 1609f606f95f03a75961498803e24bee6799a7c0885Ying Wang } 1619f606f95f03a75961498803e24bee6799a7c0885Ying Wang else 1629f606f95f03a75961498803e24bee6799a7c0885Ying Wang { 1639f606f95f03a75961498803e24bee6799a7c0885Ying Wang currentLineLength = currentLine.length(); 1649f606f95f03a75961498803e24bee6799a7c0885Ying Wang } 165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 1669f606f95f03a75961498803e24bee6799a7c0885Ying Wang // Skip leading whitespace. 1679f606f95f03a75961498803e24bee6799a7c0885Ying Wang currentIndex = 0; 1689f606f95f03a75961498803e24bee6799a7c0885Ying Wang while (currentIndex < currentLineLength && 1699f606f95f03a75961498803e24bee6799a7c0885Ying Wang Character.isWhitespace(currentLine.charAt(currentIndex))) 1709f606f95f03a75961498803e24bee6799a7c0885Ying Wang { 1719f606f95f03a75961498803e24bee6799a7c0885Ying Wang currentIndex++; 172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Find the word starting at the current index. 176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int startIndex = currentIndex; 177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int endIndex; 178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato char startChar = currentLine.charAt(startIndex); 180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 1819f606f95f03a75961498803e24bee6799a7c0885Ying Wang if (isDelimiter(startChar)) 1829f606f95f03a75961498803e24bee6799a7c0885Ying Wang { 1839f606f95f03a75961498803e24bee6799a7c0885Ying Wang // The next word is a single delimiting character. 1849f606f95f03a75961498803e24bee6799a7c0885Ying Wang endIndex = ++currentIndex; 1859f606f95f03a75961498803e24bee6799a7c0885Ying Wang } 1869f606f95f03a75961498803e24bee6799a7c0885Ying Wang else if (isQuote(startChar)) 187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // The next word is starting with a quote character. 189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Skip the opening quote. 190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato startIndex++; 191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // The next word is a quoted character string. 193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Find the closing quote. 194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato do 195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato currentIndex++; 197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (currentIndex == currentLineLength) 199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato currentWord = currentLine.substring(startIndex-1, currentIndex); 201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato throw new IOException("Missing closing quote for "+locationDescription()); 202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato while (currentLine.charAt(currentIndex) != startChar); 205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato endIndex = currentIndex++; 207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato else 209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // The next word is a simple character string. 211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Find the end of the line, the first delimiter, or the first 212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // white space. 213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato while (currentIndex < currentLineLength) 214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato char currentCharacter = currentLine.charAt(currentIndex); 2169f606f95f03a75961498803e24bee6799a7c0885Ying Wang if (isDelimiter(currentCharacter) || 2179f606f95f03a75961498803e24bee6799a7c0885Ying Wang Character.isWhitespace(currentCharacter)) 2189f606f95f03a75961498803e24bee6799a7c0885Ying Wang { 219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato break; 220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato currentIndex++; 223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato endIndex = currentIndex; 226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Remember and return the parsed word. 229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato currentWord = currentLine.substring(startIndex, endIndex); 230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 231b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return currentWord; 232b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 233b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 234b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 235b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 236b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns the comments collected before returning the last word. 237b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Starts collecting new comments. 238b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 239b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @return the collected comments, or <code>null</code> if there weren't any. 240b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 241b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public String lastComments() throws IOException 242b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 243b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (includeWordReader == null) 244b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 245b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String comments = currentComments; 246b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato currentComments = null; 247b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return comments; 248b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 249b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato else 250b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 251b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return includeWordReader.lastComments(); 252b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 253b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 254b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 255b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 256b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 257b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Constructs a readable description of the current position in this 258b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * WordReader and its included WordReader objects. 259b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 260b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @return the description. 261b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 262b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public String locationDescription() 263b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 264b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return 265b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato (includeWordReader == null ? 266b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato (currentWord == null ? 267b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato "end of " : 268b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato "'" + currentWord + "' in " ) : 269b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato (includeWordReader.locationDescription() + ",\n" + 270b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato " included from ")) + 271b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato lineLocationDescription(); 272b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 273b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 274b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 275b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 276b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Reads a line from this WordReader, or from one of its active included 277b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * WordReader objects. 278b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 279b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @return the read line. 280b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 281b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato protected abstract String nextLine() throws IOException; 282b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 283b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 284b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 285b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns a readable description of the current WordReader position. 286b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 287b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @return the description. 288b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 289b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato protected abstract String lineLocationDescription(); 290b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 291b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 292b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 293b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Closes the FileWordReader. 294b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 295b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void close() throws IOException 296b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 297b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Close and ditch the included word reader, if any. 298b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (includeWordReader != null) 299b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 300b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato includeWordReader.close(); 301b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato includeWordReader = null; 302b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 303b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 304b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 305b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 306b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Small utility methods. 307b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 308b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private boolean isDelimiter(char character) 309b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 310b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return character == '@' || 311b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato character == '{' || 312b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato character == '}' || 313b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato character == '(' || 314b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato character == ')' || 315b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato character == ',' || 316b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato character == ';' || 317b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato character == File.pathSeparatorChar; 318b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 319b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 320b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 321b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private boolean isQuote(char character) 322b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 323b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return character == '\'' || 324b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato character == '"'; 325b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 326b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 327