1 4 package gnu.kawa.util; 5 import java.io.*; 6 import java.util.*; 7 8 9 10 public class PreProcess 11 { 12 Hashtable keywords = new Hashtable(); 15 16 String filename; 17 int lineno; 18 19 void error(String msg) 20 { 21 System.err.println(filename+':'+lineno+": "+msg); 22 System.exit(-1); 23 } 24 25 public void filter (String filename) throws Throwable 26 { 27 this.filename = filename; 28 boolean changed = false; 29 BufferedInputStream in 30 = new BufferedInputStream(new FileInputStream(filename)); 31 32 byte[] buf = new byte[2000]; 33 int len = 0;; 34 int lineStart = 0; 35 int dataStart = -1; 36 int cmdLine= 0; 37 lineno = 1; 38 int commentAt = -1; 40 int curIndent = 0; 41 int nesting = 0; 42 int skipNesting = 0; 45 String cmd = null; 46 int changedLine = 0; for (;;) 48 { 49 int c = in.read(); 50 if (c < 0) 51 break; 52 if (len + 10 >= buf.length) { 54 byte[] nbuf = new byte[2 * len]; 55 System.arraycopy(buf, 0, nbuf, 0, len); 56 buf = nbuf; 57 } 58 if (c == '\n' && len > 0 && buf[len-1] == '\r') 59 { 60 buf[len++] = (byte) c; 61 continue; 62 } 63 if (commentAt >= 0 && dataStart < 0 && changedLine <= 0 64 && c != '\r' && c != '\n' 65 && (commentAt == curIndent 66 || (c != ' ' && c != '\t'))) 67 { 68 boolean doComment; 69 if (c == '/') 70 { 71 in.mark(100); 77 int d = in.read(); 78 if (d == '/') 79 doComment = false; 80 else if (d == '*') 81 { 82 do { d = in.read(); } while (d == ' ' || d == '\t'); 83 doComment = d != '#'; 84 } 85 else 86 doComment = true; 87 in.reset(); 88 } 89 else 90 doComment = true; 91 if (doComment) 92 { 93 buf[len++] = '/'; 94 buf[len++] = '/'; 95 buf[len++] = ' '; 96 changedLine = 1; 97 changed = true; 98 } 99 } 100 if (c != ' ' && c != '\t' && dataStart < 0) 101 { 102 dataStart = len; 104 if (nesting > 0 && commentAt != curIndent && c == '/') 105 { 106 c = in.read(); 107 if (c < 0) 108 break; 109 else if (c != '/') 110 buf[len++] = '/'; 111 else 112 { 113 c = in.read(); 114 if (c < 0) 115 break; 116 changedLine = -1; 117 changed = true; 118 if (c == ' ') 119 { 120 c = in.read(); 121 if (c == ' ' || c == '\t') 122 dataStart = -1; 123 } 124 } 125 } 126 } 127 buf[len] = (byte) c; 128 len++; 129 if (c == '\r' || c == '\n') 130 { 131 int firstNonSpace = -1; 132 int lastNonSpace = 0; 133 for (int i = lineStart; i < len-1; i++) 134 { 135 if (buf[i] != ' ' && buf[i] != '\t') 136 { 137 lastNonSpace = i; 138 if (firstNonSpace < 0) 139 firstNonSpace = i; 140 } 141 } 142 if (lastNonSpace - firstNonSpace >= 4 143 && buf[firstNonSpace] == '/' 144 && buf[firstNonSpace+1] == '*' 145 && buf[lastNonSpace-1] == '*' 146 && buf[lastNonSpace] == '/') 147 { 148 firstNonSpace += 2; 149 while (firstNonSpace < lastNonSpace 150 && buf[firstNonSpace] == ' ') 151 firstNonSpace++; 152 lastNonSpace -= 2; 153 while (lastNonSpace > firstNonSpace 154 && buf[lastNonSpace] == ' ') 155 lastNonSpace--; 156 if (buf[firstNonSpace] == '#') 157 { 158 String cmnt = new String (buf, firstNonSpace, 159 lastNonSpace - firstNonSpace + 1, 160 "ISO-8859-1"); 161 int sp = cmnt.indexOf(' '); 162 String rest; 163 Object binding; 164 cmdLine = lineno; 165 if (sp > 0) 166 { 167 cmd = cmnt.substring(0, sp); 168 rest = cmnt.substring(sp).trim(); 169 binding = keywords.get(rest); 170 } 171 else 172 { 173 cmd = cmnt; 174 rest = ""; 175 binding = null; 176 } 177 if ("#ifdef".equals(cmd) || "#ifndef".equals(cmd)) 178 { 179 if (binding == null) 180 { 181 System.err.println(filename+":"+lineno 182 +": warning - undefined keyword: "+rest); 183 binding = Boolean.FALSE; 184 } 185 nesting++; 186 if (skipNesting > 0) 187 commentAt = curIndent; 188 else if ((cmd.charAt(3) == 'n') 189 != (binding == Boolean.FALSE)) 190 { 191 commentAt = curIndent; 192 skipNesting = nesting; 193 } 194 } 195 else if ("#else".equals(cmd)) 196 { 197 if (nesting == 0) 198 error("unexpected "+cmd); 199 else if (nesting == skipNesting) 200 { 201 commentAt = -1; 202 skipNesting = 0; 203 } 204 else 205 { 206 commentAt = curIndent; 207 if (skipNesting == 0) 208 skipNesting = nesting; 209 } 210 } 211 else if ("#endif".equals(cmd)) 212 { 213 if (nesting == 0) 214 error("unexpected "+cmd); 215 if (nesting == skipNesting) 216 { 217 skipNesting = 0; 218 commentAt = -1; 219 } 220 else if (skipNesting > 0) 221 commentAt = curIndent; 222 nesting--; 223 } 224 else 225 error("unknown command: "+cmnt); 226 } 227 } 228 lineStart = len; 229 dataStart = -1; 230 curIndent = 0; 231 lineno++; 232 changedLine = 0; 233 } 234 else if (dataStart < 0) 235 curIndent = c == '\t' ? (curIndent + 8) & ~7 : curIndent + 1; 236 } 237 if (nesting != 0) 238 { 239 lineno = cmdLine; 240 error("unterminated "+cmd); 241 } 242 if (changed) 243 { 244 FileOutputStream out = new FileOutputStream(filename); 245 out.write(buf, 0, len); 246 out.close(); 247 System.err.println("Pre-processed "+filename); 248 } 249 } 250 251 public static void main (String [] args) 252 { 253 PreProcess pp = new PreProcess(); 254 255 pp.keywords.put("true", Boolean.TRUE); 256 pp.keywords.put("false", Boolean.FALSE); 257 258 for (int i = 0; i < args.length; i++) 259 { 260 String arg = args[i]; 261 if (arg.charAt(0) == '+') 262 pp.keywords.put(arg.substring(1), Boolean.TRUE); 263 else if (arg.charAt(0) == '-') 264 { 265 int eq = arg.indexOf('='); 266 if (eq > 1) 267 { 268 String keyword 269 = arg.substring(arg.charAt(1) == '-' ? 2 :1, eq); 270 String value = arg.substring(eq+1); 271 Boolean b = Boolean.FALSE; 272 if (value.equalsIgnoreCase("true")) 273 b = Boolean.TRUE; 274 else if (! value.equalsIgnoreCase("false")) 275 { 276 System.err.println("invalid value "+value+" for "+keyword); 277 System.exit(-1); 278 } 279 pp.keywords.put(keyword, b); 280 } 281 else 282 pp.keywords.put(arg.substring(1), Boolean.FALSE); 283 } 284 else 285 { 286 try 287 { 288 pp.filter(arg); 289 } 290 catch (Throwable ex) 291 { 292 System.err.println("caught "+ex); 293 ex.printStackTrace(); 294 System.exit(-1); 295 } 296 } 297 } 298 } 299 } 300 | Popular Tags |