From 5c99a8cdca04fc85016aed8d45018e96f9c352ea Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Tue, 2 Sep 2003 02:01:36 +0000 Subject: [PATCH] First draft of a Makefile parser. --- .../core/makefile/AbstractMakefile.java | 129 +++++++++++++++ .../make/internal/core/makefile/Command.java | 108 +++++++++++++ .../make/internal/core/makefile/Comment.java | 37 +++++ .../internal/core/makefile/EmptyLine.java | 28 ++++ .../internal/core/makefile/InferenceRule.java | 37 +++++ .../core/makefile/MacroDefinition.java | 67 ++++++++ .../make/internal/core/makefile/Makefile.java | 93 +++++++++++ .../cdt/make/internal/core/makefile/Rule.java | 61 +++++++ .../internal/core/makefile/Statement.java | 16 ++ .../make/internal/core/makefile/Target.java | 40 +++++ .../internal/core/makefile/TargetRule.java | 73 +++++++++ .../cdt/make/internal/core/makefile/Util.java | 109 +++++++++++++ .../posix/PosixBuiltinMacroDefinitions.java | 47 ++++++ .../makefile/posix/PosixBuiltinRules.java | 123 ++++++++++++++ .../core/makefile/posix/PosixMakefile.java | 153 ++++++++++++++++++ 15 files changed, 1121 insertions(+) create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/AbstractMakefile.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Command.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Comment.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/EmptyLine.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/InferenceRule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MacroDefinition.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Makefile.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Rule.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Statement.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Target.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/TargetRule.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/posix/PosixBuiltinMacroDefinitions.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixBuiltinRules.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixMakefile.java 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 new file mode 100644 index 00000000000..ff6e0f9d538 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/AbstractMakefile.java @@ -0,0 +1,129 @@ +/********************************************************************** + * 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; + +/** + * 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 AbstractMakefile { + + public AbstractMakefile() { + } + + public abstract Statement[] getStatements(); + public abstract void addStatement(Statement statement); + + public Rule[] getRules() { + Statement[] stmts = getStatements(); + List array = new ArrayList(stmts.length); + for (int i = 0; i < stmts.length; i++) { + if (stmts[i] instanceof Rule) { + array.add(stmts[i]); + } + } + return (Rule[]) array.toArray(new Rule[0]); + } + + public Rule getRule(String target) { + Rule[] rules = getRules(); + for (int i = 0; i < rules.length; i++) { + if (rules[i].getTarget().equals(target)) { + return rules[i]; + } + } + return null; + } + + public InferenceRule[] getInferenceRules() { + Rule[] rules = getRules(); + List array = new ArrayList(rules.length); + for (int i = 0; i < rules.length; i++) { + if (rules[i] instanceof InferenceRule) { + array.add(rules[i]); + } + } + return (InferenceRule[]) array.toArray(new InferenceRule[0]); + } + + public InferenceRule getInferenceRule(String target) { + InferenceRule[] irules = getInferenceRules(); + for (int i = 0; i < irules.length; i++) { + if (irules[i].getTarget().equals(target)) { + return irules[i]; + } + } + return null; + } + + public TargetRule[] getTargetRules() { + Rule[] rules = getRules(); + List array = new ArrayList(rules.length); + for (int i = 0; i < rules.length; i++) { + if (rules[i] instanceof TargetRule) { + array.add(rules[i]); + } + } + return (TargetRule[]) array.toArray(new TargetRule[0]); + } + + public TargetRule getTargetRule(String target) { + TargetRule[] trules = getTargetRules(); + for (int i = 0; i < trules.length; i++) { + if (trules[i].getTarget().equals(target)) { + return trules[i]; + } + } + return null; + } + + public MacroDefinition[] getMacroDefinitions() { + Statement[] stmts = getStatements(); + List array = new ArrayList(stmts.length); + for (int i = 0; i < stmts.length; i++) { + if (stmts[i] instanceof MacroDefinition) { + array.add(stmts[i]); + } + } + return (MacroDefinition[]) array.toArray(new MacroDefinition[0]); + } + + public MacroDefinition getMacroDefinition(String name) { + MacroDefinition[] variables = getMacroDefinitions(); + for (int i = 0; i < variables.length; i++) { + if (variables[i].getName().equals(name)) { + return variables[i]; + } + } + return null; + } + + public void addStatements(Statement[] 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/Command.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Command.java new file mode 100644 index 00000000000..564b12bbbe5 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Command.java @@ -0,0 +1,108 @@ +/********************************************************************** + * 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; + +/** + * Makefile : ( statement ) * + * statement : command | .. + * command : prefix_command string + * prefix_command : '-' | '@' | '+' + */ + +public class Command extends Statement { + + final public static char HYPHEN = '-'; + final public static String HYPHEN_STRING = "-"; + final public static char AT = '@'; + final public static String AT_STRING = "@"; + final public static char PLUS = '+'; + final public static String PLUS_STRING = "+"; + final public static char TAB = '\t'; + final public static char NL = '\n'; + + String command = ""; + char prefix = '\0'; + + public Command(String cmd) { + parse(cmd); + } + + /** + * - If the command prefix contains a hyphen, or the -i option is + * present, or the special target .IGNORE has either the current + * target as a prerequisite or has no prerequisites, any error + * found while executing the command will be ignored. + */ + public boolean shouldIgnoreError() { + // Check for the prefix hyphen in the command. + if (getPrefix() == HYPHEN) { + return true; + } + return false; + } + + /** + * @ If the command prefix contains an at sign and the + * command-line -n option is not specified, or the -s option is + * present, or the special target .SILENT has either the current + * target as a prerequisite or has no prerequisites, the command + * will not be written to standard output before it is executed. + */ + public boolean shouldBeSilent() { + // Check for the prefix at sign + if (getPrefix() == AT) { + return true; + } + return false; + } + + /** + * + If the command prefix contains a plus sign, this indicates a + * command line that will be executed even if -n, -q or -t is + * specified. + */ + public boolean shouldExecute() { + // Check for the prefix at sign + if (getPrefix() == PLUS) { + return true; + } + return false; + } + + public String toString() { + StringBuffer cmd = new StringBuffer(); + cmd.append((char) '\t'); + if (getPrefix() != 0) { + cmd.append(getPrefix()); + } + cmd.append(command).append((char) '\n'); + return cmd.toString(); + } + + public boolean equals(Command cmd) { + return cmd.getPrefix() == getPrefix() && cmd.toString().equals(toString()); + } + + char getPrefix() { + return prefix; + } + + /** + * command : prefix_command string + */ + void parse(String cmd) { + command = cmd.trim(); + if (command.startsWith(HYPHEN_STRING) || command.startsWith(AT_STRING) || command.startsWith(PLUS_STRING)) { + prefix = command.charAt(0); + command = command.substring(1); + } + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Comment.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Comment.java new file mode 100644 index 00000000000..8bf5f33a2e3 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Comment.java @@ -0,0 +1,37 @@ +/********************************************************************** + * 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; + +public class Comment extends Statement { + + final public static char pound = '#'; + final public static String square = "#"; + + String comment; + + public Comment(String cmt) { + if (cmt.startsWith(square)) { + comment = cmt.substring(1); + } else { + comment = cmt; + } + } + + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(square).append(comment).append('\n'); + return buffer.toString(); + } + + public boolean equals(Comment cmt) { + return cmt.toString().equals(toString()); + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/EmptyLine.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/EmptyLine.java new file mode 100644 index 00000000000..c5c6c95c08c --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/EmptyLine.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; + +public class EmptyLine extends Statement { + + final public static String newline = "\n"; + final public static char nl = '\n'; + + public EmptyLine() { + } + + public String toString() { + return newline; + } + + public boolean equals(EmptyLine stmt) { + return true; + } +} 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 new file mode 100644 index 00000000000..7dd436cbdbd --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/InferenceRule.java @@ -0,0 +1,37 @@ +/********************************************************************** + * 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; + +public class InferenceRule extends Rule { + + public InferenceRule(String target) { + this(target, new Command[0]); + } + + public InferenceRule(String target, Command[] commands) { + super(target, commands); + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(target).append(':'); + buffer.append('\n'); + Command[] 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/MacroDefinition.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MacroDefinition.java new file mode 100644 index 00000000000..c119786ed2f --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/MacroDefinition.java @@ -0,0 +1,67 @@ +/********************************************************************** + * 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; + +/** + */ +public class MacroDefinition extends Statement { + String name; + StringBuffer value; + + public MacroDefinition(String line) { + value = new StringBuffer(); + int index = line.indexOf('='); + if (index != -1) { + name = line.substring(0, index); + value.append(line.substring(index + 1)); + } else { + name = line; + } + } + + public MacroDefinition(String n, String v) { + name = n; + value = new StringBuffer(v); + } + + public String getName() { + return name; + } + + public void setName(String n) { + name = n; + } + + public String getValue() { + return value.toString(); + } + + public void setValue(String val) { + value = new StringBuffer(val); + } + + public void append(String val) { + value.append(' ').append(val); + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(name).append(" = ").append(value).append('\n'); + return buffer.toString(); + } + + public boolean equals(MacroDefinition v) { + return v.getName().equals(getName()); + } +} 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 new file mode 100644 index 00000000000..00ffcd2a371 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Makefile.java @@ -0,0 +1,93 @@ +/********************************************************************** + * 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; + +/** + * 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 Rule[] getRules() { + return null; + } + public Rule getRule(String target) { + return null; + } + public InferenceRule[] getInferenceRules() { + return null; + } + public InferenceRule getInferenceRule(String target) { + return null; + } + public TargetRule[] getTargetRules() { + return null; + } + public TargetRule getTargetRule(String target) { + return null; + } + + public Rule[] getBuiltinRules() { + return null; + } + public Rule getBuiltinRule(String target) { + return null; + } + public Rule[] getBuiltinInferenceRules() { + return null; + } + public Rule 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/Rule.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Rule.java new file mode 100644 index 00000000000..57f8ae6e6f5 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Rule.java @@ -0,0 +1,61 @@ +/********************************************************************** + * 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; + +public abstract class Rule extends Statement { + + Command[] commands; + String target; + + public Rule(String target) { + this(target, new Command[0]); + } + + public Rule(String tgt, Command[] cmds) { + target = tgt; + commands = cmds; + } + + public Command[] getCommands() { + return commands; + } + + public void setCommand(Command[] cmds) { + commands = cmds; + } + + public String getTarget() { + return target; + } + + public void setTarget(String tgt) { + target = tgt; + } + + public void addCommand(Command cmd) { + Command[] newCmds = new Command[commands.length + 1]; + System.arraycopy(commands, 0, newCmds, 0, commands.length); + newCmds[commands.length] = cmd; + commands = newCmds; + } + + public void addCommands(Command[] cmds) { + Command[] newCmds = new Command[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/Statement.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Statement.java new file mode 100644 index 00000000000..cbf846a5ec6 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Statement.java @@ -0,0 +1,16 @@ +/********************************************************************** + * 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; + +public abstract class Statement { + + public abstract String toString(); +} 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 new file mode 100644 index 00000000000..399c9bd42d5 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Target.java @@ -0,0 +1,40 @@ +/********************************************************************** + * 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.File; + +public class Target { + + File file; + TargetRule rule; + + public Target(TargetRule r) { + rule = r; + file = new File(rule.getTarget()); + } + + public boolean exits() { + return file.exists(); + } + + public int make(boolean echo) { + return 0; + } + + public boolean isUptodate() { + return false; + } + + public long lastModified() { + return file.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 new file mode 100644 index 00000000000..0c20d488da8 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/TargetRule.java @@ -0,0 +1,73 @@ +/********************************************************************** + * 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; + +/** + * Makefile : ( statement ) * + * statement : rule | macro_definition | comments | empty + * rule : inference_rule | target_rule + * inference_rule : target ':' ( command ) + + * target_rule : target [ ( target ) * ] ':' [ ( prerequisite ) * ] [ ';' command ] + [ ( prefix_command command ) * ] + * macro_definition : string '=' (string)* + * comments : '#' (string) * + * empty : + * command : string + * target : string + * prefix_command : '-' | '@' | '+' + * internal_macro : "$<" | "$*" | "$@" | "$?" | "$%" + */ + +public class TargetRule extends Rule { + + String[] dependencies; + + public TargetRule(String target) { + this(target, new String[0]); + } + + public TargetRule(String target, String[] pres) { + this(target, pres, new Command[0]); + } + + public TargetRule(String target, String[] deps, Command[] commands) { + super(target, commands); + dependencies = deps; + } + + public String[] getDependencies() { + return dependencies; + } + + public void setDependecies(String[] reqs) { + dependencies = reqs; + } + + /** + * @see java.lang.Object#toString() + */ + 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'); + Command[] 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..e251109388e --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/Util.java @@ -0,0 +1,109 @@ +/********************************************************************** + * 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.BufferedReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + */ +public class Util { + + private Util() { + } + + public static String readLine(BufferedReader br) throws IOException { + boolean done = false; + StringBuffer buffer = new StringBuffer(); + boolean escaped = false; + while (!done) { + String line = br.readLine(); + if (line == null) { + return null; + } + + if (escaped) { + line = line.trim(); + } + + // Eat the spaces at the beginning. + if (line.length() > 0 && line.charAt(0) == ' ') { + int i = 1; + while (i < line.length() && line.charAt(i) == ' ') { + i++; + } + line = line.substring(i); + } + + if (line.endsWith("\\")) { + escaped = true; + int index = line.indexOf('\\'); + if (index > 0) { + buffer.append(line.substring(0, index)); + buffer.append(' '); + } + } else { + done = true; + escaped = false; + buffer.append(line); + } + } + return buffer.toString(); + } + + public static String[] findTargets(String line) { + List aList = new ArrayList(); + int space; + while ((space = indexOf(line, ' ')) != -1) { + aList.add(line.substring(0, space).trim()); + line = line.substring(space + 1).trim(); + } + if (line.length() > 0) { + aList.add(line); + } + return (String[]) aList.toArray(new String[0]); + } + + public static String[] findPrerequisites(String line) { + return findTargets(line); + } + + public static boolean isMacroDefinition(char[] line) { + return indexOf(line, '=') != -1; + } + + public static boolean isRule(char[] line) { + return indexOf(line, ':') != -1; + } + + public static int indexOf(String s, char c) { + return indexOf(s.toCharArray(), c); + } + + public static int indexOf(char[] line, char c) { + int level = 0; + for (int i = 0; i < line.length; i++) { + if (line[i] == '(' || line[i] == '{') { + level++; + } else if (line[i] == ')' || line[i] == '}') { + level--; + } else if (line[i] == c) { + if (level == 0) { + return i; + } + } + } + return -1; + } + +} 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 new file mode 100644 index 00000000000..01113fda100 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixBuiltinMacroDefinitions.java @@ -0,0 +1,47 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.make.internal.core.makefile.posix; + +import org.eclipse.cdt.make.internal.core.makefile.MacroDefinition; + +public class PosixBuiltinMacroDefinitions { + MacroDefinition[] macros = + new MacroDefinition[] { + new MacroDefinition("MAKE=make"), + new MacroDefinition("AR=ar"), + new MacroDefinition("ARFLAGS=-rv"), + new MacroDefinition("YACC=yacc"), + new MacroDefinition("YFLAGS="), + new MacroDefinition("LEX=lex"), + new MacroDefinition("LFLAGS="), + new MacroDefinition("LDFLAGS="), + new MacroDefinition("CC=c89"), + new MacroDefinition("CFLAGS=-O"), + new MacroDefinition("FC=fort77"), + new MacroDefinition("FFLAGS=-O 1"), + new MacroDefinition("GET=get"), + new MacroDefinition("GFLAGS="), + new MacroDefinition("SCCSFLAGS="), + new MacroDefinition("SCCSGETFLAGS=-s")}; + + MacroDefinition getMacroDefinition(String name) { + for (int i = 0; i < macros.length; i++) { + if (name.equals(macros[i].getName())) { + return macros[i]; + } + } + return null; + } + + MacroDefinition[] getMacroDefinitions() { + return macros; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixBuiltinRules.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixBuiltinRules.java new file mode 100644 index 00000000000..991660d6218 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixBuiltinRules.java @@ -0,0 +1,123 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.make.internal.core.makefile.posix; + +import org.eclipse.cdt.make.internal.core.makefile.Command; +import org.eclipse.cdt.make.internal.core.makefile.InferenceRule; + +public class PosixBuiltinRules { + InferenceRule[] rules = new InferenceRule[] { + // Special Targets + new InferenceRule(".SCCS_GET", new Command[] { new Command("sccs $(SCCSFLAGS) get $(SCCSGETFLAGS) $@")}), + new InferenceRule(".SUFFIXES", new Command[] { new Command(" .o .c .y .l .a .sh .f .c~ .y~ .l~ .sh~ .f~")}), + // Single Suffix Rules + new InferenceRule(".c", new Command[] { new Command("$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<")}), + new InferenceRule(".f", new Command[] { new Command("$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $<")}), + new InferenceRule(".sh", new Command[] { new Command("cp $< $@"), new Command("chmod a+x $@")}), + new InferenceRule( + ".c~", + new Command[] { + new Command("$(GET) $(GFLAGS) -p $< > $*.c"), + new Command("$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $*.c")}), + new InferenceRule( + ".f~", + new Command[] { + new Command("$(GET) $(GFLAGS) -p $< > $*.f"), + new Command("$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $*.f")}), + new InferenceRule( + ".sh~", + new Command[] { + new Command("$(GET) $(GFLAGS) -p $< > $*.sh"), + new Command("cp $*.sh $@"), + new Command("chmod a+x $@")}), + + // DOUBLE SUFFIX RULES + + new InferenceRule(".c.o", new Command[] { new Command("$(CC) $(CFLAGS) -c $<")}), + new InferenceRule(".f.o", new Command[] { new Command("$(FC) $(FFLAGS) -c $<")}), + new InferenceRule( + ".y.o", + new Command[] { + new Command("$(YACC) $(YFLAGS) $<"), + new Command("$(CC) $(CFLAGS) -c y.tab.c"), + new Command("rm -f y.tab.c"), + new Command("mv y.tab.o $@")}), + new InferenceRule( + ".l.o", + new Command[] { + new Command("$(LEX) $(LFLAGS) $<"), + new Command("$(CC) $(CFLAGS) -c lex.yy.c"), + new Command("rm -f lex.yy.c"), + new Command("mv lex.yy.o $@"), + }), + new InferenceRule(".y.c", new Command[] { new Command("$(YACC) $(YFLAGS) $<"), new Command("mv y.tab.c $@")}), + new InferenceRule(".l.c", new Command[] { new Command("$(LEX) $(LFLAGS) $<"), new Command("mv lex.yy.c $@")}), + new InferenceRule( + ".c~.o", + new Command[] { new Command("$(GET) $(GFLAGS) -p $< > $*.c"), new Command("$(CC) $(CFLAGS) -c $*.c")}), + new InferenceRule( + ".f~.o", + new Command[] { new Command("$(GET) $(GFLAGS) -p $< > $*.f"), new Command("$(FC) $(FFLAGS) -c $*.f")}), + new InferenceRule( + ".y~.o", + new Command[] { + new Command("$(GET) $(GFLAGS) -p $< > $*.y"), + new Command("$(YACC) $(YFLAGS) $*.y"), + new Command("$(CC) $(CFLAGS) -c y.tab.c"), + new Command("rm -f y.tab.c"), + new Command("mv y.tab.o $@")}), + new InferenceRule( + ".l~.o", + new Command[] { + new Command("$(GET) $(GFLAGS) -p $< > $*.l"), + new Command("$(LEX) $(LFLAGS) $*.l"), + new Command("$(CC) $(CFLAGS) -c lex.yy.c"), + new Command("rm -f lex.yy.c"), + new Command("mv lex.yy.o $@")}), + new InferenceRule( + ".y~.c", + new Command[] { + new Command("$(GET) $(GFLAGS) -p $< > $*.y"), + new Command("$(YACC) $(YFLAGS) $*.y"), + new Command("mv y.tab.c $@")}), + new InferenceRule( + ".l~.c", + new Command[] { + new Command("$(GET) $(GFLAGS) -p $< > $*.l"), + new Command("$(LEX) $(LFLAGS) $*.l"), + new Command("mv lex.yy.c $@")}), + new InferenceRule( + ".c.a", + new Command[] { + new Command("$(CC) -c $(CFLAGS) $<"), + new Command("$(AR) $(ARFLAGS) $@ $*.o"), + new Command("rm -f $*.o")}), + new InferenceRule( + ".f.a", + new Command[] { + new Command("$(FC) -c $(FFLAGS) $<"), + new Command("$(AR) $(ARFLAGS) $@ $*.o"), + new Command("rm -f $*.o")}) + }; + + InferenceRule getInferenceRule(String name) { + for (int i = 0; i < rules.length; i++) { + if (name.equals(rules[i].getTarget())) { + return rules[i]; + } + } + return null; + } + + InferenceRule[] getInferenceRules() { + return rules; + } +} 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 new file mode 100644 index 00000000000..e7f8c84cd71 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/makefile/posix/PosixMakefile.java @@ -0,0 +1,153 @@ +/********************************************************************** + * 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.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.make.internal.core.makefile.AbstractMakefile; +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.EmptyLine; +import org.eclipse.cdt.make.internal.core.makefile.InferenceRule; +import org.eclipse.cdt.make.internal.core.makefile.Rule; +import org.eclipse.cdt.make.internal.core.makefile.Statement; +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.MacroDefinition; + +/** + * 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 PosixMakefile extends AbstractMakefile { + + List statements; + + public PosixMakefile(String name) throws IOException { + this(new BufferedReader(new FileReader(name))); + } + + public PosixMakefile(BufferedReader reader) throws IOException { + super(); + statements = new ArrayList(); + parse(reader); + } + + void parse(BufferedReader br) throws IOException { + String line; + Rule rule = null; + while ((line = Util.readLine(br)) != null) { + if (line.length() == 0) { + // Empty Line. + statements.add(new EmptyLine()); + } else if (line.startsWith("#")) { + // Comment. + statements.add(new Comment(line)); + } else if (line.startsWith("\t")) { + // Command. + Command cmd = new Command(line); + if (rule != null) { + rule.addCommand(cmd); + } else { + throw new IOException("Error Parsing"); + } + } else if (line.startsWith(".")) { + // Inference Rule + String tgt; + int index = Util.indexOf(line, ':'); + if (index != -1) { + tgt = line.substring(0, index); + } else { + tgt = line; + } + rule = new InferenceRule(tgt); + statements.add(rule); + } else { + char[] array = line.toCharArray(); + if (Util.isMacroDefinition(array)) { + // MacroDefinition + statements.add(new MacroDefinition(line)); + } else if (Util.isRule(array)) { + String[] targets; + String[] reqs = new String[0]; + String cmd = null; + int index = Util.indexOf(array, ':'); + if (index != -1) { + String target = line.substring(0, index); + // Break the targets + targets = Util.findTargets(target.trim()); + + String req = line.substring(index + 1); + int semicolon = Util.indexOf(req, ';'); + if (semicolon != -1) { + cmd = req.substring(semicolon + 1); + req = req.substring(0, semicolon); + } + reqs = Util.findPrerequisites(req.trim()); + } else { + targets = new String[] { line }; + } + + for (int i = 0; i < targets.length; i++) { + rule = new TargetRule(targets[i], reqs); + statements.add(rule); + if (cmd != null) { + rule.addCommand(new Command(cmd)); + } + } + } else { + } + } + } + } + + public Statement[] getStatements() { + return (Statement[]) statements.toArray(new Statement[0]); + } + + public void addStatement(Statement stmt) { + statements.add(stmt); + } + + public static void main(String[] args) { + try { + String filename = "Makefile"; + if (args.length == 1) { + filename = args[0]; + } + PosixMakefile makefile = new PosixMakefile(filename); + Statement[] 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); + } + } + +}