1 Index: src/org/eclipse/jdt/internal/compiler/batch/messages.properties
2 ===================================================================
3 RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties,v
4 retrieving revision 1.546.2.23
5 diff -u -r1.546.2.23 messages.properties
6 --- src/org/eclipse/jdt/internal/compiler/batch/messages.properties 8 Feb 2007 15:04:43 -0000 1.546.2.23
7 +++ src/org/eclipse/jdt/internal/compiler/batch/messages.properties 26 Feb 2007 18:21:06 -0000
9 template.restrictedAccess.constructor = The constructor {0} is not accessible due to restriction on classpath entry {1}
10 template.restrictedAccess.field = The field {0} from the type {1} is not accessible due to restriction on classpath entry {2}
11 template.restrictedAccess.method = The method {0} from the type {1} is not accessible due to restriction on classpath entry {2}
14 +gcc.zipArg=-fzip-target requires argument
15 +gcc.zipDepArg=-fzip-dependency requires argument
16 +gcc.noClasspath=no classpath specified
17 Index: src/org/eclipse/jdt/internal/compiler/batch/GCCMain.java
18 ===================================================================
19 RCS file: batch/org/eclipse/jdt/internal/compiler/batch/GCCMain.java
20 diff -N src/org/eclipse/jdt/internal/compiler/batch/GCCMain.java
21 --- /dev/null 1 Jan 1970 00:00:00 -0000
22 +++ src/org/eclipse/jdt/internal/compiler/batch/GCCMain.java 1 Jan 1970 00:00:00 -0000
27 +package org.eclipse.jdt.internal.compiler.batch;
29 +import java.io.BufferedOutputStream;
30 +import java.io.BufferedReader;
31 +import java.io.ByteArrayInputStream;
33 +import java.io.FileOutputStream;
34 +import java.io.FileReader;
35 +import java.io.IOException;
36 +import java.io.InputStreamReader;
37 +import java.io.OutputStream;
38 +import java.io.PrintWriter;
39 +import java.io.UnsupportedEncodingException;
40 +import java.util.ArrayList;
41 +import java.util.HashSet;
42 +import java.util.Iterator;
43 +import java.util.Map;
44 +import java.util.StringTokenizer;
45 +import java.util.zip.CRC32;
46 +import java.util.zip.ZipEntry;
47 +import java.util.zip.ZipOutputStream;
49 +import org.eclipse.jdt.core.compiler.InvalidInputException;
50 +import org.eclipse.jdt.internal.compiler.ClassFile;
51 +import org.eclipse.jdt.internal.compiler.CompilationResult;
52 +import org.eclipse.jdt.internal.compiler.env.AccessRule;
53 +import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
54 +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
55 +import org.eclipse.jdt.internal.compiler.util.Messages;
56 +import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
59 + * This is an alternate entry point for the command-line compiler which
60 + * is simpler to integrate into GCC. In particular the option processing
61 + * is more GNU-like and the recognized options are similar to those supported
62 + * by other GCC front ends.
64 +public class GCCMain extends Main {
66 + // All the compilation units specified on the command line.
67 + private HashSet commandLineCompilationUnits = new HashSet();
68 + // True if we are only checking syntax.
69 + private boolean syntaxOnly;
70 + // If not null, the name of the output zip file.
71 + // If null, we are generating class files in the file system,
73 + private String zipDestination;
74 + // The zip stream to which we're writing, or null if it hasn't been opened.
75 + private ZipOutputStream zipStream;
77 + // If not null, the name of the zip file to which dependency class files
78 + // should be written.
79 + private String zipDependencyDestination;
80 + // The zip stream to which dependency files should be written.
81 + private ZipOutputStream zipDependencyStream;
83 + public GCCMain(PrintWriter outWriter, PrintWriter errWriter,
84 + boolean systemExitWhenFinished) {
85 + super(outWriter, errWriter, systemExitWhenFinished);
86 + this.logger.setEmacs();
89 + public GCCMain(PrintWriter outWriter, PrintWriter errWriter,
90 + boolean systemExitWhenFinished, Map customDefaultOptions) {
91 + super(outWriter, errWriter, systemExitWhenFinished,
92 + customDefaultOptions);
93 + this.logger.setEmacs();
96 + private void fail(Exception t) {
97 + this.logger.logException(t);
101 + public CompilationUnit[] getCompilationUnits() throws InvalidInputException {
102 + CompilationUnit[] units = super.getCompilationUnits();
103 + for (int i = 0; i < units.length; ++i)
104 + this.commandLineCompilationUnits.add(units[i]);
108 + private String combine(char[] one, char[] two) {
109 + StringBuffer b = new StringBuffer();
112 + return b.toString();
115 + private ZipOutputStream getZipOutput() throws IOException {
116 + if (this.zipDestination != null && this.zipStream == null) {
118 + if ("-".equals(this.zipDestination)) { //$NON-NLS-1$
121 + os = new FileOutputStream(this.zipDestination);
123 + zipStream = new ZipOutputStream(new BufferedOutputStream(os));
124 + zipStream.setMethod(ZipOutputStream.STORED);
129 + private ZipOutputStream getDependencyOutput() throws IOException {
130 + if (this.zipDependencyDestination != null && this.zipDependencyStream == null) {
131 + OutputStream os = new FileOutputStream(zipDependencyDestination);
132 + zipDependencyStream = new ZipOutputStream(new BufferedOutputStream(os));
133 + zipDependencyStream.setMethod(ZipOutputStream.STORED);
135 + return zipDependencyStream;
138 + public void outputClassFiles(CompilationResult unitResult) {
139 + if (this.syntaxOnly) {
142 + if (this.zipDestination == null) {
143 + // Nothing special to do here.
144 + super.outputClassFiles(unitResult);
147 + if (unitResult == null || unitResult.hasErrors()) {
151 + // If we are compiling with indirect dispatch, we don't need
152 + // any dependent classes. If we are using the C++ ABI, then we
153 + // do need the dependencies in order to do proper layout.
154 + boolean gcjCompile = this.commandLineCompilationUnits.contains(unitResult.getCompilationUnit());
155 + if (this.zipDependencyDestination == null && !gcjCompile) {
160 + ZipOutputStream dest = gcjCompile ? getZipOutput() : getDependencyOutput();
161 + ClassFile[] classFiles = unitResult.getClassFiles();
162 + for (int i = 0; i < classFiles.length; ++i) {
163 + ClassFile classFile = classFiles[i];
164 + String filename = combine(classFile.fileName(), SuffixConstants.SUFFIX_class);
168 + Messages.compilation_write,
170 + String.valueOf(this.exportedClassFilesCounter+1),
173 + ZipEntry entry = new ZipEntry(filename);
174 + byte[] contents = classFile.getBytes();
175 + CRC32 crc = new CRC32();
176 + crc.update(contents);
177 + entry.setSize(contents.length);
178 + entry.setCrc(crc.getValue());
179 + dest.putNextEntry(entry);
180 + dest.write(contents);
183 + } catch (IOException err) {
188 + private String getArgument(String option) {
189 + int index = option.indexOf('=');
190 + return option.substring(index + 1);
193 + private void addPath(ArrayList result, String currentClasspathName) {
194 + String customEncoding = null;
195 + AccessRule[] accessRules = new AccessRule[0];
196 + String templates[] = new String[AccessRuleSet.MESSAGE_TEMPLATES_LENGTH];
197 + templates[0] = this.bind(
198 + "template.restrictedAccess.type", //$NON-NLS-1$
199 + new String[] {"{0}", currentClasspathName}); //$NON-NLS-1$
200 + templates[1] = this.bind(
201 + "template.restrictedAccess.constructor", //$NON-NLS-1$
202 + new String[] {"{0}", currentClasspathName}); //$NON-NLS-1$
203 + templates[2] = this.bind(
204 + "template.restrictedAccess.method", //$NON-NLS-1$
205 + new String[] {"{0}", "{1}", currentClasspathName}); //$NON-NLS-1$ //$NON-NLS-2$
206 + templates[3] = this.bind(
207 + "template.restrictedAccess.field", //$NON-NLS-1$
208 + new String[] {"{0}", "{1}", currentClasspathName}); //$NON-NLS-1$ //$NON-NLS-2$
209 + AccessRuleSet accessRuleSet = new AccessRuleSet(accessRules, templates);
210 + FileSystem.Classpath currentClasspath = FileSystem
211 + .getClasspath(currentClasspathName,
212 + customEncoding, accessRuleSet);
213 + if (currentClasspath != null) {
214 + result.add(currentClasspath);
218 + private void parsePath(ArrayList result, String path) {
219 + StringTokenizer iter = new StringTokenizer(path, File.pathSeparator);
220 + while (iter.hasMoreTokens()) {
221 + addPath(result, iter.nextToken());
225 + protected void handleWarningToken(String token, boolean isEnabling,
226 + boolean useEnableJavadoc) throws InvalidInputException {
227 + // Recognize this for compatibility with older versions of gcj.
228 + if ("deprecated".equals(token)) //$NON-NLS-1$
229 + token = "deprecation"; //$NON-NLS-1$
230 + else if ("static-access".equals(token) //$NON-NLS-1$
231 + || "dep-ann".equals(token) //$NON-NLS-1$
232 + || "over-ann".equals(token)) { //$NON-NLS-1$
233 + // Some exceptions to the warning naming rule.
234 + } else if ("extraneous-semicolon".equals(token)) { //$NON-NLS-1$
235 + // Compatibility with earlier versions of gcj.
236 + token = "semicolon"; //$NON-NLS-1$
238 + // Turn "foo-bar-baz" into eclipse-style "fooBarBaz".
239 + StringBuffer newToken = new StringBuffer(token.length());
240 + StringTokenizer t = new StringTokenizer(token, "-"); //$NON-NLS-1$
241 + boolean first = true;
242 + while (t.hasMoreTokens()) {
243 + String next = t.nextToken();
245 + newToken.append(next);
248 + newToken.append(Character.toUpperCase(next.charAt(0)));
249 + newToken.append(next.substring(1));
252 + token = newToken.toString();
254 + super.handleWarningToken(token, isEnabling, useEnableJavadoc);
257 + private void turnWarningsToErrors() {
258 + Object[] entries = this.options.entrySet().toArray();
259 + for (int i = 0, max = entries.length; i < max; i++) {
260 + Map.Entry entry = (Map.Entry) entries[i];
261 + if (!(entry.getKey() instanceof String))
263 + if (!(entry.getValue() instanceof String))
265 + if (((String) entry.getValue()).equals(CompilerOptions.WARNING)) {
266 + this.options.put(entry.getKey(), CompilerOptions.ERROR);
272 + * Set the debug level to the indicated value. The level should be
273 + * between 0 and 2, inclusive, but this is not checked.
274 + * @param level the debug level
276 + private void setDebugLevel(int level) {
278 + CompilerOptions.OPTION_LocalVariableAttribute,
279 + level > 1 ? CompilerOptions.GENERATE : CompilerOptions.DO_NOT_GENERATE);
281 + CompilerOptions.OPTION_LineNumberAttribute,
282 + level > 0 ? CompilerOptions.GENERATE : CompilerOptions.DO_NOT_GENERATE);
284 + CompilerOptions.OPTION_SourceFileAttribute,
285 + CompilerOptions.GENERATE);
288 + private void readFileList(String file, ArrayList result) {
290 + BufferedReader b = new BufferedReader(new FileReader(file));
292 + while ((line = b.readLine()) != null) {
293 + if (line.endsWith(SUFFIX_STRING_java))
297 + } catch (IOException err) {
302 + private void readAllFileListFiles(ArrayList fileList, ArrayList result) {
303 + Iterator it = fileList.iterator();
304 + while (it.hasNext()) {
305 + readFileList((String) it.next(), result);
309 + private void handleWall(boolean enable) throws InvalidInputException {
310 + // A somewhat arbitrary list. We use the GCC names
311 + // here, and the local handleWarningToken translates
313 + handleWarningToken("constructor-name", enable, false);
314 + handleWarningToken("pkg-default-method", enable, false);
315 + handleWarningToken("masked-catch-block", enable, false);
316 + handleWarningToken("all-deprecation", enable, false);
317 + handleWarningToken("unused-local", enable, false);
318 + handleWarningToken("unused-label", enable, false);
319 + handleWarningToken("static-receiver", enable, false);
320 + handleWarningToken("indirect-static", enable, false);
321 + handleWarningToken("no-effect-assign", enable, false);
322 + handleWarningToken("char-concat", enable, false);
323 + handleWarningToken("useless-type-check", enable, false);
324 + handleWarningToken("final-bound", enable, false);
325 + handleWarningToken("assert-identifier", enable, false);
326 + handleWarningToken("enum-identifier", enable, false);
327 + handleWarningToken("finally", enable, false);
328 + handleWarningToken("varargs-cast", enable, false);
329 + handleWarningToken("unused", enable, false);
330 + handleWarningToken("forbidden", enable, false);
333 + public void configure(String[] argv) throws InvalidInputException {
334 + if ((argv == null) || (argv.length == 0)) {
335 + // This is a "can't happen".
339 + ArrayList files = new ArrayList();
340 + ArrayList otherFiles = new ArrayList();
341 + String classpath = null;
342 + boolean haveFileList = false;
343 + boolean inhibitAllWarnings = false;
344 + boolean treatWarningsAsErrors = false;
346 + for (int i = 0; i < argv.length; ++i) {
347 + String currentArg = argv[i];
349 + if (currentArg.startsWith("-fencoding=")) { //$NON-NLS-1$
350 + // Simply accept the last one.
351 + String encoding = getArgument(currentArg);
352 + try { // ensure encoding is supported
353 + new InputStreamReader(new ByteArrayInputStream(new byte[0]), encoding);
354 + } catch (UnsupportedEncodingException e) {
355 + throw new InvalidInputException(
356 + this.bind("configure.unsupportedEncoding", encoding)); //$NON-NLS-1$
358 + this.options.put(CompilerOptions.OPTION_Encoding, encoding);
359 + } else if (currentArg.startsWith("-foutput-class-dir=")) { //$NON-NLS-1$
360 + String arg = getArgument(currentArg);
361 + if (this.destinationPath != null) {
362 + StringBuffer errorMessage = new StringBuffer();
363 + errorMessage.append("-d"); //$NON-NLS-1$
364 + errorMessage.append(' ');
365 + errorMessage.append(arg);
366 + throw new InvalidInputException(
367 + this.bind("configure.duplicateOutputPath", errorMessage.toString())); //$NON-NLS-1$
369 + this.destinationPath = arg;
370 + // this.generatePackagesStructure = true;
371 + } else if (currentArg.startsWith("-fbootclasspath=")) { //$NON-NLS-1$
372 + classpath = getArgument(currentArg);
373 + } else if (currentArg.equals("-fzip-target")) { //$NON-NLS-1$
375 + if (i >= argv.length)
376 + throw new InvalidInputException(this.bind("gcc.zipArg")); //$NON-NLS-1$
377 + this.zipDestination = argv[i];
378 + } else if (currentArg.equals("-fzip-dependency")) { //$NON-NLS-1$
380 + if (i >= argv.length)
381 + throw new InvalidInputException(this.bind("gcc.zipDepArg")); //$NON-NLS-1$
382 + this.zipDependencyDestination = argv[i];
383 + } else if (currentArg.startsWith("-g")) { //$NON-NLS-1$
384 + if (currentArg.equals("-g0")) { //$NON-NLS-1$
386 + } else if (currentArg.equals("-g2") || currentArg.equals("-g3") //$NON-NLS-1$ //$NON-NLS-2$
387 + || currentArg.equals("-g")) { //$NON-NLS-1$
390 + // Handle -g1 but also things like -gstabs.
393 + } else if (currentArg.equals("-Werror")) { //$NON-NLS-1$
394 + treatWarningsAsErrors = true;
395 + } else if (currentArg.equals("-Wno-error")) { //$NON-NLS-1$
396 + treatWarningsAsErrors = false;
397 + } else if (currentArg.equals("-Wall")) { //$NON-NLS-1$
399 + } else if (currentArg.equals("-Wno-all")) { //$NON-NLS-1$
401 + } else if (currentArg.startsWith("-Wno-")) { //$NON-NLS-1$
402 + handleWarningToken(currentArg.substring(5), false, false);
403 + } else if (currentArg.startsWith("-W")) { //$NON-NLS-1$
404 + handleWarningToken(currentArg.substring(2), true, false);
405 + } else if (currentArg.equals("-w")) { //$NON-NLS-1$
406 + inhibitAllWarnings = true;
407 + } else if (currentArg.startsWith("-O")) { //$NON-NLS-1$
409 + } else if (currentArg.equals("-v")) { //$NON-NLS-1$
410 + this.verbose = true;
411 + } else if (currentArg.equals("-fsyntax-only")) { //$NON-NLS-1$
412 + this.syntaxOnly = true;
413 + } else if (currentArg.startsWith("-fsource=")) { //$NON-NLS-1$
414 + currentArg = getArgument(currentArg);
415 + if (currentArg.equals("1.3")) { //$NON-NLS-1$
416 + this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
417 + } else if (currentArg.equals("1.4")) { //$NON-NLS-1$
418 + this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
419 + } else if (currentArg.equals("1.5") || currentArg.equals("5") || currentArg.equals("5.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
420 + this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
421 + } else if (currentArg.equals("1.6") || currentArg.equals("6") || currentArg.equals("6.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
422 + this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
424 + throw new InvalidInputException(this.bind("configure.source", currentArg)); //$NON-NLS-1$
426 + } else if (currentArg.startsWith("-ftarget=")) { //$NON-NLS-1$
427 + currentArg = getArgument(currentArg);
428 + if (currentArg.equals("1.1")) { //$NON-NLS-1$
429 + this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
430 + } else if (currentArg.equals("1.2")) { //$NON-NLS-1$
431 + this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
432 + } else if (currentArg.equals("1.3")) { //$NON-NLS-1$
433 + this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3);
434 + } else if (currentArg.equals("1.4")) { //$NON-NLS-1$
435 + this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
436 + } else if (currentArg.equals("1.5") || currentArg.equals("5") || currentArg.equals("5.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
437 + this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
438 + } else if (currentArg.equals("1.6") || currentArg.equals("6") || currentArg.equals("6.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
439 + this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
440 + } else if (currentArg.equals("jsr14")) { //$NON-NLS-1$
441 + this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_JSR14);
443 + throw new InvalidInputException(this.bind("configure.targetJDK", currentArg)); //$NON-NLS-1$
445 + } else if (currentArg.equals("-ffilelist-file")) { //$NON-NLS-1$
446 + haveFileList = true;
447 + } else if (currentArg.endsWith(SuffixConstants.SUFFIX_STRING_java)) {
448 + files.add(currentArg);
449 + } else if (currentArg.charAt(0) == '-'){
450 + // FIXME: error if not a file?
452 + otherFiles.add(currentArg);
456 + // Read the file list file. We read them all, but really there
457 + // will only be one.
459 + readAllFileListFiles(otherFiles, files);
461 + this.filenames = (String[]) files.toArray(new String[0]);
462 + this.encodings = new String[this.filenames.length];
463 + this.destinationPaths = new String[this.filenames.length];
464 + for (int i = 0; i < this.filenames.length; ++i)
465 + this.destinationPaths[i] = this.destinationPath;
467 + // Classpath processing.
468 + ArrayList result = new ArrayList();
469 + if (classpath == null)
470 + throw new InvalidInputException(this.bind("gcc.noClasspath")); //$NON-NLS-1$
471 + parsePath(result, classpath);
473 + // We must always create both output files, even if one is not used.
474 + // That way we will always pass valid zip file on to jc1.
477 + getDependencyOutput();
478 + } catch (IOException err) {
482 + if (inhibitAllWarnings)
484 + if (treatWarningsAsErrors)
485 + turnWarningsToErrors();
487 + this.checkedClasspaths = new FileSystem.Classpath[result.size()];
488 + result.toArray(this.checkedClasspaths);
490 + this.logger.logCommandLineArguments(argv);
491 + this.logger.logOptions(this.options);
492 + this.logger.logClasspath(this.checkedClasspaths);
494 + this.repetitions = 1;
497 + public boolean compile(String[] argv) {
498 + boolean result = super.compile(argv);
500 + if (zipStream != null) {
501 + zipStream.finish();
504 + if (zipDependencyStream != null) {
505 + zipDependencyStream.finish();
506 + zipDependencyStream.close();
508 + } catch (IOException err) {
514 + public static void main(String[] argv) {
515 + boolean result = new GCCMain(new PrintWriter(System.out), new PrintWriter(System.err), false).compile(argv);
516 + System.exit(result ? 0 : 1);