1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

First draft of a Makefile parser.

This commit is contained in:
Alain Magloire 2003-09-02 02:01:36 +00:00
parent 58fba52bad
commit 5c99a8cdca
15 changed files with 1121 additions and 0 deletions

View file

@ -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 ':' <nl> ( <tab> command <nl> ) +
* target_rule : target [ ( target ) * ] ':' [ ( prerequisite ) * ] [ ';' command ] <nl>
[ ( command ) * ]
* macro_definition : string '=' (string)*
* comments : ('#' (string) <nl>) *
* empty : <nl>
* command : <tab> prefix_command string <nl>
* target : string
* prefix_command : '-' | '@' | '+'
* internal_macro : "$<" | "$*" | "$@" | "$?" | "$%"
*/
public 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]);
}
}
}

View file

@ -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 : <tab> prefix_command string <nl>
* 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 : <tab> prefix_command string <nl>
*/
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);
}
}
}

View file

@ -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());
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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());
}
}

View file

@ -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 ':' <nl> ( <tab> command <nl> ) +
* target_rule : target [ ( target ) * ] ':' [ ( prerequisite ) * ] [ ';' command ] <nl>
[ ( command ) * ]
* macro_definition : string '=' (string)*
* comments : ('#' (string) <nl>) *
* empty : <nl>
* command : <tab> prefix_command string <nl>
* target : string
* prefix_command : '-' | '@' | '+'
* internal_macro : "$<" | "$*" | "$@" | "$?" | "$%"
*/
public 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;
}
}

View file

@ -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());
}
}

View file

@ -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();
}

View file

@ -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();
}
}

View file

@ -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 ':' <nl> ( <tab> command <nl> ) +
* target_rule : target [ ( target ) * ] ':' [ ( prerequisite ) * ] [ ';' command ] <nl>
[ ( <tab> prefix_command command ) * ]
* macro_definition : string '=' (string)*
* comments : '#' (string) *
* empty : <nl>
* command : string <nl>
* 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();
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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 ':' <nl> ( <tab> command <nl> ) +
* target_rule : target [ ( target ) * ] ':' [ ( prerequisite ) * ] [ ';' command ] <nl>
[ ( command ) * ]
* macro_definition : string '=' (string)*
* comments : ('#' (string) <nl>) *
* empty : <nl>
* command : <tab> prefix_command string <nl>
* target : string
* prefix_command : '-' | '@' | '+'
* internal_macro : "$<" | "$*" | "$@" | "$?" | "$%"
*/
public 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);
}
}
}