1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-09-04 06:03:18 +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 * 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 { 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 * ICommand
* Commands are associated with a rule and executed by
* the make program when building a target.
*/ */
public interface ICommand extends IDirective { public interface ICommand extends IDirective {

View file

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

View file

@ -11,11 +11,29 @@
package org.eclipse.cdt.make.core.makefile; package org.eclipse.cdt.make.core.makefile;
/** /**
* A Makefile can contain rules, macro definitons and comments.
* They are call directives.
*/ */
public interface IDirective { 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(); 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(); int getEndLine();
String toString(); String toString();

View file

@ -11,7 +11,13 @@
package org.eclipse.cdt.make.core.makefile; 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 { public interface IInferenceRule extends IRule {
} }

View file

@ -11,21 +11,50 @@
package org.eclipse.cdt.make.core.makefile; package org.eclipse.cdt.make.core.makefile;
/** /**
* IMacroDefinition * IMacroDefinitions are in the form:
* string1 = [string2]
*/ */
public interface IMacroDefinition extends IDirective { public interface IMacroDefinition extends IDirective {
/**
* Returns the name of the macro
* @return
*/
String getName(); String getName();
/**
* Returns the value of the macro
* @return
*/
StringBuffer getValue(); StringBuffer getValue();
/**
* The macro is a built-in
* @return
*/
boolean isFromDefault(); boolean isFromDefault();
/**
* The macro was found in a Makefile.
* @return
*/
boolean isFromMakefile(); boolean isFromMakefile();
/**
* The macro came from the environment.
* @return
*/
boolean isFromEnviroment(); boolean isFromEnviroment();
/**
* The macro came from the make command option -e
* @return
*/
boolean isFromEnvironmentOverride(); boolean isFromEnvironmentOverride();
/**
* The macro was pass from an option to make.
* @return
*/
boolean isFromCommand(); 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 { public interface IMakefile extends IParent {
/**
* ITargetRule | IInferenceRule | ISpecialRule
* @return
*/
IRule[] getRules(); IRule[] getRules();
IRule[] getRule(String target);
/**
* Returns IInferenceRule
* @return
*/
IInferenceRule[] getInferenceRules(); IInferenceRule[] getInferenceRules();
IInferenceRule[] getInferenceRule(String target);
/**
* Returns ITargetRule
* @return
*/
ITargetRule[] getTargetRules(); ITargetRule[] getTargetRules();
ITargetRule[] getTargetRule(String target);
/**
* Return IMacroDefintion
* @return
*/
IMacroDefinition[] getMacroDefinitions(); IMacroDefinition[] getMacroDefinitions();
IMacroDefinition[] getMacroDefinition(String name);
/**
* Return all the builtin directives.
* @return
*/
IDirective[] getBuiltins(); 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; 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; package org.eclipse.cdt.make.core.makefile;
/** /**
* IParent * IParent
*/ */
public interface IParent extends IDirective { public interface IParent extends IDirective {
IDirective[] getStatements(); IDirective[] getDirectives();
} }

View file

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

View file

@ -10,11 +10,14 @@
***********************************************************************/ ***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile; 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; String line;
public BadStatement(String s) { public BadDirective(Directive parent, String s) {
super(parent);
line = s; line = s;
} }

View file

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

View file

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

View file

@ -10,7 +10,6 @@
***********************************************************************/ ***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile; package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.ICommand;
import org.eclipse.cdt.make.core.makefile.IDefaultRule; 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 class DefaultRule extends SpecialRule implements IDefaultRule {
public DefaultRule(ICommand[] cmds) { public DefaultRule(Directive parent, Command[] cmds) {
super(new Target(".DEFAULT"), new String[0], 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; import org.eclipse.cdt.make.core.makefile.IDirective;
public abstract class Statement implements IDirective { public abstract class Directive implements IDirective {
int endLine; int endLine;
int startLine; 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); setLines(start, end);
} }
@ -33,10 +35,6 @@ public abstract class Statement implements IDirective {
return endLine; return endLine;
} }
public void setEndLine(int lineno) {
endLine = lineno;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.make.core.makefile.IDirective#getStartLine() * @see org.eclipse.cdt.make.core.makefile.IDirective#getStartLine()
*/ */
@ -44,10 +42,25 @@ public abstract class Statement implements IDirective {
return startLine; 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) { public void setStartLine(int lineno) {
startLine = lineno; startLine = lineno;
} }
public void setEndLine(int lineno) {
endLine = lineno;
}
public void setLines(int start, int end) { public void setLines(int start, int end) {
setStartLine(start); setStartLine(start);
setEndLine(end); setEndLine(end);

View file

@ -1,3 +1,4 @@
/********************************************************************** /**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others. * Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials * 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; 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 char NL = '\n';
final public static String NL_STRING = "\n"; final public static String NL_STRING = "\n";
public EmptyLine() { public EmptyLine(Directive parent) {
super(); super(parent);
} }
public String toString() { public String toString() {

View file

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

View file

@ -11,20 +11,19 @@
package org.eclipse.cdt.make.internal.core.makefile; package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.ICommand; import org.eclipse.cdt.make.core.makefile.ICommand;
import org.eclipse.cdt.make.core.makefile.ITarget;
public class InferenceRule extends Rule { public class InferenceRule extends Rule {
public InferenceRule(ITarget target) { public InferenceRule(Directive parent, Target target) {
this(target, new Command[0]); this(parent, target, new Command[0]);
} }
public InferenceRule(String tgt, ICommand[] cmds) { public InferenceRule(Directive parent, String tgt, Command[] cmds) {
this(new Target(tgt), cmds); this(parent, new Target(tgt), cmds);
} }
public InferenceRule(ITarget target, ICommand[] cmds) { public InferenceRule(Directive parent, Target target, Command[] cmds) {
super(target, 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; String name;
StringBuffer value; StringBuffer value;
boolean fromCommand; boolean fromCommand;
@ -23,11 +23,8 @@ public class MacroDefinition extends Statement implements IMacroDefinition {
boolean fromEnvironment; boolean fromEnvironment;
boolean fromEnvironmentOverride; boolean fromEnvironmentOverride;
public MacroDefinition(String n, String v) { public MacroDefinition(Directive parent, String n, StringBuffer v) {
this(n, new StringBuffer(v)); super(parent);
}
public MacroDefinition(String n, StringBuffer v) {
name = n; name = n;
value = v; value = v;
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -10,7 +10,6 @@
***********************************************************************/ ***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile; package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.ICommand;
import org.eclipse.cdt.make.core.makefile.ISccsGetRule; 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 class SccsGetRule extends SpecialRule implements ISccsGetRule {
public SccsGetRule(ICommand[] cmds) { public SccsGetRule(Directive parent, Command[] cmds) {
super(new Target(".SCCS_GET"), new String[0], 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; package org.eclipse.cdt.make.internal.core.makefile;
import org.eclipse.cdt.make.core.makefile.ISilentRule; import org.eclipse.cdt.make.core.makefile.ISilentRule;
import org.eclipse.cdt.make.core.makefile.ICommand;
/** /**
* .SILENT * .SILENT
@ -21,8 +20,8 @@ import org.eclipse.cdt.make.core.makefile.ICommand;
*/ */
public class SilentRule extends SpecialRule implements ISilentRule { public class SilentRule extends SpecialRule implements ISilentRule {
public SilentRule(String[] reqs) { public SilentRule(Directive parent, String[] reqs) {
super(new Target(".SILENT"), reqs, new ICommand[0]); super(parent, new Target(".SILENT"), reqs, new Command[0]);
} }
} }

View file

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

View file

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

View file

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

View file

@ -10,24 +10,28 @@
***********************************************************************/ ***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu; 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; 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 cond;
String arg1; String arg1;
String arg2; String arg2;
public Conditional(String conditional) { public Conditional(Directive parent, String conditional) {
super(parent);
cond = conditional; cond = conditional;
parse(); parse();
} }
public Conditional() { public Conditional(Directive parent) {
this("", "", ""); this(parent, "", "", "");
} }
public Conditional(String conditional, String argument1, String argument2) { public Conditional(Directive parent, String conditional, String argument1, String argument2) {
super(parent);
arg1 = argument1; arg1 = argument1;
arg2 = argument2; arg2 = argument2;
cond = conditional; cond = conditional;
@ -46,15 +50,39 @@ public abstract class Conditional extends Parent {
return arg2; 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" * ifeq "ARG1" "ARG2"
* ifeq "ARG1" 'ARG2' * ifeq "ARG1" 'ARG2'
* ifeq 'ARG1' "ARG2" * ifeq 'ARG1' "ARG2"
*/ */
void parse() { protected void parse() {
String line = getConditional().trim(); String line = getConditional().trim();
char terminal = line.charAt(0) == '(' ? ',' : line.charAt(0); char terminal = line.charAt(0) == '(' ? ',' : line.charAt(0);

View file

@ -10,15 +10,16 @@
***********************************************************************/ ***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu; package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class DefineVariable extends VariableDefinition { public class DefineVariable extends VariableDefinition {
public DefineVariable(String name, StringBuffer value) { public DefineVariable(Directive parent, String name, StringBuffer value) {
super(name, value); super(parent, name, value);
} }
public boolean isMultiline() { public boolean isMultiLine() {
return true; 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; package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class Else extends Conditional { public class Else extends Conditional {
public Else(Directive parent) {
super(parent);
}
public Else() { public boolean isElse() {
super(); return true;
} }
public String toString() { public String toString() {

View file

@ -10,16 +10,16 @@
***********************************************************************/ ***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu; 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(Directive parent) {
super(parent);
public Endef() {
} }
public String toString() { public boolean isEndef() {
return "endef"; return true;
} }
} }

View file

@ -10,13 +10,16 @@
***********************************************************************/ ***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu; 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() { public class Endif extends Terminal {
super();
public Endif(Directive parent) {
super(parent);
} }
public String toString() { public boolean isEndif() {
return "endif"; 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; package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class ExportVariable extends VariableDefinition { public class ExportVariable extends VariableDefinition {
public ExportVariable(String name, StringBuffer value, int type) { public ExportVariable(Directive parent, String name, StringBuffer value, int type) {
super(name, value, type); super(parent, name, value, type);
} }
public boolean isExport() { public boolean isExport() {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -10,12 +10,13 @@
***********************************************************************/ ***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu; package org.eclipse.cdt.make.internal.core.makefile.gnu;
import org.eclipse.cdt.make.internal.core.makefile.Directive;
public class OverrideVariable extends VariableDefinition { public class OverrideVariable extends VariableDefinition {
public OverrideVariable(String name, StringBuffer value, int type) { public OverrideVariable(Directive parent, String name, StringBuffer value, int type) {
super(name, value, type); super(parent, name, value, type);
} }
public boolean isOverride() { 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.ICommand;
import org.eclipse.cdt.make.core.makefile.IInferenceRule; 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.InferenceRule;
import org.eclipse.cdt.make.internal.core.makefile.Target;
/** /**
@ -28,8 +30,8 @@ public class StaticTargetRule extends InferenceRule implements IInferenceRule {
String targetPattern; String targetPattern;
String[] prereqPatterns; String[] prereqPatterns;
public StaticTargetRule(ITarget target, String target_pattern, String[] prereq_patterns, ICommand[] commands) { public StaticTargetRule(Directive parent, Target target, String target_pattern, String[] prereq_patterns, Command[] commands) {
super(target, commands); super(parent, target, commands);
targetPattern = target_pattern; targetPattern = target_pattern;
prereqPatterns = prereq_patterns; prereqPatterns = prereq_patterns;
} }

View file

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

View file

@ -10,14 +10,16 @@
***********************************************************************/ ***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu; 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 pattern;
String[] directories; String[] directories;
public VPath(String pat, String[] dirs) { public VPath(Directive parent, String pat, String[] dirs) {
super(parent);
pattern = pat; pattern = pat;
directories = dirs; directories = dirs;
} }

View file

@ -10,11 +10,13 @@
***********************************************************************/ ***********************************************************************/
package org.eclipse.cdt.make.internal.core.makefile.gnu; 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; import org.eclipse.cdt.make.internal.core.makefile.MacroDefinition;
/** /**
*/ */
public class VariableDefinition extends MacroDefinition { public class VariableDefinition extends MacroDefinition implements IVariableDefinition {
/** /**
* ? is Conditional * ? is Conditional
@ -29,16 +31,16 @@ public class VariableDefinition extends MacroDefinition {
int type; int type;
String varTarget; String varTarget;
public VariableDefinition(String name, StringBuffer value) { public VariableDefinition(Directive parent, String name, StringBuffer value) {
this(name, value, TYPE_RECURSIVE_EXPAND); this(parent, name, value, TYPE_RECURSIVE_EXPAND);
} }
public VariableDefinition(String name, StringBuffer value, int type) { public VariableDefinition(Directive parent, String name, StringBuffer value, int type) {
this("", name, value, type); this(parent, "", name, value, type);
} }
public VariableDefinition(String target, String name, StringBuffer value, int type) { public VariableDefinition(Directive parent, String target, String name, StringBuffer value, int type) {
super(name, value); super(parent, name, value);
varTarget = target; varTarget = target;
this.type = type; this.type = type;
} }
@ -78,10 +80,6 @@ public class VariableDefinition extends MacroDefinition {
return sb.toString(); return sb.toString();
} }
public boolean equals(VariableDefinition v) {
return v.getName().equals(getName());
}
public boolean isRecursivelyExpanded() { public boolean isRecursivelyExpanded() {
return type == TYPE_RECURSIVE_EXPAND; return type == TYPE_RECURSIVE_EXPAND;
} }
@ -100,7 +98,7 @@ public class VariableDefinition extends MacroDefinition {
public boolean isTargetSpecific() { public boolean isTargetSpecific() {
String t = getTarget(); String t = getTarget();
return t == null || t.length() == 0; return t != null && t.length() > 0;
} }
public boolean isExport() { 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; package org.eclipse.cdt.make.internal.core.makefile.posix;
import java.io.File;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader; 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.core.makefile.IDirective;
import org.eclipse.cdt.make.internal.core.makefile.AbstractMakefile; 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.Command;
import org.eclipse.cdt.make.internal.core.makefile.Comment; 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.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.EmptyLine;
import org.eclipse.cdt.make.internal.core.makefile.IgnoreRule; 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.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.Rule;
import org.eclipse.cdt.make.internal.core.makefile.SccsGetRule; 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.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.SuffixesRule;
import org.eclipse.cdt.make.internal.core.makefile.Target; 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.TargetRule;
import org.eclipse.cdt.make.internal.core.makefile.Util; import org.eclipse.cdt.make.internal.core.makefile.Util;
import org.eclipse.core.runtime.Path;
/** /**
* Makefile : ( statement ) * * Makefile : ( statement ) *
@ -58,14 +61,21 @@ import org.eclipse.cdt.make.internal.core.makefile.Util;
public class PosixMakefile extends AbstractMakefile { public class PosixMakefile extends AbstractMakefile {
List statements; IDirective[] builtins = null;
public PosixMakefile() { public PosixMakefile() {
statements = new ArrayList(); super(null);
} }
public void parse(String name) throws IOException { 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 { 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 // 1- Try command first, since we can not strip '#' in command line
if (PosixMakefileUtil.isCommand(line)) { if (PosixMakefileUtil.isCommand(line)) {
Command cmd = createCommand(line); Command cmd = new Command(this, line);
cmd.setLines(startLine, endLine); cmd.setLines(startLine, endLine);
// The command is added to the rules // The command is added to the rules
if (rules != null) { if (rules != null) {
for (int i = 0; i < rules.length; i++) { for (int i = 0; i < rules.length; i++) {
rules[i].addStatement(cmd); rules[i].addDirective(cmd);
rules[i].setEndLine(endLine); rules[i].setEndLine(endLine);
} }
continue; continue;
} }
// If we have no rules for the command, // 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. // 2- Strip away any comments.
int pound = Util.indexOfComment(line); int pound = Util.indexOfComment(line);
if (pound != -1) { if (pound != -1) {
Comment cmt = createComment(line.substring(pound + 1)); Comment cmt = new Comment(this, line.substring(pound + 1));
cmt.setLines(startLine, endLine); 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); line = line.substring(0, pound);
// If all we have left are spaces continue // If all we have left are spaces continue
if (Util.isEmptyLine(line)) { if (Util.isEmptyLine(line)) {
continue; 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. // keep on trying by falling through.
} }
// 3- Empty lines ? // 3- Empty lines ?
if (Util.isEmptyLine(line)) { if (Util.isEmptyLine(line)) {
Statement empty = createEmptyLine(); Directive empty = new EmptyLine(this);
empty.setLines(startLine, endLine); 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; continue;
} }
@ -125,120 +149,117 @@ public class PosixMakefile extends AbstractMakefile {
// shall begin a new entry. // shall begin a new entry.
rules = null; rules = null;
// 5- Check for the special targets. // 5- Check for the special rules.
if (PosixMakefileUtil.isDefaultRule(line)) { SpecialRule special = processSpecialRule(line);
DefaultRule dRule = createDefaultRule(line); if (special != null) {
rules = new Rule[] { dRule }; rules = new Rule[] { special };
dRule.setLines(startLine, endLine); special.setLines(startLine, endLine);
addStatement(dRule); addDirective(special);
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);
continue; continue;
} }
// 6- Check for inference rule. // 6- Check for inference rule.
if (PosixMakefileUtil.isInferenceRule(line)) { if (PosixMakefileUtil.isInferenceRule(line)) {
InferenceRule irule = createInferenceRule(line); InferenceRule irule = parseInferenceRule(line);
irule.setLines(startLine, endLine); irule.setLines(startLine, endLine);
addStatement(irule); addDirective(irule);
rules = new Rule[]{irule}; rules = new Rule[]{irule};
continue; continue;
} }
// 7- Macro Definiton ? // 7- Macro Definiton ?
if (PosixMakefileUtil.isMacroDefinition(line)) { if (PosixMakefileUtil.isMacroDefinition(line)) {
Statement stmt = createMacroDefinition(line); Directive stmt = parseMacroDefinition(line);
stmt.setLines(startLine, endLine); stmt.setLines(startLine, endLine);
addStatement(stmt); addDirective(stmt);
continue; continue;
} }
// 8- Target Rule ? // 8- Target Rule ?
if (PosixMakefileUtil.isTargetRule(line)) { if (PosixMakefileUtil.isTargetRule(line)) {
TargetRule[] trules = createTargetRule(line); TargetRule[] trules = parseTargetRule(line);
for (int i = 0; i < trules.length; i++) { for (int i = 0; i < trules.length; i++) {
trules[i].setLines(startLine, endLine); trules[i].setLines(startLine, endLine);
addStatement(trules[i]); addDirective(trules[i]);
} }
rules = trules; rules = trules;
continue; continue;
} }
// XXX ?? Should not be here. // XXX ?? Should not be here.
BadStatement stmt = new BadStatement(line); BadDirective stmt = new BadDirective(this, line);
stmt.setLines(startLine, endLine); stmt.setLines(startLine, endLine);
addStatement(stmt); addDirective(stmt);
} }
setLines(1, endLine); setLines(1, endLine);
} }
public IDirective[] getStatements() { /* (non-Javadoc)
return (IDirective[]) statements.toArray(new IDirective[0]); * @see org.eclipse.cdt.make.internal.core.makefile.AbstractMakefile#getBuiltins()
} */
public IDirective[] getBuiltins() { public IDirective[] getBuiltins() {
IDirective[] macros = new PosixBuiltinMacroDefinitions().getMacroDefinitions(); if (builtins == null) {
IDirective[] rules = new PosixBuiltinRules().getInferenceRules(); String location = "builtin" + File.separator + "posix.mk";
IDirective[] stmts = new IDirective[macros.length + rules.length]; try {
System.arraycopy(macros, 0, stmts, 0, macros.length); InputStream stream = MakeCorePlugin.getDefault().openStream(new Path(location));
System.arraycopy(rules, 0, stmts, macros.length, rules.length); PosixMakefile gnu = new PosixMakefile();
return stmts; 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) { protected SpecialRule processSpecialRule(String line) {
return new Comment(line); line = line.trim();
} String keyword = null;
String[] reqs = null;
/** SpecialRule special = null;
* EmptyLine int index = Util.indexOf(line, ':');
*/ if (index != -1) {
public EmptyLine createEmptyLine() { keyword = line.substring(0, index).trim();
return new EmptyLine(); String req = line.substring(index + 1);
} reqs = PosixMakefileUtil.findPrerequisites(req);
} else {
/** keyword = line;
* Command reqs = new String[0];
*/ }
public Command createCommand(String line) { if (".IGNORE".equals(keyword)) {
return new Command(line); 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 * Inference Rule
*/ */
public InferenceRule createInferenceRule(String line) { protected InferenceRule parseInferenceRule(String line) {
String tgt; String tgt;
int index = Util.indexOf(line, ':'); int index = Util.indexOf(line, ':');
if (index != -1) { if (index != -1) {
@ -246,13 +267,13 @@ public class PosixMakefile extends AbstractMakefile {
} else { } else {
tgt = line; tgt = line;
} }
return new InferenceRule(new Target(tgt)); return new InferenceRule(this, new Target(tgt));
} }
/** /**
* MacroDefinition * MacroDefinition
*/ */
public MacroDefinition createMacroDefinition(String line) { protected MacroDefinition parseMacroDefinition(String line) {
String name; String name;
String value; String value;
int index = Util.indexOf(line, '='); int index = Util.indexOf(line, '=');
@ -263,13 +284,13 @@ public class PosixMakefile extends AbstractMakefile {
name = line; name = line;
value = ""; value = "";
} }
return new MacroDefinition(name, value); return new MacroDefinition(this, name, new StringBuffer(value));
} }
/** /**
* TargetRule * TargetRule
*/ */
public TargetRule[] createTargetRule(String line) { protected TargetRule[] parseTargetRule(String line) {
String[] targets; String[] targets;
String[] reqs; String[] reqs;
String cmd = null; String cmd = null;
@ -296,111 +317,15 @@ public class PosixMakefile extends AbstractMakefile {
TargetRule[] targetRules = new TargetRule[targets.length]; TargetRule[] targetRules = new TargetRule[targets.length];
for (int i = 0; i < targets.length; i++) { 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) { if (cmd != null) {
Command command = createCommand(cmd); Command command = new Command(this, cmd);
targetRules[i].addStatement(command); targetRules[i].addDirective(command);
} }
} }
return targetRules; 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) { public static void main(String[] args) {
try { try {
String filename = "Makefile"; String filename = "Makefile";
@ -409,10 +334,11 @@ public class PosixMakefile extends AbstractMakefile {
} }
PosixMakefile makefile = new PosixMakefile(); PosixMakefile makefile = new PosixMakefile();
makefile.parse(filename); makefile.parse(filename);
IDirective[] statements = makefile.getStatements(); IDirective[] directives = makefile.getDirectives();
for (int i = 0; i < statements.length; i++) { //IDirective[] directives = makefile.getBuiltins();
for (int i = 0; i < directives.length; i++) {
//System.out.println("Rule[" + i +"]"); //System.out.println("Rule[" + i +"]");
System.out.print(statements[i]); System.out.print(directives[i]);
} }
} catch (IOException e) { } catch (IOException e) {
System.out.println(e); System.out.println(e);