]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/ProcessorDef.java
Changed spelling to manifest
[mirror_edk2.git] / Tools / Source / Cpptasks / net / sf / antcontrib / cpptasks / ProcessorDef.java
1 /*
2 *
3 * Copyright 2002-2004 The Ant-Contrib project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package net.sf.antcontrib.cpptasks;
18 import java.io.BufferedReader;
19 import java.io.File;
20 import java.io.FileReader;
21 import java.io.IOException;
22 import java.lang.reflect.Method;
23 import java.util.Vector;
24 import net.sf.antcontrib.cpptasks.compiler.LinkType;
25 import net.sf.antcontrib.cpptasks.compiler.Processor;
26 import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;
27 import net.sf.antcontrib.cpptasks.types.CommandLineArgument;
28 import net.sf.antcontrib.cpptasks.types.ConditionalFileSet;
29 import org.apache.tools.ant.BuildException;
30 import org.apache.tools.ant.DirectoryScanner;
31 import org.apache.tools.ant.Project;
32 import org.apache.tools.ant.types.DataType;
33 import org.apache.tools.ant.types.Environment;
34 import org.apache.tools.ant.types.Reference;
35 /**
36 * An abstract compiler/linker definition.
37 *
38 * @author Curt Arnold
39 */
40 public abstract class ProcessorDef extends DataType {
41 /**
42 * Returns the equivalent Boolean object for the specified value
43 *
44 * Equivalent to Boolean.valueOf in JDK 1.4
45 *
46 * @param val
47 * boolean value
48 * @return Boolean.TRUE or Boolean.FALSE
49 */
50 protected static Boolean booleanValueOf(boolean val) {
51 if (val) {
52 return Boolean.TRUE;
53 }
54 return Boolean.FALSE;
55 }
56 /**
57 * if true, targets will be built for debugging
58 */
59 private Boolean debug;
60 private Environment env = null;
61 /**
62 * Reference for "extends" processor definition
63 */
64 private Reference extendsRef = null;
65 /**
66 * Name of property that must be present or definition will be ignored. May
67 * be null.
68 */
69 private String ifProp;
70 /**
71 * if true, processor definition inherits values from containing <cc>
72 * element
73 */
74 private boolean inherit;
75 private Boolean libtool = null;
76 protected boolean newEnvironment = false;
77 /**
78 * Processor.
79 */
80 private Processor processor;
81 /**
82 * Collection of <compilerarg>or <linkerarg>contained by definition
83 */
84 private final Vector processorArgs = new Vector();
85 /**
86 * Collection of <compilerparam>or <linkerparam>contained by definition
87 */
88 private final Vector processorParams = new Vector();
89 /**
90 * if true, all targets will be unconditionally rebuilt
91 */
92 private Boolean rebuild;
93 /**
94 * Collection of <fileset>contained by definition
95 */
96 private final Vector srcSets = new Vector();
97 /**
98 * Name of property that if present will cause definition to be ignored.
99 * May be null.
100 */
101 private String unlessProp;
102 /**
103 * Constructor
104 *
105 */
106 protected ProcessorDef() throws NullPointerException {
107 inherit = true;
108 }
109 /**
110 * Adds a <compilerarg>or <linkerarg>
111 *
112 * @param arg
113 * command line argument, must not be null
114 * @throws NullPointerException
115 * if arg is null
116 * @throws BuildException
117 * if this definition is a reference
118 */
119 protected void addConfiguredProcessorArg(CommandLineArgument arg)
120 throws NullPointerException, BuildException {
121 if (arg == null) {
122 throw new NullPointerException("arg");
123 }
124 if (isReference()) {
125 throw noChildrenAllowed();
126 }
127 if(arg.getFile() == null ) {
128 processorArgs.addElement(arg);
129 }
130 else {
131 loadFile(arg.getFile());
132 }
133 }
134 /**
135 * Add a <compilerarg>or <linkerarg> if specify the file attribute
136 *
137 * @param arg
138 * command line argument, must not be null
139 * @throws BuildException
140 * if the specify file not exist
141 */
142 protected void loadFile(File file)
143 throws BuildException {
144 FileReader fileReader;
145 BufferedReader in;
146 String str;
147 if (! file.exists()){
148 throw new BuildException("The file " + file + " is not existed");
149 }
150 try {
151 fileReader = new FileReader(file);
152 in = new BufferedReader(fileReader);
153 while ( (str = in.readLine()) != null ){
154 if(str.trim() == ""){
155 continue ;
156 }
157 str = getProject().replaceProperties(str);
158 CommandLineArgument newarg = new CommandLineArgument();
159 newarg.setValue(str.trim());
160 processorArgs.addElement(newarg);
161 }
162 }
163 catch(Exception e){
164 throw new BuildException(e.getMessage());
165 }
166 }
167 /**
168 * Adds a <compilerarg>or <linkerarg>
169 *
170 * @param arg
171 * command line argument, must not be null
172 * @throws NullPointerException
173 * if arg is null
174 * @throws BuildException
175 * if this definition is a reference
176 */
177 protected void addConfiguredProcessorParam(ProcessorParam param)
178 throws NullPointerException, BuildException {
179 if (param == null) {
180 throw new NullPointerException("param");
181 }
182 if (isReference()) {
183 throw noChildrenAllowed();
184 }
185 processorParams.addElement(param);
186 }
187 /**
188 * Add an environment variable to the launched process.
189 */
190 public void addEnv(Environment.Variable var) {
191 if (env == null) {
192 env = new Environment();
193 }
194 env.addVariable(var);
195 }
196 /**
197 * Adds a source file set.
198 *
199 * Files in these set will be processed by this configuration and will not
200 * participate in the auction.
201 *
202 * @param srcSet
203 * Fileset identifying files that should be processed by this
204 * processor
205 * @throws BuildException
206 * if processor definition is a reference
207 */
208 public void addFileset(ConditionalFileSet srcSet) throws BuildException {
209 if (isReference()) {
210 throw noChildrenAllowed();
211 }
212 srcSet.setProject(getProject());
213 srcSets.addElement(srcSet);
214 }
215 /**
216 * Creates a configuration
217 *
218 * @param baseDef
219 * reference to def from containing <cc>element, may be null
220 * @return configuration
221 *
222 */
223 public ProcessorConfiguration createConfiguration(CCTask task,
224 LinkType linkType, ProcessorDef baseDef, TargetDef targetPlatform) {
225 if (isReference()) {
226 return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
227 "ProcessorDef")).createConfiguration(task, linkType,
228 baseDef, targetPlatform);
229 }
230 ProcessorDef[] defaultProviders = getDefaultProviders(baseDef);
231 Processor proc = getProcessor();
232 return proc.createConfiguration(task, linkType, defaultProviders, this, targetPlatform);
233 }
234 /**
235 * Prepares list of processor arguments ( <compilerarg>, <linkerarg>) that
236 * are active for the current project settings.
237 *
238 * @return active compiler arguments
239 */
240 public CommandLineArgument[] getActiveProcessorArgs() {
241 Project p = getProject();
242 if (p == null) {
243 throw new java.lang.IllegalStateException("project must be set");
244 }
245 if (isReference()) {
246 return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
247 "ProcessorDef")).getActiveProcessorArgs();
248 }
249 Vector activeArgs = new Vector(processorArgs.size());
250 for (int i = 0; i < processorArgs.size(); i++) {
251 CommandLineArgument arg = (CommandLineArgument) processorArgs
252 .elementAt(i);
253 if (arg.isActive(p)) {
254 activeArgs.addElement(arg);
255 }
256 }
257 CommandLineArgument[] array = new CommandLineArgument[activeArgs.size()];
258 activeArgs.copyInto(array);
259 return array;
260 }
261 /**
262 * Prepares list of processor arguments ( <compilerarg>, <linkerarg>) that
263 * are active for the current project settings.
264 *
265 * @return active compiler arguments
266 */
267 public ProcessorParam[] getActiveProcessorParams() {
268 Project p = getProject();
269 if (p == null) {
270 throw new java.lang.IllegalStateException("project must be set");
271 }
272 if (isReference()) {
273 return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
274 "ProcessorDef")).getActiveProcessorParams();
275 }
276 Vector activeParams = new Vector(processorParams.size());
277 for (int i = 0; i < processorParams.size(); i++) {
278 ProcessorParam param = (ProcessorParam) processorParams
279 .elementAt(i);
280 if (param.isActive(p)) {
281 activeParams.addElement(param);
282 }
283 }
284 ProcessorParam[] array = new ProcessorParam[activeParams.size()];
285 activeParams.copyInto(array);
286 return array;
287 }
288 /**
289 * Gets boolean indicating debug build
290 *
291 * @param defaultProviders
292 * array of ProcessorDef's in descending priority
293 * @param index
294 * index to first element in array that should be considered
295 * @return if true, built targets for debugging
296 */
297 public boolean getDebug(ProcessorDef[] defaultProviders, int index) {
298 if (isReference()) {
299 return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
300 "ProcessorDef")).getDebug(defaultProviders, index);
301 }
302 if (debug != null) {
303 return debug.booleanValue();
304 } else {
305 if (defaultProviders != null && index < defaultProviders.length) {
306 return defaultProviders[index].getDebug(defaultProviders,
307 index + 1);
308 }
309 }
310 return false;
311 }
312 /**
313 * Creates an chain of objects which provide default values in descending
314 * order of significance.
315 *
316 * @param baseDef
317 * corresponding ProcessorDef from CCTask, will be last element
318 * in array unless inherit = false
319 * @return default provider array
320 *
321 */
322 protected final ProcessorDef[] getDefaultProviders(ProcessorDef baseDef) {
323 ProcessorDef extendsDef = getExtends();
324 Vector chain = new Vector();
325 while (extendsDef != null && !chain.contains(extendsDef)) {
326 chain.addElement(extendsDef);
327 extendsDef = extendsDef.getExtends();
328 }
329 if (baseDef != null && getInherit()) {
330 chain.addElement(baseDef);
331 }
332 ProcessorDef[] defaultProviders = new ProcessorDef[chain.size()];
333 chain.copyInto(defaultProviders);
334 return defaultProviders;
335 }
336 /**
337 * Gets the ProcessorDef specified by the extends attribute
338 *
339 * @return Base ProcessorDef, null if extends is not specified
340 * @throws BuildException
341 * if reference is not same type object
342 */
343 public ProcessorDef getExtends() throws BuildException {
344 if (extendsRef != null) {
345 Object obj = extendsRef.getReferencedObject(getProject());
346 if (!getClass().isInstance(obj)) {
347 throw new BuildException("Referenced object "
348 + extendsRef.getRefId() + " not correct type, is "
349 + obj.getClass().getName() + " should be "
350 + getClass().getName());
351 }
352 return (ProcessorDef) obj;
353 }
354 return null;
355 }
356 /**
357 * Gets the inherit attribute. If the inherit value is true, this processor
358 * definition will inherit default values from the containing <cc>element.
359 *
360 * @return if true then properties from the containing <cc>element are
361 * used.
362 */
363 public final boolean getInherit() {
364 return inherit;
365 }
366 public boolean getLibtool() {
367 if (libtool != null) {
368 return libtool.booleanValue();
369 }
370 if (isReference()) {
371 return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
372 "ProcessorDef")).getLibtool();
373 }
374 ProcessorDef extendsDef = getExtends();
375 if (extendsDef != null) {
376 return extendsDef.getLibtool();
377 }
378 return false;
379 }
380 /**
381 * Obtains the appropriate processor (compiler, linker)
382 *
383 * @return processor
384 */
385 protected Processor getProcessor() {
386 if (isReference()) {
387 return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
388 "ProcessorDef")).getProcessor();
389 }
390 //
391 // if a processor has not been explicitly set
392 // then may be set by an extended definition
393 if (processor == null) {
394 ProcessorDef extendsDef = getExtends();
395 if (extendsDef != null) {
396 return extendsDef.getProcessor();
397 }
398 }
399 return processor;
400 }
401 /**
402 * Gets a boolean value indicating whether all targets must be rebuilt
403 * regardless of dependency analysis.
404 *
405 * @param defaultProviders
406 * array of ProcessorDef's in descending priority
407 * @param index
408 * index to first element in array that should be considered
409 * @return true if all targets should be rebuilt.
410 */
411 public boolean getRebuild(ProcessorDef[] defaultProviders, int index) {
412 if (isReference()) {
413 return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
414 "ProcessorDef")).getRebuild(defaultProviders, index);
415 }
416 if (rebuild != null) {
417 return rebuild.booleanValue();
418 } else {
419 if (defaultProviders != null && index < defaultProviders.length) {
420 return defaultProviders[index].getRebuild(defaultProviders,
421 index + 1);
422 }
423 }
424 return false;
425 }
426 /**
427 * Returns true if the processor definition contains embedded file set
428 * definitions
429 *
430 * @return true if processor definition contains embedded filesets
431 */
432 public boolean hasFileSets() {
433 if (isReference()) {
434 return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
435 "ProcessorDef")).hasFileSets();
436 }
437 return srcSets.size() > 0;
438 }
439 /**
440 * Determine if this def should be used.
441 *
442 * Definition will be active if the "if" variable (if specified) is set and
443 * the "unless" variable (if specified) is not set and that all reference
444 * or extended definitions are active
445 *
446 * @return true if processor is active
447 * @throws IllegalStateException
448 * if not properly initialized
449 * @throws BuildException
450 * if "if" or "unless" variable contains suspicious values
451 * "false" or "no" which indicates possible confusion
452 */
453 public boolean isActive() throws BuildException, IllegalStateException {
454 Project project = getProject();
455 if (!CUtil.isActive(project, ifProp, unlessProp)) {
456 return false;
457 }
458 if (isReference()) {
459 if (!((ProcessorDef) getCheckedRef(ProcessorDef.class,
460 "ProcessorDef")).isActive()) {
461 return false;
462 }
463 }
464 //
465 // walk through any extended definitions
466 //
467 ProcessorDef[] defaultProviders = getDefaultProviders(null);
468 for (int i = 0; i < defaultProviders.length; i++) {
469 if (!defaultProviders[i].isActive()) {
470 return false;
471 }
472 }
473 return true;
474 }
475 /**
476 * Sets the class name for the adapter. Use the "name" attribute when the
477 * tool is supported.
478 *
479 * @param className
480 * full class name
481 *
482 */
483 public void setClassname(String className) throws BuildException {
484 Object proc = null;
485 try {
486 Class implClass = ProcessorDef.class.getClassLoader().loadClass(
487 className);
488 try {
489 Method getInstance = implClass.getMethod("getInstance",
490 new Class[0]);
491 proc = getInstance.invoke(null, new Object[0]);
492 } catch (Exception ex) {
493 proc = implClass.newInstance();
494 }
495 } catch (Exception ex) {
496 throw new BuildException(ex);
497 }
498 setProcessor((Processor) proc);
499 }
500 /**
501 * If set true, all targets will be built for debugging.
502 *
503 * @param debug
504 * true if targets should be built for debugging
505 * @throws BuildException
506 * if processor definition is a reference
507 */
508 public void setDebug(boolean debug) throws BuildException {
509 if (isReference()) {
510 throw tooManyAttributes();
511 }
512 this.debug = booleanValueOf(debug);
513 }
514 /**
515 * Sets a description of the current data type.
516 */
517 public void setDescription(String desc) {
518 super.setDescription(desc);
519 }
520 /**
521 * Specifies that this element extends the element with id attribute with a
522 * matching value. The configuration will be constructed from the settings
523 * of this element, element referenced by extends, and the containing cc
524 * element.
525 *
526 * @param extendsRef
527 * Reference to the extended processor definition.
528 * @throws BuildException
529 * if this processor definition is a reference
530 */
531 public void setExtends(Reference extendsRef) throws BuildException {
532 if (isReference()) {
533 throw tooManyAttributes();
534 }
535 this.extendsRef = extendsRef;
536 }
537 /**
538 * Sets an id that can be used to reference this element.
539 *
540 * @param id
541 * id
542 */
543 public void setId(String id) {
544 //
545 // this is actually accomplished by a different
546 // mechanism, but we can document it
547 //
548 }
549 /**
550 * Sets the property name for the 'if' condition.
551 *
552 * The configuration will be ignored unless the property is defined.
553 *
554 * The value of the property is insignificant, but values that would imply
555 * misinterpretation ("false", "no") will throw an exception when
556 * evaluated.
557 *
558 * @param propName
559 * name of property
560 */
561 public void setIf(String propName) {
562 ifProp = propName;
563 }
564 /**
565 * If inherit has the default value of true, defines, includes and other
566 * settings from the containing <cc>element will be inherited.
567 *
568 * @param inherit
569 * new value
570 * @throws BuildException
571 * if processor definition is a reference
572 */
573 public void setInherit(boolean inherit) throws BuildException {
574 if (isReference()) {
575 throw super.tooManyAttributes();
576 }
577 this.inherit = inherit;
578 }
579 /**
580 * Set use of libtool.
581 *
582 * If set to true, the "libtool " will be prepended to the command line
583 *
584 * @param libtool
585 * If true, use libtool.
586 */
587 public void setLibtool(boolean libtool) {
588 if (isReference()) {
589 throw tooManyAttributes();
590 }
591 this.libtool = booleanValueOf(libtool);
592 }
593 /**
594 * Do not propagate old environment when new environment variables are
595 * specified.
596 */
597 public void setNewenvironment(boolean newenv) {
598 newEnvironment = newenv;
599 }
600 /**
601 * Sets the processor
602 *
603 * @param processor
604 * processor, may not be null.
605 * @throws BuildException
606 * if ProcessorDef is a reference
607 * @throws NullPointerException
608 * if processor is null
609 */
610 protected void setProcessor(Processor processor) throws BuildException,
611 NullPointerException {
612 if (processor == null) {
613 throw new NullPointerException("processor");
614 }
615 if (isReference()) {
616 throw super.tooManyAttributes();
617 }
618 if (env == null && !newEnvironment) {
619 this.processor = processor;
620 } else {
621 this.processor = processor.changeEnvironment(newEnvironment, env);
622 }
623 }
624 /**
625 * If set true, all targets will be unconditionally rebuilt.
626 *
627 * @param rebuild
628 * if true, rebuild all targets.
629 * @throws BuildException
630 * if processor definition is a reference
631 */
632 public void setRebuild(boolean rebuild) throws BuildException {
633 if (isReference()) {
634 throw tooManyAttributes();
635 }
636 this.rebuild = booleanValueOf(rebuild);
637 }
638 /**
639 * Specifies that this element should behave as if the content of the
640 * element with the matching id attribute was inserted at this location. If
641 * specified, no other attributes or child content should be specified,
642 * other than "if", "unless" and "description".
643 *
644 * @param ref
645 * Reference to other element
646 *
647 */
648 public void setRefid(org.apache.tools.ant.types.Reference ref) {
649 super.setRefid(ref);
650 }
651 /**
652 * Set the property name for the 'unless' condition.
653 *
654 * If named property is set, the configuration will be ignored.
655 *
656 * The value of the property is insignificant, but values that would imply
657 * misinterpretation ("false", "no") of the behavior will throw an
658 * exception when evaluated.
659 *
660 * @param propName
661 * name of property
662 */
663 public void setUnless(String propName) {
664 unlessProp = propName;
665 }
666 /**
667 * This method calls the FileVistor's visit function for every file in the
668 * processors definition
669 *
670 * @param visitor
671 * object whose visit method is called for every file
672 */
673 public void visitFiles(FileVisitor visitor) {
674 Project p = getProject();
675 if (p == null) {
676 throw new java.lang.IllegalStateException(
677 "project must be set before this call");
678 }
679 if (isReference()) {
680 ((ProcessorDef) getCheckedRef(ProcessorDef.class, "ProcessorDef"))
681 .visitFiles(visitor);
682 }
683 //
684 // if this processor extends another,
685 // visit its files first
686 //
687 ProcessorDef extendsDef = getExtends();
688 if (extendsDef != null) {
689 extendsDef.visitFiles(visitor);
690 }
691 for (int i = 0; i < srcSets.size(); i++) {
692 ConditionalFileSet srcSet = (ConditionalFileSet) srcSets
693 .elementAt(i);
694 if (srcSet.isActive()) {
695 // Find matching source files
696 DirectoryScanner scanner = srcSet.getDirectoryScanner(p);
697 // Check each source file - see if it needs compilation
698 String[] fileNames = scanner.getIncludedFiles();
699 File parentDir = scanner.getBasedir();
700 for (int j = 0; j < fileNames.length; j++) {
701 String currentFile = fileNames[j];
702 visitor.visit(parentDir, currentFile);
703 }
704 }
705 }
706 }
707 public Vector getSrcSets() {
708 if (isReference()) {
709 return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
710 "ProcessorDef")).getSrcSets();
711 }
712 return srcSets;
713 }
714 }