1 5 package org.h2.tools.code; 6 7 8 import java.io.*; 9 import java.util.*; 10 11 15 public class CodeSwitch { 16 private boolean recurse; 17 private ArrayList list = new ArrayList(); 18 private ArrayList switchOn = new ArrayList(); 19 private ArrayList switchOff = new ArrayList(); 20 private ArrayList switches = new ArrayList(); 21 private byte[] file; 22 private String endOfLine; 23 private ArrayList lines; 24 private boolean changed; 25 26 public static void main(String [] argv) { 27 (new CodeSwitch()).run(argv); 28 } 29 30 private void run(String [] a) { 31 if (a.length == 0) { 32 showUsage(); 33 return; 34 } 35 boolean path = false; 36 recurse = true; 37 for (int i = 0; i < a.length; i++) { 38 String p = a[i]; 39 if (p.startsWith("+")) { 40 switchOn.add(p.substring(1)); 41 } else if (p.startsWith("-r+")) { 42 recurse = true; 44 } else if (p.startsWith("-r-")) { 45 recurse = false; 46 } else if (p.startsWith("-")) { 47 switchOff.add(p.substring(1)); 48 } else { 49 addDir(p, true); 50 path = true; 51 } 52 } 53 if (!path) { 54 printError("no path specified"); 55 showUsage(); 56 } 57 process(); 58 if (switchOff.size() == 0 && switchOn.size() == 0) { 59 printSwitches(); 60 } 61 } 62 63 private void showUsage() { 64 String className = getClass().getName(); 65 System.out.println("Usage: java " + className 66 + " [-r+] [-r-] paths [+|-][labels]"); 67 System.out.println("If no labels are specified then all used"); 68 System.out.println("labels in the source code are shown."); 69 System.out.println("-r+ recurse subdirectories (default)"); 70 System.out.println("-r- do not recurse subdirectories"); 71 System.out.println("Use +MODE to switch on the things labeld MODE"); 72 System.out.println("Use -MODE to switch off the things labeld MODE"); 73 System.out 74 .println("Path: Any number of path or files may be specified."); 75 System.out 76 .println(" Use . for the current directory (including sub-directories)."); 77 System.out.println("Example: java " + className + " +JAVA2 ."); 78 System.out 79 .println("This example switches on code labeled JAVA2 in all *.java files"); 80 System.out.println("in the current directory and all subdirectories."); 81 } 82 83 private void process() { 84 int len = list.size(); 85 for (int i = 0; i < len; i++) { 86 String fileName = (String ) list.get(i); 87 if (!processFile(fileName)) { 88 System.out.println("in file " + fileName 89 + " - this file is skipped"); 90 } 91 } 92 } 93 94 private void printSwitches() { 95 System.out.println("Used labels:"); 96 for (int i = 0; i < switches.size(); i++) { 97 System.out.println((String ) (switches.get(i))); 98 } 99 } 100 101 private void addDir(String path, boolean recurseMore) { 102 File f = new File(path); 103 if (f.isFile() && path.endsWith(".java")) { 104 list.add(path); 105 } else if (f.isDirectory()) { 106 if (recurse || recurseMore) { 107 String [] files = f.list(); 109 for (int i = 0; i < files.length; i++) { 110 addDir(path + File.separatorChar + files[i], false); 111 } 112 } 113 } 114 } 115 116 private void breakIntoLines() { 118 lines = new ArrayList(); 119 int len = file.length; 120 int last = 0; 121 int cr = 0, lf = 0, crlf = 0; 122 for (int i = 0; i < len; i++) { 123 byte c = file[i]; 124 if (c == '\r' || c == '\n') { 125 if (c == '\r') { 126 if (i < len - 1 && file[i + 1] == '\n') { 127 i++; 128 crlf++; 129 } else { 130 cr++; 131 } 132 } else { 133 lf++; 134 } 135 if (i < len) { 136 lines.add(new String (file, last, i - last + 1)); 137 last = i + 1; 138 } 139 } 140 } 141 if (cr > lf && cr > crlf) { 142 endOfLine = "\r"; 143 } else if (lf > crlf) { 144 endOfLine = "\n"; 145 } else { 146 endOfLine = "\r\n"; 147 } 148 lines.add(new String (file, last, len - last)); 149 } 150 151 private String getLine(int line) { 152 return (String ) lines.get(line); 153 } 154 155 private void insertLine(int line, String s) { 156 lines.add(line, s); 157 changed = true; 158 } 159 160 private void removeLine(int line) { 161 lines.remove(line); 162 changed = true; 163 } 164 165 private boolean processFile(String name) { 166 File f = new File(name); 167 boolean switchoff = false; 168 boolean working = false; 169 int state = 0; 170 try { 171 long rawLen = f.length(); 172 if (rawLen > Integer.MAX_VALUE) { 173 printError("Files bigger than Integer.MAX_VALUE are not supported"); 174 return false; 175 } 176 int len = (int) rawLen; 177 file = new byte[len]; 178 RandomAccessFile read = new RandomAccessFile(f, "r"); 179 read.readFully(file); 180 read.close(); 181 breakIntoLines(); 182 changed = false; 183 184 for (int i = 0; i < lines.size(); i++) { 185 String line = getLine(i); 186 String lineTrim = line.trim(); 187 if (working) { 188 if (lineTrim.startsWith("/*") || lineTrim.startsWith("*/")) { 189 removeLine(i); 190 i--; 191 continue; 192 } 193 } 194 if (lineTrim.startsWith("//#")) { 195 if (lineTrim.startsWith("//#ifdef ")) { 196 if (state != 0) { 197 printError("//#ifdef not allowed inside //#ifdef"); 198 return false; 199 } 200 state = 1; 201 String s = lineTrim.substring(9); 202 boolean switchedOn = false; 203 boolean switchedOff = false; 204 if (switchOn.indexOf(s) != -1) { 205 switchedOn = true; 206 } 207 if (switchOff.indexOf(s) != -1) { 208 switchedOff = true; 209 } 210 if (s.indexOf("&&") != -1) { 211 switchedOn = true; 212 s += "&&"; 213 while (s.length() > 0) { 214 int id = s.indexOf("&&"); 215 if (id == -1) { 216 break; 217 } 218 String s1 = s.substring(0, id).trim(); 219 s = s.substring(id + 2).trim(); 220 if (switches.indexOf(s1) == -1) { 221 switches.add(s1); 222 switchedOn = false; 223 } 224 if (switchOn.indexOf(s1) == -1) { 225 switchedOff = true; 226 switchedOn = false; 227 } 228 if (switchOff.indexOf(s1) != -1) { 229 switchedOff = true; 230 switchedOn = false; 231 } 232 } 233 } 234 if (switchedOn) { 235 working = true; 236 switchoff = false; 237 } else if (switchedOff) { 238 working = true; 239 insertLine(++i, "/*" + endOfLine); 240 switchoff = true; 241 } 242 if (switches.indexOf(s) == -1) { 243 switches.add(s); 244 } 245 } else if (lineTrim.startsWith("//#else")) { 246 if (state != 1) { 247 printError("//#else without //#ifdef"); 248 return false; 249 } 250 state = 2; 251 if (working) { 252 if (switchoff) { 253 insertLine(++i, "*/" + endOfLine); 254 switchoff = false; 255 } else { 256 insertLine(++i, "/*" + endOfLine); 257 switchoff = true; 258 } 259 } 260 } else if (lineTrim.startsWith("//#endif")) { 261 if (state == 0) { 262 printError("//#endif without //#ifdef"); 263 return false; 264 } 265 state = 0; 266 if (working && switchoff) { 267 insertLine(i++, "*/" + endOfLine); 268 } 269 working = false; 270 } 271 } 272 } 273 if (state != 0) { 274 printError("//#endif missing"); 275 return false; 276 } 277 if (changed) { 278 File fnew = new File(name + ".new"); 279 FileWriter write = new FileWriter(fnew); 280 for (int i = 0; i < lines.size(); i++) { 281 write.write(getLine(i)); 282 } 283 write.close(); 284 File fbak = new File(name + ".bak"); 285 fbak.delete(); 286 f.renameTo(fbak); 287 File fcopy = new File(name); 288 fnew.renameTo(fcopy); 289 fbak.delete(); 290 System.out.println(name); 291 } 292 return true; 293 } catch (Exception e) { 294 printError(e); 295 return false; 296 } 297 } 298 299 private static void printError(Exception e) { 300 e.printStackTrace(); 301 } 302 303 private static void printError(String s) { 304 System.out.println("ERROR: " + s); 305 } 306 } 307 308 | Popular Tags |