1 24 25 32 package org.objectweb.util.cpp.lib; 33 34 import java.io.BufferedReader ; 35 import java.io.File ; 36 import java.io.FileInputStream ; 37 import java.io.FilterInputStream ; 38 import java.io.IOException ; 39 import java.io.InputStream ; 40 import java.io.InputStreamReader ; 41 import java.io.OutputStream ; 42 import java.util.Enumeration ; 43 import java.util.StringTokenizer ; 44 import java.util.Hashtable ; 45 import java.util.Vector ; 46 import java.util.Stack ; 47 48 64 65 public class JPP { 66 private static final int JPP_INST_NB = 9; 67 public static final int NO_JPP_INST = -1; 68 public static final int INST_INCLUDE = 0; 69 public static final int INST_DEFINE = 1; 70 public static final int INST_IFDEF = 2; 71 public static final int INST_IFNDEF = 3; 72 public static final int INST_IF = 4; 73 public static final int INST_ELSE = 5; 74 public static final int INST_ELIF = 6; 75 public static final int INST_ENDIF = 7; 76 public static final int INST_UNDEF = 8; 77 78 public static final int BUFSIZE = 1024; 79 80 static final String [] INST_TOKEN = 81 { "#include","#define","#ifdef","#ifndef","#if","#else","#elif","#endif","#undef" }; 82 private static final String JAVA_DELIM = " \t\n\r;,.{}()[]+-*/%<>=&|!?:#"; 83 84 private static final String NULLSTRING = ""; 85 private static final Object NULLSCOPE = new Object (); 86 private static final Object IFSCOPE = new Object (); 87 private static final Object ELSESCOPE = new Object (); 88 89 Hashtable defined_names = new Hashtable (); 90 int nb_defs = 0; 91 92 private static int jppToken(String nm) { 93 for (int i = 0;i<JPP_INST_NB;i++) if (nm.startsWith(INST_TOKEN[i])) return i; 94 return -1; 95 } 96 97 private JPPExpandedStream jpp_fIn; 98 private OutputStream jpp_fOut; 99 private int errorNumber = 0; 100 101 105 106 static class JPPExpandedStream { 107 Vector iDirs = null; 108 109 Stack fStack = null; 110 Stack nameStack = null; 111 Stack nbStack = null; 112 113 BufferedReader fCur = null; 115 String nameCur = null; 116 int nbCur = -1; 117 118 119 JPPExpandedStream (String fileName, Vector includeDirs) throws java.io.IOException { 120 fCur = new BufferedReader (new InputStreamReader (new FileInputStream (fileName))); 122 iDirs = includeDirs; 123 fStack = new Stack (); 124 nameStack = new Stack (); 125 nbStack = new Stack (); 126 nameCur = fileName; 127 nbCur = 0; 128 } 129 130 String readLine(boolean dont_include_file) throws java.io.IOException { 131 String line = fCur.readLine(); 132 nbCur++; 133 134 if (line == null) { 135 if (!fStack.empty()) { 136 fCur.close(); 137 nbCur = ((Integer ) nbStack.pop()).intValue(); 138 line = "# "+nbCur+" "+"\""+nameCur+"\""+" 2"; 139 nameCur = (String ) nameStack.pop(); 140 fCur = (BufferedReader ) fStack.pop(); 141 } 142 } else { 143 if (line.startsWith("#include")) { 144 if(dont_include_file) 145 return ""; 146 StringTokenizer stLine = new StringTokenizer (line); 147 stLine.nextToken(); 148 String fiName = stLine.nextToken(); 149 fiName = fiName.substring(1,fiName.length()-1); 150 String fiNameWithPath = this.includeFileName(fiName); 151 152 if (fiNameWithPath == null) { 153 System.err.println(nameCur+":"+nbCur+":1: " + fiName + ": No such file or directory"); 154 return ""; 155 } 156 else { 157 fStack.push(fCur); 158 nameStack.push(nameCur); 159 nbStack.push(new Integer (nbCur)); 160 161 fCur = new BufferedReader (new InputStreamReader (new FileInputStream (fiNameWithPath))); 163 nameCur = new String (fiNameWithPath); 164 line = "# "+nbCur+" "+"\""+fiNameWithPath+"\""+" 1"; 165 nbCur = 0; 166 } 167 } 168 } 169 170 return(line); 171 } 172 173 private String includeFileName(String fName) { 174 String fiName = null; 175 Enumeration dirs = iDirs.elements(); 176 while (dirs.hasMoreElements()) { 177 fiName = new String ((String )dirs.nextElement()+File.separatorChar+fName); 178 File f = new File (fiName); 179 if (f.exists()) return fiName; 180 } 181 return(null); 182 } 183 184 String getFileName() { return(nameCur); } 185 int getLineNumber() { return(nbCur); } 186 void close() throws java.io.IOException { fCur.close(); } 187 } 188 189 192 193 static class JPPInputStream extends FilterInputStream { 194 public static final int BUFSIZE = 1024; 195 public static final String NULLSTRING = ""; 196 197 byte[] buffer = new byte[BUFSIZE]; 198 boolean isMacFile; 199 200 public JPPInputStream(InputStream iS,boolean isM) { super(iS); isMacFile = isM; } 201 public JPPInputStream(InputStream iS) { this(iS,false); } 202 203 public int read() throws IOException { 204 return super.read(); 205 } 206 207 public String readLine() throws IOException { 208 int i = readLine(buffer); 209 if (i == -1) return null; 210 else return new String (buffer,0,i); 211 } 212 213 public int readLine(byte[] buf) throws IOException { 214 boolean escaped = false; 215 boolean CRLFEscaped = false; 216 boolean endWhile = false; 217 int i = -1,car = 0,maxL = buf.length-1; 218 219 while(!endWhile && i<maxL && (car = read())!= -1) { 220 switch(car) { 221 default : 222 if (escaped) { 223 buf[++i] = (byte) '\\'; 224 escaped = false; 225 } 226 buf[++i] = (byte) car; 227 if (CRLFEscaped) CRLFEscaped = false; 228 break; 229 case '\\' : 230 if (escaped) { 231 buf[++i] = (byte) '\\'; 232 buf[++i] = (byte) '\\'; 233 } 234 escaped = !escaped; 235 if (CRLFEscaped) CRLFEscaped = false; 236 break; 237 case '\r' : case '\n' : 238 if (!escaped) { 239 if (!CRLFEscaped) endWhile = true; 240 else CRLFEscaped = false; 241 } 242 else if (!CRLFEscaped) CRLFEscaped = true; 243 else CRLFEscaped = false; 244 break; 245 } 246 } 247 if (i>= 0 || endWhile) return i+1; else return -1; 248 } 249 } 250 251 259 260 public JPP(String fileNameIn, OutputStream outS, Vector includeDirs, Hashtable defNames) 261 throws java.io.IOException { 262 jpp_fIn = new JPPExpandedStream(fileNameIn, includeDirs); 263 jpp_fOut = outS; 264 defined_names = defNames; 265 } 266 267 public boolean preprocess() throws java.io.IOException { 268 String line = null; 269 int negTest = 0,posTest = 0; 270 Stack ifScope = new Stack (); 271 Object curScope = NULLSCOPE; 272 ifScope.push(curScope); 273 274 while(true) { 275 line = jpp_fIn.readLine(negTest>0); 276 if (line == null) { 277 jpp_fIn.close(); 278 return (errorNumber == 0); 279 } 280 281 StringTokenizer stLine; 282 String nom1,nom2; 283 284 switch(jppToken(line)) { 285 case INST_DEFINE : 286 if (negTest>0) break; 287 stLine = new StringTokenizer (line.trim()); 288 stLine.nextToken(); 289 if (stLine.hasMoreTokens()) nom1 = stLine.nextToken(); 290 else { 291 printErrorMsg(jpp_fIn,"Illegal empty definition of preprocessor variable",true); 292 break; 293 } 294 if (stLine.hasMoreTokens()) { 295 nom2 = stLine.nextToken(); 296 while (stLine.hasMoreTokens()) nom2 = nom2 + " " + stLine.nextToken(); 297 } else { 298 nom2 = NULLSTRING; 299 } 300 if (defined_names.containsKey(nom1)) { 301 printErrorMsg(jpp_fIn,"Redefinition of preprocessor variable "+nom1,false); 302 } else { 303 nb_defs++; 304 } 305 defined_names.put(nom1,nom2); 306 break; 307 case INST_UNDEF : 308 if (negTest>0) break; 309 stLine = new StringTokenizer (line); 310 stLine.nextToken(); 311 if (stLine.hasMoreTokens()) nom1 = stLine.nextToken(); 312 else { 313 printErrorMsg(jpp_fIn,"Illegal empty (un)definition of preprocessor variable",true); 314 break; 315 } 316 if (defined_names.containsKey(nom1)) { 317 defined_names.remove(nom1); 318 nb_defs--; 319 } else { 320 printErrorMsg(jpp_fIn,"(un)definition of unknown preprocessor variable "+nom1,false); 321 } 322 break; 323 case INST_IFDEF : 324 curScope = IFSCOPE; 325 ifScope.push(curScope); 326 if (negTest>0) { negTest++; break; } 327 stLine = new StringTokenizer (line); 328 stLine.nextToken(); 329 if (stLine.hasMoreTokens()) nom1 = stLine.nextToken(); 330 else { 331 printErrorMsg(jpp_fIn,"Illegal empty #ifdef test of preprocessor variable",true); 332 break; 333 } 334 if (defined_names.containsKey(nom1)) posTest++; else negTest++; 335 break; 336 case INST_IFNDEF : 337 curScope = IFSCOPE; 338 ifScope.push(curScope); 339 if (negTest>0) { negTest++; break; } 340 stLine = new StringTokenizer (line); 341 stLine.nextToken(); 342 if (stLine.hasMoreTokens()) nom1 = stLine.nextToken(); 343 else { 344 printErrorMsg(jpp_fIn,"Illegal empty #ifndef test of preprocessor variable",true); 345 break; 346 } 347 if (!defined_names.containsKey(nom1)) posTest++; else negTest++; 348 break; 349 case INST_IF : 350 printErrorMsg(jpp_fIn,"Unsupported #if processor directive",true); 351 break; 352 case INST_ENDIF : 353 if (curScope == NULLSCOPE) { 354 printErrorMsg(jpp_fIn,"Unbalanced #endif processor directive",true); 355 break; 356 } 357 curScope =ifScope.pop(); 358 if (negTest>0) negTest--; 359 else if (posTest>0) posTest--; 360 break; 361 case INST_ELIF : 362 printErrorMsg(jpp_fIn,"Unsupported #elif processor directive ",true); 363 break; 364 case INST_ELSE : 365 if (curScope != IFSCOPE) { 366 printErrorMsg(jpp_fIn,"Unbalanced #else processor directive ",true); 367 break; 368 } 369 ifScope.pop(); 370 curScope = ELSESCOPE; 371 ifScope.push(curScope); 372 if (negTest>0) negTest--; 373 else { negTest++; posTest--; } 374 break; 375 case NO_JPP_INST : 376 if (negTest>0) break; 377 if (nb_defs == 0) { 378 jpp_fOut.write(line.getBytes()); 379 jpp_fOut.write('\n'); 380 } 381 else { 382 stLine = new StringTokenizer (line.trim(),JAVA_DELIM,true); 383 String line2; 384 if (stLine.hasMoreTokens()) { 385 line2 = ""; 386 while (stLine.hasMoreTokens()) { 387 String tok2 = stLine.nextToken(); 388 String tok3 = (String ) defined_names.get(tok2); 389 if (tok3 == null) line2 = line2+tok2; 390 else line2 = line2+tok3; 391 } 392 jpp_fOut.write(line2.getBytes()); 393 } 394 jpp_fOut.write('\n'); 395 } 396 break; 397 case INST_INCLUDE : 398 printErrorMsg(jpp_fIn,"Unexpected #include directive",true); 399 } 400 } 401 } 402 403 void printErrorMsg(JPPExpandedStream jE,String msg,boolean isErr) { 404 System.err.println(jE.getFileName()+":"+jE.getLineNumber()+":1: "+msg); 405 if (isErr) errorNumber++; 406 } 407 } 408 | Popular Tags |