001 package escjava.ant; 002 003 import org.apache.tools.ant.BuildException; 004 import org.apache.tools.ant.Project; 005 import org.apache.tools.ant.taskdefs.Execute; 006 import org.apache.tools.ant.taskdefs.Javac; 007 import org.apache.tools.ant.taskdefs.LogStreamHandler; 008 import org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter; 009 import org.apache.tools.ant.types.Commandline; 010 import org.apache.tools.ant.types.Path; 011 import org.apache.tools.ant.util.FileUtils; 012 013 import java.io.File; 014 import java.io.FileWriter; 015 import java.io.IOException; 016 import java.io.PrintWriter; 017 018 /** 019 * Define an Escj compiler adapter. This class is only a very simple 020 * wrapper and does not try to implement of the command line options 021 * of escj. 022 * 023 * @author wsargent 024 * @version $Revision: 1.3 $ 025 * 026 * @since May 16, 2004 027 */ 028 public class ESCJavaTask extends DefaultCompilerAdapter 029 { 030 private FileUtils fileUtils = FileUtils.newFileUtils(); 031 032 /* (non-Javadoc) 033 * @see org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter#execute() 034 */ 035 public boolean execute() throws BuildException 036 { 037 if (super.attributes == null) 038 { 039 throw new BuildException("Null attributes"); 040 } 041 042 if (super.project == null) 043 { 044 throw new BuildException("Null project"); 045 } 046 047 Javac javac = getJavac(); 048 049 if (javac == null) 050 { 051 throw new BuildException("null javac"); 052 } 053 054 super.attributes.log("Using escj compiler", 3); 055 056 Path classpath = new Path(super.project); 057 058 if (super.bootclasspath != null) 059 { 060 classpath.append(super.bootclasspath); 061 } 062 063 classpath.addExtdirs(super.extdirs); 064 065 if ((super.bootclasspath == null) || (super.bootclasspath.size() == 0)) 066 { 067 super.includeJavaRuntime = true; 068 } 069 070 classpath.append(getCompileClasspath()); 071 072 if (super.compileSourcepath != null) 073 { 074 classpath.append(super.compileSourcepath); 075 } else 076 { 077 classpath.append(super.src); 078 } 079 080 Commandline cmd = new Commandline(); 081 String exec = javac.getExecutable(); 082 cmd.setExecutable((exec != null) ? exec : "java"); 083 084 String simplifyProperty = super.project.getProperty( 085 "build.compiler.simplify"); 086 087 // Make sure the simplify argument comes before... 088 if (simplifyProperty != null) 089 { 090 cmd.createArgument().setValue("-Dsimplify=" + simplifyProperty); 091 } 092 093 cmd.createArgument().setValue("-classpath"); 094 cmd.createArgument().setPath(classpath); 095 096 cmd.createArgument().setValue("escjava.Main"); 097 098 cmd.createArgument().setValue("-classpath"); 099 cmd.createArgument().setPath(classpath); 100 101 /* 102 if (super.deprecation) 103 { 104 cmd.createArgument().setValue("-deprecation"); 105 } 106 */ 107 /* 108 if (super.destDir != null) 109 { 110 cmd.createArgument().setValue("-d"); 111 cmd.createArgument().setFile(super.destDir); 112 } 113 */ 114 /* 115 if (super.encoding != null) 116 { 117 cmd.createArgument().setValue("-encoding"); 118 cmd.createArgument().setValue(super.encoding); 119 } 120 */ 121 /* 122 if (super.debug) 123 { 124 cmd.createArgument().setValue("-g"); 125 } 126 */ 127 /* 128 if (super.optimize) 129 { 130 cmd.createArgument().setValue("-O"); 131 } 132 */ 133 setCounterExample(cmd); 134 setDepend(cmd); 135 setEajava(cmd); 136 setEajml(cmd); 137 setEnableAssertions(cmd); 138 setLoopsafe(cmd); 139 setLoop(cmd); 140 setNoCheck(cmd); 141 setNoCautions(cmd); 142 setNoRedundancy(cmd); 143 setNoTrace(cmd); 144 setNoWarn(cmd); 145 setPxLog(cmd); 146 setPlainWarning(cmd); 147 setQuiet(cmd); 148 setRoutine(cmd); 149 setRoutineIndirect(cmd); 150 setSource(cmd); 151 setSourcePath(cmd); 152 setSuggest(cmd); 153 setSxLog(cmd); 154 setTarget(cmd); 155 setTypeCheck(cmd); 156 setUseVars(cmd); 157 setUseFcns(cmd); 158 setUseVarsForModelVars(cmd); 159 setUseFcnsForModelVars(cmd); 160 setWarn(cmd); 161 setVerbose(cmd); 162 163 // Set the -f value to use the files following. 164 cmd.createArgument().setValue("-f"); 165 166 addCurrentCompilerArgs(cmd); 167 168 int firstFileName = cmd.size(); 169 logAndAddFilesToCompile(cmd); 170 171 return executeExternalCompile(cmd.getCommandline(), firstFileName) == 0; 172 } 173 174 /** 175 * @param cmd 176 */ 177 private void setUseFcnsForModelVars(/*@ non_null @*/ Commandline cmd) throws BuildException 178 { 179 setTextArgument(cmd, "usefcnsformodelvars", "useFcnsForModelVars"); 180 } 181 182 /** 183 * @param cmd 184 */ 185 private void setUseVarsForModelVars(/*@ non_null @*/ Commandline cmd) throws BuildException 186 { 187 setTextArgument(cmd, "usevarsformodelvars", "useVarsForModelVars"); 188 } 189 190 /** 191 * @param cmd 192 */ 193 private void setWarn(/*@ non_null @*/ Commandline cmd) throws BuildException 194 { 195 setTextArgument(cmd, "warn", "warn"); 196 } 197 198 /** 199 * @param cmd 200 */ 201 private void setUseFcns(/*@ non_null @*/ Commandline cmd) throws BuildException 202 { 203 setArgument(cmd, "usefcns", "useFcns"); 204 } 205 206 /** 207 * @param cmd 208 */ 209 private void setRoutineIndirect(/*@ non_null @*/ Commandline cmd) throws BuildException 210 { 211 setTextArgument(cmd, "routineindirect", "routineIndirect"); 212 } 213 214 /** 215 * @param cmd 216 */ 217 private void setPlainWarning(/*@ non_null @*/ Commandline cmd) throws BuildException 218 { 219 setArgument(cmd, "plainwarning", "plainwarning"); 220 } 221 222 /** 223 * @param cmd 224 */ 225 private void setRoutine(/*@ non_null @*/ Commandline cmd) throws BuildException 226 { 227 String arg = "routine"; 228 setTextArgument(cmd, arg, arg); 229 } 230 231 /** 232 * @param cmd 233 */ 234 private void setLoop(/*@ non_null @*/ Commandline cmd) throws BuildException 235 { 236 String arg = "loop"; 237 setTextArgument(cmd, arg, arg); 238 } 239 240 /** 241 * Sets the -quiet option. 242 * 243 * @param cmd 244 */ 245 private void setQuiet(/*@ non_null @*/ Commandline cmd) throws BuildException 246 { 247 String arg = "quiet"; 248 setArgument(cmd, arg, arg); 249 } 250 251 private void setVerbose(/*@ non_null @*/ Commandline cmd) 252 { 253 if (super.verbose) 254 { 255 cmd.createArgument().setValue("-v"); 256 } 257 } 258 259 private void setDepend(/*@ non_null @*/ Commandline cmd) 260 { 261 if (super.depend) 262 { 263 cmd.createArgument().setValue("-depend"); 264 } 265 } 266 267 private void setTarget(/*@ non_null @*/ Commandline cmd) 268 { 269 if (super.target != null) 270 { 271 cmd.createArgument().setValue("-target"); 272 cmd.createArgument().setValue(super.target); 273 } 274 } 275 276 private void setNoWarn(/*@ non_null @*/ Commandline cmd) throws BuildException 277 { 278 if (super.attributes == null) 279 { 280 throw new BuildException("Null attributes"); 281 } 282 283 if (super.attributes.getNowarn()) 284 { 285 cmd.createArgument().setValue("-nowarn"); 286 } 287 } 288 289 private void setSource(/*@ non_null @*/ Commandline cmd) throws BuildException 290 { 291 if (super.attributes == null) 292 { 293 throw new BuildException("Null attributes"); 294 } 295 296 if (super.attributes.getSource() != null) 297 { 298 cmd.createArgument().setValue("-source"); 299 cmd.createArgument().setValue(super.attributes.getSource()); 300 } 301 } 302 303 private void setSourcePath(/*@ non_null @*/ Commandline cmd) throws BuildException 304 { 305 if (super.attributes == null) 306 { 307 throw new BuildException("Null attributes"); 308 } 309 310 if (super.attributes.getSourcepath() != null) 311 { 312 cmd.createArgument().setValue("-sourcepath"); 313 314 Path path = super.attributes.getSourcepath(); 315 String pathString = (path == null) ? null : path.toString(); 316 cmd.createArgument().setValue(pathString); 317 } 318 } 319 320 private void setSxLog(/*@ non_null @*/ Commandline cmd) throws BuildException 321 { 322 setTextArgument(cmd, "sxlog", "sxLog"); 323 } 324 325 private void setPxLog(/*@ non_null @*/ Commandline cmd) throws BuildException 326 { 327 setTextArgument(cmd, "pxlog", "pxLog"); 328 } 329 330 private void setCounterExample(/*@ non_null @*/ Commandline cmd) throws BuildException 331 { 332 String arg = "counterexample"; 333 setArgument(cmd, arg, arg); 334 } 335 336 private void setEajava(/*@ non_null @*/ Commandline cmd) throws BuildException 337 { 338 String arg = "eajava"; 339 setArgument(cmd, arg, arg); 340 } 341 342 private void setEajml(/*@ non_null @*/ Commandline cmd) throws BuildException 343 { 344 String arg = "eajml"; 345 setArgument(cmd, arg, arg); 346 } 347 348 private void setEnableAssertions(/*@ non_null @*/ Commandline cmd) throws BuildException 349 { 350 String arg = "enableassertions"; 351 setArgument(cmd, arg, arg); 352 } 353 354 private void setUseVars(/*@ non_null @*/ Commandline cmd) throws BuildException 355 { 356 String arg = "usevars"; 357 setArgument(cmd, arg, "useVars"); 358 } 359 360 private void setTypeCheck(/*@ non_null @*/ Commandline cmd) throws BuildException 361 { 362 String arg = "typecheck"; 363 setArgument(cmd, arg, arg); 364 } 365 366 private void setSuggest(/*@ non_null @*/ Commandline cmd) throws BuildException 367 { 368 String arg = "suggest"; 369 setArgument(cmd, arg, arg); 370 } 371 372 private void setNoTrace(/*@ non_null @*/ Commandline cmd) throws BuildException 373 { 374 String arg = "notrace"; 375 setArgument(cmd, arg, arg); 376 } 377 378 private void setNoRedundancy(/*@ non_null @*/ Commandline cmd) throws BuildException 379 { 380 String arg = "noredundancy"; 381 setArgument(cmd, arg, arg); 382 } 383 384 private void setNoCautions(/*@ non_null @*/ Commandline cmd) throws BuildException 385 { 386 String arg = "nocautions"; 387 setArgument(cmd, arg, "noCautions"); 388 } 389 390 private void setNoCheck(/*@ non_null @*/ Commandline cmd) throws BuildException 391 { 392 String arg = "nocheck"; 393 setArgument(cmd, arg, arg); 394 } 395 396 private void setLoopsafe(/*@ non_null @*/ Commandline cmd) throws BuildException 397 { 398 String arg = "loopsafe"; 399 setArgument(cmd, arg, arg); 400 } 401 402 /** 403 * Do the compile with the specified arguments. 404 * 405 * @param args - arguments to pass to process on command line 406 * @param firstFileName - index of the first source file in args, if the 407 * index is negative, no temporary file will ever be created, but 408 * this may hit the command line length limit on your system. 409 * @param quoteFiles - if set to true, filenames containing spaces will be 410 * quoted when they appear in the external file. This is necessary 411 * when running JDK 1.4's javac and probably others. 412 * 413 * @return DOCUMENT ME! 414 * 415 * @throws BuildException DOCUMENT ME! 416 * 417 * @since Ant 1.6 418 */ 419 //@ also 420 //@ requires args != null; 421 protected int executeExternalCompile(String[] args, 422 int firstFileName, 423 boolean quoteFiles) 424 { 425 String[] commandArray = null; 426 File tmpFile = null; 427 428 try 429 { 430 431 /* 432 * Many system have been reported to get into trouble with 433 * long command lines - no, not only Windows ;-). 434 * 435 * POSIX seems to define a lower limit of 4k, so use a temporary 436 * file if the total length of the command line exceeds this limit. 437 */ 438 if ((Commandline.toString(args).length() > 4096) && (firstFileName >= 0)) 439 { 440 PrintWriter out = null; 441 442 try 443 { 444 File userDir = getJavac().getTempdir(); 445 446 if (userDir == null) 447 { 448 String userDirName = System.getProperty("user.dir"); 449 userDir = new File(userDirName); 450 } 451 452 tmpFile = fileUtils.createTempFile("files", "", userDir); 453 tmpFile.deleteOnExit(); 454 out = new PrintWriter(new FileWriter(tmpFile)); 455 456 for (int i = firstFileName; i < args.length; i++) 457 { 458 if (quoteFiles && (args[i].indexOf(" ") > -1)) 459 { 460 args[i] = args[i].replace('\\', '/'); 461 out.println("\"" + args[i] + "\""); 462 } else 463 { 464 out.println(args[i]); 465 } 466 } 467 468 out.flush(); 469 commandArray = new String[firstFileName + 1]; 470 System.arraycopy(args, 0, commandArray, 0, firstFileName); 471 commandArray[firstFileName] = tmpFile.toString(); 472 } catch (IOException e) 473 { 474 throw new BuildException("Error creating temporary file", 475 e, location); 476 } finally 477 { 478 if (out != null) 479 { 480 try 481 { 482 out.close(); 483 } catch (Throwable t) 484 { 485 // ignore 486 } 487 } 488 } 489 } else 490 { 491 commandArray = args; 492 } 493 494 try 495 { 496 Execute exe = new Execute(new LogStreamHandler(attributes, 497 Project.MSG_INFO, Project.MSG_WARN)); 498 exe.setAntRun(project); 499 exe.setWorkingDirectory(project.getBaseDir()); 500 exe.setCommandline(commandArray); 501 exe.execute(); 502 503 return exe.getExitValue(); 504 } catch (IOException e) 505 { 506 throw new BuildException("Error running " + args[0] + 507 " compiler", e, location); 508 } 509 } finally 510 { 511 if (tmpFile != null) 512 { 513 tmpFile.delete(); 514 } 515 } 516 } 517 518 /** 519 * Sets an argument with a text value from a property. 520 * 521 * @param cmd 522 * @param pPropertyName 523 * @param pArgumentName 524 * 525 * @throws BuildException if one of the arguments is null. 526 */ 527 private void setTextArgument(/*@ non_null @*/ Commandline cmd, 528 /*@ non_null @*/ String pPropertyName, 529 /*@ non_null @*/ String pArgumentName) throws BuildException 530 { 531 if (cmd == null) 532 { 533 throw new BuildException("null cmd"); 534 } 535 536 if (pPropertyName == null) 537 { 538 throw new BuildException("null pName"); 539 } 540 541 if (pArgumentName == null) 542 { 543 throw new BuildException("null pArgument"); 544 } 545 546 if (super.project == null) 547 { 548 throw new BuildException("null project"); 549 } 550 551 String propertyValue = super.project.getProperty("build.compiler." + 552 pPropertyName); 553 554 if (propertyValue != null) 555 { 556 cmd.createArgument().setValue("-" + pArgumentName + "=" + 557 propertyValue); 558 } 559 } 560 561 /** 562 * Sets an argument on the commandline from a boolean property. 563 * 564 * @param cmd 565 * @param pPropertyName 566 * @param pArgumentName 567 * 568 * @throws BuildException DOCUMENT ME! 569 */ 570 private void setArgument(/*@ non_null @*/ Commandline cmd, 571 /*@ non_null @*/ String pPropertyName, 572 /*@ non_null @*/ String pArgumentName) throws BuildException 573 { 574 if (cmd == null) 575 { 576 throw new BuildException("null cmd"); 577 } 578 579 if (pPropertyName == null) 580 { 581 throw new BuildException("null pName"); 582 } 583 584 if (pArgumentName == null) 585 { 586 throw new BuildException("null pArgument"); 587 } 588 589 if (super.project == null) 590 { 591 throw new BuildException("null super.project"); 592 } 593 594 String propertyName = super.project.getProperty("build.compiler." + 595 pPropertyName); 596 597 if ((propertyName != null) && Project.toBoolean(propertyName)) 598 { 599 cmd.createArgument().setValue("-" + pArgumentName); 600 } 601 } 602 }