diff --git a/build/org.eclipse.cdt.make.core.tests/build.properties b/build/org.eclipse.cdt.make.core.tests/build.properties index d985ee0868f..a88598e0c46 100644 --- a/build/org.eclipse.cdt.make.core.tests/build.properties +++ b/build/org.eclipse.cdt.make.core.tests/build.properties @@ -11,5 +11,6 @@ source.. = src/ output.. = bin/ bin.includes = .,\ - META-INF/ + META-INF/,\ + data/ src.includes = about.html diff --git a/build/org.eclipse.cdt.make.core.tests/data/Makefile.main b/build/org.eclipse.cdt.make.core.tests/data/Makefile.main new file mode 100644 index 00000000000..32c5fefcc80 --- /dev/null +++ b/build/org.eclipse.cdt.make.core.tests/data/Makefile.main @@ -0,0 +1,4 @@ +VAR = foo +include Makefile.incl +main: $(VAR) + nothing diff --git a/build/org.eclipse.cdt.make.core.tests/data/incl/Makefile.incl b/build/org.eclipse.cdt.make.core.tests/data/incl/Makefile.incl new file mode 100644 index 00000000000..0cbb66f3ce9 --- /dev/null +++ b/build/org.eclipse.cdt.make.core.tests/data/incl/Makefile.incl @@ -0,0 +1,2 @@ +INCLVAR = bar +foo.o: .PHONY diff --git a/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/core/tests/MakefileReaderProviderTests.java b/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/core/tests/MakefileReaderProviderTests.java index 0d9a38dbfce..553d808c70b 100644 --- a/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/core/tests/MakefileReaderProviderTests.java +++ b/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/core/tests/MakefileReaderProviderTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008 Nokia and others. + * Copyright (c) 2008, 2011 Nokia and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,20 +7,34 @@ * * Contributors: * Nokia (Ed Swartz) - initial API and implementation + * Wind River Systems - Bug 338936 *******************************************************************************/ - package org.eclipse.cdt.make.core.tests; -import org.eclipse.cdt.make.core.MakeCorePlugin; -import org.eclipse.cdt.make.core.makefile.*; -import org.eclipse.core.filesystem.URIUtil; -import org.eclipse.core.runtime.*; - -import java.io.*; -import java.net.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; import junit.framework.Test; import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.core.makefile.IMacroDefinition; +import org.eclipse.cdt.make.core.makefile.IMakefile; +import org.eclipse.cdt.make.core.makefile.IMakefileReaderProvider; +import org.eclipse.cdt.make.core.makefile.IRule; +import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; public class MakefileReaderProviderTests extends TestCase { private String[] inclDirs; @@ -91,7 +105,7 @@ public class MakefileReaderProviderTests extends TestCase { public void testInMemoryReaderProvider() throws Exception { IMakefile makefile = MakeCorePlugin.createMakefile( - URIUtil.toURI("Makefile.main"), true, inclDirs, + URIUtil.toURI("/memory/Makefile.main"), true, inclDirs, new IMakefileReaderProvider() { public Reader getReader(URI fileURI) throws IOException { @@ -119,6 +133,25 @@ public class MakefileReaderProviderTests extends TestCase { assertMakefileContents(makefile); } + public void testReaderIsClosed_Bug338936() throws Exception { + final boolean[] streamIsClosed = { false }; + MakeCorePlugin.createMakefile( + URIUtil.toURI("Makefile.main"), true, inclDirs, + new IMakefileReaderProvider() { + public Reader getReader(URI fileURI) throws IOException { + return new StringReader("") { + @Override + public void close() { + super.close(); + streamIsClosed[0] = true; + } + }; + } + + }); + assertTrue("Stream is not closed", streamIsClosed[0]); + } + /** * @param makefile */ @@ -152,19 +185,18 @@ public class MakefileReaderProviderTests extends TestCase { } private URL getPluginRelativeURL(IPath path) throws Exception { - if (MakeTestsPlugin.getDefault() != null) - return FileLocator.find( + if (MakeTestsPlugin.getDefault() != null) { + URL url = FileLocator.find( MakeTestsPlugin.getDefault().getBundle(), path, null); + return url != null ? FileLocator.toFileURL(url) : null; + } else { return new URL("file", null, path.toFile().getAbsolutePath()); } } - /** - * @return - */ public static Test suite() { - return new MakefileReaderProviderTests(); + return new TestSuite(MakefileReaderProviderTests.class); } } 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 37c4fb89579..66d639bb491 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 QNX Software Systems and others. + * Copyright (c) 2000, 2011 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * QNX Software Systems - Initial API and implementation + * Wind River Systems - Bug 338936 *******************************************************************************/ package org.eclipse.cdt.make.internal.core.makefile.gnu; @@ -137,206 +138,210 @@ public class GNUMakefile extends AbstractMakefile implements IGNUMakefile { setFileURI(fileURI); - while ((line = reader.readLine()) != null) { - startLine = endLine + 1; - endLine = reader.getLineNumber(); + try { + 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". + // Check if we enter in "define" + if (GNUMakefileUtil.isEndef(line)) { + // We should have a "define" for a "endef". + if (!defines.empty()) { + VariableDefinition def = defines.pop(); + def.setEndLine(endLine); + } + Endef endef = new Endef(this); + endef.setLines(startLine, endLine); + addDirective(conditions, endef); + continue; + } else if (GNUMakefileUtil.isDefine(line)) { + VariableDefinition def = parseVariableDefinition(line); + def.setLines(startLine, endLine); + addDirective(conditions, def); + defines.push(def); + continue; + } else if (GNUMakefileUtil.isOverrideDefine(line)) { + VariableDefinition oDef = parseVariableDefinition(line); + oDef.setLines(startLine, endLine); + addDirective(conditions, oDef); + defines.push(oDef); + continue; + } + + // We still in a define. if (!defines.empty()) { - VariableDefinition def = defines.pop(); - def.setEndLine(endLine); - } - Endef endef = new Endef(this); - endef.setLines(startLine, endLine); - addDirective(conditions, endef); - continue; - } else if (GNUMakefileUtil.isDefine(line)) { - VariableDefinition def = parseVariableDefinition(line); - def.setLines(startLine, endLine); - addDirective(conditions, def); - defines.push(def); - continue; - } else if (GNUMakefileUtil.isOverrideDefine(line)) { - VariableDefinition oDef = parseVariableDefinition(line); - oDef.setLines(startLine, endLine); - addDirective(conditions, oDef); - defines.push(oDef); - continue; - } - - // We still in a define. - if (!defines.empty()) { - VariableDefinition def = 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 (PosixMakefileUtil.isCommand(line)) { - Command cmd = new Command(this, line); - cmd.setLines(startLine, endLine); - if (!conditions.empty()) { - addDirective(conditions, cmd); - continue; - } else if (rules != null) { - // The command is added to the rules - for (Rule rule : rules) { - rule.addDirective(cmd); - rule.setEndLine(endLine); + VariableDefinition def = defines.peek(); + StringBuffer sb = def.getValue(); + if (sb.length() > 0) { + sb.append('\n'); } + sb.append(line); continue; } - // If we have no rules/condition for the command, - // give the other directives a chance by falling through - } - // 2- Strip away any comments. - int pound = Util.indexOfComment(line); - if (pound != -1) { - Comment cmt = new Comment(this, line.substring(pound + 1)); - cmt.setLines(startLine, endLine); - if (rules != null) { - // The comment is added to the rules. - for (Rule rule : rules) { - rule.addDirective(cmt); - rule.setEndLine(endLine); + // 1- Try command first, since we can not strip '#' in command line + if (PosixMakefileUtil.isCommand(line)) { + Command cmd = new Command(this, line); + cmd.setLines(startLine, endLine); + if (!conditions.empty()) { + addDirective(conditions, cmd); + continue; + } else if (rules != null) { + // The command is added to the rules + for (Rule rule : rules) { + rule.addDirective(cmd); + rule.setEndLine(endLine); + } + continue; } - } else { - addDirective(conditions, cmt); + // If we have no rules/condition for the command, + // give the other directives a chance by falling through } - line = line.substring(0, pound); - // If all we have left are spaces continue + + // 2- Strip away any comments. + int pound = Util.indexOfComment(line); + if (pound != -1) { + Comment cmt = new Comment(this, line.substring(pound + 1)); + cmt.setLines(startLine, endLine); + if (rules != null) { + // The comment is added to the rules. + for (Rule rule : rules) { + rule.addDirective(cmt); + rule.setEndLine(endLine); + } + } else { + addDirective(conditions, cmt); + } + line = line.substring(0, pound); + // If all we have left are spaces continue + if (Util.isEmptyLine(line)) { + continue; + } + // The rest of the line maybe a valid directives. + // keep on trying by falling through. + } + + // 3- Empty lines ? if (Util.isEmptyLine(line)) { + Directive empty = new EmptyLine(this); + empty.setLines(startLine, endLine); + if (rules != null) { + // The EmptyLine is added to the rules. + for (Rule rule : rules) { + rule.addDirective(empty); + rule.setEndLine(endLine); + } + } else { + addDirective(conditions, empty); + } continue; } - // The rest of the line maybe a valid directives. - // keep on trying by falling through. - } - // 3- Empty lines ? - if (Util.isEmptyLine(line)) { - Directive empty = new EmptyLine(this); - empty.setLines(startLine, endLine); - if (rules != null) { - // The EmptyLine is added to the rules. - for (Rule rule : rules) { - rule.addDirective(empty); - rule.setEndLine(endLine); + // 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)) { + Conditional elseDirective = parseConditional(line); + elseDirective.setLines(startLine, endLine); + // Are we missing a if condition ? + if (!conditions.empty()) { + Conditional cond = (Conditional) conditions.pop(); + cond.setEndLine(endLine - 1); } - } else { - addDirective(conditions, empty); + addDirective(conditions, elseDirective); + conditions.push(elseDirective); + continue; + } else if (GNUMakefileUtil.isEndif(line)) { + Endif endif = new Endif(this); + endif.setLines(startLine, endLine); + // Are we missing a if/else condition ? + if (!conditions.empty()) { + Conditional cond = (Conditional) conditions.pop(); + cond.setEndLine(endLine); + } + addDirective(conditions, endif); + continue; } - 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)) { - Conditional elseDirective = parseConditional(line); - elseDirective.setLines(startLine, endLine); - // Are we missing a if condition ? - if (!conditions.empty()) { - Conditional cond = (Conditional) conditions.pop(); - cond.setEndLine(endLine - 1); + // 5- Check for the conditionnals. + Directive directive = processConditions(line); + if (directive != null) { + directive.setLines(startLine, endLine); + addDirective(conditions, directive); + conditions.push(directive); + continue; } - addDirective(conditions, elseDirective); - conditions.push(elseDirective); - continue; - } else if (GNUMakefileUtil.isEndif(line)) { - Endif endif = new Endif(this); - endif.setLines(startLine, endLine); - // Are we missing a if/else condition ? - if (!conditions.empty()) { - Conditional cond = (Conditional) conditions.pop(); - cond.setEndLine(endLine); + + // 6- Check for other special gnu directives. + directive = processGNUDirectives(line); + if (directive != null) { + directive.setLines(startLine, endLine); + addDirective(conditions, directive); + continue; } - addDirective(conditions, endif); - continue; - } - // 5- Check for the conditionnals. - Directive directive = processConditions(line); - if (directive != null) { - directive.setLines(startLine, endLine); - addDirective(conditions, directive); - conditions.push(directive); - continue; - } - - // 6- Check for other special gnu directives. - directive = processGNUDirectives(line); - if (directive != null) { - directive.setLines(startLine, endLine); - addDirective(conditions, directive); - continue; - } - - // 7- Check for GNU special rules. - SpecialRule special = processSpecialRules(line); - if (special != null) { - rules = new Rule[] { special }; - special.setLines(startLine, endLine); - addDirective(conditions, special); - continue; - } - - // - Check for inference rule. - if (PosixMakefileUtil.isInferenceRule(line)) { - InferenceRule irule = parseInferenceRule(line); - irule.setLines(startLine, endLine); - addDirective(conditions, irule); - rules = new Rule[] { irule }; - continue; - } - - // - Variable Definiton ? - if (GNUMakefileUtil.isVariableDefinition(line)) { - VariableDefinition vd = parseVariableDefinition(line); - vd.setLines(startLine, endLine); - addDirective(conditions, vd); - if (!vd.isTargetSpecific()) { - continue; + // 7- Check for GNU special rules. + SpecialRule special = processSpecialRules(line); + if (special != null) { + rules = new Rule[] { special }; + special.setLines(startLine, endLine); + addDirective(conditions, special); + continue; } - } - // - GNU Static Target rule ? - if (GNUMakefileUtil.isStaticTargetRule(line)) { - StaticTargetRule[] srules = parseStaticTargetRule(line); - for (StaticTargetRule srule : srules) { - srule.setLines(startLine, endLine); - addDirective(conditions, srule); + // - Check for inference rule. + if (PosixMakefileUtil.isInferenceRule(line)) { + InferenceRule irule = parseInferenceRule(line); + irule.setLines(startLine, endLine); + addDirective(conditions, irule); + rules = new Rule[] { irule }; + continue; } - rules = srules; - continue; - } - // - Target Rule ? - if (GNUMakefileUtil.isGNUTargetRule(line)) { - TargetRule[] trules = parseGNUTargetRules(line); - for (TargetRule trule : trules) { - trule.setLines(startLine, endLine); - addDirective(conditions, trule); + // - Variable Definiton ? + if (GNUMakefileUtil.isVariableDefinition(line)) { + VariableDefinition vd = parseVariableDefinition(line); + vd.setLines(startLine, endLine); + addDirective(conditions, vd); + if (!vd.isTargetSpecific()) { + continue; + } } - rules = trules; - continue; + + // - GNU Static Target rule ? + if (GNUMakefileUtil.isStaticTargetRule(line)) { + StaticTargetRule[] srules = parseStaticTargetRule(line); + for (StaticTargetRule srule : srules) { + srule.setLines(startLine, endLine); + addDirective(conditions, srule); + } + rules = srules; + continue; + } + + // - Target Rule ? + if (GNUMakefileUtil.isGNUTargetRule(line)) { + TargetRule[] trules = parseGNUTargetRules(line); + for (TargetRule trule : trules) { + trule.setLines(startLine, endLine); + addDirective(conditions, trule); + } + rules = trules; + continue; + } + + // XXX ?? Should not be here. + BadDirective stmt = new BadDirective(this, line); + stmt.setLines(startLine, endLine); + addDirective(conditions, stmt); + } - - // XXX ?? Should not be here. - BadDirective stmt = new BadDirective(this, line); - stmt.setLines(startLine, endLine); - addDirective(conditions, stmt); - + setLines(1, endLine); + } finally { + reader.close(); } - setLines(1, endLine); // TEST please remove. //GNUMakefileValidator validator = new GNUMakefileValidator(); //validator.validateDirectives(null, getDirectives()); 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 ba036dc6511..fd026d905b0 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 QNX Software Systems and others. + * Copyright (c) 2000, 2011 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * QNX Software Systems - Initial API and implementation + * Wind River Systems - Bug 338936 *******************************************************************************/ package org.eclipse.cdt.make.internal.core.makefile.posix; @@ -117,111 +118,115 @@ public class PosixMakefile extends AbstractMakefile { setFileURI(fileURI); - while ((line = reader.readLine()) != null) { - startLine = endLine + 1; - endLine = reader.getLineNumber(); + try { + while ((line = reader.readLine()) != null) { + startLine = endLine + 1; + endLine = reader.getLineNumber(); - // 1- Try command first, since we can not strip '#' in command line - if (PosixMakefileUtil.isCommand(line)) { - Command cmd = new Command(this, line); - cmd.setLines(startLine, endLine); - // The command is added to the rules - if (rules != null) { - for (int i = 0; i < rules.length; i++) { - rules[i].addDirective(cmd); - rules[i].setEndLine(endLine); + // 1- Try command first, since we can not strip '#' in command line + if (PosixMakefileUtil.isCommand(line)) { + Command cmd = new Command(this, line); + cmd.setLines(startLine, endLine); + // The command is added to the rules + if (rules != null) { + for (int i = 0; i < rules.length; i++) { + rules[i].addDirective(cmd); + rules[i].setEndLine(endLine); + } + continue; } - continue; + // If we have no rules for the command, + // give the other directives a chance by falling through } - // If we have no rules for the command, - // give the other directives a chance by falling through - } - // 2- Strip away any comments. - int pound = Util.indexOfComment(line); - if (pound != -1) { - Comment cmt = new Comment(this, line.substring(pound + 1)); - cmt.setLines(startLine, endLine); - if (rules != null) { - for (int i = 0; i < rules.length; i++) { - rules[i].addDirective(cmt); - rules[i].setEndLine(endLine); + // 2- Strip away any comments. + int pound = Util.indexOfComment(line); + if (pound != -1) { + Comment cmt = new Comment(this, line.substring(pound + 1)); + cmt.setLines(startLine, endLine); + if (rules != null) { + for (int i = 0; i < rules.length; i++) { + rules[i].addDirective(cmt); + rules[i].setEndLine(endLine); + } + } else { + addDirective(cmt); } - } else { - addDirective(cmt); + line = line.substring(0, pound); + // If all we have left are spaces continue + if (Util.isEmptyLine(line)) { + continue; + } + // The rest of the line maybe a valid directive. + // keep on trying by falling through. } - line = line.substring(0, pound); - // If all we have left are spaces continue + + // 3- Empty lines ? if (Util.isEmptyLine(line)) { + Directive empty = new EmptyLine(this); + empty.setLines(startLine, endLine); + if (rules != null) { + for (int i = 0; i < rules.length; i++) { + rules[i].addDirective(empty); + rules[i].setEndLine(endLine); + } + } else { + addDirective(empty); + } continue; } - // The rest of the line maybe a valid directive. - // keep on trying by falling through. - } - // 3- Empty lines ? - if (Util.isEmptyLine(line)) { - Directive empty = new EmptyLine(this); - empty.setLines(startLine, endLine); - if (rules != null) { - for (int i = 0; i < rules.length; i++) { - rules[i].addDirective(empty); - rules[i].setEndLine(endLine); - } - } else { - addDirective(empty); + // 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 rules. + SpecialRule special = processSpecialRule(line); + if (special != null) { + rules = new Rule[] { special }; + special.setLines(startLine, endLine); + addDirective(special); + continue; } - 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; + // 6- Check for inference rule. + if (PosixMakefileUtil.isInferenceRule(line)) { + InferenceRule irule = parseInferenceRule(line); + irule.setLines(startLine, endLine); + addDirective(irule); + rules = new Rule[]{irule}; + continue; + } - // 5- Check for the special rules. - SpecialRule special = processSpecialRule(line); - if (special != null) { - rules = new Rule[] { special }; - special.setLines(startLine, endLine); - addDirective(special); - continue; - } + // 7- Macro Definiton ? + if (PosixMakefileUtil.isMacroDefinition(line)) { + Directive stmt = parseMacroDefinition(line); + stmt.setLines(startLine, endLine); + addDirective(stmt); + continue; + } - // 6- Check for inference rule. - if (PosixMakefileUtil.isInferenceRule(line)) { - InferenceRule irule = parseInferenceRule(line); - irule.setLines(startLine, endLine); - addDirective(irule); - rules = new Rule[]{irule}; - continue; - } + // 8- Target Rule ? + if (PosixMakefileUtil.isTargetRule(line)) { + TargetRule[] trules = parseTargetRule(line); + for (int i = 0; i < trules.length; i++) { + trules[i].setLines(startLine, endLine); + addDirective(trules[i]); + } + rules = trules; + continue; + } - // 7- Macro Definiton ? - if (PosixMakefileUtil.isMacroDefinition(line)) { - Directive stmt = parseMacroDefinition(line); + // XXX ?? Should not be here. + BadDirective stmt = new BadDirective(this, line); stmt.setLines(startLine, endLine); addDirective(stmt); - continue; } - - // 8- Target Rule ? - if (PosixMakefileUtil.isTargetRule(line)) { - TargetRule[] trules = parseTargetRule(line); - for (int i = 0; i < trules.length; i++) { - trules[i].setLines(startLine, endLine); - addDirective(trules[i]); - } - rules = trules; - continue; - } - - // XXX ?? Should not be here. - BadDirective stmt = new BadDirective(this, line); - stmt.setLines(startLine, endLine); - addDirective(stmt); + setLines(1, endLine); + } finally { + reader.close(); } - setLines(1, endLine); } /* (non-Javadoc)