/******************************************************************************* * Copyright (c) 2004, 2016 IBM Corporation 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM - Initial API and implementation * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.scanner; import java.util.Collections; import junit.framework.TestSuite; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.parser.ExtendedScannerInfo; import org.eclipse.cdt.core.parser.FileContent; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ScannerInfo; import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.util.TestSourceReader; import org.eclipse.cdt.internal.core.pdom.indexer.PDOMNullIndexer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.runtime.NullProgressMonitor; /** * Scanner2Tests ported to use the CPreprocessor */ public class InclusionTests extends PreprocessorTestsBase { public static TestSuite suite() { return suite(InclusionTests.class); } private ICProject fProject; public InclusionTests() { super(); } public InclusionTests(String name) { super(name); } @Override protected void tearDown() throws Exception { if (fProject != null) { CProjectHelper.delete(fProject); fProject= null; } super.tearDown(); } public final static int SIZEOF_TRUTHTABLE = 10; private IFile importFile(String fileName, String contents) throws Exception { if (fProject == null) { fProject= CProjectHelper.createCProject(getClass().getName(), null, PDOMNullIndexer.ID); } return TestSourceReader.createFile(fProject.getProject(), fileName, contents); } private IFolder importFolder(String name) throws Exception { if (fProject == null) { fProject= CProjectHelper.createCProject(getClass().getName(), null, PDOMNullIndexer.ID); } IFolder folder= fProject.getProject().getFolder(name); if (!folder.exists()) { folder.create(true, true, new NullProgressMonitor()); } return folder; } // #include "one.h" // #include "f1/two.h" // #include "f1/f2/three.h" public void testIncludeVariables_69529() throws Exception { String content= getAboveComment(); IFolder f0 = importFolder(".framework"); importFolder("f1.framework"); importFolder("f1"); importFolder("f1.framework/f2"); importFolder("f3"); IFile base = importFile("base.cpp", content); importFile(".framework/one.h", "1"); importFile("f1.framework/two.h", "2"); importFile("f1.framework/f2/three.h", "3"); String[] path = { f0.getLocation().removeLastSegments(1) + "/__framework__.framework/__header__" }; IScannerInfo scannerInfo = new ExtendedScannerInfo(Collections.EMPTY_MAP, path, new String[]{}, null); FileContent reader= FileContent.create(base); initializeScanner(reader, ParserLanguage.C, ParserMode.COMPLETE_PARSE, scannerInfo); // first file is not picked up (no framework) validateInteger("2"); validateInteger("3"); validateEOF(); } public void testIncludeNext() throws Exception { String baseFile = "int zero; \n#include \"foo.h\""; //$NON-NLS-1$ String i1Next = "int one; \n#include_next <bar/foo.h>"; //$NON-NLS-1$ String i2Next = "int two; \n#include_next \"bar/foo.h\""; //$NON-NLS-1$ String i3Next = "int three; \n"; //$NON-NLS-1$ IFolder one = importFolder("one"); //$NON-NLS-1$ IFolder oneTwo = importFolder("one/two"); //$NON-NLS-1$ IFolder oneTwoBar = importFolder("one/two/bar"); //$NON-NLS-1$ IFolder oneThree = importFolder("one/three"); //$NON-NLS-1$ IFolder oneThreeBar = importFolder("one/three/bar"); //$NON-NLS-1$ IFile base = importFile("base.cpp", baseFile); //$NON-NLS-1$ importFile("one/foo.h", i1Next); //$NON-NLS-1$ importFile("one/two/bar/foo.h", i2Next); //$NON-NLS-1$ importFile("one/three/bar/foo.h", i3Next); //$NON-NLS-1$ String[] path = new String[3]; path[0] = one.getLocation().toOSString(); path[1] = oneTwo.getLocation().toOSString(); path[2] = oneThree.getLocation().toOSString(); IScannerInfo scannerInfo = new ExtendedScannerInfo(Collections.EMPTY_MAP, path, new String[]{}, null); FileContent reader= FileContent.create(base); initializeScanner(reader, ParserLanguage.C, ParserMode.COMPLETE_PARSE, scannerInfo); validateToken(IToken.t_int); validateIdentifier("zero"); validateToken(IToken.tSEMI); validateToken(IToken.t_int); validateIdentifier("one"); validateToken(IToken.tSEMI); validateToken(IToken.t_int); validateIdentifier("two"); validateToken(IToken.tSEMI); validateToken(IToken.t_int); validateIdentifier("three"); validateToken(IToken.tSEMI); validateEOF(); } public void testIncludeNext_286081() throws Exception { String baseFile = "0 \n#include \"foo.h\""; //$NON-NLS-1$ String foo1 = "1 \n#include \"intermed.h\""; //$NON-NLS-1$ String intermed = "2 \n#include_next <foo.h>"; //$NON-NLS-1$ String foo2 = "3 \n"; //$NON-NLS-1$ IFolder one = importFolder("one"); //$NON-NLS-1$ IFolder two = importFolder("two"); //$NON-NLS-1$ IFile base = importFile("base.cpp", baseFile); //$NON-NLS-1$ importFile("one/foo.h", foo1); //$NON-NLS-1$ importFile("one/intermed.h", intermed); //$NON-NLS-1$ importFile("two/foo.h", foo2); //$NON-NLS-1$ String[] path = new String[2]; path[0] = one.getLocation().toOSString(); path[1] = two.getLocation().toOSString(); IScannerInfo scannerInfo = new ExtendedScannerInfo(Collections.EMPTY_MAP, path, new String[]{}, null); FileContent reader= FileContent.create(base); initializeScanner(reader, ParserLanguage.C, ParserMode.COMPLETE_PARSE, scannerInfo); validateInteger("0"); validateInteger("1"); validateInteger("2"); validateInteger("3"); validateEOF(); } public void testIncludePathOrdering() throws Exception { // create directory structure: // project/base.cpp // project/foo.h // project/two/foo.h // project/three/foo.h // this test sets the include path to be two;three and include foo.h (we should see the contents of two/foo.h // then we change to three;two and we should see the contents of three/foo.h. String baseFile = "#include <foo.h>"; //$NON-NLS-1$ String i1Next = "int one;\n"; //$NON-NLS-1$ String i2Next = "int two;\n"; //$NON-NLS-1$ String i3Next = "int three;\n"; //$NON-NLS-1$ IFile base = importFile( "base.cpp", baseFile ); //$NON-NLS-1$ importFile( "foo.h", i1Next ); //$NON-NLS-1$ IFolder twof = importFolder("two"); //$NON-NLS-1$ IFolder threef = importFolder("three"); //$NON-NLS-1$ importFile( "two/foo.h", i2Next ); //$NON-NLS-1$ importFile( "three/foo.h", i3Next ); //$NON-NLS-1$ String [] path = new String[2]; path[0] = twof.getLocation().toOSString(); path[1] = threef.getLocation().toOSString(); IScannerInfo scannerInfo = new ExtendedScannerInfo( Collections.EMPTY_MAP, path, new String[]{}, null ); FileContent reader= FileContent.create(base); initializeScanner(reader, ParserLanguage.C, ParserMode.COMPLETE_PARSE, scannerInfo); validateToken(IToken.t_int); validateIdentifier("two"); validateToken(IToken.tSEMI); validateEOF(); path[0] = threef.getLocation().toOSString(); path[1] = twof.getLocation().toOSString(); scannerInfo = new ExtendedScannerInfo( Collections.EMPTY_MAP, path, new String[]{}, null ); initializeScanner(reader, ParserLanguage.C, ParserMode.COMPLETE_PARSE, scannerInfo); validateToken(IToken.t_int); validateIdentifier("three"); validateToken(IToken.tSEMI); validateEOF(); } public void testBug91086() throws Exception { IFile inclusion = importFile( "file.h", "#define FOUND 666\n" ); //$NON-NLS-1$ //$NON-NLS-2$ StringBuilder buffer = new StringBuilder( "#include \"" ); //$NON-NLS-1$ buffer.append( inclusion.getLocation().toOSString() ); buffer.append( "\"\n"); //$NON-NLS-1$ buffer.append( "int var = FOUND;\n"); //$NON-NLS-1$ IFile base = importFile( "base.cpp", buffer.toString() ); //$NON-NLS-1$ FileContent reader= FileContent.create(base); ParserLanguage lang[]= {ParserLanguage.C, ParserLanguage.CPP}; for (ParserLanguage element : lang) { initializeScanner(reader, element, ParserMode.COMPLETE_PARSE, new ScannerInfo()); validateToken(IToken.t_int); validateIdentifier("var"); validateToken(IToken.tASSIGN); validateInteger("666"); validateToken(IToken.tSEMI); validateEOF(); } } public void testBug156990() throws Exception { IFile inclusion = importFile( "file.h", "ok" ); StringBuilder buffer = new StringBuilder( "#include \"file.h\"" ); IFile base = importFile( "base.cpp", buffer.toString() ); //$NON-NLS-1$ FileContent reader= FileContent.create(base); initializeScanner(reader, ParserLanguage.CPP, ParserMode.COMPLETE_PARSE, new ScannerInfo()); validateIdentifier("ok"); validateEOF(); } // #include <inc/test.h> public void testRelativeIncludes_243170() throws Exception { String content= getAboveComment(); IFolder f0 = importFolder("f1"); importFolder("f1/f2"); importFolder("f1/f2/inc"); importFile("f1/f2/inc/test.h", "1"); IFile base = importFile("f1/base.cpp", getAboveComment()); String[] path = {"f2"}; // relative include IScannerInfo scannerInfo = new ExtendedScannerInfo(Collections.EMPTY_MAP, path, new String[]{}, null); FileContent reader= FileContent.create(base); initializeScanner(reader, ParserLanguage.C, ParserMode.COMPLETE_PARSE, scannerInfo); validateInteger("1"); validateEOF(); } // #include "test.h" public void testSuppressingUseOfCurrentFileDirectory() throws Exception { String content= getAboveComment(); importFolder("f1"); IFolder inc = importFolder("f1/inc"); importFile("f1/test.h", "1"); importFile("f1/inc/test.h", "2"); IFile base = importFile("f1/base.cpp", getAboveComment()); String[] path = {inc.getLocation().toFile().toString()}; IScannerInfo scannerInfo = new ExtendedScannerInfo(Collections.EMPTY_MAP, path, new String[]{}, null); FileContent reader= FileContent.create(base); initializeScanner(reader, ParserLanguage.C, ParserMode.COMPLETE_PARSE, scannerInfo); validateInteger("1"); validateEOF(); path = new String[] {inc.getLocation().toFile().toString(), "-"}; // Suppress use of current file directory scannerInfo = new ExtendedScannerInfo(Collections.EMPTY_MAP, path, new String[]{}, null); reader= FileContent.create(base); initializeScanner(reader, ParserLanguage.C, ParserMode.COMPLETE_PARSE, scannerInfo); validateInteger("2"); validateEOF(); } }