001 /* 002 Copyright (C) 2002 Julien van Malderen 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU Lesser General Public License as 006 published by the Free Software Foundation; either version 2 of the 007 License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU Lesser General Public License for more details. 013 014 You should have received a copy of the GNU Lesser General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 017 018 package org.objectweb.jac.util.preparse; 019 020 import java.io.BufferedReader; 021 import java.io.BufferedWriter; 022 import java.io.File; 023 import java.io.FileInputStream; 024 import java.io.FileOutputStream; 025 import java.io.FileReader; 026 import java.io.InputStreamReader; 027 import java.io.OutputStream; 028 import java.io.OutputStreamWriter; 029 import java.io.Writer; 030 import java.util.Iterator; 031 import java.util.Vector; 032 033 public class Preparse 034 { 035 public static final String CFGNAME = "preparse.cfg"; 036 public static final String EXTENSION = ".modified"; 037 038 Vector tokenList = new Vector(); 039 040 // if in a string 041 boolean isInString = false; 042 043 // if in a quote 044 boolean isInQuote = false; 045 046 // if the next char is escaped 047 boolean isEscaped = false; 048 049 // number of opened parentheses 050 int parenthLvl = 0; 051 052 // initial level of parenth before function ro remove call 053 int endLvl = -1; 054 055 protected void writeToOutput(String str, Writer output) 056 throws Exception 057 { 058 output.write(str); 059 } 060 061 /** 062 * @param line line of text 063 * @param i offset in line of text 064 * @param output 065 */ 066 protected int treat(String line, int i, Writer output) 067 throws Exception 068 { 069 int lineLength = line.length(); 070 071 //System.out.println("treat: `"+line+"' offset="+i+", length="+lineLength); 072 073 if (!isInString) 074 { 075 Iterator j = tokenList.iterator(); 076 while (j.hasNext()) 077 { 078 Config token = (Config) j.next(); 079 080 int tokenLength = token.token.length(); 081 //System.out.println(" token="+token.token+", tokenLength="+tokenLength); 082 if ((tokenLength < lineLength - i + 1) 083 && (line.substring(i, i + tokenLength) 084 .equals(token.token))) 085 { 086 if (token.hasArguments) 087 endLvl = parenthLvl; 088 writeToOutput("/* a " + token.token + " was here */", output); 089 //System.out.println(" found token "+token.token); 090 return (i + tokenLength - 1); 091 } 092 } 093 } 094 /* 095 System.out.println("treat: `"+line.charAt(i)+"' isEscaped="+isEscaped+ 096 "; isInQuote="+isInQuote); 097 */ 098 switch (line.charAt(i)) 099 { 100 case '\"' : 101 if ((!isEscaped) && (!isInQuote)) { 102 isInString = !isInString; 103 //System.out.println("Found \" -> "+isInString); 104 } 105 isEscaped = false; 106 break; 107 case '\'': 108 if ((!isInString) && (!isEscaped)) { 109 isInQuote = !isInQuote; 110 //System.out.println("Found ' -> "+isInQuote); 111 } 112 isEscaped = false; 113 break; 114 case '\\': 115 if (isInString || isInQuote) { 116 isEscaped = true; 117 //System.out.println("Found \\ -> "+isEscaped); 118 } 119 break; 120 case '(': 121 if (!isInString) { 122 parenthLvl++; 123 //System.out.println("Found ( -> "+parenthLvl+"/"+endLvl); 124 } 125 isEscaped = false; 126 break; 127 case ')': 128 if (!isInString) 129 { 130 parenthLvl--; 131 132 //System.out.println("Found ) -> "+parenthLvl+"/"+endLvl); 133 134 if ((endLvl != -1) && (parenthLvl == endLvl)) 135 { 136 endLvl = -1; 137 return i; 138 } 139 } 140 isEscaped = false; 141 break; 142 default: 143 isEscaped = false; 144 break; 145 } 146 147 if (endLvl == -1) { 148 output.write(line.charAt(i)); 149 //System.out.println("print `"+line.charAt(i)+"'"); 150 } else { 151 //System.out.println("skip `"+line.charAt(i)+"'"); 152 } 153 return i; 154 } 155 156 int lineNumber = 0; 157 158 public void parse(ParseInput input, Writer output) 159 { 160 String line; 161 162 lineNumber = 0; 163 try { 164 line = input.readLine(); 165 //System.out.println("read line ("+isInString+","+isInQuote+"=: "+line); 166 lineNumber++; 167 while (line != null) 168 { 169 int lineLength = line.length(); 170 171 for (int i = 0; i < lineLength ; i++) 172 { 173 if ((!isInString) && 174 ((line.charAt(i) == '/') && (i < lineLength - 1))) 175 { 176 // skipping '//' comments 177 if (line.charAt(i + 1) == '/') 178 { 179 //System.out.println("Found // comment"); 180 writeToOutput(line.substring(i), output); 181 break; 182 } 183 184 // skipping '/* */' comments 185 else if (line.charAt(i + 1) == '*') 186 { 187 //System.out.println("Found /* */ comment"); 188 writeToOutput(input.skipTo(i, "*/"), output); 189 break; 190 } 191 else 192 i = treat(line, i, output); 193 } 194 else 195 i = treat(line, i, output); 196 } 197 if (!input.isModified()) 198 output.write('\n'); 199 line = input.readLine(); 200 lineNumber++; 201 //System.out.println("read line ("+isInString+"): "+line); 202 } 203 } 204 catch (Exception e) 205 { 206 e.printStackTrace(); 207 } 208 } 209 210 protected String[] getTokens(String str) 211 throws Exception 212 { 213 if (str == null) 214 return null; 215 216 if (str.length() == 0) 217 return new String[] {}; 218 219 Vector result = new Vector(); 220 221 int begin = 0; 222 int end = 0; 223 224 int strLength = str.length(); 225 226 while (begin < strLength) 227 { 228 while ((begin < strLength) 229 && ((str.charAt(begin) == ' ') || (str.charAt(begin) == '\t'))) 230 begin++; 231 232 end = begin; 233 while ((end < strLength) 234 && ((str.charAt(end) != ' ') && (str.charAt(end) != '\t'))) 235 end++; 236 result.add(str.substring(begin, end)); 237 begin = end + 1; 238 } 239 return (String[]) result.toArray(new String[] {}); 240 } 241 242 public void readConfigFile(String filename) 243 throws Exception 244 { 245 try { 246 BufferedReader config = 247 new BufferedReader( 248 new FileReader(filename)); 249 250 String line = config.readLine(); 251 while (line != null) 252 { 253 line = line.trim(); 254 if ((line.length() > 0) && (line.charAt(0) != '#')) { 255 String[] tokens = getTokens(line); 256 tokenList.add(new Config(tokens[0],!tokens[1].equals("0"))); 257 } 258 line = config.readLine(); 259 } 260 config.close(); 261 } 262 catch (Exception e) 263 { 264 e.printStackTrace(); 265 throw new Exception ("problem with config file '" 266 + filename 267 +"' : " + e.getMessage()); 268 } 269 } 270 271 272 public String modifName(String javaName) 273 { 274 int i = javaName.length() - 1; 275 while ((i >= 0) && (javaName.charAt(i) != '.')) 276 i--; 277 if (i == 0) 278 return javaName + Preparse.EXTENSION; 279 return javaName.substring(0, i) + Preparse.EXTENSION; 280 } 281 282 /** 283 * Usage: java org.objectweb.jac.util.preparse.PreParse <config_file> <dest_dir> [<file> ...] 284 */ 285 public static void main(String[] args) 286 throws Exception 287 { 288 Preparse parser = new Preparse(); 289 290 if (args.length == 0) 291 { 292 System.err.println("Error: a configuration file must be specified"); 293 return; 294 } 295 296 parser.readConfigFile(args[0]); 297 298 String msg = new String(); 299 for (int i = 1; i < args.length; i++) 300 msg += args[i] + " "; 301 302 File destDir = new File(args[1]); 303 if (!destDir.exists()) { 304 destDir.mkdirs(); 305 } 306 307 for (int i=2; i<args.length; i++) 308 { 309 try { 310 //System.out.println("Preparse: Treating " + args[i] + " ..."); 311 File inputFile = new File(args[i]); 312 File outputFile = new File(destDir,args[i]); 313 if (inputFile.lastModified()>outputFile.lastModified()) { 314 ParseInput input = 315 new ParseInput( 316 new InputStreamReader( 317 new FileInputStream(inputFile), 318 "UTF-8")); 319 System.out.println("Preparse: "+inputFile+" -> "+outputFile); 320 File outputDir = outputFile.getParentFile(); 321 if (!outputDir.exists()) { 322 outputDir.mkdirs(); 323 } 324 Writer output = 325 new BufferedWriter( 326 new OutputStreamWriter( 327 new FileOutputStream(outputFile), 328 "UTF-8")); 329 330 parser.parse(input, output); 331 input.close(); 332 output.close(); 333 } 334 } 335 catch (Exception e) { 336 System.err.println("Error: " + e.getMessage()); 337 } 338 } 339 } 340 341 static class Config { 342 public String token; 343 public boolean hasArguments; 344 public Config(String token, boolean hasArguments) { 345 this.token = token; 346 this.hasArguments = hasArguments; 347 } 348 } 349 }