1 /* 2 * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 import java.io.*; 26 import java.util.*; 27 28 public class MacroDefinitions { 29 private Vector macros; 30 31 public MacroDefinitions() { 32 macros = new Vector(); 33 } 34 35 private String lookup(String name) throws NoSuchElementException { 36 for (Iterator iter = macros.iterator(); iter.hasNext(); ) { 37 Macro macro = (Macro) iter.next(); 38 if (macro.name.equals(name)) { 39 return macro.contents; 40 } 41 } 42 throw new NoSuchElementException(name); 43 } 44 45 public void addMacro(String name, String contents) { 46 Macro macro = new Macro(); 47 macro.name = name; 48 macro.contents = contents; 49 macros.add(macro); 50 } 51 52 private boolean lineIsEmpty(String s) { 53 for (int i = 0; i < s.length(); i++) { 54 if (!Character.isWhitespace(s.charAt(i))) { 55 return false; 56 } 57 } 58 return true; 59 } 60 61 public void readFrom(String fileName, boolean missingOk) 62 throws FileNotFoundException, FileFormatException, IOException { 63 BufferedReader reader = null; 64 try { 65 reader = new BufferedReader(new FileReader(fileName)); 66 } catch (FileNotFoundException e) { 67 if (missingOk) { 68 return; 69 } else { 70 throw(e); 71 } 72 } 73 String line; 74 do { 75 line = reader.readLine(); 76 if (line != null) { 77 // This had to be rewritten (compare to Database.java) 78 // because the Solaris platform file has been 79 // repurposed and now contains "macros" with spaces in 80 // them. 81 82 if ((!line.startsWith("//")) && 83 (!lineIsEmpty(line))) { 84 int nameBegin = -1; 85 int nameEnd = -1; 86 boolean gotEquals = false; 87 int contentsBegin = -1; 88 int contentsEnd = -1; 89 90 int i = 0; 91 // Scan forward for beginning of name 92 while (i < line.length()) { 93 if (!Character.isWhitespace(line.charAt(i))) { 94 break; 95 } 96 i++; 97 } 98 nameBegin = i; 99 100 // Scan forward for end of name 101 while (i < line.length()) { 102 if (Character.isWhitespace(line.charAt(i))) { 103 break; 104 } 105 i++; 106 } 107 nameEnd = i; 108 109 // Scan forward for equals sign 110 while (i < line.length()) { 111 if (line.charAt(i) == '=') { 112 gotEquals = true; 113 break; 114 } 115 i++; 116 } 117 118 // Scan forward for start of contents 119 i++; 120 while (i < line.length()) { 121 if (!Character.isWhitespace(line.charAt(i))) { 122 break; 123 } 124 i++; 125 } 126 contentsBegin = i; 127 128 // Scan *backward* for end of contents 129 i = line.length() - 1; 130 while (i >= 0) { 131 if (!Character.isWhitespace(line.charAt(i))) { 132 break; 133 } 134 } 135 contentsEnd = i+1; 136 137 // Now do consistency check 138 if (!((nameBegin < nameEnd) && 139 (nameEnd < contentsBegin) && 140 (contentsBegin < contentsEnd) && 141 (gotEquals == true))) { 142 throw new FileFormatException( 143 "Expected \"macroname = value\", " + 144 "but found: " + line 145 ); 146 } 147 148 String name = line.substring(nameBegin, nameEnd); 149 String contents = line.substring(contentsBegin, 150 contentsEnd); 151 addMacro(name, contents); 152 } 153 } 154 } while (line != null); 155 reader.close(); 156 } 157 158 /** Throws IllegalArgumentException if passed token is illegally 159 formatted */ 160 public String expand(String token) 161 throws IllegalArgumentException { 162 // the token may contain one or more <macroName>'s 163 164 String out = ""; 165 166 // emacs lingo 167 int mark = 0; 168 int point = 0; 169 170 int len = token.length(); 171 172 if (len == 0) 173 return out; 174 175 do { 176 // Scan "point" forward until hitting either the end of 177 // the string or the beginning of a macro 178 if (token.charAt(point) == '<') { 179 // Append (point - mark) to out 180 if ((point - mark) != 0) { 181 out += token.substring(mark, point); 182 } 183 mark = point + 1; 184 // Scan forward from point for right bracket 185 point++; 186 while ((point < len) && 187 (token.charAt(point) != '>')) { 188 point++; 189 } 190 if (point == len) { 191 throw new IllegalArgumentException( 192 "Could not find right angle-bracket in token " + token 193 ); 194 } 195 String name = token.substring(mark, point); 196 if (name == null) { 197 throw new IllegalArgumentException( 198 "Empty macro in token " + token 199 ); 200 } 201 try { 202 String contents = lookup(name); 203 out += contents; 204 point++; 205 mark = point; 206 } catch (NoSuchElementException e) { 207 throw new IllegalArgumentException( 208 "Unknown macro " + name + " in token " + token 209 ); 210 } 211 } else { 212 point++; 213 } 214 } while (point != len); 215 216 if (mark != point) { 217 out += token.substring(mark, point); 218 } 219 220 return out; 221 } 222 223 public MacroDefinitions copy() { 224 MacroDefinitions ret = new MacroDefinitions(); 225 for (Iterator iter = macros.iterator(); 226 iter.hasNext(); ) { 227 Macro orig = (Macro) iter.next(); 228 Macro macro = new Macro(); 229 macro.name = orig.name; 230 macro.contents = orig.contents; 231 ret.macros.add(macro); 232 } 233 return ret; 234 } 235 236 public void setAllMacroBodiesTo(String s) { 237 for (Iterator iter = macros.iterator(); 238 iter.hasNext(); ) { 239 Macro macro = (Macro) iter.next(); 240 macro.contents = s; 241 } 242 } 243 244 /** This returns an Iterator of Macros. You should not mutate the 245 returned Macro objects or use the Iterator to remove 246 macros. */ 247 public Iterator getMacros() { 248 return macros.iterator(); 249 } 250 251 private void error(String text) throws FileFormatException { 252 throw new FileFormatException( 253 "Expected \"macroname = value\", but found: " + text 254 ); 255 } 256 }