1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-19 15:05:36 +02:00

More work on the GNU makefile parser.

This commit is contained in:
Alain Magloire 2003-09-21 19:09:27 +00:00
parent 7c7237d20c
commit 9c0b2ed659
81 changed files with 2908 additions and 815 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,92 @@
MAKE = make
AR = ar
ARFLAGS = -rv
YACC = yacc
YFLAGS =
LEX = lex
LFLAGS =
LDFLAGS =
CC = c89
CFLAGS = -O
FC = fort77
FFLAGS = -O 1
GET = get
GFLAGS =
SCCSFLAGS =
SCCSGETFLAGS = -s
.SUFFIXES: .o .c .y .l .a .sh .f .c~ .y~ .l~ .sh~ .f~
.SCCS_GET:
sccs $(SCCSFLAGS) get $(SCCSGETFLAGS) $@
.c:
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
.f:
$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $<
.sh:
cp $< $@
chmod a+x $@
.c~:
$(GET) $(GFLAGS) -p $< > $*.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $*.c
.f~:
$(GET) $(GFLAGS) -p $< > $*.f
$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $*.f
.sh~:
$(GET) $(GFLAGS) -p $< > $*.sh
cp $*.sh $@
chmod a+x $@
.c.o:
$(CC) $(CFLAGS) -c $<
.f.o:
$(FC) $(FFLAGS) -c $<
.y.o:
$(YACC) $(YFLAGS) $<
$(CC) $(CFLAGS) -c y.tab.c
rm -f y.tab.c
mv y.tab.o $@
.l.o:
$(LEX) $(LFLAGS) $<
$(CC) $(CFLAGS) -c lex.yy.c
rm -f lex.yy.c
mv lex.yy.o $@
.y.c:
$(YACC) $(YFLAGS) $<
mv y.tab.c $@
.l.c:
$(LEX) $(LFLAGS) $<
mv lex.yy.c $@
.c~.o:
$(GET) $(GFLAGS) -p $< > $*.c
$(CC) $(CFLAGS) -c $*.c
.f~.o:
$(GET) $(GFLAGS) -p $< > $*.f
$(FC) $(FFLAGS) -c $*.f
.y~.o:
$(GET) $(GFLAGS) -p $< > $*.y
$(YACC) $(YFLAGS) $*.y
$(CC) $(CFLAGS) -c y.tab.c
rm -f y.tab.c
mv y.tab.o $@
.l~.o:
$(GET) $(GFLAGS) -p $< > $*.l
$(LEX) $(LFLAGS) $*.l
$(CC) $(CFLAGS) -c lex.yy.c
rm -f lex.yy.c
mv lex.yy.o $@
.y~.c:
$(GET) $(GFLAGS) -p $< > $*.y
$(YACC) $(YFLAGS) $*.y
mv y.tab.c $@
.l~.c:
$(GET) $(GFLAGS) -p $< > $*.l
$(LEX) $(LFLAGS) $*.l
mv lex.yy.c $@
.c.a:
$(CC) -c $(CFLAGS) $<
$(AR) $(ARFLAGS) $@ $*.o
rm -f $*.o
.f.a:
$(FC) -c $(FFLAGS) $<
$(AR) $(ARFLAGS) $@ $*.o
rm -f $*.o

View file

@ -12,8 +12,18 @@ package org.eclipse.cdt.make.core.makefile;
/**
* IArchiveTarget
* Archive files, are files maintained by the program "ar".
* They contain objects, the members of the Archive.
* For example:
* foolib(hack.o) : hack.o
* ar cr foolib hack.o
* ArchiveTarget(member) -- foolib(hack.o);
*/
public interface IArchiveTarget extends ITarget {
String getMember();
/**
* Returns the members the point by archive target.
* @return String
*/
String[] getMembers();
}

View file

@ -0,0 +1,18 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile;
/**
* Represent an error in the makefile syntax
*/
public interface IBadDirective {
}

View file

