From 0de973e3c5fc8ff932c5c2d0d66815d992b7df23 Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Fri, 19 Sep 2003 05:03:27 +0000 Subject: [PATCH] Improve on the GNU makefile parser --- .../eclipse/cdt/make/core/MakeCorePlugin.java | 24 + .../make/core/makefile/IArchiveTarget.java | 19 + .../cdt/make/core/makefile/ICommand.java | 14 +- .../cdt/make/core/makefile/IComment.java | 2 +- .../cdt/make/core/makefile/IDefaultRule.java | 20 + .../{IStatement.java => IDirective.java} | 2 +- .../cdt/make/core/makefile/IEmptyLine.java | 2 +- .../cdt/make/core/makefile/IIgnoreRule.java | 19 + .../make/core/makefile/IMacroDefinition.java | 16 +- .../cdt/make/core/makefile/IMakefile.java | 11 +- .../cdt/make/core/makefile/IParent.java | 19 + .../cdt/make/core/makefile/IPosixRule.java | 19 + .../cdt/make/core/makefile/IPreciousRule.java | 19 + .../eclipse/cdt/make/core/makefile/IRule.java | 4 +- .../cdt/make/core/makefile/ISccsGetRule.java | 20 + .../cdt/make/core/makefile/ISilentRule.java | 20 + .../cdt/make/core/makefile/ISpecialRule.java | 23 + .../cdt/make/core/makefile/ISuffixesRule.java | 19 + .../cdt/make/core/makefile/ITarget.java | 5 +- .../cdt/make/core/makefile/ITargetRule.java | 5 +- .../core/makefile/AbstractMakefile.java | 21 +- .../internal/core/makefile/ArchiveTarget.java | 33 + .../make/internal/core/makefile/Command.java | 20 +- .../internal/core/makefile/DefaultRule.java | 27 + .../internal/core/makefile/IgnoreRule.java | 28 + .../internal/core/makefile/InferenceRule.java | 15 +- .../core/makefile/MacroDefinition.java | 99 +- .../make/internal/core/makefile/Makefile.java | 95 -- .../core/makefile/MakefileReader.java | 6 +- .../internal/core/makefile/MakefileUtil.java | 161 ---- .../internal/core/makefile/NullMakefile.java | 24 +- .../make/internal/core/makefile/Parent.java | 56 ++ .../internal/core/makefile/PosixRule.java | 26 + .../internal/core/makefile/PreciousRule.java | 27 + .../cdt/make/internal/core/makefile/Rule.java | 30 +- .../internal/core/makefile/SccsGetRule.java | 29 + .../internal/core/makefile/SilentRule.java | 28 + .../internal/core/makefile/SpecialRule.java | 48 + .../internal/core/makefile/Statement.java | 12 +- .../internal/core/makefile/SuffixesRule.java | 28 + .../make/internal/core/makefile/Target.java | 8 - .../internal/core/makefile/TargetRule.java | 39 +- .../cdt/make/internal/core/makefile/Util.java | 86 ++ .../core/makefile/gnu/Conditional.java | 124 +++ .../gnu/{Define.java => DefineVariable.java} | 35 +- .../make/internal/core/makefile/gnu/Else.java | 6 +- .../internal/core/makefile/gnu/Endif.java | 7 +- .../internal/core/makefile/gnu/Export.java | 55 -- .../core/makefile/gnu/ExportVariable.java | 23 + .../core/makefile/gnu/GNUMakefile.java | 855 +++++++++++++++++- .../core/makefile/gnu/GNUMakefileUtil.java | 115 ++- .../core/makefile/gnu/GNUTargetRule.java | 69 ++ .../internal/core/makefile/gnu/Ifdef.java | 30 +- .../make/internal/core/makefile/gnu/Ifeq.java | 33 +- .../internal/core/makefile/gnu/Ifndef.java | 30 +- .../internal/core/makefile/gnu/Ifneq.java | 32 +- .../internal/core/makefile/gnu/Include.java | 52 +- .../internal/core/makefile/gnu/Override.java | 54 -- .../core/makefile/gnu/OverrideDefine.java | 44 +- .../core/makefile/gnu/OverrideVariable.java | 25 + .../core/makefile/gnu/StaticTargetRule.java | 74 ++ .../core/makefile/gnu/TargetVariable.java | 34 + .../internal/core/makefile/gnu/UnExport.java | 26 +- .../internal/core/makefile/gnu/VPath.java | 49 +- .../core/makefile/gnu/VariableDefinition.java | 132 +++ .../posix/PosixBuiltinMacroDefinitions.java | 32 +- .../core/makefile/posix/PosixMakefile.java | 418 ++++++--- .../makefile/posix/PosixMakefileUtil.java | 160 ++++ 68 files changed, 2793 insertions(+), 949 deletions(-) create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IArchiveTarget.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IDefaultRule.java rename build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/{IStatement.java => IDirective.java} (95%) create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IIgnoreRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IParent.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IPosixRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IPreciousRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISccsGetRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISilentRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISpecialRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISuffixesRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/ArchiveTarget.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/DefaultRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/IgnoreRule.java delete mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Makefile.java delete mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MakefileUtil.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Parent.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/PosixRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/PreciousRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SccsGetRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SilentRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SpecialRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SuffixesRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Util.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Conditional.java rename build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/{Define.java => DefineVariable.java} (53%) delete mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Export.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/ExportVariable.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/GNUTargetRule.java delete mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Override.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/OverrideVariable.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/StaticTargetRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/TargetVariable.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/VariableDefinition.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixMakefileUtil.java diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeCorePlugin.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeCorePlugin.java index d87f67b42b7..8a8d68f007b 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeCorePlugin.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeCorePlugin.java @@ -10,6 +10,7 @@ ***********************************************************************/ package org.eclipse.cdt.make.core; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; import java.util.Map; @@ -17,8 +18,11 @@ import java.util.MissingResourceException; import java.util.ResourceBundle; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.make.core.makefile.IMakefile; import org.eclipse.cdt.make.internal.core.BuildInfoFactory; import org.eclipse.cdt.make.internal.core.MakeTargetManager; +import org.eclipse.cdt.make.internal.core.makefile.gnu.GNUMakefile; +import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; @@ -147,6 +151,25 @@ public class MakeCorePlugin extends Plugin { } return fTargetManager; } + + public IMakefile createMakefile(IFile file) { + GNUMakefile gnu = new GNUMakefile(); + try { + gnu.parse(file.getLocation().toOSString()); + String[] dirs = gnu.getIncludeDirectories(); + String[] includes = new String[dirs.length + 1]; + System.arraycopy(dirs, 0, includes, 0, dirs.length); + String cwd = file.getLocation().removeLastSegments(1).toOSString(); + includes[dirs.length] = cwd; + gnu.setIncludeDirectories(includes); + } catch (IOException e) { + } + return gnu; + // + // base on a preference to chose GNU vs Posix + //return PosixMakefile(file.getLocation); + } + public void shutdown() throws CoreException { super.shutdown(); if ( fTargetManager != null) { @@ -154,4 +177,5 @@ public class MakeCorePlugin extends Plugin { fTargetManager = null; } } + } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IArchiveTarget.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IArchiveTarget.java new file mode 100644 index 00000000000..9e61d0c8c34 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IArchiveTarget.java @@ -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; + +/** + * IArchiveTarget + */ +public interface IArchiveTarget extends ITarget { + + String getMember(); +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ICommand.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ICommand.java index 875e1eb0ffd..78edbe1acda 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ICommand.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ICommand.java @@ -10,11 +10,14 @@ ***********************************************************************/ package org.eclipse.cdt.make.core.makefile; +import java.io.File; +import java.io.IOException; + /** * ICommand */ -public interface ICommand extends IStatement { +public interface ICommand extends IDirective { final public static char HYPHEN = '-'; @@ -54,4 +57,11 @@ public interface ICommand extends IStatement { */ boolean shouldExecute(); -} \ No newline at end of file + + /** + * Executes the command in a separate process with the + * specified environment and working directory. + * + */ + Process execute(String shell, String[] envp, File dir) throws IOException; +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IComment.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IComment.java index 4af9fde950c..7d7606962cc 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IComment.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IComment.java @@ -13,7 +13,7 @@ package org.eclipse.cdt.make.core.makefile; /** * IComment */ -public interface IComment extends IStatement { +public interface IComment extends IDirective { final public static char POUND = '#'; diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IDefaultRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IDefaultRule.java new file mode 100644 index 00000000000..77db59f5424 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IDefaultRule.java @@ -0,0 +1,20 @@ +/********************************************************************** + * 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; + +/** + * .DEFAULT + * If the makefile uses this special target, the application shall ensure that it is + * specified with commands, but without prerequisites. + * The commands shall be used by make if there are no other rules available to build a target. + */ +public interface IDefaultRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IStatement.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IDirective.java similarity index 95% rename from build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IStatement.java rename to build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IDirective.java index 4cfe39aabf8..a8e0620a224 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IStatement.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IDirective.java @@ -12,7 +12,7 @@ package org.eclipse.cdt.make.core.makefile; /** */ -public interface IStatement { +public interface IDirective { int getStartLine(); diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IEmptyLine.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IEmptyLine.java index 2a481740292..17f2feca003 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IEmptyLine.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IEmptyLine.java @@ -13,5 +13,5 @@ package org.eclipse.cdt.make.core.makefile; /** * IEmptyLine */ -public interface IEmptyLine extends IStatement { +public interface IEmptyLine extends IDirective { } \ No newline at end of file diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IIgnoreRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IIgnoreRule.java new file mode 100644 index 00000000000..00906fbc1bc --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IIgnoreRule.java @@ -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; + +/** + * .IGNORE + * Prerequisites of this special target are targets themselves; this shall cause errors + * from commands associated with them to be ignored in the same manner as specified by the -i option. + */ +public interface IIgnoreRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IMacroDefinition.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IMacroDefinition.java index 41a2e508724..ae692b9eef0 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IMacroDefinition.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IMacroDefinition.java @@ -13,9 +13,19 @@ package org.eclipse.cdt.make.core.makefile; /** * IMacroDefinition */ -public interface IMacroDefinition extends IStatement { +public interface IMacroDefinition extends IDirective { - public abstract String getName(); + String getName(); - public abstract String getValue(); + StringBuffer getValue(); + + boolean isFromDefault(); + + boolean isFromMakefile(); + + boolean isFromEnviroment(); + + boolean isFromEnvironmentOverride(); + + boolean isFromCommand(); } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IMakefile.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IMakefile.java index 28004f1f627..8483bba9ce4 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IMakefile.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IMakefile.java @@ -10,12 +10,14 @@ ***********************************************************************/ package org.eclipse.cdt.make.core.makefile; +import java.io.IOException; +import java.io.Reader; + /** * IMakefile */ -public interface IMakefile { - IStatement[] getStatements(); +public interface IMakefile extends IParent { IRule[] getRules(); IRule[] getRule(String target); IInferenceRule[] getInferenceRules(); @@ -24,5 +26,6 @@ public interface IMakefile { ITargetRule[] getTargetRule(String target); IMacroDefinition[] getMacroDefinitions(); IMacroDefinition[] getMacroDefinition(String name); - IStatement[] getBuiltins(); -} \ No newline at end of file + IDirective[] getBuiltins(); + void parse(Reader makefile) throws IOException; +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IParent.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IParent.java new file mode 100644 index 00000000000..c35e3acb3fc --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IParent.java @@ -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; + + +/** + * IParent + */ +public interface IParent extends IDirective { + IDirective[] getStatements(); +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IPosixRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IPosixRule.java new file mode 100644 index 00000000000..f725e7b9bab --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IPosixRule.java @@ -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; + +/** + * .POSIX + * The application shall ensure that this special target is specified without + * prerequisites or commands. + */ +public interface IPosixRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IPreciousRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IPreciousRule.java new file mode 100644 index 00000000000..1ec04f908ce --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IPreciousRule.java @@ -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; + +/** + * .PRECIOUS + * Prerequisites of this special target shall not be removed if make recieves an + * asynchronous events. + */ +public interface IPreciousRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IRule.java index 2edec5edec1..0228acfa48e 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IRule.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/IRule.java @@ -13,7 +13,7 @@ package org.eclipse.cdt.make.core.makefile; /** * There are two kinds of rules: Inference rules and target rules */ -public interface IRule extends IStatement { +public interface IRule extends IParent { /** * Array of command for the rule. * @return @@ -26,4 +26,4 @@ public interface IRule extends IStatement { */ ITarget getTarget(); -} \ No newline at end of file +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISccsGetRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISccsGetRule.java new file mode 100644 index 00000000000..aa167735742 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISccsGetRule.java @@ -0,0 +1,20 @@ +/********************************************************************** + * 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; + +/** + * .SCCS_GET + * The application shall ensure that this special target is specified without prerequesites. + * The commands specified with this target shall replace the default + * commands associated with this special target. + */ +public interface ISccsGetRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISilentRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISilentRule.java new file mode 100644 index 00000000000..59a986eb4ef --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISilentRule.java @@ -0,0 +1,20 @@ +/********************************************************************** + * 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; + +/** + * .SILENT + * Prerequisites of this special target are targets themselves; this shall case + * commands associated with them not to be written to the standard output before + * they are executed. + */ +public interface ISilentRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISpecialRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISpecialRule.java new file mode 100644 index 00000000000..ec7220786e8 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISpecialRule.java @@ -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; + +/** + * Target rule that have special meaning for Make. + */ +public interface ISpecialRule extends IRule { + + /** + * The meaning of the prerequistes are specific to + * each rules. + */ + String[] getPrerequisites(); +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISuffixesRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISuffixesRule.java new file mode 100644 index 00000000000..40a08a51660 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ISuffixesRule.java @@ -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; + +/** + * .SUFFIXES + * Prerequesites of .SUFFIXES shall be appended to the list of known suffixes and are + * used in conjunction with the inference rules. + */ +public interface ISuffixesRule extends ISpecialRule { +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ITarget.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ITarget.java index 84b1825b456..a9df18cb4fc 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ITarget.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ITarget.java @@ -14,6 +14,7 @@ package org.eclipse.cdt.make.core.makefile; * ITarget */ public interface ITarget { + String toString(); - boolean isUptodate(); -} \ No newline at end of file + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ITargetRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ITargetRule.java index 3377ce6058b..45b98f9bc25 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ITargetRule.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/makefile/ITargetRule.java @@ -14,5 +14,6 @@ package org.eclipse.cdt.make.core.makefile; * ITargetRule */ public interface ITargetRule extends IRule { - ITarget[] getDependencies(); -} \ No newline at end of file + + String[] getPrerequisites(); +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/AbstractMakefile.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/AbstractMakefile.java index fc40a0cb61a..349cb58bd7b 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/AbstractMakefile.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/AbstractMakefile.java @@ -17,7 +17,7 @@ import org.eclipse.cdt.make.core.makefile.IInferenceRule; import org.eclipse.cdt.make.core.makefile.IMacroDefinition; import org.eclipse.cdt.make.core.makefile.IMakefile; import org.eclipse.cdt.make.core.makefile.IRule; -import org.eclipse.cdt.make.core.makefile.IStatement; +import org.eclipse.cdt.make.core.makefile.IDirective; import org.eclipse.cdt.make.core.makefile.ITargetRule; /** @@ -36,17 +36,15 @@ import org.eclipse.cdt.make.core.makefile.ITargetRule; * internal_macro : "$<" | "$*" | "$@" | "$?" | "$%" */ -public abstract class AbstractMakefile implements IMakefile { +public abstract class AbstractMakefile extends Parent implements IMakefile { public AbstractMakefile() { } - public abstract IStatement[] getStatements(); - public abstract IStatement[] getBuiltins(); - public abstract void addStatement(IStatement statement); + public abstract IDirective[] getBuiltins(); public IRule[] getRules() { - IStatement[] stmts = getStatements(); + IDirective[] stmts = getStatements(); List array = new ArrayList(stmts.length); for (int i = 0; i < stmts.length; i++) { if (stmts[i] instanceof IRule) { @@ -112,7 +110,7 @@ public abstract class AbstractMakefile implements IMakefile { } public IMacroDefinition[] getMacroDefinitions() { - IStatement[] stmts = getStatements(); + IDirective[] stmts = getStatements(); List array = new ArrayList(stmts.length); for (int i = 0; i < stmts.length; i++) { if (stmts[i] instanceof IMacroDefinition) { @@ -134,7 +132,7 @@ public abstract class AbstractMakefile implements IMakefile { } public IMacroDefinition[] getBuiltinMacroDefinitions() { - IStatement[] stmts = getBuiltins(); + IDirective[] stmts = getBuiltins(); List array = new ArrayList(stmts.length); for (int i = 0; i < stmts.length; i++) { if (stmts[i] instanceof IMacroDefinition) { @@ -156,7 +154,7 @@ public abstract class AbstractMakefile implements IMakefile { } public IInferenceRule[] getBuiltinInferenceRules() { - IStatement[] stmts = getBuiltins(); + IDirective[] stmts = getBuiltins(); List array = new ArrayList(stmts.length); for (int i = 0; i < stmts.length; i++) { if (stmts[i] instanceof IInferenceRule) { @@ -177,9 +175,4 @@ public abstract class AbstractMakefile implements IMakefile { return (IInferenceRule[]) array.toArray(new IInferenceRule[0]); } - public void addStatements(IStatement[] stmts) { - for (int i = 0; i < stmts.length; i++) { - addStatement(stmts[i]); - } - } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/ArchiveTarget.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/ArchiveTarget.java new file mode 100644 index 00000000000..ea11178a2b9 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/ArchiveTarget.java @@ -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; + +/** + * IArchiveTarget + */ +public class ArchiveTarget extends Target { + + String member; + + public ArchiveTarget(String lib, String obj) { + super(lib); + member = obj; + } + + public String getMember() { + return member; + } + + public String getLibaryName() { + return toString(); + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Command.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Command.java index 764217ee966..b957045f370 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Command.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Command.java @@ -10,6 +10,9 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile; +import java.io.File; +import java.io.IOException; + import org.eclipse.cdt.make.core.makefile.ICommand; /** @@ -73,16 +76,16 @@ public class Command extends Statement implements ICommand { public String toString() { StringBuffer cmd = new StringBuffer(); - cmd.append((char) '\t'); + cmd.append( '\t'); if (getPrefix() != 0) { cmd.append(getPrefix()); } - cmd.append(command).append((char) '\n'); + cmd.append(command).append('\n'); return cmd.toString(); } public boolean equals(Command cmd) { - return cmd.getPrefix() == getPrefix() && cmd.toString().equals(toString()); + return cmd.toString().equals(toString()); } char getPrefix() { @@ -96,7 +99,16 @@ public class Command extends Statement implements ICommand { command = cmd.trim(); if (command.startsWith(HYPHEN_STRING) || command.startsWith(AT_STRING) || command.startsWith(PLUS_STRING)) { prefix = command.charAt(0); - command = command.substring(1); + command = command.substring(1).trim(); } } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.ICommand#execute(java.lang.String[], java.io.File) + */ + public Process execute(String shell, String[] envp, File dir) throws IOException { + String[] cmdArray = new String[] { shell, "-c", command}; + return Runtime.getRuntime().exec(cmdArray, envp, dir); + } + } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/DefaultRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/DefaultRule.java new file mode 100644 index 00000000000..2ab8cb26f0f --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/DefaultRule.java @@ -0,0 +1,27 @@ +/********************************************************************** + * 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; + +import org.eclipse.cdt.make.core.makefile.ICommand; +import org.eclipse.cdt.make.core.makefile.IDefaultRule; + +/** + * .DEFAULT + * If the makefile uses this special target, the application shall ensure that it is + * specified with commands, but without prerequisites. + */ +public class DefaultRule extends SpecialRule implements IDefaultRule { + + public DefaultRule(ICommand[] cmds) { + super(new Target(".DEFAULT"), new String[0], cmds); + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/IgnoreRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/IgnoreRule.java new file mode 100644 index 00000000000..e38c1f1e4fd --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/IgnoreRule.java @@ -0,0 +1,28 @@ +/********************************************************************** + * 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; + +import org.eclipse.cdt.make.core.makefile.IIgnoreRule; +import org.eclipse.cdt.make.core.makefile.ICommand; + +/** + * .IGNORE + * Prerequistes of this special target are targets themselves; this shall cause errors + * from commands associated with them to be ignored in the same manner as + * specified by the -i option. + */ +public class IgnoreRule extends SpecialRule implements IIgnoreRule { + + public IgnoreRule(String[] reqs) { + super(new Target(".IGNORE"), reqs, new ICommand[0]); + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/InferenceRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/InferenceRule.java index e3d92ddd174..581046411fb 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/InferenceRule.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/InferenceRule.java @@ -15,20 +15,16 @@ import org.eclipse.cdt.make.core.makefile.ITarget; public class InferenceRule extends Rule { - public InferenceRule(String tgt) { - this (new Target(tgt)); - } - public InferenceRule(ITarget target) { this(target, new Command[0]); } - public InferenceRule(String tgt, ICommand[] commands) { - this(new Target(tgt), commands); + public InferenceRule(String tgt, ICommand[] cmds) { + this(new Target(tgt), cmds); } - public InferenceRule(ITarget target, ICommand[] commands) { - super(target, commands); + public InferenceRule(ITarget target, ICommand[] cmds) { + super(target, cmds); } /** @@ -36,8 +32,7 @@ public class InferenceRule extends Rule { */ public String toString() { StringBuffer buffer = new StringBuffer(); - buffer.append(target).append(':'); - buffer.append('\n'); + buffer.append(getTarget().toString()).append(":\n"); ICommand[] cmds = getCommands(); for (int i = 0; i < cmds.length; i++) { buffer.append(cmds[i].toString()); diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MacroDefinition.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MacroDefinition.java index 1101513a8a0..eb89c3987e1 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MacroDefinition.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MacroDefinition.java @@ -17,30 +17,19 @@ import org.eclipse.cdt.make.core.makefile.IMacroDefinition; public class MacroDefinition extends Statement implements IMacroDefinition { String name; StringBuffer value; - char sepChar; - - public MacroDefinition(String line) { - value = new StringBuffer(); - int index = line.indexOf('='); - if (index != -1) { - int separator = index; - // Check for "+=", ":=" - if (index > 0) { - sepChar = line.charAt(index - 1); - if (sepChar == ':' || sepChar =='+' || sepChar == '?') { - separator = index - 1; - } - } - name = line.substring(0, separator).trim(); - value.append(line.substring(index + 1)); - } else { - name = line; - } - } + boolean fromCommand; + boolean fromDefault; + boolean fromMakefile; + boolean fromEnvironment; + boolean fromEnvironmentOverride; public MacroDefinition(String n, String v) { + this(n, new StringBuffer(v)); + } + + public MacroDefinition(String n, StringBuffer v) { name = n; - value = new StringBuffer(v); + value = v; } public String getName() { @@ -51,16 +40,8 @@ public class MacroDefinition extends Statement implements IMacroDefinition { name = (n == null) ? "" : n.trim() ; } - public String getValue() { - return value.toString().trim(); - } - - public void setValue(String val) { - value = new StringBuffer(val); - } - - public void append(String val) { - value.append(' ').append(val); + public StringBuffer getValue() { + return value; } /** @@ -75,4 +56,60 @@ public class MacroDefinition extends Statement implements IMacroDefinition { public boolean equals(MacroDefinition v) { return v.getName().equals(getName()); } + + public void setFromCommand(boolean from) { + fromCommand = from; + } + + public void setFromDefault(boolean from) { + fromDefault = from; + } + + public void setFromEnviroment(boolean from) { + fromEnvironment = from; + } + + public void setFromEnviromentOverride(boolean from) { + fromEnvironmentOverride = from; + } + + public void setFromMakefile(boolean from) { + fromMakefile = from; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IMacroDefinition#isFromCommand() + */ + public boolean isFromCommand() { + return fromCommand; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IMacroDefinition#isFromDefault() + */ + public boolean isFromDefault() { + return fromDefault; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IMacroDefinition#isFromEnviroment() + */ + public boolean isFromEnviroment() { + return fromEnvironment; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IMacroDefinition#isFromEnviroment() + */ + public boolean isFromEnvironmentOverride() { + return fromEnvironmentOverride; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IMacroDefinition#isFromMakefile() + */ + public boolean isFromMakefile() { + return fromMakefile; + } + } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Makefile.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Makefile.java deleted file mode 100644 index db6dbf75fad..00000000000 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Makefile.java +++ /dev/null @@ -1,95 +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; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.List; - -import org.eclipse.cdt.make.core.makefile.*; - -/** - * Makefile : ( statement ) * - * statement : rule | macro_definition | comments | empty - * rule : inference_rule | target_rule - * inference_rule : target ':' ( command ) + - * target_rule : target [ ( target ) * ] ':' [ ( prerequisite ) * ] [ ';' command ] - [ ( command ) * ] - * macro_definition : string '=' (string)* - * comments : ('#' (string) ) * - * empty : - * command : prefix_command string - * target : string - * prefix_command : '-' | '@' | '+' - * internal_macro : "$<" | "$*" | "$@" | "$?" | "$%" - */ - -public abstract class Makefile { - - String filename; - - public Makefile(String name) throws FileNotFoundException, IOException { - filename = name; - } - - public abstract List getStatements(); - - public abstract List getBuiltins(); - - public String getFileName() { - return filename; - } - - public IInferenceRule[] getRules() { - return null; - } - public IInferenceRule getRule(String target) { - return null; - } - public InferenceRule[] getInferenceRules() { - return null; - } - public InferenceRule getInferenceRule(String target) { - return null; - } - public ITargetRule[] getTargetRules() { - return null; - } - public ITargetRule getTargetRule(String target) { - return null; - } - - public IInferenceRule[] getBuiltinRules() { - return null; - } - public IInferenceRule getBuiltinRule(String target) { - return null; - } - public IInferenceRule[] getBuiltinInferenceRules() { - return null; - } - public IInferenceRule getBuiltinInferenceRule(String target) { - return null; - } - - public MacroDefinition[] getMacros() { - return null; - } - public MacroDefinition getMacro(String name) { - return null; - } - public MacroDefinition[] getBuiltinMacros() { - return null; - } - public MacroDefinition getBuiltinMacro(String name) { - return null; - } -} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MakefileReader.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MakefileReader.java index c77ac2cc154..fb61f8f28e5 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MakefileReader.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MakefileReader.java @@ -42,7 +42,7 @@ public class MakefileReader extends LineNumberReader { if (escapedLine && line.length() > 0) { // Eat the spaces at the beginning. int i = 0; - while (i < line.length() && (MakefileUtil.isSpace(line.charAt(i)))) { + while (i < line.length() && (Util.isSpace(line.charAt(i)))) { i++ ; } line = line.substring(i); @@ -61,10 +61,10 @@ public class MakefileReader extends LineNumberReader { // When an escaped is found in a command line in a makefile, // the command line shall contain the backslash, the , and the next line, // except that the first character of the next line shall not be included if it is a - if (MakefileUtil.isEscapedLine(line)) { + if (Util.isEscapedLine(line)) { int index = line.lastIndexOf('\\'); if (index > 0) { - if (!escapedLine && MakefileUtil.isCommand(line)) { + if (!escapedLine && Util.isCommand(line)) { escapedCommand = true; buffer.append(line); } else { diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MakefileUtil.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MakefileUtil.java deleted file mode 100644 index 892770454da..00000000000 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MakefileUtil.java +++ /dev/null @@ -1,161 +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; - -import java.util.ArrayList; -import java.util.List; - -/** - */ -public class MakefileUtil { - - private MakefileUtil() { - } - - public static String[] findPrerequisites(String line) { - return findTargets(line); - } - public static String[] findTargets(String line) { - List aList = new ArrayList(); - int space; - // Trim away trailing and prepending spaces. - line = line.trim(); - while ((space = indexOf(line, ' ')) != -1) { - aList.add(line.substring(0, space).trim()); - line = line.substring(space + 1).trim(); - } - // The last target. - if (line.length() > 0) { - aList.add(line); - } - return (String[]) aList.toArray(new String[0]); - } - - public static boolean isMacroDefinition(String line) { - return isMacroDefinition(line.toCharArray()); - } - public static boolean isMacroDefinition(char[] line) { - return indexOf(line, '=') != -1; - } - - public static boolean isTargetRule(String line) { - return isTargetRule(line.toCharArray()); - } - public static boolean isTargetRule(char[] line) { - int colon = indexOf(line, ':'); - if (colon != -1) { - colon++; - // Things like := are not targets but :: is - if (colon < line.length) { - char c = line[colon]; - if (c == '=') { - return false; - } - } - return true; - } - return false; - } - - public static boolean isCommand(String line) { - return line.length() > 1 && line.startsWith("\t"); - } - public static boolean isCommand(char[] line) { - return (line.length > 1 && line[0] == '\t'); - } - - public static boolean isEscapedLine(String line) { - return (line.endsWith("\\") && !line.endsWith("\\\\")); - } - - public static boolean isEmptyLine(String line) { - return isEmptyLine(line.toCharArray()); - } - public static boolean isEmptyLine(char[] line) { - boolean empty = true; - for (int i = 0; i < line.length; i++) { - if (!isSpace(line[i])) { - empty = false; - break; - } - } - return empty; - } - - public static boolean isInferenceRule(String line) { - return line.startsWith(".") && line.indexOf(':') != -1; - } - public static boolean isInferenceRule(char[] line) { - boolean period = false; - boolean colon = false; - for (int i = 0; i < line.length; i++) { - if (line[0] == '.') { - period = true; - } - if (line[i] == ':') { - colon = true; - } - } - return period && colon; - } - - public static boolean isSpace(char c) { - return (c == ' ' || c == '\t' || c == '\r' || c == '\n'); - } - - - public static int indexOfComment(String line) { - return indexOfComment(line.toCharArray()); - } - public static int indexOfComment(char[] line) { - boolean escaped = false; - for (int i = 0; i < line.length; i++) { - if (line[i] == '#' && !escaped) { - return i; - } - escaped = line[i] == '\\'; - } - return -1; - } - - public static int indexOf(String line, char c) { - return indexOf(line.toCharArray(), c); - } - - /** - * Special indexOf() method that makes sure that what we are searching - * is not between parentheses, brackets or quotes - */ - public static int indexOf(char[] line, char c) { - int paren = 0; - int bracket = 0; - boolean escaped = false; - - for (int i = 0; i < line.length; i++) { - if (line[i] == '(' && !escaped) { - paren++; - } else if (line[i] == '{' && !escaped) { - bracket++; - } else if (line[i] == ')' && !escaped) { - paren--; - } else if (line[i] == '}' && !escaped) { - bracket--; - } else if (line[i] == c) { - if (paren == 0 && bracket == 0) { - return i; - } - } - escaped = line[i] == '\\'; - } - return -1; - } - -} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/NullMakefile.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/NullMakefile.java index b3c99b138c6..d376b3c9ec3 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/NullMakefile.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/NullMakefile.java @@ -10,7 +10,10 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile; -import org.eclipse.cdt.make.core.makefile.IStatement; +import java.io.IOException; +import java.io.Reader; + +import org.eclipse.cdt.make.core.makefile.IDirective; /** * Makefile : ( statement ) * @@ -30,19 +33,30 @@ import org.eclipse.cdt.make.core.makefile.IStatement; public class NullMakefile extends AbstractMakefile { - public static IStatement[] empty = new IStatement[0]; + public static IDirective[] empty = new IDirective[0]; public NullMakefile() { } - public IStatement[] getStatements() { + public IDirective[] getStatements() { return empty; } - public IStatement[] getBuiltins() { + public IDirective[] getBuiltins() { return empty; } - public void addStatement(IStatement statement) { + public void addStatement(IDirective statement) { } + + public String toString() { + return new String(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.makefile.IMakefile#parse(java.io.Reader) + */ + public void parse(Reader makefile) throws IOException { + } + } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Parent.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Parent.java new file mode 100644 index 00000000000..6d016ae89f6 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Parent.java @@ -0,0 +1,56 @@ +/********************************************************************** + * 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; + +import java.util.ArrayList; +import java.util.Arrays; + +import org.eclipse.cdt.make.core.makefile.IParent; +import org.eclipse.cdt.make.core.makefile.IDirective; + +/** + * IParent + */ + +public abstract class Parent extends Statement implements IParent { + + ArrayList children = new ArrayList(); + + public IDirective[] getStatements() { + children.trimToSize(); + return (IDirective[]) children.toArray(new IDirective[0]); + } + + public void addStatement(IDirective statement) { + children.add(statement); + } + + public void addStatements(IDirective[] statements) { + children.addAll(Arrays.asList(statements)); + } + + public void clearStatements() { + children.clear(); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + IDirective[] stmts = getStatements(); + for (int i = 0; i < stmts.length; i++) { + sb.append(stmts[i]); + } + return sb.toString(); + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/PosixRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/PosixRule.java new file mode 100644 index 00000000000..9c9d7a8cc07 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/PosixRule.java @@ -0,0 +1,26 @@ +/********************************************************************** + * 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; + +import org.eclipse.cdt.make.core.makefile.IPosixRule; +import org.eclipse.cdt.make.core.makefile.ICommand; + +/** + * .POSIX + * The appliation shall ensure that this special target is specified without + * prerequisites or commands. + */ +public class PosixRule extends SpecialRule implements IPosixRule { + + public PosixRule() { + super(new Target(".POSIX:"), new String[0], new ICommand[0]); + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/PreciousRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/PreciousRule.java new file mode 100644 index 00000000000..a237d06d6b6 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/PreciousRule.java @@ -0,0 +1,27 @@ +/********************************************************************** + * 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; + +import org.eclipse.cdt.make.core.makefile.IPreciousRule; +import org.eclipse.cdt.make.core.makefile.ICommand; + +/** + * .PRECIOUS + * Prerequisites of this special target shall not be removed if make recieves an + * asynchronous events. + */ +public class PreciousRule extends SpecialRule implements IPreciousRule { + + public PreciousRule(String[] targets) { + super(new Target(".PRECIOUS:"), targets, new ICommand[0]); + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Rule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Rule.java index 08d8f2f7441..2ee8c87509a 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Rule.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Rule.java @@ -11,13 +11,12 @@ package org.eclipse.cdt.make.internal.core.makefile; import org.eclipse.cdt.make.core.makefile.ICommand; -import org.eclipse.cdt.make.core.makefile.IInferenceRule; import org.eclipse.cdt.make.core.makefile.IRule; +import org.eclipse.cdt.make.core.makefile.IDirective; import org.eclipse.cdt.make.core.makefile.ITarget; -public abstract class Rule extends Statement implements IRule, IInferenceRule { +public abstract class Rule extends Parent implements IRule { - ICommand[] commands; ITarget target; public Rule(ITarget tgt) { @@ -26,15 +25,14 @@ public abstract class Rule extends Statement implements IRule, IInferenceRule { public Rule(ITarget tgt, ICommand[] cmds) { target = tgt; - commands = cmds; + addStatements(cmds); } public ICommand[] getCommands() { - return commands; - } - - public void setCommand(ICommand[] cmds) { - commands = cmds; + IDirective[] stmts = getStatements(); + ICommand[] cmds = new ICommand[stmts.length]; + System.arraycopy(stmts, 0, cmds, 0, stmts.length); + return cmds; } public ITarget getTarget() { @@ -45,20 +43,6 @@ public abstract class Rule extends Statement implements IRule, IInferenceRule { target = tgt; } - public void addCommand(ICommand cmd) { - ICommand[] newCmds = new ICommand[commands.length + 1]; - System.arraycopy(commands, 0, newCmds, 0, commands.length); - newCmds[commands.length] = cmd; - commands = newCmds; - } - - public void addCommands(ICommand[] cmds) { - ICommand[] newCmds = new ICommand[commands.length + cmds.length]; - System.arraycopy(commands, 0, newCmds, 0, commands.length); - System.arraycopy(cmds, 0, newCmds, commands.length, cmds.length); - commands = newCmds; - } - public boolean equals(Rule r) { return r.getTarget().equals(getTarget()); } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SccsGetRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SccsGetRule.java new file mode 100644 index 00000000000..7058efb28b1 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SccsGetRule.java @@ -0,0 +1,29 @@ +/********************************************************************** + * 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; + +import org.eclipse.cdt.make.core.makefile.ICommand; +import org.eclipse.cdt.make.core.makefile.ISccsGetRule; + +/** + * .SCCS_GET + * The application shall ensure that this special target is specified without + * prerequesites. + * The commands specifeied with this target shall replace the default + * commands associated with this special target. + */ +public class SccsGetRule extends SpecialRule implements ISccsGetRule { + + public SccsGetRule(ICommand[] cmds) { + super(new Target(".SCCS_GET"), new String[0], cmds); + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SilentRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SilentRule.java new file mode 100644 index 00000000000..0e2cc912a34 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SilentRule.java @@ -0,0 +1,28 @@ +/********************************************************************** + * 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; + +import org.eclipse.cdt.make.core.makefile.ISilentRule; +import org.eclipse.cdt.make.core.makefile.ICommand; + +/** + * .SILENT + * Prerequisties of this special target are targets themselves; this shall cause + * commands associated with them not to be written to the standard output before + * they are executed. + */ +public class SilentRule extends SpecialRule implements ISilentRule { + + public SilentRule(String[] reqs) { + super(new Target(".SILENT"), reqs, new ICommand[0]); + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SpecialRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SpecialRule.java new file mode 100644 index 00000000000..dbdc8d8616a --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SpecialRule.java @@ -0,0 +1,48 @@ +/********************************************************************** + * 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; + +import org.eclipse.cdt.make.core.makefile.ISpecialRule; +import org.eclipse.cdt.make.core.makefile.ITarget; +import org.eclipse.cdt.make.core.makefile.ICommand; + +/** + * Targets that have special meaning for Make. + */ +public abstract class SpecialRule extends Rule implements ISpecialRule { + + String[] prerequisites; + + public SpecialRule(ITarget target, String[] reqs, ICommand[] cmds) { + super(target, cmds); + prerequisites = reqs; + } + + public String[] getPrerequisites() { + return prerequisites; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(target).append(":"); + String[] reqs = getPrerequisites(); + for (int i = 0; i < reqs.length; i++) { + sb.append(' ').append(reqs[i]); + } + sb.append('\n'); + ICommand[] cmds = getCommands(); + for (int i = 0; i < cmds.length; i++) { + sb.append(cmds[i]); + } + return sb.toString(); + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Statement.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Statement.java index f4b1ccdfc1f..cd4e78248a4 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Statement.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Statement.java @@ -10,9 +10,9 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile; -import org.eclipse.cdt.make.core.makefile.IStatement; +import org.eclipse.cdt.make.core.makefile.IDirective; -public abstract class Statement implements IStatement { +public abstract class Statement implements IDirective { int endLine; int startLine; @@ -20,10 +20,14 @@ public abstract class Statement implements IStatement { public Statement() { } + public Statement(int start, int end) { + setLines(start, end); + } + public abstract String toString(); /* (non-Javadoc) - * @see org.eclipse.cdt.make.core.makefile.IStatement#getEndLine() + * @see org.eclipse.cdt.make.core.makefile.IDirective#getEndLine() */ public int getEndLine() { return endLine; @@ -34,7 +38,7 @@ public abstract class Statement implements IStatement { } /* (non-Javadoc) - * @see org.eclipse.cdt.make.core.makefile.IStatement#getStartLine() + * @see org.eclipse.cdt.make.core.makefile.IDirective#getStartLine() */ public int getStartLine() { return startLine; diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SuffixesRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SuffixesRule.java new file mode 100644 index 00000000000..0a55c3b384c --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/SuffixesRule.java @@ -0,0 +1,28 @@ +/********************************************************************** + * 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; + +import org.eclipse.cdt.make.core.makefile.ISuffixesRule; +import org.eclipse.cdt.make.core.makefile.ICommand; + +/** + * .SUFFIXES + * Prerequesites of .SUFFIXES shall be appended tothe list of known suffixes and are + * used inconjucntion with the inference rules. + * + */ +public class SuffixesRule extends SpecialRule implements ISuffixesRule { + + public SuffixesRule(String[] suffixes) { + super(new Target(".SUFFIXES:"), suffixes, new ICommand[0]); + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Target.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Target.java index 0c608cb5e71..42c1ae2d4cf 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Target.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Target.java @@ -30,14 +30,6 @@ public class Target implements ITarget { return new File(target).exists(); } - public int make(boolean echo) { - return 0; - } - - public boolean isUptodate() { - return false; - } - public long lastModified() { return new File(target).lastModified(); } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/TargetRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/TargetRule.java index edcc042f44e..f9a2eda865f 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/TargetRule.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/TargetRule.java @@ -32,27 +32,27 @@ import org.eclipse.cdt.make.core.makefile.ITargetRule; public class TargetRule extends Rule implements ITargetRule { - ITarget[] dependencies; + String[] prerequisites; public TargetRule(ITarget target) { - this(target, new ITarget[0]); + this(target, new String[0], new ICommand[0]); } - public TargetRule(ITarget target, ITarget[] deps) { + public TargetRule(ITarget target, String[] deps) { this(target, deps, new ICommand[0]); } - public TargetRule(ITarget target, ITarget[] deps, ICommand[] commands) { + public TargetRule(ITarget target, String[] reqs, ICommand[] commands) { super(target, commands); - dependencies = deps; + prerequisites = reqs; } - public ITarget[] getDependencies() { - return dependencies; + public String[] getPrerequisites() { + return prerequisites; } - public void setDependecies(ITarget[] reqs) { - dependencies = reqs; + public void setDependecies(String[] reqs) { + prerequisites = reqs; } /** @@ -60,17 +60,16 @@ public class TargetRule extends Rule implements ITargetRule { */ public String toString() { StringBuffer buffer = new StringBuffer(); - buffer.append(target); - if (buffer.length() > 0) { - buffer.append(": "); - for (int i = 0; i < dependencies.length; i++) { - buffer.append(dependencies[i]).append(' '); - } - buffer.append('\n'); - ICommand[] cmds = getCommands(); - for (int i = 0; i < cmds.length; i++) { - buffer.append(cmds[i].toString()); - } + buffer.append(getTarget().toString()); + buffer.append(':'); + String[] reqs = getPrerequisites(); + for (int i = 0; i < reqs.length; i++) { + buffer.append(' ').append(reqs[i]); + } + buffer.append('\n'); + ICommand[] cmds = getCommands(); + for (int i = 0; i < cmds.length; i++) { + buffer.append(cmds[i].toString()); } return buffer.toString(); } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Util.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Util.java new file mode 100644 index 00000000000..d7c4e044526 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Util.java @@ -0,0 +1,86 @@ +/********************************************************************** + * 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; + +/** + * Utility methods. + */ +public class Util { + + private Util() { + } + + public static boolean isCommand(String line) { + return line.length() > 1 && line.startsWith("\t"); + } + + public static boolean isEscapedLine(String line) { + return (line.endsWith("\\") && !line.endsWith("\\\\")); + } + + public static boolean isEmptyLine(String line) { + return line.trim().length() == 0; + } + + public static int indexOfComment(String line) { + boolean escaped = false; + for (int i = 0; i < line.length(); i++) { + if (line.charAt(i) == '#' && !escaped) { + return i; + } + escaped = line.charAt(i) == '\\'; + } + return -1; + } + + public static boolean isSpace(char c) { + return (c == ' ' || c == '\t' || c == '\r' || c == '\n'); + } + + public static int indexOf(String line, char c) { + return indexOf(line, Character.toString(c)); + } + + /** + * Special indexOf() method that makes sure that what we are searching + * is not between parentheses and brackets like a macro $(foo) ${bar} + */ + public static int indexOf(String line, String tokens) { + int paren = 0; + int bracket = 0; + char prev = 0; + char pprev = 0; + for (int i = 0; i < line.length(); i++) { + char ch = line.charAt(i); + if (ch == '(' && prev == '$' && pprev != '\\') { + paren++; + } else if (ch == '{' && prev == '$' && pprev != '\\') { + bracket++; + } else if (ch == ')' && prev != '\\') { + if (paren > 0) { + paren--; + } + } else if (ch == '}' && prev != '\\') { + if (bracket > 0) { + bracket--; + } + } else if (tokens.indexOf(ch) != -1) { + if (paren == 0 && bracket == 0) { + return i; + } + } + pprev = prev; + prev = ch; + } + return -1; + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Conditional.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Conditional.java new file mode 100644 index 00000000000..103153ccb28 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Conditional.java @@ -0,0 +1,124 @@ +/********************************************************************** + * 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.internal.core.makefile.Parent; + +public abstract class Conditional extends Parent { + + String cond; + String arg1; + String arg2; + + public Conditional(String conditional) { + cond = conditional; + parse(); + } + + public Conditional() { + this("", "", ""); + } + + public Conditional(String conditional, String argument1, String argument2) { + arg1 = argument1; + arg2 = argument2; + cond = conditional; + } + + + public String getConditional() { + return cond; + } + + public String getArg1() { + return arg1; + } + + public String getArg2() { + return arg2; + } + + /** + * Formats of the contional. + * ifeq (ARG1, ARG2) + * ifeq 'ARG1' 'ARG2' + * ifeq "ARG1" "ARG2" + * ifeq "ARG1" 'ARG2' + * ifeq 'ARG1' "ARG2" + */ + void parse() { + String line = getConditional().trim(); + + char terminal = line.charAt(0) == '(' ? ',' : line.charAt(0); + + if (line.length() < 5 && terminal != ',' && terminal != '"' && terminal != '\'') { + arg1 = arg2 = ""; + return; + } + + // Find the end of the first string. + int count = 0; + // For the (ARG1, ARG2) format. + if (terminal == ',') { + int paren = 0; + for (count = 0; count < line.length(); count++) { + char ch = line.charAt(count); + if (ch == '(') { + paren++; + } else if (ch == ')') { + paren--; + } else if (ch == terminal && paren <= 0) { + break; + } + } + } else { + for (count = 1; count < line.length(); count++) { + if (line.charAt(count) == terminal) { + break; + } + } + } + + arg1 = line.substring(1, count); + + /* Find the start of the second string. */ + line = line.substring(count + 1).trim(); + + terminal = terminal == ',' ? ')' : line.charAt(0); + if (terminal != ')' && terminal != '"' && terminal != '\'') { + arg2 = ""; + return; + } + + count = 0; + /* Find the end of the second string. */ + if (terminal == ')') { + int paren = 0; + for (count = 0; count < line.length(); count++) { + char ch = line.charAt(count); + if (ch == '(') { + paren++; + } else if (ch == ')') { + paren--; + } else if (ch == terminal && paren <= 0) { + break; + } + } + } else { + for (count = 1; count < line.length(); count++) { + if (line.charAt(count) == terminal) { + break; + } + } + } + arg2 = line.substring(1, count); + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Define.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/DefineVariable.java similarity index 53% rename from build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Define.java rename to build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/DefineVariable.java index ddbd7ca460f..2e178aaa089 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Define.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/DefineVariable.java @@ -10,40 +10,23 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile.gnu; -import org.eclipse.cdt.make.internal.core.makefile.MakefileUtil; -import org.eclipse.cdt.make.internal.core.makefile.Statement; -public class Define extends Statement { +public class DefineVariable extends VariableDefinition { - String variable; + public DefineVariable(String name, StringBuffer value) { + super(name, value); + } - public Define(String line) { - parse(line); + public boolean isMultiline() { + return true; } public String toString() { StringBuffer sb = new StringBuffer("define"); - sb.append(' ').append(variable); + sb.append(getName()).append('\n'); + sb.append(getValue()); + sb.append("endef"); return sb.toString(); } - - public String getVariable() { - return variable; - } - - /** - * Format of the include directive: - * export Variabe ... - */ - protected void parse(String line) { - line = line.trim(); - for (int i = 0; i < line.length(); i++) { - if (MakefileUtil.isSpace(line.charAt(i))) { - line = line.substring(i).trim(); - break; - } - } - variable = line; - } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Else.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Else.java index 2af6d11de13..f5229bde64c 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Else.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Else.java @@ -10,13 +10,11 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile.gnu; -import org.eclipse.cdt.make.internal.core.makefile.Statement; - - -public class Else extends Statement { +public class Else extends Conditional { public Else() { + super(); } public String toString() { diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Endif.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Endif.java index 68c81718ee0..724f7f582a8 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Endif.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Endif.java @@ -10,13 +10,10 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile.gnu; -import org.eclipse.cdt.make.internal.core.makefile.Statement; - - -public class Endif extends Statement { - +public class Endif extends Conditional { public Endif() { + super(); } public String toString() { diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Export.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Export.java deleted file mode 100644 index 7f50e3bf559..00000000000 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Export.java +++ /dev/null @@ -1,55 +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.gnu; - -import java.util.StringTokenizer; - -import org.eclipse.cdt.make.internal.core.makefile.Statement; - -public class Export extends Statement { - - String variable; - - public Export(String line) { - parse(line); - } - - public String toString() { - StringBuffer sb = new StringBuffer("export"); - sb.append(' ').append(variable); - return sb.toString(); - } - - public String getVariable() { - return variable; - } - - /** - * Format of the include directive: - * export Variabe ... - */ - protected void parse(String line) { - StringTokenizer st = new StringTokenizer(line); - int count = st.countTokens(); - if (count > 0) { - for (int i = 0; i < count; i++) { - if (i == 0) { - // ignore the "export" keyword. - continue; - } - variable = st.nextToken(); - } - } - if (variable == null) { - variable = new String(); - } - } -} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/ExportVariable.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/ExportVariable.java new file mode 100644 index 00000000000..2b521461c50 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/ExportVariable.java @@ -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.internal.core.makefile.gnu; + + +public class ExportVariable extends VariableDefinition { + + public ExportVariable(String name, StringBuffer value, int type) { + super(name, value, type); + } + + public boolean isExport() { + return true; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/GNUMakefile.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/GNUMakefile.java index 8d236e8e9b6..2cceae04fc4 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/GNUMakefile.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/GNUMakefile.java @@ -13,31 +13,862 @@ package org.eclipse.cdt.make.internal.core.makefile.gnu; import java.io.FileReader; import java.io.IOException; import java.io.Reader; +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; +import java.util.StringTokenizer; -import org.eclipse.cdt.make.core.makefile.IStatement; +import org.eclipse.cdt.make.core.makefile.ICommand; +import org.eclipse.cdt.make.core.makefile.IDirective; +import org.eclipse.cdt.make.internal.core.makefile.AbstractMakefile; +import org.eclipse.cdt.make.internal.core.makefile.BadStatement; +import org.eclipse.cdt.make.internal.core.makefile.Command; +import org.eclipse.cdt.make.internal.core.makefile.Comment; +import org.eclipse.cdt.make.internal.core.makefile.DefaultRule; +import org.eclipse.cdt.make.internal.core.makefile.EmptyLine; +import org.eclipse.cdt.make.internal.core.makefile.IgnoreRule; +import org.eclipse.cdt.make.internal.core.makefile.InferenceRule; import org.eclipse.cdt.make.internal.core.makefile.MakefileReader; -import org.eclipse.cdt.make.internal.core.makefile.posix.PosixMakefile; +import org.eclipse.cdt.make.internal.core.makefile.Parent; +import org.eclipse.cdt.make.internal.core.makefile.PosixRule; +import org.eclipse.cdt.make.internal.core.makefile.PreciousRule; +import org.eclipse.cdt.make.internal.core.makefile.Rule; +import org.eclipse.cdt.make.internal.core.makefile.SccsGetRule; +import org.eclipse.cdt.make.internal.core.makefile.SilentRule; +import org.eclipse.cdt.make.internal.core.makefile.Statement; +import org.eclipse.cdt.make.internal.core.makefile.SuffixesRule; +import org.eclipse.cdt.make.internal.core.makefile.Target; +import org.eclipse.cdt.make.internal.core.makefile.TargetRule; +import org.eclipse.cdt.make.internal.core.makefile.Util; +import org.eclipse.cdt.make.internal.core.makefile.posix.PosixBuiltinMacroDefinitions; +import org.eclipse.cdt.make.internal.core.makefile.posix.PosixBuiltinRules; +import org.eclipse.cdt.make.internal.core.makefile.posix.PosixMakefileUtil; /** - * GNUMakefile + * Makefile : ( statement ) * + * statement : rule | macro_definition | comments | empty + * rule : inference_rule | target_rule + * inference_rule : target ':' ( command ) + + * target_rule : target [ ( target ) * ] ':' [ ( prerequisite ) * ] [ ';' command ] + [ ( command ) * ] + * macro_definition : string '=' (string)* + * comments : ('#' (string) ) * + * empty : + * command : prefix_command string + * target : string + * prefix_command : '-' | '@' | '+' + * internal_macro : "$<" | "$*" | "$@" | "$?" | "$%" */ -public class GNUMakefile extends PosixMakefile { + +public class GNUMakefile extends AbstractMakefile { public static String PATH_SEPARATOR = System.getProperty("path.separator", ":"); + public static String FILE_SEPARATOR = System.getProperty("file.separator", "/"); - public GNUMakefile(String name) throws IOException { - this(new FileReader(name)); + String[] includeDirectories = new String[0]; + + public GNUMakefile() { + super(); } - public GNUMakefile(Reader reader) throws IOException { - this(new MakefileReader(reader)); + public void parse(String name) throws IOException { + parse(new FileReader(name)); } - public GNUMakefile(MakefileReader reader) throws IOException { - super(reader); + public void parse(Reader reader) throws IOException { + parse(new MakefileReader(reader)); } - protected IStatement processLine(String line, int startLine, int endLine) { - return null; + protected void parse(MakefileReader reader) throws IOException { + String line; + Rule[] rules = null; + Stack conditions = new Stack(); + Stack defines = new Stack(); + int startLine = 0; + int endLine = 0; + + // Clear any old statements. + clearStatements(); + + while ((line = reader.readLine()) != null) { + startLine = endLine + 1; + endLine = reader.getLineNumber(); + + // Check if we enter in "define" + if (GNUMakefileUtil.isEndef(line)) { + // We should have a "define" for a "endef". + if (!defines.empty()) { + DefineVariable def = (DefineVariable) defines.pop(); + def.setEndLine(endLine); + } + Endef endef = createEndef(); + endef.setLines(startLine, endLine); + addStatement(conditions, endef); + continue; + } else if (GNUMakefileUtil.isDefine(line)) { + VariableDefinition def = createVariableDefinition(line); + def.setLines(startLine, endLine); + addStatement(conditions, def); + defines.push(def); + continue; + } else if (GNUMakefileUtil.isOverrideDefine(line)) { + VariableDefinition oDef = createVariableDefinition(line); + oDef.setLines(startLine, endLine); + addStatement(conditions, oDef); + defines.push(oDef); + continue; + } + + // We still in a define. + if (!defines.empty()) { + DefineVariable def = (DefineVariable) defines.peek(); + StringBuffer sb = def.getValue(); + if (sb.length() > 0) { + sb.append('\n'); + } + sb.append(line); + continue; + } + + // 1- Try command first, since we can not strip '#' in command line + if (GNUMakefileUtil.isCommand(line)) { + Command cmd = createCommand(line); + cmd.setLines(startLine, endLine); + if (!conditions.empty()) { + addStatement(conditions, cmd); + continue; + } else if (rules != null) { + // The command is added to the rules + for (int i = 0; i < rules.length; i++) { + rules[i].addStatement(cmd); + rules[i].setEndLine(endLine); + } + continue; + } + // If we have no rules/condition for the command, + // give the other statements a chance by falling through + } + + // 2- Strip away any comments. + int pound = Util.indexOfComment(line); + if (pound != -1) { + Comment cmt = createComment(line.substring(pound + 1)); + cmt.setLines(startLine, endLine); + addStatement(conditions, cmt); + line = line.substring(0, pound); + // If all we have left are spaces continue + if (Util.isEmptyLine(line)) { + continue; + } + // The rest of the line maybe a valid statement. + // keep on trying by falling through. + } + + // 3- Empty lines ? + if (Util.isEmptyLine(line)) { + Statement empty = createEmptyLine(); + empty.setLines(startLine, endLine); + addStatement(conditions, empty); + continue; + } + + // 4- reset the rules to null + // The first non empty line that does not begin with a or '#' + // shall begin a new entry. + rules = null; + + if (GNUMakefileUtil.isElse(line)) { + Statement elseDirective = createConditional(line); + elseDirective.setLines(startLine, endLine); + // Are we missing a if condition ? + if (!conditions.empty()) { + Statement cond = (Statement) conditions.pop(); + cond.setEndLine(endLine - 1); + } + addStatement(conditions, elseDirective); + conditions.push(elseDirective); + continue; + } else if (GNUMakefileUtil.isEndif(line)) { + Conditional endif = createConditional(line); + endif.setLines(startLine, endLine); + // Are we missing a if/else condition ? + if (!conditions.empty()) { + Statement cond = (Statement) conditions.pop(); + cond.setEndLine(endLine - 1); + } + addStatement(conditions, endif); + continue; + } + + // 5- Check for the conditionnals. + Statement statement = processConditions(line); + if (statement != null) { + statement.setLines(startLine, endLine); + addStatement(conditions, statement); + conditions.push(statement); + continue; + } + + // 6- Check for other special gnu directives. + statement = processGNUDirectives(line); + if (statement != null) { + statement.setLines(startLine, endLine); + addStatement(conditions, statement); + continue; + } + + // 7- Check for GNU special rules. + Rule rule = processSpecialRules(line); + if (rule != null) { + rules = new Rule[] { rule }; + rule.setLines(startLine, endLine); + addStatement(conditions, rule); + continue; + } + + // - Check for inference rule. + if (GNUMakefileUtil.isInferenceRule(line)) { + InferenceRule irule = createInferenceRule(line); + irule.setLines(startLine, endLine); + addStatement(conditions, irule); + rules = new Rule[] { irule }; + continue; + } + + // - Variable Definiton ? + if (GNUMakefileUtil.isVariableDefinition(line)) { + Statement stmt = createVariableDefinition(line); + stmt.setLines(startLine, endLine); + addStatement(conditions, stmt); + continue; + } + + if (GNUMakefileUtil.isStaticTargetRule(line)) { + StaticTargetRule[] srules = createStaticTargetRule(line); + for (int i = 0; i < srules.length; i++) { + srules[i].setLines(startLine, endLine); + addStatement(conditions, srules[i]); + } + rules = srules; + continue; + } + + // - Target Rule ? + if (GNUMakefileUtil.isGNUTargetRule(line)) { + TargetRule[] trules = createGNUTargetRules(line); + for (int i = 0; i < trules.length; i++) { + trules[i].setLines(startLine, endLine); + addStatement(conditions, trules[i]); + } + rules = trules; + continue; + } + + // XXX ?? Should not be here. + BadStatement stmt = new BadStatement(line); + stmt.setLines(startLine, endLine); + addStatement(conditions, stmt); + + } + setLines(1, endLine); } + + protected void addStatement(Stack conditions, IDirective statement) { + if (conditions.empty()) { + addStatement(statement); + } else { + Parent p = (Parent) conditions.peek(); + p.addStatement(statement); + p.setEndLine(statement.getEndLine()); + } + } + + protected Statement processConditions(String line) { + Statement stmt = null; + if (GNUMakefileUtil.isIfdef(line)) { + stmt = createConditional(line); + } else if (GNUMakefileUtil.isIfndef(line)) { + stmt = createConditional(line); + } else if (GNUMakefileUtil.isIfeq(line)) { + stmt = createConditional(line); + } else if (GNUMakefileUtil.isIfneq(line)) { + stmt = createConditional(line); + } + return stmt; + } + + protected Statement processGNUDirectives(String line) { + Statement stmt = null; + if (GNUMakefileUtil.isUnExport(line)) { + stmt = createUnExport(line); + } else if (GNUMakefileUtil.isVPath(line)) { + stmt = createVPath(line); + } else if (GNUMakefileUtil.isInclude(line)) { + stmt = createInclude(line); + } + return stmt; + } + + protected Rule processSpecialRules(String line) { + Rule stmt = null; + if (GNUMakefileUtil.isIgnoreRule(line)) { + stmt = createIgnoreRule(line); + } else if (GNUMakefileUtil.isPosixRule(line)) { + stmt = createPosixRule(); + } else if (GNUMakefileUtil.isPreciousRule(line)) { + stmt = createPreciousRule(line); + } else if (GNUMakefileUtil.isSilentRule(line)) { + stmt = createSilentRule(line); + } else if (GNUMakefileUtil.isSuffixesRule(line)) { + stmt = createSuffixesRule(line); + } else if (GNUMakefileUtil.isDefaultRule(line)) { + stmt = createDefaultRule(line); + } else if (GNUMakefileUtil.isSccsGetRule(line)) { + stmt = createSccsGetRule(line); + } + return stmt; + } + + /** + * @param line + * @return + */ + protected Rule 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]); + } + + /** + * @param line + * @return + */ + protected Rule createSilentRule(String line) { + int index = Util.indexOf(line, ':'); + if (index != -1) { + String req = line.substring(index + 1); + String[] reqs = GNUMakefileUtil.findPrerequisites(req); + return new SilentRule(reqs); + } + return new SilentRule(new String[0]); + } + + /** + * @param line + * @return + */ + protected Rule createPreciousRule(String line) { + int index = Util.indexOf(line, ':'); + if (index != -1) { + String req = line.substring(index + 1); + String[] reqs = GNUMakefileUtil.findPrerequisites(req); + return new PreciousRule(reqs); + } + return new PreciousRule(new String[0]); + } + + /** + * @param line + * @return + */ + protected Rule createIgnoreRule(String line) { + int index = Util.indexOf(line, ':'); + if (index != -1) { + String req = line.substring(index + 1); + String[] reqs = GNUMakefileUtil.findPrerequisites(req); + return new IgnoreRule(reqs); + } + return new IgnoreRule(new String[0]); + } + + /** + * + * ifdef CONDITIONAL + * ifeq CONDITIONAL + * ifneq CONDITIONAL + * else + * endif + * + * @param line + * @return + */ + public Conditional createConditional(String line) { + Conditional condition = null; + line = line.trim(); + String keyword = null; + // Move pass the keyword + for (int i = 0; i < line.length(); i++) { + if (Util.isSpace(line.charAt(i))) { + keyword = line.substring(0, i); + line = line.substring(i).trim(); + break; + } + } + if (keyword == null) { + keyword = line; + } + if (keyword.equals("ifdef")) { + condition = new Ifdef(line); + } else if (keyword.equals("ifndef")) { + condition = new Ifndef(line); + } else if (keyword.equals("ifeq")) { + condition = new Ifeq(line); + } else if (keyword.equals("ifneq")) { + condition = new Ifneq(line); + } else if (keyword.equals("else")) { + condition = new Else(); + } else if (keyword.equals("endif")) { + condition = new Endif(); + } + return condition; + } + + /** + * Format of the include directive: + * include filename1 filename2 ... + */ + protected Include createInclude(String line) { + String[] filenames; + StringTokenizer st = new StringTokenizer(line); + int count = st.countTokens(); + if (count > 0) { + filenames = new String[count - 1]; + for (int i = 0; i < count; i++) { + if (i == 0) { + st.nextToken(); + // ignore the "include" keyword. + continue; + } + filenames[i - 1] = st.nextToken(); + } + } else { + filenames = new String[0]; + } + return new Include(filenames, getIncludeDirectories()); + } + + /** + * There are three forms of the "vpath" directive: + * "vpath PATTERN DIRECTORIES" + * Specify the search path DIRECTORIES for file names that match PATTERN. + * + * The search path, DIRECTORIES, is a list of directories to be + * searched, separated by colons (semi-colons on MS-DOS and + * MS-Windows) or blanks, just like the search path used in the `VPATH' variable. + * + * "vpath PATTERN" + * Clear out the search path associated with PATTERN. + * + * "vpath" + * Clear all search paths previously specified with `vpath' directives. + */ + public VPath createVPath(String line) { + String pattern = null; + String[] directories; + StringTokenizer st = new StringTokenizer(line); + int count = st.countTokens(); + List dirs = new ArrayList(count); + if (count > 0) { + for (int i = 0; i < count; i++) { + if (count == 0) { + // ignore the "vpath" directive + st.nextToken(); + } else if (count == 1) { + pattern = st.nextToken(); + } else if (count == 3) { + String delim = " \t\n\r\f" + GNUMakefile.PATH_SEPARATOR; + dirs.add(st.nextToken(delim)); + } else { + dirs.add(st.nextToken()); + } + } + } + directories = (String[]) dirs.toArray(new String[0]); + if (pattern == null) { + pattern = new String(); + } + return new VPath(pattern, directories); + } + + public Endef createEndef() { + return new Endef(); + } + + /** + * @param line + * @return + */ + protected UnExport createUnExport(String line) { + // Pass over "unexport" + for (int i = 0; i < line.length(); i++) { + if (Util.isSpace(line.charAt(i))) { + line = line.substring(i).trim(); + break; + } + } + return new UnExport(line); + } + + protected Command createCommand(String line) { + return new Command(line); + } + + protected Comment createComment(String line) { + return new Comment(line); + } + + protected EmptyLine createEmptyLine() { + return new EmptyLine(); + } + + protected InferenceRule[] createInferenceRules(String line) { + // Inference Rule + String tgt; + int index = Util.indexOf(line, ':'); + if (index != -1) { + tgt = line.substring(0, index); + } else { + tgt = line; + } + return new InferenceRule[] { new InferenceRule(new Target(tgt))}; + } + + protected GNUTargetRule[] createGNUTargetRules(String line) { + String[] targetNames; + String[] normalReqs; + String[] orderReqs; + String cmd = null; + boolean doubleColon = false; + int index = Util.indexOf(line, ':'); + if (index != -1) { + // Break the targets + String target = line.substring(0, index); + targetNames = GNUMakefileUtil.findTargets(target.trim()); + + // Some TargetRule have "::" for separator + String req = line.substring(index + 1); + doubleColon = req.startsWith(":"); + if (doubleColon) { + // move pass the second ':' + req = req.substring(1); + } + + // Check for command + int semicolon = Util.indexOf(req, ';'); + if (semicolon != -1) { + cmd = req.substring(semicolon + 1); + req = req.substring(0, semicolon); + } + + // Check for Normal and order prerequisites + String normalReq = null; + String orderReq = null; + int pipe = Util.indexOf(req, '|'); + if (pipe != -1) { + normalReq = req.substring(0, pipe); + orderReq = req.substring(pipe + 1); + } else { + normalReq = req; + orderReq = ""; + } + + normalReqs = GNUMakefileUtil.findPrerequisites(normalReq.trim()); + orderReqs = GNUMakefileUtil.findPrerequisites(orderReq.trim()); + } else { + targetNames = GNUMakefileUtil.findTargets(line); + normalReqs = new String[0]; + orderReqs = new String[0]; + } + + GNUTargetRule[] rules = new GNUTargetRule[targetNames.length]; + for (int i = 0; i < targetNames.length; i++) { + rules[i] = new GNUTargetRule(createTarget(targetNames[i]), doubleColon, normalReqs, orderReqs, new ICommand[0]); + if (cmd != null) { + rules[i].addStatement(createCommand(cmd)); + } + } + return rules; + } + + protected VariableDefinition createVariableDefinition(String line) { + line = line.trim(); + VariableDefinition vd; + + // the default type. + int type = VariableDefinition.TYPE_RECURSIVE_EXPAND; + boolean isDefine = false; + boolean isOverride = false; + boolean isTargetVariable = false; + boolean isExport = false; + String targetName = ""; + + String name; + StringBuffer value = new StringBuffer(); + + // Check for Target: Variable-assignment + if (GNUMakefileUtil.isTargetVariable(line)) { + // move to the first ':' + int colon = Util.indexOf(line, ':'); + if (colon != -1) { + targetName = line.substring(0, colon).trim(); + line = line.substring(colon + 1).trim(); + } else { + targetName = ""; + } + } + + // Check for Override condition. + if (GNUMakefileUtil.isOverride(line)) { + isOverride = true; + // Move pass the keyword override. + for (int i = 0; i < line.length(); i++) { + if (Util.isSpace(line.charAt(i))) { + line = line.substring(i).trim(); + break; + } + } + } + + // Check for "define" + if (GNUMakefileUtil.isOverrideDefine(line)) { + isDefine = true; + // Move pass the keyword define. + for (int i = 0; i < line.length(); i++) { + if (Util.isSpace(line.charAt(i))) { + line = line.substring(i).trim(); + break; + } + } + } + + // Check for Override condition. + if (GNUMakefileUtil.isExport(line)) { + isExport = true; + // Move pass the keyword export. + for (int i = 0; i < line.length(); i++) { + if (Util.isSpace(line.charAt(i))) { + line = line.substring(i).trim(); + break; + } + } + } + + // Check for Target-variable + + int index = line.indexOf('='); + if (index != -1) { + int separator = index; + // Check for "+=", ":=", "?=" + if (index > 0) { + type = line.charAt(index - 1); + if (type == VariableDefinition.TYPE_SIMPLE_EXPAND + || type == VariableDefinition.TYPE_APPEND + || type == VariableDefinition.TYPE_CONDITIONAL) { + separator = index - 1; + } else { + type = VariableDefinition.TYPE_RECURSIVE_EXPAND; + } + } + name = line.substring(0, separator).trim(); + value.append(line.substring(index + 1).trim()); + } else { + name = line; + } + + if (isTargetVariable) { + vd = new TargetVariable(targetName, name, value, isOverride, type); + } + if (isOverride && isDefine) { + vd = new OverrideDefine(name, value); + } else if (isDefine) { + vd = new DefineVariable(name, value); + } else if (isOverride) { + vd = new OverrideVariable(name, value, type); + } else if (isExport) { + vd = new ExportVariable(name, value, type); + } else { + vd = new VariableDefinition(name, value, type); + } + return vd; + } + + protected Target createTarget(String line) { + return new Target(line); + } + + protected StaticTargetRule[] createStaticTargetRule(String line) { + // first colon: the Targets + String targetPattern; + String[] prereqPatterns; + String[] targets; + int colon = Util.indexOf(line, ':'); + if (colon > 1) { + String targetLine = line.substring(0, colon).trim(); + targets = GNUMakefileUtil.findTargets(targetLine); + // second colon: Target-Pattern + line = line.substring(colon + 1); + colon = Util.indexOf(line, ':'); + if (colon != -1) { + targetPattern = line.substring(0, colon).trim(); + line = line.substring(colon + 1); + StringTokenizer st = new StringTokenizer(line); + int count = st.countTokens(); + prereqPatterns = new String[count]; + for (int i = 0; i < count; i++) { + prereqPatterns[i] = st.nextToken(); + } + } else { + targetPattern = ""; + prereqPatterns = new String[0]; + } + } else { + targets = new String[0]; + targetPattern = ""; + prereqPatterns = new String[0]; + } + + StaticTargetRule[] staticRules = new StaticTargetRule[targets.length]; + for (int i = 0; i < targets.length; i++) { + staticRules[i] = new StaticTargetRule(createTarget(targets[i]), targetPattern, prereqPatterns, new ICommand[0]); + } + return staticRules; + } + + /** + * @param line + * @return + */ + private TargetRule[] createTargetRule(String line) { + String[] targets; + String[] reqs; + String cmd = null; + int index = Util.indexOf(line, ':'); + if (index != -1) { + String target = line.substring(0, index); + // Tokenize the targets + targets = GNUMakefileUtil.findTargets(target); + + String req = line.substring(index + 1); + int semicolon = Util.indexOf(req, ';'); + if (semicolon != -1) { + String c = req.substring(semicolon + 1).trim(); + if (c.length() > 0) { + cmd = c; + } + req = req.substring(0, semicolon); + } + reqs = GNUMakefileUtil.findPrerequisites(req); + } else { + targets = GNUMakefileUtil.findTargets(line); + reqs = new String[0]; + } + + TargetRule[] targetRules = new TargetRule[targets.length]; + for (int i = 0; i < targets.length; i++) { + targetRules[i] = new TargetRule(new Target(targets[i]), reqs); + if (cmd != null) { + Command command = createCommand(cmd); + targetRules[i].addStatement(command); + } + } + return targetRules; + } + + /** + * @param line + * @return + */ + private InferenceRule createInferenceRule(String line) { + String tgt; + int index = Util.indexOf(line, ':'); + if (index != -1) { + tgt = line.substring(0, index); + } else { + tgt = line; + } + return new InferenceRule(new Target(tgt)); + } + + /** + * @param line + * @return + */ + private SccsGetRule createSccsGetRule(String line) { + int semicolon = Util.indexOf(line, ';'); + if (semicolon != -1) { + String cmd = line.substring(semicolon + 1).trim(); + if (cmd.length() > 0) { + ICommand[] cmds = new ICommand[] { new Command(cmd)}; + return new SccsGetRule(cmds); + } + } + return new SccsGetRule(new ICommand[0]); + } + + /** + * @param line + * @return + */ + private DefaultRule createDefaultRule(String line) { + int semicolon = Util.indexOf(line, ';'); + if (semicolon > 0) { + String cmd = line.substring(semicolon + 1).trim(); + if (cmd.length() > 0) { + ICommand[] cmds = new ICommand[] { new Command(cmd)}; + return new DefaultRule(cmds); + } + } + return new DefaultRule(new ICommand[0]); + + } + + /** + * @return + */ + private PosixRule createPosixRule() { + return new PosixRule(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.makefile.AbstractMakefile#getBuiltins() + */ + public IDirective[] getBuiltins() { + IDirective[] macros = new PosixBuiltinMacroDefinitions().getMacroDefinitions(); + IDirective[] rules = new PosixBuiltinRules().getInferenceRules(); + IDirective[] stmts = new IDirective[macros.length + rules.length]; + System.arraycopy(macros, 0, stmts, 0, macros.length); + System.arraycopy(rules, 0, stmts, macros.length, rules.length); + return stmts; + } + + public void setIncludeDirectories(String[] dirs) { + includeDirectories = dirs; + } + + public String[] getIncludeDirectories() { + return includeDirectories; + } + + public static void main(String[] args) { + try { + String filename = "Makefile"; + if (args.length == 1) { + filename = args[0]; + } + GNUMakefile makefile = new GNUMakefile(); + makefile.parse(filename); + IDirective[] statements = makefile.getStatements(); + for (int i = 0; i < statements.length; i++) { + //System.out.println("Rule[" + i +"]"); + System.out.print(statements[i]); + } + } catch (IOException e) { + System.out.println(e); + } + } + } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/GNUMakefileUtil.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/GNUMakefileUtil.java index 9a7810aadf7..118c5e3f699 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/GNUMakefileUtil.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/GNUMakefileUtil.java @@ -10,12 +10,15 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile.gnu; +import org.eclipse.cdt.make.internal.core.makefile.Util; +import org.eclipse.cdt.make.internal.core.makefile.posix.PosixMakefileUtil; + /** * GNUMakefile */ -public class GNUMakefileUtil { +public class GNUMakefileUtil extends PosixMakefileUtil { - public static boolean isIncludeDirective(String line) { + public static boolean isInclude(String line) { line = line.trim(); boolean isInclude = line.startsWith("include") && line.length() > 7 && Character.isWhitespace(line.charAt(7)); boolean isDashInclude = line.startsWith("-include") && line.length() > 8 && Character.isWhitespace(line.charAt(8)); @@ -23,76 +26,130 @@ public class GNUMakefileUtil { return isInclude || isDashInclude || isSInclude; } - public static boolean isVPathDirective(String line) { + public static boolean isVPath(String line) { line = line.trim(); - return line.equals("vpath") || - line.startsWith("vpath") && line.length() > 5 && Character.isWhitespace(line.charAt(5)); + return line.equals("vpath") || line.startsWith("vpath") && line.length() > 5 && Character.isWhitespace(line.charAt(5)); } public static boolean isExport(String line) { line = line.trim(); - return line.equals("export") || - line.startsWith("export") && line.length() > 6 && Character.isWhitespace(line.charAt(6)); + return line.equals("export") || line.startsWith("export") && line.length() > 6 && Character.isWhitespace(line.charAt(6)); } public static boolean isUnExport(String line) { line = line.trim(); - return line.equals("unexport") || - line.startsWith("unexport") && line.length() > 8 && Character.isWhitespace(line.charAt(8)); + return line.startsWith("unexport") && line.length() > 8 && Character.isWhitespace(line.charAt(8)); } public static boolean isDefine(String line) { line = line.trim(); - return line.equals("define") || - line.startsWith("define") && line.length() > 6 && Character.isWhitespace(line.charAt(6)); + return line.startsWith("define") && line.length() > 6 && Character.isWhitespace(line.charAt(6)); } public static boolean isEndef(String line) { - line = line.trim(); - return line.equals("endef") || - line.startsWith("endef") && line.length() > 5 && Character.isWhitespace(line.charAt(5)); + return line.trim().equals("endef"); } public static boolean isOverride(String line) { line = line.trim(); - return line.equals("override") || - line.startsWith("override") && line.length() > 8 && Character.isWhitespace(line.charAt(8)); + return line.startsWith("override") && line.length() > 8 && Character.isWhitespace(line.charAt(8)); } public static boolean isIfeq(String line) { line = line.trim(); - return line.equals("ifeq") || - line.startsWith("ifeq") && line.length() > 4 && Character.isWhitespace(line.charAt(4)); + return line.startsWith("ifeq") && line.length() > 4 && Character.isWhitespace(line.charAt(4)); } public static boolean isIfneq(String line) { line = line.trim(); - return line.equals("ifneq") || - line.startsWith("ifneq") && line.length() > 5 && Character.isWhitespace(line.charAt(5)); + return line.startsWith("ifneq") && line.length() > 5 && Character.isWhitespace(line.charAt(5)); } public static boolean isIfdef(String line) { line = line.trim(); - return line.equals("ifdef") || - line.startsWith("ifdef") && line.length() > 5 && Character.isWhitespace(line.charAt(5)); + return line.startsWith("ifdef") && line.length() > 5 && Character.isWhitespace(line.charAt(5)); } public static boolean isIfndef(String line) { line = line.trim(); - return line.equals("ifndef") || - line.startsWith("ifndef") && line.length() > 5 && Character.isWhitespace(line.charAt(5)); + return line.startsWith("ifndef") && line.length() > 5 && Character.isWhitespace(line.charAt(5)); } public static boolean isElse(String line) { - line = line.trim(); - return line.equals("else") || - line.startsWith("else") && line.length() > 4 && Character.isWhitespace(line.charAt(4)); + return line.trim().equals("else"); } public static boolean isEndif(String line) { + return line.trim().equals("endif"); + } + + public static boolean isOverrideDefine(String line) { line = line.trim(); - return line.equals("endif") || - line.startsWith("endif") && line.length() > 5 && Character.isWhitespace(line.charAt(5)); + if (line.startsWith("override")) { + int i = 8; + for (; i < line.length() && Character.isWhitespace(line.charAt(i)); i++); + if (line.startsWith("define", i)) { + return true; + } + } + return false; + } + + public static boolean isTargetVariable(String line) { + line = line.trim(); + int index = Util.indexOf(line, ':'); + if (index > 1) { + line = line.substring(index + 1).trim(); + int equal = Util.indexOf(line, '='); + if (equal > 1) { + return true; + } + } + return false; + } + + public static boolean isVariableDefinition(String line) { + return isOverrideDefine(line) + || isTargetVariable(line) + || isDefine(line) + || isOverride(line) + || isExport(line) + || isMacroDefinition(line); + } + + /** + * @param line + * @return + */ + public static boolean isStaticTargetRule(String line) { + line = line.trim(); + int colon1 = Util.indexOf(line, ':'); + if (colon1 > 0) { + // move pass colon1 + line = line.substring(colon1 + 1); + int colon2 = Util.indexOf(line, ':'); + // Catch operator "::" not a static pattern rule + return (colon2 > 0); + } + return false; + } + + /** + * @param line + * @return + */ + public static boolean isGNUTargetRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + colon++; + // Catch VariableDefiniton with operator ":=" + if (colon < line.length()) { + return line.charAt(colon) != '='; + } + return true; + } + return false; } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/GNUTargetRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/GNUTargetRule.java new file mode 100644 index 00000000000..d36357b5765 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/GNUTargetRule.java @@ -0,0 +1,69 @@ +/********************************************************************** + * 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.ICommand; +import org.eclipse.cdt.make.core.makefile.ITarget; +import org.eclipse.cdt.make.internal.core.makefile.TargetRule; + +/** + */ + +public class GNUTargetRule extends TargetRule { + + String[] orderOnlyPrerequisites; + boolean doubleColon; + + public GNUTargetRule(ITarget target, boolean double_colon, String[] normal_prereqs, String[] order_prereqs, ICommand[] commands) { + super(target, normal_prereqs, commands); + orderOnlyPrerequisites = order_prereqs; + doubleColon = double_colon; + } + + public boolean isDoubleColon() { + return doubleColon; + } + + public String[] getNormalPrerequisites() { + return getPrerequisites(); + } + + public String[] getOrderOnlyPrerequisites() { + return orderOnlyPrerequisites; + } + + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(getTarget().toString()); + buffer.append(':'); + String[] reqs = getNormalPrerequisites(); + for (int i = 0; i < reqs.length; i++) { + buffer.append(' ').append(reqs[i]); + } + reqs = getOrderOnlyPrerequisites(); + if (reqs.length > 0) { + buffer.append(" |"); + for (int i = 0; i < reqs.length; i++) { + buffer.append(' ').append(reqs[i]); + } + } + buffer.append('\n'); + ICommand[] cmds = getCommands(); + for (int i = 0; i < cmds.length; i++) { + buffer.append(cmds[i].toString()); + } + return buffer.toString(); + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifdef.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifdef.java index cf7b8004b47..8c1c100e77f 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifdef.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifdef.java @@ -10,40 +10,20 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile.gnu; -import org.eclipse.cdt.make.internal.core.makefile.MakefileUtil; -import org.eclipse.cdt.make.internal.core.makefile.Statement; +public class Ifdef extends Conditional { - -public class Ifdef extends Statement { - - String variable; - - public Ifdef(String line) { - parse(line); + public Ifdef(String var) { + super(var, "", ""); } public String toString() { StringBuffer sb = new StringBuffer("ifdef"); - sb.append(' ').append(variable); + sb.append(' ').append(getVariable()); return sb.toString(); } public String getVariable() { - return variable; + return getConditional(); } - /** - * Format of the include directive: - * ifeq condional-directive - */ - protected void parse(String line) { - line = line.trim(); - for (int i = 0; i < line.length(); i++) { - if (MakefileUtil.isSpace(line.charAt(i))) { - line = line.substring(i).trim(); - break; - } - } - variable = line; - } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifeq.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifeq.java index 381ccc930d8..1df531e2093 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifeq.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifeq.java @@ -10,41 +10,16 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile.gnu; -import org.eclipse.cdt.make.internal.core.makefile.MakefileUtil; -import org.eclipse.cdt.make.internal.core.makefile.Statement; +public class Ifeq extends Conditional { - -public class Ifeq extends Statement { - - String conditional; - - public Ifeq(String line) { - parse(line); + public Ifeq(String cond) { + super(cond); } public String toString() { StringBuffer sb = new StringBuffer("ifeq"); - sb.append(' ').append(conditional); + sb.append(' ').append(getConditional()); return sb.toString(); } - public String getConditional() { - return conditional; - } - - /** - * Format of the include directive: - * ifeq condional-directive - */ - protected void parse(String line) { - line = line.trim(); - for (int i = 0; i < line.length(); i++) { - if (MakefileUtil.isSpace(line.charAt(i))) { - line = line.substring(i).trim(); - break; - } - } - - conditional = line; - } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifndef.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifndef.java index 16091f4aff7..3bcd56dcf6f 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifndef.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifndef.java @@ -10,40 +10,20 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile.gnu; -import org.eclipse.cdt.make.internal.core.makefile.MakefileUtil; -import org.eclipse.cdt.make.internal.core.makefile.Statement; +public class Ifndef extends Conditional { - -public class Ifndef extends Statement { - - String variable; - - public Ifndef(String line) { - parse(line); + public Ifndef(String var) { + super(var, "", ""); } public String toString() { StringBuffer sb = new StringBuffer("ifndef"); - sb.append(' ').append(variable); + sb.append(' ').append(getVariable()); return sb.toString(); } public String getVariable() { - return variable; + return getConditional(); } - /** - * Format of the include directive: - * ifeq condional-directive - */ - protected void parse(String line) { - line = line.trim(); - for (int i = 0; i < line.length(); i++) { - if (MakefileUtil.isSpace(line.charAt(i))) { - line = line.substring(i).trim(); - break; - } - } - variable = line; - } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifneq.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifneq.java index 617f60d1577..33ade5db757 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifneq.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Ifneq.java @@ -10,40 +10,16 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile.gnu; -import org.eclipse.cdt.make.internal.core.makefile.MakefileUtil; -import org.eclipse.cdt.make.internal.core.makefile.Statement; +public class Ifneq extends Conditional { - -public class Ifneq extends Statement { - - String conditional; - - public Ifneq(String line) { - parse(line); + public Ifneq(String cond) { + super(cond); } public String toString() { StringBuffer sb = new StringBuffer("ifneq"); - sb.append(' ').append(conditional); + sb.append(' ').append(getConditional()); return sb.toString(); } - public String getConditional() { - return conditional; - } - - /** - * Format of the include directive: - * ifeq condional-directive - */ - protected void parse(String line) { - line = line.trim(); - for (int i = 0; i < line.length(); i++) { - if (MakefileUtil.isSpace(line.charAt(i))) { - line = line.substring(i).trim(); - break; - } - } - conditional = line; - } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Include.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Include.java index 900388c3cf8..ffa53233b5a 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Include.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Include.java @@ -10,16 +10,19 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile.gnu; -import java.util.StringTokenizer; +import java.io.IOException; -import org.eclipse.cdt.make.internal.core.makefile.Statement; +import org.eclipse.cdt.make.core.makefile.IDirective; +import org.eclipse.cdt.make.internal.core.makefile.Parent; -public class Include extends Statement { +public class Include extends Parent { String[] filenames; + String[] dirs; - public Include(String line) { - parse(line); + public Include(String[] files, String[] directories) { + filenames = files; + dirs = directories; } public String toString() { @@ -34,24 +37,29 @@ public class Include extends Statement { return filenames; } - /** - * Format of the include directive: - * include filename1 filename2 ... - */ - protected void parse(String line) { - StringTokenizer st = new StringTokenizer(line); - int count = st.countTokens(); - if (count > 0) { - filenames = new String[count - 1]; - for (int i = 0; i < count; i++) { - if (i == 0) { - // ignore the "include" keyword. - continue; - } - filenames[i] = st.nextToken(); + public IDirective[] getStatements() { + GNUMakefile gnu = new GNUMakefile(); + clearStatements(); + for (int i = 0; i < filenames.length; i++) { + // Try the current directory. + try { + gnu.parse(filenames[i]); + addStatements(gnu.getStatements()); + continue; + } catch (IOException e) { + } + if (!filenames[i].startsWith(GNUMakefile.FILE_SEPARATOR) && dirs != null) { + for (int j = 0; j < dirs.length; j++) { + try { + String filename = dirs[j] + GNUMakefile.FILE_SEPARATOR + filenames[i]; + gnu.parse(filename); + addStatements(gnu.getStatements()); + break; + } catch (IOException e) { + } + } } - } else { - filenames = new String[0]; } + return super.getStatements(); } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Override.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Override.java deleted file mode 100644 index 3ce2cdeca82..00000000000 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/Override.java +++ /dev/null @@ -1,54 +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.gnu; - -import org.eclipse.cdt.make.internal.core.makefile.MakefileUtil; -import org.eclipse.cdt.make.internal.core.makefile.Statement; - - -public class Override extends Statement { - - String variable; - - public Override(String line) { - parse(line); - } - - public String toString() { - StringBuffer sb = new StringBuffer("override"); - sb.append(' ').append(variable); - return sb.toString(); - } - - public String getVariable() { - return variable; - } - - /** - * Format: - * override VARIABLE := VALUE - */ - protected void parse(String line) { - int i = 0; - line = line.trim(); - for (; i < line.length(); i++) { - if (MakefileUtil.isSpace(line.charAt(i))) { - break; - } - } - - if (i < line.length()) { - variable = line.substring(i).trim(); - } else { - variable = new String(); - } - } -} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/OverrideDefine.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/OverrideDefine.java index ed259346645..1602f0d20f1 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/OverrideDefine.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/OverrideDefine.java @@ -10,51 +10,25 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile.gnu; -import org.eclipse.cdt.make.internal.core.makefile.MakefileUtil; -import org.eclipse.cdt.make.internal.core.makefile.Statement; -public class OverrideDefine extends Statement { +public class OverrideDefine extends DefineVariable { - String variable; - public OverrideDefine(String line) { - parse(line); + public OverrideDefine(String name, StringBuffer value) { + super(name, value); } public String toString() { - StringBuffer sb = new StringBuffer("override define"); - sb.append(' ').append(variable); + StringBuffer sb = new StringBuffer("override define "); + sb.append(getName()).append('\n'); + sb.append(getValue()); + sb.append("endef"); return sb.toString(); } - public String getVariable() { - return variable; + public boolean isOverride() { + return true; } - /** - * Format: - * override define VARIABLE - */ - protected void parse(String line) { - line = line.trim(); - - // Pass over "override" - for (int i = 0; i < line.length(); i++) { - if (MakefileUtil.isSpace(line.charAt(i))) { - line = line.substring(i).trim(); - break; - } - } - - // Pass over "define" - for (int i = 0; i < line.length(); i++) { - if (MakefileUtil.isSpace(line.charAt(i))) { - line = line.substring(i).trim(); - break; - } - } - - variable = line; - } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/OverrideVariable.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/OverrideVariable.java new file mode 100644 index 00000000000..02d14287699 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/OverrideVariable.java @@ -0,0 +1,25 @@ +/********************************************************************** + * 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; + + + +public class OverrideVariable extends VariableDefinition { + + public OverrideVariable(String name, StringBuffer value, int type) { + super(name, value, type); + } + + public boolean isOverride() { + return true; + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/StaticTargetRule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/StaticTargetRule.java new file mode 100644 index 00000000000..ddb19026fd8 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/StaticTargetRule.java @@ -0,0 +1,74 @@ +/********************************************************************** + * 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.ICommand; +import org.eclipse.cdt.make.core.makefile.IInferenceRule; +import org.eclipse.cdt.make.core.makefile.ITarget; +import org.eclipse.cdt.make.internal.core.makefile.InferenceRule; + + +/** + * Here is the syntax of a static pattern rule: + * + * TARGETS ...: TARGET-PATTERN: DEP-PATTERNS ... + * COMMANDS + * ... + */ +public class StaticTargetRule extends InferenceRule implements IInferenceRule { + + String targetPattern; + String[] prereqPatterns; + + public StaticTargetRule(ITarget target, String target_pattern, String[] prereq_patterns, ICommand[] commands) { + super(target, commands); + targetPattern = target_pattern; + prereqPatterns = prereq_patterns; + } + + public String[] getPrerequisitePatterns() { + return prereqPatterns; + } + + public void setPrerequesitePatterns(String[] prereqs) { + prereqPatterns = prereqs; + } + + public String getTargetPattern() { + return targetPattern; + } + + public void setTargetPattern(String target_pattern) { + targetPattern = target_pattern; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(getTarget()).append(':'); + String pattern = getTargetPattern(); + if (pattern != null && pattern.length() > 0) { + buffer.append(' ').append(targetPattern); + } + buffer.append(':'); + for (int i = 0; i < prereqPatterns.length; i++) { + buffer.append(' ').append(prereqPatterns[i]); + } + buffer.append('\n'); + ICommand[] cmds = getCommands(); + for (int i = 0; i < cmds.length; i++) { + buffer.append(cmds[i].toString()); + } + return buffer.toString(); + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/TargetVariable.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/TargetVariable.java new file mode 100644 index 00000000000..41be8cc1750 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/TargetVariable.java @@ -0,0 +1,34 @@ +/********************************************************************** + * 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; + + + +/** + * Here is the syntax of a static pattern rule: + * + * TARGETS ...: VARIABLE-ASSIGNMENT + * TARGETS ...: override VARIABLE-ASSIGNMENT + */ +public class TargetVariable extends VariableDefinition { + + boolean override; + + public TargetVariable(String target, String name, StringBuffer value, boolean override, int type) { + super(target, name, value, type); + this.override = override; + } + + public boolean isOverride() { + return override; + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/UnExport.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/UnExport.java index 0bd6061e912..5a55138c297 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/UnExport.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/UnExport.java @@ -10,16 +10,14 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile.gnu; -import java.util.StringTokenizer; - import org.eclipse.cdt.make.internal.core.makefile.Statement; public class UnExport extends Statement { String variable; - public UnExport(String line) { - parse(line); + public UnExport(String var) { + variable = var; } public String toString() { @@ -32,24 +30,4 @@ public class UnExport extends Statement { return variable; } - /** - * Format of the include directive: - * export Variabe ... - */ - protected void parse(String line) { - StringTokenizer st = new StringTokenizer(line); - int count = st.countTokens(); - if (count > 0) { - for (int i = 0; i < count; i++) { - if (i == 0) { - // ignore the "unexport" keyword. - continue; - } - variable = st.nextToken(); - } - } - if (variable == null) { - variable = new String(); - } - } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/VPath.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/VPath.java index 91a093f269b..cee1d5ad483 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/VPath.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/VPath.java @@ -10,10 +10,6 @@ ***********************************************************************/ package org.eclipse.cdt.make.internal.core.makefile.gnu; -import java.util.ArrayList; -import java.util.List; -import java.util.StringTokenizer; - import org.eclipse.cdt.make.internal.core.makefile.Statement; public class VPath extends Statement { @@ -21,8 +17,9 @@ public class VPath extends Statement { String pattern; String[] directories; - public VPath(String line) { - parse(line); + public VPath(String pat, String[] dirs) { + pattern = pat; + directories = dirs; } public String toString() { @@ -43,44 +40,4 @@ public class VPath extends Statement { public String getPattern() { return pattern; } - - /** - * There are three forms of the "vpath" directive: - * "vpath PATTERN DIRECTORIES" - * Specify the search path DIRECTORIES for file names that match PATTERN. - * - * The search path, DIRECTORIES, is a list of directories to be - * searched, separated by colons (semi-colons on MS-DOS and - * MS-Windows) or blanks, just like the search path used in the `VPATH' variable. - * - * "vpath PATTERN" - * Clear out the search path associated with PATTERN. - * - * "vpath" - * Clear all search paths previously specified with `vpath' directives. - */ - protected void parse(String line) { - StringTokenizer st = new StringTokenizer(line); - int count = st.countTokens(); - List dirs = new ArrayList(count); - if (count > 0) { - for (int i = 0; i < count; i++) { - if (count == 0) { - // ignore the "vpath" directive - st.nextToken(); - } else if (count == 1) { - pattern = st.nextToken(); - } else if (count == 3) { - String delim = " \t\n\r\f" + GNUMakefile.PATH_SEPARATOR; - dirs.add(st.nextToken(delim)); - } else { - dirs.add(st.nextToken()); - } - } - } - directories = (String[]) dirs.toArray(new String[0]); - if (pattern == null) { - pattern = new String(); - } - } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/VariableDefinition.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/VariableDefinition.java new file mode 100644 index 00000000000..be49501e759 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/gnu/VariableDefinition.java @@ -0,0 +1,132 @@ +/********************************************************************** + * 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.internal.core.makefile.MacroDefinition; + +/** + */ +public class VariableDefinition extends MacroDefinition { + + /** + * ? is Conditional + * : is Simply-expanded + * + is append + * 0 is recusively-expanded. + */ + final static int TYPE_RECURSIVE_EXPAND = 0; + final static int TYPE_SIMPLE_EXPAND = ':'; + final static int TYPE_CONDITIONAL = '?'; + final static int TYPE_APPEND = '+'; + int type; + String varTarget; + + public VariableDefinition(String name, StringBuffer value) { + this(name, value, TYPE_RECURSIVE_EXPAND); + } + + public VariableDefinition(String name, StringBuffer value, int type) { + this("", name, value, type); + } + + public VariableDefinition(String target, String name, StringBuffer value, int type) { + super(name, value); + varTarget = target; + this.type = type; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + if (isTargetSpecific()) { + sb.append(getTarget()).append(": "); + } + if (isOverride()) { + sb.append("override "); + } + if (isMultiLine()) { + sb.append("define "); + sb.append(getName()).append('\n'); + sb.append(getValue()).append('\n'); + sb.append("endef\n"); + } else { + if (isExport()) { + sb.append("export "); + } + sb.append(getName()); + if (isRecursivelyExpanded()) { + sb.append(" = "); + } else if (isSimplyExpanded()) { + sb.append(" := "); + } else if (isConditional()) { + sb.append(" ?= "); + } else if (isAppend()) { + sb.append(" += "); + } + sb.append(getValue()).append('\n'); + } + return sb.toString(); + } + + public boolean equals(VariableDefinition v) { + return v.getName().equals(getName()); + } + + public boolean isRecursivelyExpanded() { + return type == TYPE_RECURSIVE_EXPAND; + } + + public boolean isSimplyExpanded() { + return type == TYPE_SIMPLE_EXPAND; + } + + public boolean isConditional() { + return type == TYPE_CONDITIONAL; + } + + public boolean isAppend() { + return type == TYPE_APPEND; + } + + public boolean isTargetSpecific() { + String t = getTarget(); + return t == null || t.length() == 0; + } + + public boolean isExport() { + return false; + } + + public boolean isMultiLine() { + return false; + } + + /** + * Variable from an `override' directive. + */ + public boolean isOverride() { + return false; + } + + /** + * Automatic variable -- cannot be set. + */ + public boolean isAutomatic() { + return false; + } + + public String getTarget() { + return varTarget; + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixBuiltinMacroDefinitions.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixBuiltinMacroDefinitions.java index 636529d887d..1654ddecc45 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixBuiltinMacroDefinitions.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixBuiltinMacroDefinitions.java @@ -15,22 +15,22 @@ 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")}; + 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++) { diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixMakefile.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixMakefile.java index 432a3d05e6e..6d1647a70ac 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixMakefile.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixMakefile.java @@ -16,30 +16,39 @@ import java.io.Reader; import java.util.ArrayList; import java.util.List; -import org.eclipse.cdt.make.core.makefile.IStatement; +import org.eclipse.cdt.make.core.makefile.ICommand; +import org.eclipse.cdt.make.core.makefile.IDirective; import org.eclipse.cdt.make.internal.core.makefile.AbstractMakefile; import org.eclipse.cdt.make.internal.core.makefile.BadStatement; import org.eclipse.cdt.make.internal.core.makefile.Command; import org.eclipse.cdt.make.internal.core.makefile.Comment; +import org.eclipse.cdt.make.internal.core.makefile.DefaultRule; import org.eclipse.cdt.make.internal.core.makefile.EmptyLine; +import org.eclipse.cdt.make.internal.core.makefile.IgnoreRule; import org.eclipse.cdt.make.internal.core.makefile.InferenceRule; import org.eclipse.cdt.make.internal.core.makefile.MacroDefinition; import org.eclipse.cdt.make.internal.core.makefile.MakefileReader; -import org.eclipse.cdt.make.internal.core.makefile.MakefileUtil; +import org.eclipse.cdt.make.internal.core.makefile.PosixRule; +import org.eclipse.cdt.make.internal.core.makefile.PreciousRule; import org.eclipse.cdt.make.internal.core.makefile.Rule; +import org.eclipse.cdt.make.internal.core.makefile.SccsGetRule; +import org.eclipse.cdt.make.internal.core.makefile.SilentRule; import org.eclipse.cdt.make.internal.core.makefile.Statement; +import org.eclipse.cdt.make.internal.core.makefile.SuffixesRule; import org.eclipse.cdt.make.internal.core.makefile.Target; import org.eclipse.cdt.make.internal.core.makefile.TargetRule; +import org.eclipse.cdt.make.internal.core.makefile.Util; /** * Makefile : ( statement ) * * statement : rule | macro_definition | comments | empty - * rule : inference_rule | target_rule - * inference_rule : target ':' ( command ) + - * target_rule : target [ ( target ) * ] ':' [ ( prerequisite ) * ] [ ';' command ] - [ ( command ) * ] - * macro_definition : string '=' (string)* - * comments : ('#' (string) ) * + * rule : inference_rule | target_rule | special_rule + * inference_rule : target ':' [ ';' command ] + [ ( command ) * ] + * target_rule : [ ( target ) + ] ':' [ ( prerequisite ) * ] [ ';' command ] + [ ( command ) * ] + * macro_definition : string '=' ( string )* + * comments : ('#' ( string ) ) * * empty : * command : prefix_command string * target : string @@ -51,21 +60,19 @@ public class PosixMakefile extends AbstractMakefile { List statements; - public PosixMakefile(String name) throws IOException { - this(new FileReader(name)); - } - - public PosixMakefile(Reader reader) throws IOException { - this(new MakefileReader(reader)); - } - - public PosixMakefile(MakefileReader reader) throws IOException { - super(); + public PosixMakefile() { statements = new ArrayList(); - parse(reader); } - void parse(MakefileReader reader) throws IOException { + public void parse(String name) throws IOException { + parse(new FileReader(name)); + } + + public void parse(Reader reader) throws IOException { + parse(new MakefileReader(reader)); + } + + protected void parse(MakefileReader reader) throws IOException { String line; Rule[] rules = null; int startLine = 0; @@ -74,143 +81,324 @@ public class PosixMakefile extends AbstractMakefile { startLine = endLine + 1; endLine = reader.getLineNumber(); - // 1- Try command first, since we do not strip '#' in commands - if (MakefileUtil.isCommand(line)) { - Command cmd = new Command(line); + // 1- Try command first, since we can not strip '#' in command line + if (PosixMakefileUtil.isCommand(line)) { + Command cmd = createCommand(line); cmd.setLines(startLine, endLine); - // The commands are added to a Rule + // The command is added to the rules if (rules != null) { for (int i = 0; i < rules.length; i++) { - rules[i].addCommand(cmd); + rules[i].addStatement(cmd); rules[i].setEndLine(endLine); } continue; } - // If it is not a command give the other rules a chance a fallthrough + // If we have no rules for the command, + // give the other statements a chance by falling through } // 2- Strip away any comments. - int pound = MakefileUtil.indexOfComment(line); + int pound = Util.indexOfComment(line); if (pound != -1) { - // Comment. - Statement stmt = new Comment(line.substring(pound + 1)); - stmt.setLines(startLine, endLine); - addStatement(stmt); + Comment cmt = createComment(line.substring(pound + 1)); + cmt.setLines(startLine, endLine); + addStatement(cmt); line = line.substring(0, pound); // If all we have left are spaces continue - if (MakefileUtil.isEmptyLine(line)) { + if (Util.isEmptyLine(line)) { continue; } + // The rest of the line maybe a valid statement. + // keep on trying by falling through. } // 3- Empty lines ? - if (MakefileUtil.isEmptyLine(line)) { - // Empty Line. - Statement stmt = new EmptyLine(); - stmt.setLines(startLine, endLine); - addStatement(stmt); + if (Util.isEmptyLine(line)) { + Statement empty = createEmptyLine(); + empty.setLines(startLine, endLine); + addStatement(empty); continue; } - // 4- Check for inference rule. - if (MakefileUtil.isInferenceRule(line)) { - // Inference Rule - String tgt; - int index = MakefileUtil.indexOf(line, ':'); - if (index != -1) { - tgt = line.substring(0, index); - } else { - tgt = line; - } - InferenceRule irule = new InferenceRule(new Target(tgt)); + // 4- reset the rules to null + // The first non empty line that does not begin with a or '#' + // shall begin a new entry. + rules = null; + + // 5- Check for the special targets. + if (PosixMakefileUtil.isDefaultRule(line)) { + DefaultRule dRule = createDefaultRule(line); + rules = new Rule[] { dRule }; + dRule.setLines(startLine, endLine); + addStatement(dRule); + continue; + } else if (PosixMakefileUtil.isIgnoreRule(line)) { + IgnoreRule ignore = createIgnoreRule(line); + ignore.setLines(startLine, endLine); + addStatement(ignore); + continue; + } else if (PosixMakefileUtil.isPosixRule(line)) { + PosixRule pRule = createPosixRule(); + pRule.setLines(startLine, endLine); + addStatement(pRule); + continue; + } else if (PosixMakefileUtil.isPreciousRule(line)) { + PreciousRule precious = createPreciousRule(line); + precious.setLines(startLine, endLine); + addStatement(precious); + continue; + } else if (PosixMakefileUtil.isSccsGetRule(line)) { + SccsGetRule sccs = createSccsGetRule(line); + rules = new Rule[] { sccs }; + sccs.setLines(startLine, endLine); + addStatement(sccs); + continue; + } else if (PosixMakefileUtil.isSilentRule(line)) { + SilentRule silent = createSilentRule(line); + silent.setLines(startLine, endLine); + addStatement(silent); + continue; + } else if (PosixMakefileUtil.isSuffixesRule(line)) { + SuffixesRule suffixes = createSuffixesRule(line); + suffixes.setLines(startLine, endLine); + addStatement(suffixes); + continue; + } + + // 6- Check for inference rule. + if (PosixMakefileUtil.isInferenceRule(line)) { + InferenceRule irule = createInferenceRule(line); irule.setLines(startLine, endLine); addStatement(irule); rules = new Rule[]{irule}; continue; } - // 5- Macro Definiton ? - if (MakefileUtil.isMacroDefinition(line)) { - // MacroDefinition - Statement stmt = new MacroDefinition(line); + // 7- Macro Definiton ? + if (PosixMakefileUtil.isMacroDefinition(line)) { + Statement stmt = createMacroDefinition(line); stmt.setLines(startLine, endLine); addStatement(stmt); continue; } - // 6- Target Rule ? - if (MakefileUtil.isTargetRule(line)) { - String[] targets; - String[] reqs = new String[0]; - String cmd = null; - int index = MakefileUtil.indexOf(line.toCharArray(), ':'); - if (index != -1) { - String target = line.substring(0, index); - // Break the targets, some target have "::" for separator - if (target.startsWith(":")) { - target = target.substring(1); - } - targets = MakefileUtil.findTargets(target.trim()); - - String req = line.substring(index + 1); - int semicolon = MakefileUtil.indexOf(req, ';'); - if (semicolon != -1) { - cmd = req.substring(semicolon + 1); - req = req.substring(0, semicolon); - } - reqs = MakefileUtil.findPrerequisites(req.trim()); - } else { - targets = MakefileUtil.findTargets(line); - } - - Target[] preqs = new Target[reqs.length]; - for (int i = 0; i < reqs.length; i++) { - preqs[i] = new Target(reqs[i]); - } - - rules = new Rule[targets.length]; - for (int i = 0; i < targets.length; i++) { - Rule rule = new TargetRule(new Target(targets[i]), preqs); - rule.setLines(startLine, endLine); - addStatement(rule); - if (cmd != null) { - rule.addCommand(new Command(cmd)); - } - rules[i] = rule; + // 8- Target Rule ? + if (PosixMakefileUtil.isTargetRule(line)) { + TargetRule[] trules = createTargetRule(line); + for (int i = 0; i < trules.length; i++) { + trules[i].setLines(startLine, endLine); + addStatement(trules[i]); } + rules = trules; continue; } - // Other type of processing ? - Statement stmt = processLine(line); - if (stmt == null) { - // Should not be here. - stmt = new BadStatement(line); - } + // XXX ?? Should not be here. + BadStatement stmt = new BadStatement(line); stmt.setLines(startLine, endLine); addStatement(stmt); } + setLines(1, endLine); } - protected Statement processLine(String line) { - return null; + public IDirective[] getStatements() { + return (IDirective[]) statements.toArray(new IDirective[0]); } - public IStatement[] getStatements() { - return (IStatement[]) statements.toArray(new IStatement[0]); - } - - public IStatement[] getBuiltins() { - IStatement[] macros = new PosixBuiltinMacroDefinitions().getMacroDefinitions(); - IStatement[] rules = new PosixBuiltinRules().getInferenceRules(); - IStatement[] stmts = new IStatement[macros.length + rules.length]; + public IDirective[] getBuiltins() { + IDirective[] macros = new PosixBuiltinMacroDefinitions().getMacroDefinitions(); + IDirective[] rules = new PosixBuiltinRules().getInferenceRules(); + IDirective[] stmts = new IDirective[macros.length + rules.length]; System.arraycopy(macros, 0, stmts, 0, macros.length); System.arraycopy(rules, 0, stmts, macros.length, rules.length); return stmts; } - public void addStatement(Statement stmt) { - statements.add(stmt); + /** + * Comment + */ + public Comment createComment(String line) { + return new Comment(line); + } + + /** + * EmptyLine + */ + public EmptyLine createEmptyLine() { + return new EmptyLine(); + } + + /** + * Command + */ + public Command createCommand(String line) { + return new Command(line); + } + + /** + * Inference Rule + */ + public InferenceRule createInferenceRule(String line) { + String tgt; + int index = Util.indexOf(line, ':'); + if (index != -1) { + tgt = line.substring(0, index); + } else { + tgt = line; + } + return new InferenceRule(new Target(tgt)); + } + + /** + * MacroDefinition + */ + public MacroDefinition createMacroDefinition(String line) { + String name; + String value; + int index = Util.indexOf(line, '='); + if (index != -1) { + name = line.substring(0, index).trim(); + value = line.substring(index + 1).trim(); + } else { + name = line; + value = ""; + } + return new MacroDefinition(name, value); + } + + /** + * TargetRule + */ + public TargetRule[] createTargetRule(String line) { + String[] targets; + String[] reqs; + String cmd = null; + int index = Util.indexOf(line, ':'); + if (index != -1) { + String target = line.substring(0, index); + // Tokenize the targets + targets = PosixMakefileUtil.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 = PosixMakefileUtil.findPrerequisites(req); + } else { + targets = PosixMakefileUtil.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; + } + + /** + * .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) { @@ -219,8 +407,9 @@ public class PosixMakefile extends AbstractMakefile { if (args.length == 1) { filename = args[0]; } - PosixMakefile makefile = new PosixMakefile(filename); - IStatement[] statements = makefile.getStatements(); + PosixMakefile makefile = new PosixMakefile(); + makefile.parse(filename); + IDirective[] statements = makefile.getStatements(); for (int i = 0; i < statements.length; i++) { //System.out.println("Rule[" + i +"]"); System.out.print(statements[i]); @@ -230,11 +419,4 @@ public class PosixMakefile extends AbstractMakefile { } } - /* (non-Javadoc) - * @see org.eclipse.cdt.make.internal.core.makefile.AbstractMakefile#addStatement(org.eclipse.cdt.make.core.makefile.IStatement) - */ - public void addStatement(IStatement statement) { - statements.add(statement); - } - } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixMakefileUtil.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixMakefileUtil.java new file mode 100644 index 00000000000..f1539eaad4d --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixMakefileUtil.java @@ -0,0 +1,160 @@ +/********************************************************************** + * 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 java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.make.internal.core.makefile.Util; + +/** + */ +public class PosixMakefileUtil { + + public static String[] findPrerequisites(String line) { + return findTargets(line); + } + + public static String[] findTargets(String line) { + List aList = new ArrayList(); + int space; + // Trim away trailing and prepending spaces. + line = line.trim(); + while ((space = Util.indexOf(line, " \t")) != -1) { + aList.add(line.substring(0, space).trim()); + line = line.substring(space + 1).trim(); + } + // The last target. + if (line.length() > 0) { + aList.add(line); + } + return (String[]) aList.toArray(new String[0]); + } + + public static boolean isMacroDefinition(String line) { + return Util.indexOf(line, '=') != -1; + } + + public static boolean isTargetRule(String line) { + return Util.indexOf(line, ':') != -1; + } + + public static boolean isCommand(String line) { + return line.length() > 1 && line.charAt(0) == '\t'; + } + + public static boolean isEmptyLine(String line) { + return line.trim().length() == 0; + } + + public static boolean isInferenceRule(String line) { + line = line.trim(); + if (line.startsWith(".")) { + int index = Util.indexOf(line, ':'); + if (index > 1) { + line = line.substring(index + 1).trim(); + if (line.length() == 0 || line.equals(";")) { + return true; + } + } + } + return false; + } + + public static boolean isDefaultRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(".DEFAULT"); + } + return false; + } + + public static boolean isIgnoreRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(".IGNORE"); + } + return false; + } + + public static boolean isPosixRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(".POSIX"); + } + return false; + } + + public static boolean isPreciousRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(".PRECIOUS"); + } + return false; + } + + public static boolean isSccsGetRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(".SCCS_GET"); + } + return false; + } + + public static boolean isSilentRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(".SILENT"); + } + return false; + } + + public static boolean isSuffixesRule(String line) { + line = line.trim(); + int colon = Util.indexOf(line, ':'); + if (colon > 0) { + line = line.substring(0, colon).trim(); + return line.equals(".SUFFIXES"); + } + return false; + } + + public static boolean isLibraryTarget(String line) { + char prev = 0; + int paren = 0; + + for (int i = 0; i < line.length(); i++) { + char ch = line.charAt(i); + if (ch == '(' && prev != '$' && prev != '\\') { + paren++; + } else if (ch == ')' && prev != '\\') { + if (paren > 0) { + return true; + } + } + prev = ch; + } + return false; + } + +}