@ -16,6 +16,8 @@ import java.io.IOException;
/**
* ICommand
* Commands are associated with a rule and executed by
* the make program when building a target.
*/
public interface ICommand extends IDirective {

View file

@ -11,7 +11,7 @@
package org.eclipse.cdt.make.core.makefile;
/**
* IComment
* Comments start with '#' and until the end of the line.
*/
public interface IComment extends IDirective {

View file

@ -11,11 +11,29 @@
package org.eclipse.cdt.make.core.makefile;
/**
* A Makefile can contain rules, macro definitons and comments.
* They are call directives.
*/
public interface IDirective {
/**
* Returns the parent of this directive, null if none.
* @return
*/
IDirective getParent();
/**
* The starting line number of this directive.
* The numbering starts at 1 .i.e the first line is not 0
* @return
*/
int getStartLine();
/**
* The ending line number of this directive.
* The numbering starts at 1 .i.e the first line is not 0
* @return
*/
int getEndLine();
String toString();

View file

@ -11,7 +11,13 @@
package org.eclipse.cdt.make.core.makefile;
/**
* IInferenceRule
* IInferenceRules are formated as follows:
* target:
* <tab>command
* [<tab>command]
*
* The target is of the form .s2 or .s1.s2
* There are no prerequisites.
*/
public interface IInferenceRule extends IRule {
}

View file

@ -11,21 +11,50 @@
package org.eclipse.cdt.make.core.makefile;
/**
* IMacroDefinition
* IMacroDefinitions are in the form:
* string1 = [string2]
*/
public interface IMacroDefinition extends IDirective {
/**
* Returns the name of the macro
* @return
*/
String getName();
/**
* Returns the value of the macro
* @return
*/
StringBuffer getValue();
/**
* The macro is a built-in
* @return
*/
boolean isFromDefault();
/**
* The macro was found in a Makefile.
* @return
*/
boolean isFromMakefile();
/**
* The macro came from the environment.
* @return
*/
boolean isFromEnviroment();
/**
* The macro came from the make command option -e
* @return
*/
boolean isFromEnvironmentOverride();
/**
* The macro was pass from an option to make.
* @return
*/
boolean isFromCommand();
}

View file

@ -15,17 +15,65 @@ import java.io.Reader;
/**
* IMakefile
* IMakefile:
*
* Makefile : ( directive ) *
* directive : rule | macro_definition | comments | empty
* rule : inference_rule | target_rule | special_rule
* inference_rule : target ':' [ ';' command ] <nl>
* [ ( command ) * ]
* target_rule : [ ( target ) + ] ':' [ ( prerequisite ) * ] [ ';' command ] <nl>
* [ ( command ) * ]
* macro_definition : string '=' ( string )*
* comments : ('#' ( string ) <nl>) *
* empty : <nl>
* command : <tab> prefix_command string <nl>
* target : string
* prefix_command : '-' | '@' | '+'
* internal_macro : "$<" | "$*" | "$@" | "$?" | "$%"
*/
public interface IMakefile extends IParent {
/**
* ITargetRule | IInferenceRule | ISpecialRule
* @return
*/
IRule[] getRules();
IRule[] getRule(String target);
/**
* Returns IInferenceRule
* @return
*/
IInferenceRule[] getInferenceRules();
IInferenceRule[] getInferenceRule(String target);
/**
* Returns ITargetRule
* @return
*/
ITargetRule[] getTargetRules();
ITargetRule[] getTargetRule(String target);
/**
* Return IMacroDefintion
* @return
*/
IMacroDefinition[] getMacroDefinitions();
IMacroDefinition[] getMacroDefinition(String name);
/**
* Return all the builtin directives.
* @return
*/
IDirective[] getBuiltins();
/**
* Return all the buil-in MacroDefintions
* @return
*/
IMacroDefinition[] getBuiltinMacroDefinitions();
/**
* Clear the all statements and (re)parse the Makefile
* @param makefile
* @throws IOException
*/
void parse(Reader makefile) throws IOException;
}

View file

@ -0,0 +1,22 @@
/*
* Created on Sep 21, 2003
*
* To change the template for this generated file go to
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
*/
package org.eclipse.cdt.make.core.makefile;
import org.eclipse.cdt.core.IMarkerGenerator;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* @author alain
*
* To change the template for this generated type comment go to
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
*/
public interface IMakefileValidator {
public abstract void setMarkerGenerator(IMarkerGenerator errorHandler);
public abstract void checkFile(IFile file, IProgressMonitor monitor);
}

View file

@ -10,10 +10,9 @@
***********************************************************************/
package org.eclipse.cdt.make.core.makefile;
/**
* IParent
*/
public interface IParent extends IDirective {
IDirective[] getStatements();
IDirective[] getDirectives();
}

View file

@ -11,7 +11,9 @@
package org.eclipse.cdt.make.core.makefile;
/**
* There are two kinds of rules: Inference rules and target rules
* There are several kinds of rules: Inference rules, target rules
* Some make provides special rules for example:
* .DEFAULT, .IGNORE etc ...
*/
public interface IRule extends IParent {
/**

View file

@ -0,0 +1,35 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.IDirective;
/**
*/
public interface IConditional extends IDirective {
String getConditional();
String getArg1();
String getArg2();
boolean isIfdef();
boolean isIfndef();
boolean isIfeq();
boolean isIfneq();
boolean isElse();
}

View file

@ -0,0 +1,23 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.ISpecialRule;
/**
* .DELETE_ON_ERROR'
* If `.DELETE_ON_ERROR' is mentioned as a target anywhere in the
* makefile, then `make' will delete the target of a rule if it has
* changed and its commands exit with a nonzero exit status, just as
* it does when it receives a signal.
*/
public interface IDeleteOnErrorRule extends ISpecialRule {
}

View file

@ -0,0 +1,21 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.ISpecialRule;
/**
* .EXPORT_ALL_VARIABLES
* Simply by being mentioned as a target, this tells `make' to export
* all variables to child processes by default.
*/
public interface IExportAllVariablesRule extends ISpecialRule {
}

View file

@ -0,0 +1,31 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.IMakefile;
/**
*/
public interface IGNUMakefile extends IMakefile {
/**
* Set the search include directories for the
* "include" directive
* @param paths
*/
void setIncludeDirectories(String[] paths);
/**
* Get the include directories search paths.
* @return
*/
String[] getIncludeDirectories();
}

View file

@ -0,0 +1,19 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.IParent;
/**
*/
public interface IInclude extends IParent {
String[] getFilenames();
}

View file

@ -0,0 +1,21 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.ISpecialRule;
/**
* .INTERMEDIATE
* The targets which `.INTERMEDIATE' depends on are treated as intermediate files.
* `.INTERMEDIATE' with no prerequisites has no effect.
*/
public interface IIntermediateRule extends ISpecialRule {
}

View file

@ -0,0 +1,22 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.ISpecialRule;
/**
* .LOW_RESOLUTION_TIME
* If you specify prerequisites for `.LOW_RESOLUTION_TIME', `make'
* assumes that these files are created by commands that generate low
* resolution time stamps.
*/
public interface ILowResolutionTimeRule extends ISpecialRule {
}

View file

@ -0,0 +1,24 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.ISpecialRule;
/**
* .NOTPARALLEL
* If `.NOTPARALLEL' is mentioned as a target, then this invocation of
* `make' will be run serially, even if the `-j' option is given.
* Any recursively invoked `make' command will still be run in
* parallel (unless its makefile contains this target). Any
* prerequisites on this target are ignored.
*/
public interface INotParallelRule extends ISpecialRule {
}

View file

@ -0,0 +1,22 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.ISpecialRule;
/**
* .PHONY
* The prerequisites of the special target `.PHONY' are considered to be phony targets.
* When it is time to consider such a target, `make' will run its commands unconditionally, regardless of
* whether a file with that name exists or what its last-modification time is.
*/
public interface IPhonyRule extends ISpecialRule {
}

View file

@ -0,0 +1,24 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.ISpecialRule;
/**
* .SECONDARY
* The targets which `.SECONDARY' depends on are treated as
* intermediate files, except that they are never automatically deleted.
*
* `.SECONDARY' with no prerequisites causes all targets to be treated
* as secondary (i.e., no target is removed because it is considered intermediate).
*/
public interface ISecondaryRule extends ISpecialRule {
}

View file

@ -0,0 +1,24 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.IDirective;
/**
* ITerminal finish a block.
*/
public interface ITerminal extends IDirective {
boolean isEndef();
boolean isEndif();
}

View file

@ -0,0 +1,18 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile.gnu;
/**
*/
public interface IUnExport {
String getVariable();
}

View file

@ -0,0 +1,22 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.IDirective;
/**
*/
public interface IVPath extends IDirective {
String[] getDirectories();
String getPattern();
}

View file

@ -0,0 +1,43 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.IMacroDefinition;
/**
*/
public interface IVariableDefinition extends IMacroDefinition {
boolean isRecursivelyExpanded();
boolean isSimplyExpanded();
boolean isConditional();
boolean isAppend();
boolean isTargetSpecific();
boolean isExport();
boolean isMultiLine();
/**
* Variable from an `override' directive.
*/
boolean isOverride();
/**
* Automatic variable -- cannot be set.
*/
boolean isAutomatic();
String getTarget();
}

View file

@ -38,13 +38,14 @@ import org.eclipse.cdt.make.core.makefile.ITargetRule;
public abstract class AbstractMakefile extends Parent implements IMakefile {
public AbstractMakefile() {
public AbstractMakefile(Directive parent) {
super(parent);
}
public abstract IDirective[] getBuiltins();
public IRule[] getRules() {
IDirective[] stmts = getStatements();
IDirective[] stmts = getDirectives();
List array = new ArrayList(stmts.length);
for (int i = 0; i < stmts.length; i++) {
if (stmts[i] instanceof IRule) {
@ -110,7 +111,7 @@ public abstract class AbstractMakefile extends Parent implements IMakefile {
}
public IMacroDefinition[] getMacroDefinitions() {
IDirective[] stmts = getStatements();
IDirective[] stmts = getDirectives();
List array = new ArrayList(stmts.length);
for (int i = 0; i < stmts.length; i++) {
if (stmts[i] instanceof IMacroDefinition) {

View file

@ -10,11 +10,14 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile;
public class BadStatement extends Statement {
import org.eclipse.cdt.make.core.makefile.IBadDirective;
public class BadDirective extends Directive implements IBadDirective {
String line;
public BadStatement(String s) {
public BadDirective(Directive parent, String s) {
super(parent);
line = s;
}

View file

@ -21,14 +21,15 @@ import org.eclipse.cdt.make.core.makefile.ICommand;
* command : <tab> prefix_command string <nl>
* prefix_command : '-' | '@' | '+'
*/
public class Command extends Statement implements ICommand {
public class Command extends Directive implements ICommand {
final public static char NL = '\n';
String command = "";
char prefix = '\0';
public Command(String cmd) {
public Command(Directive parent, String cmd) {
super(parent);
parse(cmd);
}

View file

@ -12,11 +12,12 @@ package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.IComment;
public class Comment extends Statement implements IComment {
public class Comment extends Directive implements IComment {
String comment;
public Comment(String cmt) {
public Comment(Directive parent, String cmt) {
super(parent);
if (cmt.startsWith(POUND_STRING)) {
comment = cmt.substring(1);
} else {

View file

@ -10,7 +10,6 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.ICommand;
import org.eclipse.cdt.make.core.makefile.IDefaultRule;
/**
@ -20,8 +19,8 @@ import org.eclipse.cdt.make.core.makefile.IDefaultRule;
*/
public class DefaultRule extends SpecialRule implements IDefaultRule {
public DefaultRule(ICommand[] cmds) {
super(new Target(".DEFAULT"), new String[0], cmds);
public DefaultRule(Directive parent, Command[] cmds) {
super(parent, new Target(".DEFAULT"), new String[0], cmds);
}
}

View file

@ -12,15 +12,17 @@ package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.IDirective;
public abstract class Statement implements IDirective {
public abstract class Directive implements IDirective {
int endLine;
int startLine;
Directive parent;
public Statement() {
public Directive(Directive owner) {
parent = owner;
}
public Statement(int start, int end) {
public Directive(int start, int end) {
setLines(start, end);
}
@ -33,10 +35,6 @@ public abstract class Statement implements IDirective {
return endLine;
}
public void setEndLine(int lineno) {
endLine = lineno;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.make.core.makefile.IDirective#getStartLine()
*/
@ -44,10 +42,25 @@ public abstract class Statement implements IDirective {
return startLine;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.make.core.makefile.IDirective#getParent()
*/
public IDirective getParent() {
return parent;
}
public void setParent(Directive owner) {
parent = owner;
}
public void setStartLine(int lineno) {
startLine = lineno;
}
public void setEndLine(int lineno) {
endLine = lineno;
}
public void setLines(int start, int end) {
setStartLine(start);
setEndLine(end);

View file

@ -1,3 +1,4 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
@ -12,13 +13,13 @@ package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.IEmptyLine;
public class EmptyLine extends Statement implements IEmptyLine {
public class EmptyLine extends Directive implements IEmptyLine {
final public static char NL = '\n';
final public static String NL_STRING = "\n";
public EmptyLine() {
super();
public EmptyLine(Directive parent) {
super(parent);
}
public String toString() {

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.IIgnoreRule;
import org.eclipse.cdt.make.core.makefile.ICommand;
/**
* .IGNORE
@ -21,8 +20,8 @@ import org.eclipse.cdt.make.core.makefile.ICommand;
*/
public class IgnoreRule extends SpecialRule implements IIgnoreRule {
public IgnoreRule(String[] reqs) {
super(new Target(".IGNORE"), reqs, new ICommand[0]);
public IgnoreRule(Directive parent, String[] reqs) {
super(parent, new Target(".IGNORE"), reqs, new Command[0]);
}
}

View file

@ -11,20 +11,19 @@
package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.ICommand;
import org.eclipse.cdt.make.core.makefile.ITarget;
public class InferenceRule extends Rule {
public InferenceRule(ITarget target) {
this(target, new Command[0]);
public InferenceRule(Directive parent, Target target) {
this(parent, target, new Command[0]);
}
public InferenceRule(String tgt, ICommand[] cmds) {
this(new Target(tgt), cmds);
public InferenceRule(Directive parent, String tgt, Command[] cmds) {
this(parent, new Target(tgt), cmds);
}
public InferenceRule(ITarget target, ICommand[] cmds) {
super(target, cmds);
public InferenceRule(Directive parent, Target target, Command[] cmds) {
super(parent, target, cmds);
}
/**

View file

@ -14,7 +14,7 @@ import org.eclipse.cdt.make.core.makefile.IMacroDefinition;
/**
*/
public class MacroDefinition extends Statement implements IMacroDefinition {
public class MacroDefinition extends Directive implements IMacroDefinition {
String name;
StringBuffer value;
boolean fromCommand;
@ -23,11 +23,8 @@ public class MacroDefinition extends Statement implements IMacroDefinition {
boolean fromEnvironment;
boolean fromEnvironmentOverride;
public MacroDefinition(String n, String v) {
this(n, new StringBuffer(v));
}
public MacroDefinition(String n, StringBuffer v) {
public MacroDefinition(Directive parent, String n, StringBuffer v) {
super(parent);
name = n;
value = v;
}

View file

@ -36,9 +36,10 @@ public class NullMakefile extends AbstractMakefile {
public static IDirective[] empty = new IDirective[0];
public NullMakefile() {
super(null);
}
public IDirective[] getStatements() {
public IDirective[] getDirectives() {
return empty;
}
@ -46,7 +47,7 @@ public class NullMakefile extends AbstractMakefile {
return empty;
}
public void addStatement(IDirective statement) {
public void addDirective(IDirective directive) {
}
public String toString() {

View file

@ -20,35 +20,50 @@ import org.eclipse.cdt.make.core.makefile.IDirective;
* IParent
*/
public abstract class Parent extends Statement implements IParent {
public abstract class Parent extends Directive implements IParent {
ArrayList children = new ArrayList();
public IDirective[] getStatements() {
public Parent(Directive parent) {
super(parent);
}
public IDirective[] getDirectives() {
children.trimToSize();
return (IDirective[]) children.toArray(new IDirective[0]);
}
public void addStatement(IDirective statement) {
children.add(statement);
public void addDirective(Directive directive) {
children.add(directive);
// reparent
directive.setParent(this);
}
public void addStatements(IDirective[] statements) {
children.addAll(Arrays.asList(statements));
public void addDirectives(Directive[] directives) {
children.addAll(Arrays.asList(directives));
// reparent
for (int i = 0; i < directives.length; i++) {
directives[i].setParent(this);
}
}
public void clearStatements() {
public void clearDirectives() {
children.clear();
}
public Directive[] getStatements() {
children.trimToSize();
return (Directive[]) children.toArray(new Directive[0]);
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString() {
StringBuffer sb = new StringBuffer();
IDirective[] stmts = getStatements();
for (int i = 0; i < stmts.length; i++) {
sb.append(stmts[i]);
IDirective[] directives = getDirectives();
for (int i = 0; i < directives.length; i++) {
sb.append(directives[i]);
}
return sb.toString();
}

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.IPosixRule;
import org.eclipse.cdt.make.core.makefile.ICommand;
/**
* .POSIX
@ -20,7 +19,7 @@ import org.eclipse.cdt.make.core.makefile.ICommand;
*/
public class PosixRule extends SpecialRule implements IPosixRule {
public PosixRule() {
super(new Target(".POSIX:"), new String[0], new ICommand[0]);
public PosixRule(Directive parent) {
super(parent, new Target(".POSIX"), new String[0], new Command[0]);
}
}

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.IPreciousRule;
import org.eclipse.cdt.make.core.makefile.ICommand;
/**
* .PRECIOUS
@ -20,8 +19,8 @@ import org.eclipse.cdt.make.core.makefile.ICommand;
*/
public class PreciousRule extends SpecialRule implements IPreciousRule {
public PreciousRule(String[] targets) {
super(new Target(".PRECIOUS:"), targets, new ICommand[0]);
public PreciousRule(Directive parent, String[] reqs) {
super(parent, new Target(".PRECIOUS"), reqs, new Command[0]);
}
}

View file

@ -10,6 +10,8 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile;
import java.util.ArrayList;
import org.eclipse.cdt.make.core.makefile.ICommand;
import org.eclipse.cdt.make.core.makefile.IRule;
import org.eclipse.cdt.make.core.makefile.IDirective;
@ -17,29 +19,34 @@ import org.eclipse.cdt.make.core.makefile.ITarget;
public abstract class Rule extends Parent implements IRule {
ITarget target;
Target target;
public Rule(ITarget tgt) {
this(tgt, new Command[0]);
public Rule(Directive parent, Target tgt) {
this(parent, tgt, new Command[0]);
}
public Rule(ITarget tgt, ICommand[] cmds) {
public Rule(Directive parent, Target tgt, Command[] cmds) {
super(parent);
target = tgt;
addStatements(cmds);
addDirectives(cmds);
}
public ICommand[] getCommands() {
IDirective[] stmts = getStatements();
ICommand[] cmds = new ICommand[stmts.length];
System.arraycopy(stmts, 0, cmds, 0, stmts.length);
return cmds;
IDirective[] directives = getDirectives();
ArrayList cmds = new ArrayList(directives.length);
for (int i = 0; i < directives.length; i++) {
if (directives[i] instanceof ICommand) {
cmds.add(directives[i]);
}
}
return (ICommand[])cmds.toArray(new ICommand[0]);
}
public ITarget getTarget() {
return target;
}
public void setTarget(ITarget tgt) {
public void setTarget(Target tgt) {
target = tgt;
}

View file

@ -10,7 +10,6 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.ICommand;
import org.eclipse.cdt.make.core.makefile.ISccsGetRule;
/**
@ -22,8 +21,8 @@ import org.eclipse.cdt.make.core.makefile.ISccsGetRule;
*/
public class SccsGetRule extends SpecialRule implements ISccsGetRule {
public SccsGetRule(ICommand[] cmds) {
super(new Target(".SCCS_GET"), new String[0], cmds);
public SccsGetRule(Directive parent, Command[] cmds) {
super(parent, new Target(".SCCS_GET"), new String[0], cmds);
}
}

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.ISilentRule;
import org.eclipse.cdt.make.core.makefile.ICommand;
/**
* .SILENT
@ -21,8 +20,8 @@ import org.eclipse.cdt.make.core.makefile.ICommand;
*/
public class SilentRule extends SpecialRule implements ISilentRule {
public SilentRule(String[] reqs) {
super(new Target(".SILENT"), reqs, new ICommand[0]);
public SilentRule(Directive parent, String[] reqs) {
super(parent, new Target(".SILENT"), reqs, new Command[0]);
}
}

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.ISpecialRule;
import org.eclipse.cdt.make.core.makefile.ITarget;
import org.eclipse.cdt.make.core.makefile.ICommand;
/**
@ -21,8 +20,8 @@ public abstract class SpecialRule extends Rule implements ISpecialRule {
String[] prerequisites;
public SpecialRule(ITarget target, String[] reqs, ICommand[] cmds) {
super(target, cmds);
public SpecialRule(Directive parent, Target target, String[] reqs, Command[] cmds) {
super(parent, target, cmds);
prerequisites = reqs;
}

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.ISuffixesRule;
import org.eclipse.cdt.make.core.makefile.ICommand;
/**
* .SUFFIXES
@ -21,8 +20,8 @@ import org.eclipse.cdt.make.core.makefile.ICommand;
*/
public class SuffixesRule extends SpecialRule implements ISuffixesRule {
public SuffixesRule(String[] suffixes) {
super(new Target(".SUFFIXES:"), suffixes, new ICommand[0]);
public SuffixesRule(Directive parent, String[] suffixes) {
super(parent, new Target(".SUFFIXES"), suffixes, new Command[0]);
}
}

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.ICommand;
import org.eclipse.cdt.make.core.makefile.ITarget;
import org.eclipse.cdt.make.core.makefile.ITargetRule;
/**
@ -34,16 +33,16 @@ public class TargetRule extends Rule implements ITargetRule {
String[] prerequisites;
public TargetRule(ITarget target) {
this(target, new String[0], new ICommand[0]);
public TargetRule(Directive parent, Target target) {
this(parent, target, new String[0], new Command[0]);
}
public TargetRule(ITarget target, String[] deps) {
this(target, deps, new ICommand[0]);
public TargetRule(Directive parent, Target target, String[] deps) {
this(parent, target, deps, new Command[0]);
}
public TargetRule(ITarget target, String[] reqs, ICommand[] commands) {
super(target, commands);
public TargetRule(Directive parent, Target target, String[] reqs, Command[] commands) {
super(parent, target, commands);
prerequisites = reqs;
}

View file

@ -10,24 +10,28 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.gnu.IConditional;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
import org.eclipse.cdt.make.internal.core.makefile.Parent;
public abstract class Conditional extends Parent {
public abstract class Conditional extends Parent implements IConditional {
String cond;
String arg1;
String arg2;
public Conditional(String conditional) {
public Conditional(Directive parent, String conditional) {
super(parent);
cond = conditional;
parse();
}
public Conditional() {
this("", "", "");
public Conditional(Directive parent) {
this(parent, "", "", "");
}
public Conditional(String conditional, String argument1, String argument2) {
public Conditional(Directive parent, String conditional, String argument1, String argument2) {
super(parent);
arg1 = argument1;
arg2 = argument2;
cond = conditional;
@ -46,15 +50,39 @@ public abstract class Conditional extends Parent {
return arg2;
}
public boolean isIfdef() {
return false;
}
public boolean isIfndef() {
return false;
}
public boolean isIfeq() {
return false;
}
public boolean isIfneq() {
return false;
}
public boolean isElse() {
return false;
}
public boolean isEndif() {
return false;
}
/**
* Formats of the contional.
* Formats of the conditional string.
* ifeq (ARG1, ARG2)
* ifeq 'ARG1' 'ARG2'
* ifeq "ARG1" "ARG2"
* ifeq "ARG1" 'ARG2'
* ifeq 'ARG1' "ARG2"
*/
void parse() {
protected void parse() {
String line = getConditional().trim();
char terminal = line.charAt(0) == '(' ? ',' : line.charAt(0);

View file

@ -10,15 +10,16 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class DefineVariable extends VariableDefinition {
public DefineVariable(String name, StringBuffer value) {
super(name, value);
public DefineVariable(Directive parent, String name, StringBuffer value) {
super(parent, name, value);
}
public boolean isMultiline() {
public boolean isMultiLine() {
return true;
}

View file

@ -0,0 +1,32 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.gnu.IDeleteOnErrorRule;
import org.eclipse.cdt.make.internal.core.makefile.Command;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
import org.eclipse.cdt.make.internal.core.makefile.SpecialRule;
import org.eclipse.cdt.make.internal.core.makefile.Target;
/**
* .DELETE_ON_ERROR
* If `.DELETE_ON_ERROR' is mentioned as a target anywhere in the
* makefile, then `make' will delete the target of a rule if it has
* changed and its commands exit with a nonzero exit status, just as
* it does when it receives a signal.
*/
public class DeleteOnErrorRule extends SpecialRule implements IDeleteOnErrorRule {
public DeleteOnErrorRule(Directive parent, String[] reqs) {
super(parent, new Target(".DELETE_ON_ERROR"), reqs, new Command[0]);
}
}

View file

@ -10,11 +10,17 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class Else extends Conditional {
public Else(Directive parent) {
super(parent);
}
public Else() {
super();
public boolean isElse() {
return true;
}
public String toString() {

View file

@ -10,16 +10,16 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Statement;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class Endef extends Terminal {
public class Endef extends Statement {
public Endef() {
public Endef(Directive parent) {
super(parent);
}
public String toString() {
return "endef";
public boolean isEndef() {
return true;
}
}

View file

@ -10,13 +10,16 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
public class Endif extends Conditional {
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public Endif() {
super();
public class Endif extends Terminal {
public Endif(Directive parent) {
super(parent);
}
public String toString() {
return "endif";
public boolean isEndif() {
return true;
}
}

View file

@ -0,0 +1,30 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.gnu.IExportAllVariablesRule;
import org.eclipse.cdt.make.internal.core.makefile.Command;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
import org.eclipse.cdt.make.internal.core.makefile.SpecialRule;
import org.eclipse.cdt.make.internal.core.makefile.Target;
/**
* .EXPORT_ALL_VARIABLES
* Simply by being mentioned as a target, this tells `make' to export
* all variables to child processes by default.
*/
public class ExportAllVariablesRule extends SpecialRule implements IExportAllVariablesRule {
public ExportAllVariablesRule(Directive parent, String[] reqs) {
super(parent, new Target(".EXPORT_ALL_VARIABLES"), reqs, new Command[0]);
}
}

View file

@ -10,11 +10,13 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class ExportVariable extends VariableDefinition {
public ExportVariable(String name, StringBuffer value, int type) {
super(name, value, type);
public ExportVariable(Directive parent, String name, StringBuffer value, int type) {
super(parent, name, value, type);
}
public boolean isExport() {

View file

@ -10,39 +10,42 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.StringTokenizer;
import org.eclipse.cdt.make.core.makefile.ICommand;
import org.eclipse.cdt.make.core.MakeCorePlugin;
import org.eclipse.cdt.make.core.makefile.IDirective;
import org.eclipse.cdt.make.core.makefile.gnu.IGNUMakefile;
import org.eclipse.cdt.make.internal.core.makefile.AbstractMakefile;
import org.eclipse.cdt.make.internal.core.makefile.BadStatement;
import org.eclipse.cdt.make.internal.core.makefile.BadDirective;
import org.eclipse.cdt.make.internal.core.makefile.Command;
import org.eclipse.cdt.make.internal.core.makefile.Comment;
import org.eclipse.cdt.make.internal.core.makefile.DefaultRule;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
import org.eclipse.cdt.make.internal.core.makefile.EmptyLine;
import org.eclipse.cdt.make.internal.core.makefile.IgnoreRule;
import org.eclipse.cdt.make.internal.core.makefile.InferenceRule;
import org.eclipse.cdt.make.internal.core.makefile.MacroDefinition;
import org.eclipse.cdt.make.internal.core.makefile.MakefileReader;
import org.eclipse.cdt.make.internal.core.makefile.Parent;
import org.eclipse.cdt.make.internal.core.makefile.PosixRule;
import org.eclipse.cdt.make.internal.core.makefile.PreciousRule;
import org.eclipse.cdt.make.internal.core.makefile.Rule;
import org.eclipse.cdt.make.internal.core.makefile.SccsGetRule;
import org.eclipse.cdt.make.internal.core.makefile.SilentRule;
import org.eclipse.cdt.make.internal.core.makefile.Statement;
import org.eclipse.cdt.make.internal.core.makefile.SpecialRule;
import org.eclipse.cdt.make.internal.core.makefile.SuffixesRule;
import org.eclipse.cdt.make.internal.core.makefile.Target;
import org.eclipse.cdt.make.internal.core.makefile.TargetRule;
import org.eclipse.cdt.make.internal.core.makefile.Util;
import org.eclipse.cdt.make.internal.core.makefile.posix.PosixBuiltinMacroDefinitions;
import org.eclipse.cdt.make.internal.core.makefile.posix.PosixBuiltinRules;
import org.eclipse.cdt.make.internal.core.makefile.posix.PosixMakefileUtil;
import org.eclipse.core.runtime.Path;
/**
* Makefile : ( statement ) *
@ -60,19 +63,27 @@ import org.eclipse.cdt.make.internal.core.makefile.posix.PosixMakefileUtil;
* internal_macro : "$<" | "$*" | "$@" | "$?" | "$%"
*/
public class GNUMakefile extends AbstractMakefile {
public class GNUMakefile extends AbstractMakefile implements IGNUMakefile {
public static String PATH_SEPARATOR = System.getProperty("path.separator", ":");
public static String FILE_SEPARATOR = System.getProperty("file.separator", "/");
String[] includeDirectories = new String[0];
IDirective[] builtins = null;
public GNUMakefile() {
super();
super(null);
}
public void parse(String name) throws IOException {
parse(new FileReader(name));
FileReader stream = new FileReader(name);
parse(stream);
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
}
}
}
public void parse(Reader reader) throws IOException {
@ -87,8 +98,8 @@ public class GNUMakefile extends AbstractMakefile {
int startLine = 0;
int endLine = 0;
// Clear any old statements.
clearStatements();
// Clear any old directives.
clearDirectives();
while ((line = reader.readLine()) != null) {
startLine = endLine + 1;
@ -101,20 +112,20 @@ public class GNUMakefile extends AbstractMakefile {
VariableDefinition def = (VariableDefinition) defines.pop();
def.setEndLine(endLine);
}
Endef endef = createEndef();
Endef endef = new Endef(this);
endef.setLines(startLine, endLine);
addStatement(conditions, endef);
addDirective(conditions, endef);
continue;
} else if (GNUMakefileUtil.isDefine(line)) {
VariableDefinition def = createVariableDefinition(line);
VariableDefinition def = parseVariableDefinition(line);
def.setLines(startLine, endLine);
addStatement(conditions, def);
addDirective(conditions, def);
defines.push(def);
continue;
} else if (GNUMakefileUtil.isOverrideDefine(line)) {
VariableDefinition oDef = createVariableDefinition(line);
VariableDefinition oDef = parseVariableDefinition(line);
oDef.setLines(startLine, endLine);
addStatement(conditions, oDef);
addDirective(conditions, oDef);
defines.push(oDef);
continue;
}
@ -132,43 +143,59 @@ public class GNUMakefile extends AbstractMakefile {
// 1- Try command first, since we can not strip '#' in command line
if (GNUMakefileUtil.isCommand(line)) {
Command cmd = createCommand(line);
Command cmd = new Command(this, line);
cmd.setLines(startLine, endLine);
if (!conditions.empty()) {
addStatement(conditions, cmd);
addDirective(conditions, cmd);
continue;
} else if (rules != null) {
// The command is added to the rules
for (int i = 0; i < rules.length; i++) {
rules[i].addStatement(cmd);
rules[i].addDirective(cmd);
rules[i].setEndLine(endLine);
}
continue;
}
// If we have no rules/condition for the command,
// give the other statements a chance by falling through
// give the other directives a chance by falling through
}
// 2- Strip away any comments.
int pound = Util.indexOfComment(line);
if (pound != -1) {
Comment cmt = createComment(line.substring(pound + 1));
Comment cmt = new Comment(this, line.substring(pound + 1));
cmt.setLines(startLine, endLine);
addStatement(conditions, cmt);
if (rules != null) {
// The comment is added to the rules.
for (int i = 0; i < rules.length; i++) {
rules[i].addDirective(cmt);
rules[i].setEndLine(endLine);
}
} else {
addDirective(conditions, cmt);
}
line = line.substring(0, pound);
// If all we have left are spaces continue
if (Util.isEmptyLine(line)) {
continue;
}
// The rest of the line maybe a valid statement.
// The rest of the line maybe a valid directives.
// keep on trying by falling through.
}
// 3- Empty lines ?
if (Util.isEmptyLine(line)) {
Statement empty = createEmptyLine();
Directive empty = new EmptyLine(this);
empty.setLines(startLine, endLine);
addStatement(conditions, empty);
if (rules != null) {
// The EmptyLine is added to the rules.
for (int i = 0; i < rules.length; i++) {
rules[i].addDirective(empty);
rules[i].setEndLine(endLine);
}
} else {
addDirective(conditions, empty);
}
continue;
}
@ -178,76 +205,77 @@ public class GNUMakefile extends AbstractMakefile {
rules = null;
if (GNUMakefileUtil.isElse(line)) {
Statement elseDirective = createConditional(line);
Conditional elseDirective = parseConditional(line);
elseDirective.setLines(startLine, endLine);
// Are we missing a if condition ?
if (!conditions.empty()) {
Statement cond = (Statement) conditions.pop();
Conditional cond = (Conditional) conditions.pop();
cond.setEndLine(endLine - 1);
}
addStatement(conditions, elseDirective);
addDirective(conditions, elseDirective);
conditions.push(elseDirective);
continue;
} else if (GNUMakefileUtil.isEndif(line)) {
Conditional endif = createConditional(line);
Endif endif = new Endif(this);
endif.setLines(startLine, endLine);
// Are we missing a if/else condition ?
if (!conditions.empty()) {
Statement cond = (Statement) conditions.pop();
cond.setEndLine(endLine - 1);
Conditional cond = (Conditional) conditions.pop();
cond.setEndLine(endLine);
}
addStatement(conditions, endif);
addDirective(conditions, endif);
continue;
}
// 5- Check for the conditionnals.
Statement statement = processConditions(line);
if (statement != null) {
statement.setLines(startLine, endLine);
addStatement(conditions, statement);
conditions.push(statement);
Directive directive = processConditions(line);
if (directive != null) {
directive.setLines(startLine, endLine);
addDirective(conditions, directive);
conditions.push(directive);
continue;
}
// 6- Check for other special gnu directives.
statement = processGNUDirectives(line);
if (statement != null) {
statement.setLines(startLine, endLine);
addStatement(conditions, statement);
directive = processGNUDirectives(line);
if (directive != null) {
directive.setLines(startLine, endLine);
addDirective(conditions, directive);
continue;
}
// 7- Check for GNU special rules.
Rule rule = processSpecialRules(line);
if (rule != null) {
rules = new Rule[] { rule };
rule.setLines(startLine, endLine);
addStatement(conditions, rule);
SpecialRule special = processSpecialRules(line);
if (special != null) {
rules = new Rule[] { special };
special.setLines(startLine, endLine);
addDirective(conditions, special);
continue;
}
// - Check for inference rule.
if (GNUMakefileUtil.isInferenceRule(line)) {
InferenceRule irule = createInferenceRule(line);
InferenceRule irule = parseInferenceRule(line);
irule.setLines(startLine, endLine);
addStatement(conditions, irule);
addDirective(conditions, irule);
rules = new Rule[] { irule };
continue;
}
// - Variable Definiton ?
if (GNUMakefileUtil.isVariableDefinition(line)) {
Statement stmt = createVariableDefinition(line);
Directive stmt = parseVariableDefinition(line);
stmt.setLines(startLine, endLine);
addStatement(conditions, stmt);
addDirective(conditions, stmt);
continue;
}
// - GNU Static Target rule ?
if (GNUMakefileUtil.isStaticTargetRule(line)) {
StaticTargetRule[] srules = createStaticTargetRule(line);
StaticTargetRule[] srules = parseStaticTargetRule(line);
for (int i = 0; i < srules.length; i++) {
srules[i].setLines(startLine, endLine);
addStatement(conditions, srules[i]);
addDirective(conditions, srules[i]);
}
rules = srules;
continue;
@ -255,76 +283,93 @@ public class GNUMakefile extends AbstractMakefile {
// - Target Rule ?
if (GNUMakefileUtil.isGNUTargetRule(line)) {
TargetRule[] trules = createGNUTargetRules(line);
TargetRule[] trules = parseGNUTargetRules(line);
for (int i = 0; i < trules.length; i++) {
trules[i].setLines(startLine, endLine);
addStatement(conditions, trules[i]);
addDirective(conditions, trules[i]);
}
rules = trules;
continue;
}
// XXX ?? Should not be here.
BadStatement stmt = new BadStatement(line);
BadDirective stmt = new BadDirective(this, line);
stmt.setLines(startLine, endLine);
addStatement(conditions, stmt);
addDirective(conditions, stmt);
}
setLines(1, endLine);
// TEST please remove.
//GNUMakefileValidator validator = new GNUMakefileValidator();
//validator.validateDirectives(null, getDirectives());
}
protected void addStatement(Stack conditions, IDirective statement) {
private void addDirective(Stack conditions, Directive directive) {
if (conditions.empty()) {
addStatement(statement);
addDirective(directive);
} else {
Parent p = (Parent) conditions.peek();
p.addStatement(statement);
p.setEndLine(statement.getEndLine());
Conditional cond = (Conditional) conditions.peek();
cond.addDirective(directive);
cond.setEndLine(directive.getEndLine());
}
}
protected Statement processConditions(String line) {
Statement stmt = null;
protected Conditional processConditions(String line) {
Conditional stmt = null;
if (GNUMakefileUtil.isIfdef(line)) {
stmt = createConditional(line);
stmt = parseConditional(line);
} else if (GNUMakefileUtil.isIfndef(line)) {
stmt = createConditional(line);
stmt = parseConditional(line);
} else if (GNUMakefileUtil.isIfeq(line)) {
stmt = createConditional(line);
stmt = parseConditional(line);
} else if (GNUMakefileUtil.isIfneq(line)) {
stmt = createConditional(line);
stmt = parseConditional(line);
}
return stmt;
}
protected Statement processGNUDirectives(String line) {
Statement stmt = null;
protected Directive processGNUDirectives(String line) {
Directive stmt = null;
if (GNUMakefileUtil.isUnExport(line)) {
stmt = createUnExport(line);
stmt = parseUnExport(line);
} else if (GNUMakefileUtil.isVPath(line)) {
stmt = createVPath(line);
stmt = parseVPath(line);
} else if (GNUMakefileUtil.isInclude(line)) {
stmt = createInclude(line);
stmt = parseInclude(line);
}
return stmt;
}
protected Rule processSpecialRules(String line) {
Rule stmt = null;
protected SpecialRule processSpecialRules(String line) {
SpecialRule stmt = null;
if (GNUMakefileUtil.isIgnoreRule(line)) {
stmt = createIgnoreRule(line);
stmt = parseSpecialRule(line);
} else if (GNUMakefileUtil.isPosixRule(line)) {
stmt = createPosixRule();
stmt = parseSpecialRule(line);
} else if (GNUMakefileUtil.isPreciousRule(line)) {
stmt = createPreciousRule(line);
stmt = parseSpecialRule(line);
} else if (GNUMakefileUtil.isSilentRule(line)) {
stmt = createSilentRule(line);
stmt = parseSpecialRule(line);
} else if (GNUMakefileUtil.isSuffixesRule(line)) {
stmt = createSuffixesRule(line);
stmt = parseSpecialRule(line);
} else if (GNUMakefileUtil.isDefaultRule(line)) {
stmt = createDefaultRule(line);
stmt = parseSpecialRule(line);
} else if (GNUMakefileUtil.isSccsGetRule(line)) {
stmt = createSccsGetRule(line);
stmt = parseSpecialRule(line);
} else if (GNUMakefileUtil.isPhonyRule(line)) {
stmt = parseSpecialRule(line);
} else if (GNUMakefileUtil.isIntermediateRule(line)) {
stmt = parseSpecialRule(line);
} else if (GNUMakefileUtil.isSecondaryRule(line)) {
stmt = parseSpecialRule(line);
} else if (GNUMakefileUtil.isDeleteOnErrorRule(line)) {
stmt = parseSpecialRule(line);
} else if (GNUMakefileUtil.isLowResolutionTimeRule(line)) {
stmt = parseSpecialRule(line);
} else if (GNUMakefileUtil.isExportAllVariablesRule(line)) {
stmt = parseSpecialRule(line);
} else if (GNUMakefileUtil.isNotParallelRule(line)) {
stmt = parseSpecialRule(line);
}
return stmt;
}
@ -333,56 +378,50 @@ public class GNUMakefile extends AbstractMakefile {
* @param line
* @return
*/
protected Rule createSuffixesRule(String line) {
protected SpecialRule parseSpecialRule(String line) {
line = line.trim();
String keyword = null;
String[] reqs = null;
SpecialRule special = null;
int index = Util.indexOf(line, ':');
if (index != -1) {
keyword = line.substring(0, index).trim();
String req = line.substring(index + 1);
String[] reqs = PosixMakefileUtil.findPrerequisites(req);
return new SuffixesRule(reqs);
reqs = GNUMakefileUtil.findPrerequisites(req);
} else {
keyword = line;
reqs = new String[0];
}
return new SuffixesRule(new String[0]);
}
/**
* @param line
* @return
*/
protected Rule createSilentRule(String line) {
int index = Util.indexOf(line, ':');
if (index != -1) {
String req = line.substring(index + 1);
String[] reqs = GNUMakefileUtil.findPrerequisites(req);
return new SilentRule(reqs);
if (".IGNORE".equals(keyword)) {
special = new IgnoreRule(this, reqs);
} else if (".POSIX".equals(keyword)) {
special = new PosixRule(this);
} else if (".PRECIOUS".equals(keyword)) {
special = new PreciousRule(this, reqs);
} else if (".SILENT".equals(keyword)) {
special = new SilentRule(this, reqs);
} else if (".SUFFIXES".equals(keyword)) {
special = new SuffixesRule(this, reqs);
} else if (".DEFAULT".equals(keyword)) {
special = new DefaultRule(this, new Command[0]);
} else if (".SCCS_GET".equals(keyword)) {
special = new SccsGetRule(this, new Command[0]);
} else if (".PHONY".equals(keyword)) {
special = new PhonyRule(this, reqs);
} else if (".INTERMEDIATE".equals(keyword)) {
special = new IntermediateRule(this, reqs);
} else if (".SECONDARY".equals(keyword)) {
special = new SecondaryRule(this, reqs);
} else if (".DELETE_ON_ERROR".equals(keyword)) {
special = new DeleteOnErrorRule(this, reqs);
} else if (".LOW_RESOLUTION_TIME".equals(keyword)) {
special = new LowResolutionTimeRule(this, reqs);
} else if (".EXPORT_ALL_VARIABLES".equals(keyword)) {
special = new ExportAllVariablesRule(this, reqs);
} else if (".NOTPARALLEL".equals(keyword)) {
special = new NotParallelRule(this, reqs);
}
return new SilentRule(new String[0]);
}
/**
* @param line
* @return
*/
protected Rule createPreciousRule(String line) {
int index = Util.indexOf(line, ':');
if (index != -1) {
String req = line.substring(index + 1);
String[] reqs = GNUMakefileUtil.findPrerequisites(req);
return new PreciousRule(reqs);
}
return new PreciousRule(new String[0]);
}
/**
* @param line
* @return
*/
protected Rule createIgnoreRule(String line) {
int index = Util.indexOf(line, ':');
if (index != -1) {
String req = line.substring(index + 1);
String[] reqs = GNUMakefileUtil.findPrerequisites(req);
return new IgnoreRule(reqs);
}
return new IgnoreRule(new String[0]);
return special;
}
/**
@ -391,12 +430,11 @@ public class GNUMakefile extends AbstractMakefile {
* ifeq CONDITIONAL
* ifneq CONDITIONAL
* else
* endif
*
* @param line
* @return
*/
public Conditional createConditional(String line) {
protected Conditional parseConditional(String line) {
Conditional condition = null;
line = line.trim();
String keyword = null;
@ -412,17 +450,15 @@ public class GNUMakefile extends AbstractMakefile {
keyword = line;
}
if (keyword.equals("ifdef")) {
condition = new Ifdef(line);
condition = new Ifdef(this, line);
} else if (keyword.equals("ifndef")) {
condition = new Ifndef(line);
condition = new Ifndef(this, line);
} else if (keyword.equals("ifeq")) {
condition = new Ifeq(line);
condition = new Ifeq(this, line);
} else if (keyword.equals("ifneq")) {
condition = new Ifneq(line);
condition = new Ifneq(this, line);
} else if (keyword.equals("else")) {
condition = new Else();
} else if (keyword.equals("endif")) {
condition = new Endif();
condition = new Else(this);
}
return condition;
}
@ -431,7 +467,7 @@ public class GNUMakefile extends AbstractMakefile {
* Format of the include directive:
* include filename1 filename2 ...
*/
protected Include createInclude(String line) {
protected Include parseInclude(String line) {
String[] filenames;
StringTokenizer st = new StringTokenizer(line);
int count = st.countTokens();
@ -448,7 +484,7 @@ public class GNUMakefile extends AbstractMakefile {
} else {
filenames = new String[0];
}
return new Include(filenames, getIncludeDirectories());
return new Include(this, filenames, getIncludeDirectories());
}
/**
@ -466,7 +502,7 @@ public class GNUMakefile extends AbstractMakefile {
* "vpath"
* Clear all search paths previously specified with `vpath' directives.
*/
public VPath createVPath(String line) {
protected VPath parseVPath(String line) {
String pattern = null;
String[] directories;
StringTokenizer st = new StringTokenizer(line);
@ -491,18 +527,14 @@ public class GNUMakefile extends AbstractMakefile {
if (pattern == null) {
pattern = new String();
}
return new VPath(pattern, directories);
}
public Endef createEndef() {
return new Endef();
return new VPath(this, pattern, directories);
}
/**
* @param line
* @return
*/
protected UnExport createUnExport(String line) {
protected UnExport parseUnExport(String line) {
// Pass over "unexport"
for (int i = 0; i < line.length(); i++) {
if (Util.isSpace(line.charAt(i))) {
@ -510,34 +542,10 @@ public class GNUMakefile extends AbstractMakefile {
break;
}
}
return new UnExport(line);
return new UnExport(this, line);
}
protected Command createCommand(String line) {
return new Command(line);
}
protected Comment createComment(String line) {
return new Comment(line);
}
protected EmptyLine createEmptyLine() {
return new EmptyLine();
}
protected InferenceRule[] createInferenceRules(String line) {
// Inference Rule
String tgt;
int index = Util.indexOf(line, ':');
if (index != -1) {
tgt = line.substring(0, index);
} else {
tgt = line;
}
return new InferenceRule[] { new InferenceRule(new Target(tgt))};
}
protected GNUTargetRule[] createGNUTargetRules(String line) {
protected GNUTargetRule[] parseGNUTargetRules(String line) {
String[] targetNames;
String[] normalReqs;
String[] orderReqs;
@ -586,15 +594,15 @@ public class GNUMakefile extends AbstractMakefile {
GNUTargetRule[] rules = new GNUTargetRule[targetNames.length];
for (int i = 0; i < targetNames.length; i++) {
rules[i] = new GNUTargetRule(createTarget(targetNames[i]), doubleColon, normalReqs, orderReqs, new ICommand[0]);
rules[i] = new GNUTargetRule(this, new Target(targetNames[i]), doubleColon, normalReqs, orderReqs, new Command[0]);
if (cmd != null) {
rules[i].addStatement(createCommand(cmd));
rules[i].addDirective(new Command(this, cmd));
}
}
return rules;
}
protected VariableDefinition createVariableDefinition(String line) {
protected VariableDefinition parseVariableDefinition(String line) {
line = line.trim();
VariableDefinition vd;
@ -634,7 +642,7 @@ public class GNUMakefile extends AbstractMakefile {
}
// Check for "define"
if (GNUMakefileUtil.isOverrideDefine(line)) {
if (GNUMakefileUtil.isDefine(line)) {
isDefine = true;
// Move pass the keyword define.
for (int i = 0; i < line.length(); i++) {
@ -680,27 +688,23 @@ public class GNUMakefile extends AbstractMakefile {
}
if (isTargetVariable) {
vd = new TargetVariable(targetName, name, value, isOverride, type);
vd = new TargetVariable(this, targetName, name, value, isOverride, type);
}
if (isOverride && isDefine) {
vd = new OverrideDefine(name, value);
vd = new OverrideDefine(this, name, value);
} else if (isDefine) {
vd = new DefineVariable(name, value);
vd = new DefineVariable(this, name, value);
} else if (isOverride) {
vd = new OverrideVariable(name, value, type);
vd = new OverrideVariable(this, name, value, type);
} else if (isExport) {
vd = new ExportVariable(name, value, type);
vd = new ExportVariable(this, name, value, type);
} else {
vd = new VariableDefinition(name, value, type);
vd = new VariableDefinition(this, name, value, type);
}
return vd;
}
protected Target createTarget(String line) {
return new Target(line);
}
protected StaticTargetRule[] createStaticTargetRule(String line) {
protected StaticTargetRule[] parseStaticTargetRule(String line) {
// first colon: the Targets
String targetPattern;
String[] prereqPatterns;
@ -733,7 +737,7 @@ public class GNUMakefile extends AbstractMakefile {
StaticTargetRule[] staticRules = new StaticTargetRule[targets.length];
for (int i = 0; i < targets.length; i++) {
staticRules[i] = new StaticTargetRule(createTarget(targets[i]), targetPattern, prereqPatterns, new ICommand[0]);
staticRules[i] = new StaticTargetRule(this, new Target(targets[i]), targetPattern, prereqPatterns, new Command[0]);
}
return staticRules;
}
@ -742,47 +746,7 @@ public class GNUMakefile extends AbstractMakefile {
* @param line
* @return
*/
private TargetRule[] createTargetRule(String line) {
String[] targets;
String[] reqs;
String cmd = null;
int index = Util.indexOf(line, ':');
if (index != -1) {
String target = line.substring(0, index);
// Tokenize the targets
targets = GNUMakefileUtil.findTargets(target);
String req = line.substring(index + 1);
int semicolon = Util.indexOf(req, ';');
if (semicolon != -1) {
String c = req.substring(semicolon + 1).trim();
if (c.length() > 0) {
cmd = c;
}
req = req.substring(0, semicolon);
}
reqs = GNUMakefileUtil.findPrerequisites(req);
} else {
targets = GNUMakefileUtil.findTargets(line);
reqs = new String[0];
}
TargetRule[] targetRules = new TargetRule[targets.length];
for (int i = 0; i < targets.length; i++) {
targetRules[i] = new TargetRule(new Target(targets[i]), reqs);
if (cmd != null) {
Command command = createCommand(cmd);
targetRules[i].addStatement(command);
}
}
return targetRules;
}
/**
* @param line
* @return
*/
private InferenceRule createInferenceRule(String line) {
protected InferenceRule parseInferenceRule(String line) {
String tgt;
int index = Util.indexOf(line, ':');
if (index != -1) {
@ -790,59 +754,33 @@ public class GNUMakefile extends AbstractMakefile {
} else {
tgt = line;
}
return new InferenceRule(new Target(tgt));
}
/**
* @param line
* @return
*/
private SccsGetRule createSccsGetRule(String line) {
int semicolon = Util.indexOf(line, ';');
if (semicolon != -1) {
String cmd = line.substring(semicolon + 1).trim();
if (cmd.length() > 0) {
ICommand[] cmds = new ICommand[] { new Command(cmd)};
return new SccsGetRule(cmds);
}
}
return new SccsGetRule(new ICommand[0]);
}
/**
* @param line
* @return
*/
private DefaultRule createDefaultRule(String line) {
int semicolon = Util.indexOf(line, ';');
if (semicolon > 0) {
String cmd = line.substring(semicolon + 1).trim();
if (cmd.length() > 0) {
ICommand[] cmds = new ICommand[] { new Command(cmd)};
return new DefaultRule(cmds);
}
}
return new DefaultRule(new ICommand[0]);
}
/**
* @return
*/
private PosixRule createPosixRule() {
return new PosixRule();
return new InferenceRule(this, new Target(tgt));
}
/* (non-Javadoc)
* @see org.eclipse.cdt.make.internal.core.makefile.AbstractMakefile#getBuiltins()
*/
public IDirective[] getBuiltins() {
IDirective[] macros = new PosixBuiltinMacroDefinitions().getMacroDefinitions();
IDirective[] rules = new PosixBuiltinRules().getInferenceRules();
IDirective[] stmts = new IDirective[macros.length + rules.length];
System.arraycopy(macros, 0, stmts, 0, macros.length);
System.arraycopy(rules, 0, stmts, macros.length, rules.length);
return stmts;
if (builtins == null) {
String location = "builtin" + File.separator + "gnu.mk";
try {
InputStream stream = MakeCorePlugin.getDefault().openStream(new Path(location));
GNUMakefile gnu = new GNUMakefile();
gnu.parse(new InputStreamReader(stream));
builtins = gnu.getDirectives();
for (int i = 0; i < builtins.length; i++) {
if (builtins[i] instanceof MacroDefinition) {
((MacroDefinition)builtins[i]).setFromDefault(true);
}
}
} catch (Exception e) {
//e.printStackTrace();
}
if (builtins == null) {
builtins = new IDirective[0];
}
}
return builtins;
}
public void setIncludeDirectories(String[] dirs) {
@ -861,10 +799,10 @@ public class GNUMakefile extends AbstractMakefile {
}
GNUMakefile makefile = new GNUMakefile();
makefile.parse(filename);
IDirective[] statements = makefile.getStatements();
for (int i = 0; i < statements.length; i++) {
IDirective[] directive = makefile.getDirectives();
for (int i = 0; i < directive.length; i++) {
//System.out.println("Rule[" + i +"]");
System.out.print(statements[i]);
System.out.print(directive[i]);
}
} catch (IOException e) {
System.out.println(e);

View file

@ -0,0 +1,152 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.model.ICModelMarker;
import org.eclipse.cdt.core.resources.ACBuilder;
import org.eclipse.cdt.make.core.makefile.IMakefileValidator;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
public class GNUMakefileChecker extends ACBuilder {
public class MyResourceDeltaVisitor implements IResourceDeltaVisitor {
IProgressMonitor monitor;
public MyResourceDeltaVisitor(IProgressMonitor monitor) {
this.monitor = monitor;
}
public boolean visit(IResourceDelta delta) throws CoreException {
IResource resource = delta.getResource();
if (resource != null && resource.getProject() == getProject()) {
if (resource instanceof IFile) {
// see if this a makefile candidate
IFile candidate = (IFile) resource;
if (isMakefileCandidate(candidate)) {
// ok verify.
if (delta.getKind() != IResourceDelta.REMOVED) {
checkMakefile(candidate, monitor);
}
}
}
}
return true;
}
}
protected Map validatorMap = new HashMap();
public GNUMakefileChecker() {
}
/**
* @see IncrementalProjectBuilder#build
*/
protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
IResourceDelta delta = null;
// For non-full-build fetch the deltas
if (kind != FULL_BUILD) {
delta = getDelta(getProject());
}
if (delta == null || kind == FULL_BUILD) {
// Full build
checkProject(getProject(), monitor);
} else {
MyResourceDeltaVisitor vis = new MyResourceDeltaVisitor(monitor);
if (delta != null) {
delta.accept(vis);
}
}
checkCancel(monitor);
return new IProject[0];
}
/**
* Check whether the build has been canceled.
*/
public void checkCancel(IProgressMonitor monitor) {
if (monitor != null && monitor.isCanceled()) {
throw new OperationCanceledException();
}
}
protected void checkProject(IProject project, IProgressMonitor monitor) {
IFile[] files = getCandidateMakefiles(project);
for (int i = 0; i < files.length; i++) {
checkMakefile(files[i], monitor);
}
}
protected boolean isMakefileCandidate(IFile file) {
IFile[] files = getCandidateMakefiles(file.getProject());
for (int i = 0; i < files.length; i++) {
if (files[i].getFullPath().equals(file.getFullPath())) {
return true;
}
}
return false;
}
protected void checkMakefile(IFile file, IProgressMonitor monitor) {
IMakefileValidator validator = getMakefileValidator(file);
try {
removeAllMarkers(file);
} catch (CoreException e) {
//e.printStackTrace();
}
validator.checkFile(file, monitor);
}
protected IFile[] getCandidateMakefiles(IProject proj) {
// FIXME: Find the candidate in the store somewhere.
IFile defaultMakefile = proj.getFile(new Path("Makefile"));
if (defaultMakefile.exists()) {
return new IFile[] {defaultMakefile};
}
return new IFile[0];
}
protected IMakefileValidator getMakefileValidator(IFile file) {
IMakefileValidator validator = (IMakefileValidator) validatorMap.get(file.getProject());
if (validator == null) {
// FIXME: look int the preference store for a value.
validator = new GNUMakefileValidator();
validator.setMarkerGenerator(this);
validatorMap.put(file.getProject(), validator);
}
return validator;
}
private void removeAllMarkers(IFile file) throws CoreException {
IWorkspace workspace = file.getWorkspace();
// remove all markers
IMarker[] markers = file.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
if (markers != null) {
workspace.deleteMarkers(markers);
}
}
}

View file

@ -152,4 +152,74 @@ public class GNUMakefileUtil extends PosixMakefileUtil {
return false;
}
public static boolean isPhonyRule(String line) {
line = line.trim();
int colon = Util.indexOf(line, ':');
if (colon > 0) {
line = line.substring(0, colon).trim();
return line.equals(".PHONY");
}
return false;
}
public static boolean isIntermediateRule(String line) {
line = line.trim();
int colon = Util.indexOf(line, ':');
if (colon > 0) {
line = line.substring(0, colon).trim();
return line.equals(".INTERMEDIATE");
}
return false;
}
public static boolean isSecondaryRule(String line) {
line = line.trim();
int colon = Util.indexOf(line, ':');
if (colon > 0) {
line = line.substring(0, colon).trim();
return line.equals(".SECONDARY");
}
return false;
}
public static boolean isDeleteOnErrorRule(String line) {
line = line.trim();
int colon = Util.indexOf(line, ':');
if (colon > 0) {
line = line.substring(0, colon).trim();
return line.equals(".DELETE_ON_ERROR");
}
return false;
}
public static boolean isLowResolutionTimeRule(String line) {
line = line.trim();
int colon = Util.indexOf(line, ':');
if (colon > 0) {
line = line.substring(0, colon).trim();
return line.equals(".LOW_RESOLUTION_TIME");
}
return false;
}
public static boolean isExportAllVariablesRule(String line) {
line = line.trim();
int colon = Util.indexOf(line, ':');
if (colon > 0) {
line = line.substring(0, colon).trim();
return line.equals(".EXPORT_ALL_VARIABLES");
}
return false;
}
public static boolean isNotParallelRule(String line) {
line = line.trim();
int colon = Util.indexOf(line, ':');
if (colon > 0) {
line = line.substring(0, colon).trim();
return line.equals(".NOTPARALLEL");
}
return false;
}
}

View file

@ -0,0 +1,216 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import org.eclipse.cdt.core.IMarkerGenerator;
import org.eclipse.cdt.make.core.makefile.*;
import org.eclipse.cdt.make.core.makefile.IBadDirective;
import org.eclipse.cdt.make.core.makefile.IDirective;
import org.eclipse.cdt.make.core.makefile.ISpecialRule;
import org.eclipse.cdt.make.core.makefile.gnu.IConditional;
import org.eclipse.cdt.make.core.makefile.gnu.ITerminal;
import org.eclipse.cdt.make.core.makefile.gnu.IVariableDefinition;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
public class GNUMakefileValidator implements IMakefileValidator {
IMarkerGenerator reporter;
public GNUMakefileValidator() {
}
public GNUMakefileValidator(IMarkerGenerator errorHandler) {
setMarkerGenerator(errorHandler);
}
public void setMarkerGenerator(IMarkerGenerator errorHandler) {
reporter = errorHandler;
}
public IMarkerGenerator getMarkerGenerator() {
if (reporter == null) {
reporter = new IMarkerGenerator() {
public void addMarker(IResource file, int lineNumber, String errorDesc, int severity, String errorVar) {
String name = "Makefile";
if (file != null) {
name = file.getName();
}
StringBuffer sb = new StringBuffer(name);
sb.append(':').append(lineNumber).append(':').append(getSeverity(severity));
if (errorDesc != null) {
sb.append(':').append(errorDesc);
}
if (errorVar != null ) {
sb.append(':').append(errorVar);
}
sb.append('\n');
System.out.println(sb.toString());
}
public String getSeverity(int severity) {
if (severity == IMarkerGenerator.SEVERITY_ERROR_BUILD) {
return "Error Build";
} else if (severity == IMarkerGenerator.SEVERITY_ERROR_RESOURCE) {
return "Error resource";
} else if (severity == IMarkerGenerator.SEVERITY_INFO) {
return "Warning info";
} else if (severity == IMarkerGenerator.SEVERITY_WARNING) {
return "Warning";
}
return "unknown";
}
};
}
return reporter;
}
public void checkFile(IFile file, IProgressMonitor monitor) {
String message = "Checking file : " + file.getFullPath().toString();
monitor.subTask(message);
GNUMakefile gnu = new GNUMakefile();
InputStream stream = null;
try {
stream = file.getContents();
Reader source = new InputStreamReader(stream);
gnu.parse(source);
validateDirectives(file, gnu.getDirectives());
} catch (CoreException e) {
} catch (IOException e) {
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
}
}
}
monitor.subTask("File checked");
monitor.done();
}
public void validateDirectives(IResource res, IDirective[] directives) {
IMarkerGenerator marker = getMarkerGenerator();
int conditionCount = 0;
int defineCount = 0;
IDirective directive = null;
for (int i = 0; i < directives.length; i++) {
directive = directives[i];
if (directive instanceof IConditional) {
IConditional condition = (IConditional)directive;
validateCondition(condition);
if (!condition.isElse()) {
conditionCount++;
} else {
if (conditionCount == 0) {
// ERROR else missing conditon.
int startLine = condition.getStartLine();
String msg = "else missing if condition";
int severity = IMarkerGenerator.SEVERITY_ERROR_RESOURCE;
String varName = condition.toString().trim();
marker.addMarker(res, startLine, msg, severity, varName);
}
}
} else if (directive instanceof ITerminal) {
ITerminal terminal = (ITerminal)directive;
if (terminal.isEndif()) {
if (conditionCount == 0) {
// ERROR missing condition.
int startLine = terminal.getStartLine();
String msg = "Endif missing if/else condition";
int severity = IMarkerGenerator.SEVERITY_ERROR_RESOURCE;
String varName = terminal.toString().trim();
marker.addMarker(res, startLine, msg, severity, varName);
} else {
conditionCount--;
}
} else if (terminal.isEndef()) {
if (defineCount == 0) {
// ERROR missing define.
int startLine = terminal.getStartLine();
String msg = "endef missing [override] define";
int severity = IMarkerGenerator.SEVERITY_ERROR_RESOURCE;
String varName = terminal.toString().trim();
marker.addMarker(res, startLine, msg, severity, varName);
} else {
defineCount--;
}
}
} else if (directive instanceof IVariableDefinition) {
IVariableDefinition definition = (IVariableDefinition)directive;
if (definition.isMultiLine()) {
defineCount++;
}
} else if (directive instanceof IBadDirective) {
// ERROR unknow statement.
int startLine = directive.getStartLine();
String msg = "unknow directive";
int severity = IMarkerGenerator.SEVERITY_ERROR_RESOURCE;
String varName = directive.toString().trim();
marker.addMarker(res, startLine, msg, severity, varName);
} else if (directive instanceof ISpecialRule) {
validateSpecialRule((ISpecialRule)directive);
}
}
if (conditionCount > 0) {
// ERROR no matching endif for condition.
int startLine = 0;
String varName = "";
int severity = IMarkerGenerator.SEVERITY_ERROR_RESOURCE;
for (int i = directives.length - 1; i >= 0; i--) {
if (directives[i] instanceof IConditional) {
startLine = directives[i].getStartLine();
varName = directives[i].toString().trim();
break;
}
}
String msg = "No matching endif for condition";
marker.addMarker(res, startLine, msg, severity, varName);
}
if (defineCount > 0) {
// ERROR no matching endef for define.
int startLine = 0;
String varName = "";
int severity = IMarkerGenerator.SEVERITY_ERROR_RESOURCE;
for (int i = directives.length - 1; i >= 0; i--) {
if (directives[i] instanceof IVariableDefinition) {
IVariableDefinition definition = (IVariableDefinition)directives[i];
if (definition.isMultiLine()) {
startLine = definition.getStartLine();
varName = definition.toString().trim();
break;
}
}
}
String msg = "No matching endef for [override] define";
marker.addMarker(res, startLine, msg, severity, varName);
}
}
public void validateCondition(IConditional condition) {
// Check if the condition are good formats
}
public void validateSpecialRule(ISpecialRule rule) {
// Check for special rules: .POSIX, .IGNORE etc ...
}
}

View file

@ -11,19 +11,20 @@
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.ICommand;
import org.eclipse.cdt.make.core.makefile.ITarget;
import org.eclipse.cdt.make.internal.core.makefile.Command;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
import org.eclipse.cdt.make.internal.core.makefile.Target;
import org.eclipse.cdt.make.internal.core.makefile.TargetRule;
/**
*/
public class GNUTargetRule extends TargetRule {
String[] orderOnlyPrerequisites;
boolean doubleColon;
public GNUTargetRule(ITarget target, boolean double_colon, String[] normal_prereqs, String[] order_prereqs, ICommand[] commands) {
super(target, normal_prereqs, commands);
public GNUTargetRule(Directive parent, Target target, boolean double_colon, String[] normal_prereqs, String[] order_prereqs, Command[] commands) {
super(parent, target, normal_prereqs, commands);
orderOnlyPrerequisites = order_prereqs;
doubleColon = double_colon;
}

View file

@ -10,10 +10,17 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class Ifdef extends Conditional {
public Ifdef(String var) {
super(var, "", "");
public Ifdef(Directive parent, String var) {
super(parent, var, "", "");
}
public boolean isIfdef() {
return true;
}
public String toString() {

View file

@ -10,10 +10,17 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class Ifeq extends Conditional {
public Ifeq(String cond) {
super(cond);
public Ifeq(Directive parent, String cond) {
super(parent, cond);
}
public boolean isIfeq() {
return true;
}
public String toString() {

View file

@ -10,10 +10,17 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class Ifndef extends Conditional {
public Ifndef(String var) {
super(var, "", "");
public Ifndef(Directive parent, String var) {
super(parent, var, "", "");
}
public boolean isIfndef() {
return true;
}
public String toString() {

View file

@ -10,10 +10,17 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class Ifneq extends Conditional {
public Ifneq(String cond) {
super(cond);
public Ifneq(Directive parent, String cond) {
super(parent, cond);
}
public boolean isIfneq() {
return true;
}
public String toString() {

View file

@ -13,14 +13,17 @@ package org.eclipse.cdt.make.internal.core.makefile.gnu;
import java.io.IOException;
import org.eclipse.cdt.make.core.makefile.IDirective;
import org.eclipse.cdt.make.core.makefile.gnu.IInclude;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
import org.eclipse.cdt.make.internal.core.makefile.Parent;
public class Include extends Parent {
public class Include extends Parent implements IInclude {
String[] filenames;
String[] dirs;
public Include(String[] files, String[] directories) {
public Include(Directive parent, String[] files, String[] directories) {
super(parent);
filenames = files;
dirs = directories;
}
@ -37,14 +40,14 @@ public class Include extends Parent {
return filenames;
}
public IDirective[] getStatements() {
public IDirective[] getDirectives() {
GNUMakefile gnu = new GNUMakefile();
clearStatements();
clearDirectives();
for (int i = 0; i < filenames.length; i++) {
// Try the current directory.
try {
gnu.parse(filenames[i]);
addStatements(gnu.getStatements());
addDirectives(gnu.getStatements());
continue;
} catch (IOException e) {
}
@ -53,13 +56,13 @@ public class Include extends Parent {
try {
String filename = dirs[j] + GNUMakefile.FILE_SEPARATOR + filenames[i];
gnu.parse(filename);
addStatements(gnu.getStatements());
addDirectives(gnu.getStatements());
break;
} catch (IOException e) {
}
}
}
}
return super.getStatements();
return super.getDirectives();
}
}

View file

@ -0,0 +1,30 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.gnu.IIntermediateRule;
import org.eclipse.cdt.make.internal.core.makefile.Command;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
import org.eclipse.cdt.make.internal.core.makefile.SpecialRule;
import org.eclipse.cdt.make.internal.core.makefile.Target;
/**
* .INTERMEDIATE
* The targets which `.INTERMEDIATE' depends on are treated as intermediate files.
* `.INTERMEDIATE' with no prerequisites has no effect.
*/
public class IntermediateRule extends SpecialRule implements IIntermediateRule {
public IntermediateRule(Directive parent, String[] reqs) {
super(parent, new Target(".INTERMEDIATE"), reqs, new Command[0]);
}
}

View file

@ -0,0 +1,31 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.gnu.ILowResolutionTimeRule;
import org.eclipse.cdt.make.internal.core.makefile.Command;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
import org.eclipse.cdt.make.internal.core.makefile.SpecialRule;
import org.eclipse.cdt.make.internal.core.makefile.Target;
/**
* .LOW_RESOLUTION_TIME'
* If you specify prerequisites for `.LOW_RESOLUTION_TIME', `make'
* assumes that these files are created by commands that generate low
* resolution time stamps.
*/
public class LowResolutionTimeRule extends SpecialRule implements ILowResolutionTimeRule {
public LowResolutionTimeRule(Directive parent, String[] reqs) {
super(parent, new Target(".LOW_RESOLUTION_TIME"), reqs, new Command[0]);
}
}

View file

@ -0,0 +1,33 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.gnu.INotParallelRule;
import org.eclipse.cdt.make.internal.core.makefile.Command;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
import org.eclipse.cdt.make.internal.core.makefile.SpecialRule;
import org.eclipse.cdt.make.internal.core.makefile.Target;
/**
* .NOTPARALLEL
* If `.NOTPARALLEL' is mentioned as a target, then this invocation of
* `make' will be run serially, even if the `-j' option is given.
* Any recursively invoked `make' command will still be run in
* parallel (unless its makefile contains this target). Any
* prerequisites on this target are ignored.
*/
public class NotParallelRule extends SpecialRule implements INotParallelRule {
public NotParallelRule(Directive parent, String[] reqs) {
super(parent, new Target(".NOTPARALLEL"), reqs, new Command[0]);
}
}

View file

@ -10,13 +10,13 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class OverrideDefine extends DefineVariable {
public OverrideDefine(String name, StringBuffer value) {
super(name, value);
public OverrideDefine(Directive parent, String name, StringBuffer value) {
super(parent, name, value);
}
public String toString() {

View file

@ -10,12 +10,13 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class OverrideVariable extends VariableDefinition {
public OverrideVariable(String name, StringBuffer value, int type) {
super(name, value, type);
public OverrideVariable(Directive parent, String name, StringBuffer value, int type) {
super(parent, name, value, type);
}
public boolean isOverride() {

View file

@ -0,0 +1,31 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.gnu.IPhonyRule;
import org.eclipse.cdt.make.internal.core.makefile.Command;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
import org.eclipse.cdt.make.internal.core.makefile.SpecialRule;
import org.eclipse.cdt.make.internal.core.makefile.Target;
/**
* .PHONY
* The prerequisites of the special target `.PHONY' are considered to be phony targets.
* When it is time to consider such a target, `make' will run its commands unconditionally, regardless of
* whether a file with that name exists or what its last-modification time is.
*/
public class PhonyRule extends SpecialRule implements IPhonyRule {
public PhonyRule(Directive parent, String[] reqs) {
super(parent, new Target(".PHONY"), reqs, new Command[0]);
}
}

View file

@ -0,0 +1,33 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.gnu.ISecondaryRule;
import org.eclipse.cdt.make.internal.core.makefile.Command;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
import org.eclipse.cdt.make.internal.core.makefile.SpecialRule;
import org.eclipse.cdt.make.internal.core.makefile.Target;
/**
* .SECONDARY
* The targets which `.SECONDARY' depends on are treated as
* intermediate files, except that they are never automatically deleted.
*
* `.SECONDARY' with no prerequisites causes all targets to be treated
* as secondary (i.e., no target is removed because it is considered intermediate).
*/
public class SecondaryRule extends SpecialRule implements ISecondaryRule {
public SecondaryRule(Directive parent, String[] reqs) {
super(parent, new Target(".SECONDARY"), reqs, new Command[0]);
}
}

View file

@ -12,8 +12,10 @@ package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.ICommand;
import org.eclipse.cdt.make.core.makefile.IInferenceRule;
import org.eclipse.cdt.make.core.makefile.ITarget;
import org.eclipse.cdt.make.internal.core.makefile.Command;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
import org.eclipse.cdt.make.internal.core.makefile.InferenceRule;
import org.eclipse.cdt.make.internal.core.makefile.Target;
/**
@ -28,8 +30,8 @@ public class StaticTargetRule extends InferenceRule implements IInferenceRule {
String targetPattern;
String[] prereqPatterns;
public StaticTargetRule(ITarget target, String target_pattern, String[] prereq_patterns, ICommand[] commands) {
super(target, commands);
public StaticTargetRule(Directive parent, Target target, String target_pattern, String[] prereq_patterns, Command[] commands) {
super(parent, target, commands);
targetPattern = target_pattern;
prereqPatterns = prereq_patterns;
}

View file

@ -10,7 +10,7 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
/**
* Here is the syntax of a static pattern rule:
@ -22,8 +22,8 @@ public class TargetVariable extends VariableDefinition {
boolean override;
public TargetVariable(String target, String name, StringBuffer value, boolean override, int type) {
super(target, name, value, type);
public TargetVariable(Directive parent, String target, String name, StringBuffer value, boolean override, int type) {
super(parent, target, name, value, type);
this.override = override;
}

View file

@ -0,0 +1,38 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.gnu.ITerminal;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class Terminal extends Directive implements ITerminal {
public Terminal(Directive parent) {
super(parent);
}
public boolean isEndif() {
return false;
}
public boolean isEndef() {
return false;
}
public String toString() {
if (isEndif()) {
return "endif\n";
} else if (isEndef()){
return "endef\n";
}
return "\n";
}
}

View file

@ -10,13 +10,15 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Statement;
import org.eclipse.cdt.make.core.makefile.gnu.IUnExport;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class UnExport extends Statement {
public class UnExport extends Directive implements IUnExport {
String variable;
public UnExport(String var) {
public UnExport(Directive parent, String var) {
super(parent);
variable = var;
}

View file

@ -10,14 +10,16 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Statement;
import org.eclipse.cdt.make.core.makefile.gnu.IVPath;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class VPath extends Statement {
public class VPath extends Directive implements IVPath {
String pattern;
String[] directories;
public VPath(String pat, String[] dirs) {
public VPath(Directive parent, String pat, String[] dirs) {
super(parent);
pattern = pat;
directories = dirs;
}

View file

@ -10,11 +10,13 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.core.makefile.gnu.IVariableDefinition;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
import org.eclipse.cdt.make.internal.core.makefile.MacroDefinition;
/**
*/
public class VariableDefinition extends MacroDefinition {
public class VariableDefinition extends MacroDefinition implements IVariableDefinition {
/**
* ? is Conditional
@ -29,16 +31,16 @@ public class VariableDefinition extends MacroDefinition {
int type;
String varTarget;
public VariableDefinition(String name, StringBuffer value) {
this(name, value, TYPE_RECURSIVE_EXPAND);
public VariableDefinition(Directive parent, String name, StringBuffer value) {
this(parent, name, value, TYPE_RECURSIVE_EXPAND);
}
public VariableDefinition(String name, StringBuffer value, int type) {
this("", name, value, type);
public VariableDefinition(Directive parent, String name, StringBuffer value, int type) {
this(parent, "", name, value, type);
}
public VariableDefinition(String target, String name, StringBuffer value, int type) {
super(name, value);
public VariableDefinition(Directive parent, String target, String name, StringBuffer value, int type) {
super(parent, name, value);
varTarget = target;
this.type = type;
}
@ -78,10 +80,6 @@ public class VariableDefinition extends MacroDefinition {
return sb.toString();
}
public boolean equals(VariableDefinition v) {
return v.getName().equals(getName());
}
public boolean isRecursivelyExpanded() {
return type == TYPE_RECURSIVE_EXPAND;
}
@ -100,7 +98,7 @@ public class VariableDefinition extends MacroDefinition {
public boolean isTargetSpecific() {
String t = getTarget();
return t == null || t.length() == 0;
return t != null && t.length() > 0;
}
public boolean isExport() {

View file

@ -1,47 +0,0 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.posix;
import org.eclipse.cdt.make.internal.core.makefile.MacroDefinition;
public class PosixBuiltinMacroDefinitions {
MacroDefinition[] macros =
new MacroDefinition[] {
new MacroDefinition("MAKE", "make"),
new MacroDefinition("AR", "ar"),
new MacroDefinition("ARFLAGS", "-rv"),
new MacroDefinition("YACC", "yacc"),
new MacroDefinition("YFLAGS", ""),
new MacroDefinition("LEX", "lex"),
new MacroDefinition("LFLAGS", ""),
new MacroDefinition("LDFLAGS", ""),
new MacroDefinition("CC", "c89"),
new MacroDefinition("CFLAGS", "-O"),
new MacroDefinition("FC", "fort77"),
new MacroDefinition("FFLAGS", "-O 1"),
new MacroDefinition("GET", "get"),
new MacroDefinition("GFLAGS", ""),
new MacroDefinition("SCCSFLAGS", ""),
new MacroDefinition("SCCSGETFLAGS", "-s")};
public MacroDefinition getMacroDefinition(String name) {
for (int i = 0; i < macros.length; i++) {
if (name.equals(macros[i].getName())) {
return macros[i];
}
}
return null;
}
public MacroDefinition[] getMacroDefinitions() {
return macros;
}
}

View file

@ -1,123 +0,0 @@
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.posix;
import org.eclipse.cdt.make.internal.core.makefile.Command;
import org.eclipse.cdt.make.internal.core.makefile.InferenceRule;
public class PosixBuiltinRules {
InferenceRule[] rules = new InferenceRule[] {
// Special Targets
new InferenceRule(".SCCS_GET", new Command[] { new Command("sccs $(SCCSFLAGS) get $(SCCSGETFLAGS) $@")}),
new InferenceRule(".SUFFIXES", new Command[] { new Command(" .o .c .y .l .a .sh .f .c~ .y~ .l~ .sh~ .f~")}),
// Single Suffix Rules
new InferenceRule(".c", new Command[] { new Command("$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<")}),
new InferenceRule(".f", new Command[] { new Command("$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $<")}),
new InferenceRule(".sh", new Command[] { new Command("cp $< $@"), new Command("chmod a+x $@")}),
new InferenceRule(
".c~",
new Command[] {
new Command("$(GET) $(GFLAGS) -p $< > $*.c"),
new Command("$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $*.c")}),
new InferenceRule(
".f~",
new Command[] {
new Command("$(GET) $(GFLAGS) -p $< > $*.f"),
new Command("$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $*.f")}),
new InferenceRule(
".sh~",
new Command[] {
new Command("$(GET) $(GFLAGS) -p $< > $*.sh"),
new Command("cp $*.sh $@"),
new Command("chmod a+x $@")}),
// DOUBLE SUFFIX RULES
new InferenceRule(".c.o", new Command[] { new Command("$(CC) $(CFLAGS) -c $<")}),
new InferenceRule(".f.o", new Command[] { new Command("$(FC) $(FFLAGS) -c $<")}),
new InferenceRule(
".y.o",
new Command[] {
new Command("$(YACC) $(YFLAGS) $<"),
new Command("$(CC) $(CFLAGS) -c y.tab.c"),
new Command("rm -f y.tab.c"),
new Command("mv y.tab.o $@")}),
new InferenceRule(
".l.o",
new Command[] {
new Command("$(LEX) $(LFLAGS) $<"),
new Command("$(CC) $(CFLAGS) -c lex.yy.c"),
new Command("rm -f lex.yy.c"),
new Command("mv lex.yy.o $@"),
}),
new InferenceRule(".y.c", new Command[] { new Command("$(YACC) $(YFLAGS) $<"), new Command("mv y.tab.c $@")}),
new InferenceRule(".l.c", new Command[] { new Command("$(LEX) $(LFLAGS) $<"), new Command("mv lex.yy.c $@")}),
new InferenceRule(
".c~.o",
new Command[] { new Command("$(GET) $(GFLAGS) -p $< > $*.c"), new Command("$(CC) $(CFLAGS) -c $*.c")}),
new InferenceRule(
".f~.o",
new Command[] { new Command("$(GET) $(GFLAGS) -p $< > $*.f"), new Command("$(FC) $(FFLAGS) -c $*.f")}),
new InferenceRule(
".y~.o",
new Command[] {
new Command("$(GET) $(GFLAGS) -p $< > $*.y"),
new Command("$(YACC) $(YFLAGS) $*.y"),
new Command("$(CC) $(CFLAGS) -c y.tab.c"),
new Command("rm -f y.tab.c"),
new Command("mv y.tab.o $@")}),
new InferenceRule(
".l~.o",
new Command[] {
new Command("$(GET) $(GFLAGS) -p $< > $*.l"),
new Command("$(LEX) $(LFLAGS) $*.l"),
new Command("$(CC) $(CFLAGS) -c lex.yy.c"),
new Command("rm -f lex.yy.c"),
new Command("mv lex.yy.o $@")}),
new InferenceRule(
".y~.c",
new Command[] {
new Command("$(GET) $(GFLAGS) -p $< > $*.y"),
new Command("$(YACC) $(YFLAGS) $*.y"),
new Command("mv y.tab.c $@")}),
new InferenceRule(
".l~.c",
new Command[] {
new Command("$(GET) $(GFLAGS) -p $< > $*.l"),
new Command("$(LEX) $(LFLAGS) $*.l"),
new Command("mv lex.yy.c $@")}),
new InferenceRule(
".c.a",
new Command[] {
new Command("$(CC) -c $(CFLAGS) $<"),
new Command("$(AR) $(ARFLAGS) $@ $*.o"),
new Command("rm -f $*.o")}),
new InferenceRule(
".f.a",
new Command[] {
new Command("$(FC) -c $(FFLAGS) $<"),
new Command("$(AR) $(ARFLAGS) $@ $*.o"),
new Command("rm -f $*.o")})
};
public InferenceRule getInferenceRule(String name) {
for (int i = 0; i < rules.length; i++) {
if (name.equals(rules[i].getTarget())) {
return rules[i];
}
}
return null;
}
public InferenceRule[] getInferenceRules() {
return rules;
}
}

View file

@ -10,19 +10,21 @@
***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.posix;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.make.core.makefile.ICommand;
import org.eclipse.cdt.make.core.MakeCorePlugin;
import org.eclipse.cdt.make.core.makefile.IDirective;
import org.eclipse.cdt.make.internal.core.makefile.AbstractMakefile;
import org.eclipse.cdt.make.internal.core.makefile.BadStatement;
import org.eclipse.cdt.make.internal.core.makefile.BadDirective;
import org.eclipse.cdt.make.internal.core.makefile.Command;
import org.eclipse.cdt.make.internal.core.makefile.Comment;
import org.eclipse.cdt.make.internal.core.makefile.DefaultRule;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
import org.eclipse.cdt.make.internal.core.makefile.EmptyLine;
import org.eclipse.cdt.make.internal.core.makefile.IgnoreRule;
import org.eclipse.cdt.make.internal.core.makefile.InferenceRule;
@ -33,11 +35,12 @@ import org.eclipse.cdt.make.internal.core.makefile.PreciousRule;
import org.eclipse.cdt.make.internal.core.makefile.Rule;
import org.eclipse.cdt.make.internal.core.makefile.SccsGetRule;
import org.eclipse.cdt.make.internal.core.makefile.SilentRule;
import org.eclipse.cdt.make.internal.core.makefile.Statement;
import org.eclipse.cdt.make.internal.core.makefile.SpecialRule;
import org.eclipse.cdt.make.internal.core.makefile.SuffixesRule;
import org.eclipse.cdt.make.internal.core.makefile.Target;
import org.eclipse.cdt.make.internal.core.makefile.TargetRule;
import org.eclipse.cdt.make.internal.core.makefile.Util;
import org.eclipse.core.runtime.Path;
/**
* Makefile : ( statement ) *
@ -58,14 +61,21 @@ import org.eclipse.cdt.make.internal.core.makefile.Util;
public class PosixMakefile extends AbstractMakefile {
List statements;
IDirective[] builtins = null;
public PosixMakefile() {
statements = new ArrayList();
super(null);
}
public void parse(String name) throws IOException {
parse(new FileReader(name));
FileReader stream = new FileReader(name);
parse(stream);
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
}
}
}
public void parse(Reader reader) throws IOException {
@ -83,40 +93,54 @@ public class PosixMakefile extends AbstractMakefile {
// 1- Try command first, since we can not strip '#' in command line
if (PosixMakefileUtil.isCommand(line)) {
Command cmd = createCommand(line);
Command cmd = new Command(this, line);
cmd.setLines(startLine, endLine);
// The command is added to the rules
if (rules != null) {
for (int i = 0; i < rules.length; i++) {
rules[i].addStatement(cmd);
rules[i].addDirective(cmd);
rules[i].setEndLine(endLine);
}
continue;
}
// If we have no rules for the command,
// give the other statements a chance by falling through
// give the other directives a chance by falling through
}
// 2- Strip away any comments.
int pound = Util.indexOfComment(line);
if (pound != -1) {
Comment cmt = createComment(line.substring(pound + 1));
Comment cmt = new Comment(this, line.substring(pound + 1));
cmt.setLines(startLine, endLine);
addStatement(cmt);
if (rules != null) {
for (int i = 0; i < rules.length; i++) {
rules[i].addDirective(cmt);
rules[i].setEndLine(endLine);
}
} else {
addDirective(cmt);
}
line = line.substring(0, pound);
// If all we have left are spaces continue
if (Util.isEmptyLine(line)) {
continue;
}
// The rest of the line maybe a valid statement.
// The rest of the line maybe a valid directive.
// keep on trying by falling through.
}
// 3- Empty lines ?
if (Util.isEmptyLine(line)) {
Statement empty = createEmptyLine();
Directive empty = new EmptyLine(this);
empty.setLines(startLine, endLine);
addStatement(empty);
if (rules != null) {
for (int i = 0; i < rules.length; i++) {
rules[i].addDirective(empty);
rules[i].setEndLine(endLine);
}
} else {
addDirective(empty);
}
continue;
}
@ -125,120 +149,117 @@ public class PosixMakefile extends AbstractMakefile {
// shall begin a new entry.
rules = null;
// 5- Check for the special targets.
if (PosixMakefileUtil.isDefaultRule(line)) {
DefaultRule dRule = createDefaultRule(line);
rules = new Rule[] { dRule };
dRule.setLines(startLine, endLine);
addStatement(dRule);
continue;
} else if (PosixMakefileUtil.isIgnoreRule(line)) {
IgnoreRule ignore = createIgnoreRule(line);
ignore.setLines(startLine, endLine);
addStatement(ignore);
continue;
} else if (PosixMakefileUtil.isPosixRule(line)) {
PosixRule pRule = createPosixRule();
pRule.setLines(startLine, endLine);
addStatement(pRule);
continue;
} else if (PosixMakefileUtil.isPreciousRule(line)) {
PreciousRule precious = createPreciousRule(line);
precious.setLines(startLine, endLine);
addStatement(precious);
continue;
} else if (PosixMakefileUtil.isSccsGetRule(line)) {
SccsGetRule sccs = createSccsGetRule(line);
rules = new Rule[] { sccs };
sccs.setLines(startLine, endLine);
addStatement(sccs);
continue;
} else if (PosixMakefileUtil.isSilentRule(line)) {
SilentRule silent = createSilentRule(line);
silent.setLines(startLine, endLine);
addStatement(silent);
continue;
} else if (PosixMakefileUtil.isSuffixesRule(line)) {
SuffixesRule suffixes = createSuffixesRule(line);
suffixes.setLines(startLine, endLine);
addStatement(suffixes);
// 5- Check for the special rules.
SpecialRule special = processSpecialRule(line);
if (special != null) {
rules = new Rule[] { special };
special.setLines(startLine, endLine);
addDirective(special);
continue;
}
// 6- Check for inference rule.
if (PosixMakefileUtil.isInferenceRule(line)) {
InferenceRule irule = createInferenceRule(line);
InferenceRule irule = parseInferenceRule(line);
irule.setLines(startLine, endLine);
addStatement(irule);
addDirective(irule);
rules = new Rule[]{irule};
continue;
}
// 7- Macro Definiton ?
if (PosixMakefileUtil.isMacroDefinition(line)) {
Statement stmt = createMacroDefinition(line);
Directive stmt = parseMacroDefinition(line);
stmt.setLines(startLine, endLine);
addStatement(stmt);
addDirective(stmt);
continue;
}
// 8- Target Rule ?
if (PosixMakefileUtil.isTargetRule(line)) {
TargetRule[] trules = createTargetRule(line);
TargetRule[] trules = parseTargetRule(line);
for (int i = 0; i < trules.length; i++) {
trules[i].setLines(startLine, endLine);
addStatement(trules[i]);
addDirective(trules[i]);
}
rules = trules;
continue;
}
// XXX ?? Should not be here.
BadStatement stmt = new BadStatement(line);
BadDirective stmt = new BadDirective(this, line);
stmt.setLines(startLine, endLine);
addStatement(stmt);
addDirective(stmt);
}
setLines(1, endLine);
}
public IDirective[] getStatements() {
return (IDirective[]) statements.toArray(new IDirective[0]);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.make.internal.core.makefile.AbstractMakefile#getBuiltins()
*/
public IDirective[] getBuiltins() {
IDirective[] macros = new PosixBuiltinMacroDefinitions().getMacroDefinitions();
IDirective[] rules = new PosixBuiltinRules().getInferenceRules();
IDirective[] stmts = new IDirective[macros.length + rules.length];
System.arraycopy(macros, 0, stmts, 0, macros.length);
System.arraycopy(rules, 0, stmts, macros.length, rules.length);
return stmts;
if (builtins == null) {
String location = "builtin" + File.separator + "posix.mk";
try {
InputStream stream = MakeCorePlugin.getDefault().openStream(new Path(location));
PosixMakefile gnu = new PosixMakefile();
gnu.parse(new InputStreamReader(stream));
builtins = gnu.getDirectives();
for (int i = 0; i < builtins.length; i++) {
if (builtins[i] instanceof MacroDefinition) {
((MacroDefinition)builtins[i]).setFromDefault(true);
}
}
} catch (Exception e) {
//e.printStackTrace();
}
if (builtins == null) {
builtins = new IDirective[0];
}
}
return builtins;
}
/**
* Comment
* @param line
* @return
*/
public Comment createComment(String line) {
return new Comment(line);
}
/**
* EmptyLine
*/
public EmptyLine createEmptyLine() {
return new EmptyLine();
}
/**
* Command
*/
public Command createCommand(String line) {
return new Command(line);
protected SpecialRule processSpecialRule(String line) {
line = line.trim();
String keyword = null;
String[] reqs = null;
SpecialRule special = null;
int index = Util.indexOf(line, ':');
if (index != -1) {
keyword = line.substring(0, index).trim();
String req = line.substring(index + 1);
reqs = PosixMakefileUtil.findPrerequisites(req);
} else {
keyword = line;
reqs = new String[0];
}
if (".IGNORE".equals(keyword)) {
special = new IgnoreRule(this, reqs);
} else if (".POSIX".equals(keyword)) {
special = new PosixRule(this);
} else if (".PRECIOUS".equals(keyword)) {
special = new PreciousRule(this, reqs);
} else if (".SILENT".equals(keyword)) {
special = new SilentRule(this, reqs);
} else if (".SUFFIXES".equals(keyword)) {
special = new SuffixesRule(this, reqs);
} else if (".DEFAULT".equals(keyword)) {
special = new DefaultRule(this, new Command[0]);
} else if (".SCCS_GET".equals(keyword)) {
special = new SccsGetRule(this, new Command[0]);
}
return special;
}
/**
* Inference Rule
*/
public InferenceRule createInferenceRule(String line) {
protected InferenceRule parseInferenceRule(String line) {
String tgt;
int index = Util.indexOf(line, ':');
if (index != -1) {
@ -246,13 +267,13 @@ public class PosixMakefile extends AbstractMakefile {
} else {
tgt = line;
}
return new InferenceRule(new Target(tgt));
return new InferenceRule(this, new Target(tgt));
}
/**
* MacroDefinition
*/
public MacroDefinition createMacroDefinition(String line) {
protected MacroDefinition parseMacroDefinition(String line) {
String name;
String value;
int index = Util.indexOf(line, '=');
@ -263,13 +284,13 @@ public class PosixMakefile extends AbstractMakefile {
name = line;
value = "";
}
return new MacroDefinition(name, value);
return new MacroDefinition(this, name, new StringBuffer(value));
}
/**
* TargetRule
*/
public TargetRule[] createTargetRule(String line) {
protected TargetRule[] parseTargetRule(String line) {
String[] targets;
String[] reqs;
String cmd = null;
@ -296,111 +317,15 @@ public class PosixMakefile extends AbstractMakefile {
TargetRule[] targetRules = new TargetRule[targets.length];
for (int i = 0; i < targets.length; i++) {
targetRules[i] = new TargetRule(new Target(targets[i]), reqs);
targetRules[i] = new TargetRule(this, new Target(targets[i]), reqs);
if (cmd != null) {
Command command = createCommand(cmd);
targetRules[i].addStatement(command);
Command command = new Command(this, cmd);
targetRules[i].addDirective(command);
}
}
return targetRules;
}
/**
* .DEFAULT
*/
public DefaultRule createDefaultRule(String line) {
int semicolon = Util.indexOf(line, ';');
if (semicolon > 0) {
String cmd = line.substring(semicolon + 1).trim();
if (cmd.length() > 0) {
ICommand[] cmds = new ICommand[] { new Command(cmd)};
return new DefaultRule(cmds);
}
}
return new DefaultRule(new ICommand[0]);
}
/**
* .IGNORE
*/
public IgnoreRule createIgnoreRule(String line) {
int index = Util.indexOf(line, ':');
if (index != -1) {
String req = line.substring(index + 1);
String[] reqs = PosixMakefileUtil.findPrerequisites(req);
return new IgnoreRule(reqs);
}
return new IgnoreRule(new String[0]);
}
/**
* .POSIX
*/
public PosixRule createPosixRule() {
return new PosixRule();
}
/**
* .PRECIOUS
*/
public PreciousRule createPreciousRule(String line) {
int index = Util.indexOf(line, ':');
if (index != -1) {
String req = line.substring(index + 1);
String[] reqs = PosixMakefileUtil.findPrerequisites(req);
return new PreciousRule(reqs);
}
return new PreciousRule(new String[0]);
}
/**
* .SCCS_GET
*/
public SccsGetRule createSccsGetRule(String line) {
int semicolon = Util.indexOf(line, ';');
if (semicolon != -1) {
String cmd = line.substring(semicolon + 1).trim();
if (cmd.length() > 0) {
ICommand[] cmds = new ICommand[] { new Command(cmd)};
return new SccsGetRule(cmds);
}
}
return new SccsGetRule(new ICommand[0]);
}
/**
* .SILENT
*/
public SilentRule createSilentRule(String line) {
int index = Util.indexOf(line, ':');
if (index != -1) {
String req = line.substring(index + 1);
String[] reqs = PosixMakefileUtil.findPrerequisites(req);
return new SilentRule(reqs);
}
return new SilentRule(new String[0]);
}
/**
* .SUFFIXES
*/
public SuffixesRule createSuffixesRule(String line) {
int index = Util.indexOf(line, ':');
if (index != -1) {
String req = line.substring(index + 1);
String[] reqs = PosixMakefileUtil.findPrerequisites(req);
return new SuffixesRule(reqs);
}
return new SuffixesRule(new String[0]);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.make.internal.core.makefile.AbstractMakefile#addStatement(org.eclipse.cdt.make.core.makefile.IDirective)
*/
public void addStatement(IDirective statement) {
statements.add(statement);
}
public static void main(String[] args) {
try {
String filename = "Makefile";
@ -409,10 +334,11 @@ public class PosixMakefile extends AbstractMakefile {
}
PosixMakefile makefile = new PosixMakefile();
makefile.parse(filename);
IDirective[] statements = makefile.getStatements();
for (int i = 0; i < statements.length; i++) {
IDirective[] directives = makefile.getDirectives();
//IDirective[] directives = makefile.getBuiltins();
for (int i = 0; i < directives.length; i++) {
//System.out.println("Rule[" + i +"]");
System.out.print(statements[i]);
System.out.print(directives[i]);
}
} catch (IOException e) {
System.out.println(e);