/******************************************************************************* * Copyright (c) 2002, 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * QNX Software Systems - Initial API and implementation * Nokia - Bug 163094 * Wind River Systems - Bug 316502 *******************************************************************************/ package org.eclipse.cdt.make.core; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import org.eclipse.cdt.make.core.makefile.IMakefile; import org.eclipse.cdt.make.core.makefile.IMakefileReaderProvider; import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager; import org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider; import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo; import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser; import org.eclipse.cdt.make.internal.core.BuildInfoFactory; import org.eclipse.cdt.make.internal.core.MakeTargetManager; import org.eclipse.cdt.make.internal.core.makefile.gnu.GNUMakefile; import org.eclipse.cdt.make.internal.core.makefile.posix.PosixMakefile; import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathManager; import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerConfigInfoFactory; import org.eclipse.cdt.make.internal.core.scannerconfig.gnu.GCCScannerConfigUtil; import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileInfo; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Preferences; import org.eclipse.core.runtime.Status; import org.osgi.framework.BundleContext; /** * The main plugin class to be used in the desktop. * * @noextend This class is not intended to be subclassed by clients. * @noinstantiate This class is not intended to be instantiated by clients. */ public class MakeCorePlugin extends Plugin { private static class FileStoreReaderProvider implements IMakefileReaderProvider { private final String fEncoding; private FileStoreReaderProvider(String encoding) { fEncoding = encoding != null ? encoding : ResourcesPlugin.getEncoding(); } public Reader getReader(URI fileURI) throws IOException { try { final IFileStore store = EFS.getStore(fileURI); final IFileInfo info = store.fetchInfo(); if (!info.exists() || info.isDirectory()) throw new IOException(); return new InputStreamReader(store.openInputStream(EFS.NONE, null), fEncoding); } catch (CoreException e) { MakeCorePlugin.log(e); throw new IOException(e.getMessage()); } } } public static final String PLUGIN_ID = "org.eclipse.cdt.make.core"; //$NON-NLS-1$ public static final String MAKE_PROJECT_ID = MakeCorePlugin.getUniqueIdentifier() + ".make"; //$NON-NLS-1$ public static final String OLD_BUILDER_ID = "org.eclipse.cdt.core.cbuilder"; //$NON-NLS-1$ public static final String EXTERNAL_SI_PROVIDER_SIMPLE_ID = "ExternalScannerInfoProvider"; //$NON-NLS-1$ public static final String SI_CONSOLE_PARSER_SIMPLE_ID = "ScannerInfoConsoleParser"; //$NON-NLS-1$ public static final String DEFAULT_EXTERNAL_SI_PROVIDER_ID = MakeCorePlugin.getUniqueIdentifier() + ".DefaultExternalScannerInfoProvider"; //$NON-NLS-1$ public static final String GCC_SPECS_CONSOLE_PARSER_ID = MakeCorePlugin.getUniqueIdentifier() + ".GCCSpecsConsoleParser"; //$NON-NLS-1$ public static final String GCC_SCANNER_INFO_CONSOLE_PARSER_ID = MakeCorePlugin.getUniqueIdentifier() + ".GCCScannerInfoConsoleParser"; //$NON-NLS-1$ public static final String MAKEFILE_STYLE = PLUGIN_ID + "editor_makefile_style"; //$NON-NLS-1$ public static final String MAKEFILE_DIRS = PLUGIN_ID + "editor_makefile_dirs"; //$NON-NLS-1$ public static final String CFG_DATA_PROVIDER_ID = PLUGIN_ID + ".configurationDataProvider"; //$NON-NLS-1$ private MakeTargetManager fTargetManager; private DiscoveredPathManager fDiscoveryPathManager; //The shared instance. private static MakeCorePlugin plugin; /** * The constructor. */ public MakeCorePlugin() { super(); plugin = this; } /** * Returns the shared instance. */ public static MakeCorePlugin getDefault() { return plugin; } public static void log(Throwable e) { if (e instanceof InvocationTargetException) e = ((InvocationTargetException) e).getTargetException(); IStatus status = null; if (e instanceof CoreException) status = ((CoreException) e).getStatus(); else status = new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.OK, e.getMessage(), e); log(status); } public static void log(IStatus status) { ResourcesPlugin.getPlugin().getLog().log(status); } public static String getUniqueIdentifier() { if (getDefault() == null) { // If the default instance is not yet initialized, // return a static identifier. This identifier must // match the plugin id defined in plugin.xml return PLUGIN_ID; } return getDefault().getBundle().getSymbolicName(); } public static IMakeBuilderInfo createBuildInfo(Preferences prefs, String builderID, boolean useDefaults) { return BuildInfoFactory.create(prefs, builderID, useDefaults); } public static IMakeBuilderInfo createBuildInfo(IProject project, String builderID) throws CoreException { return BuildInfoFactory.create(project, builderID); } public static IMakeBuilderInfo createBuildInfo(Map<String, String> args, String builderID) { return BuildInfoFactory.create(args, builderID); } public IMakeTargetManager getTargetManager() { if ( fTargetManager == null) { fTargetManager = new MakeTargetManager(); fTargetManager.startup(); } return fTargetManager; } public boolean isMakefileGNUStyle() { String style = getPluginPreferences().getString(MAKEFILE_STYLE); return (style != null && style.equalsIgnoreCase("GNU")); //$NON-NLS-1$ } public String[] getMakefileDirs() { String stringList = getPluginPreferences().getString(MAKEFILE_DIRS); StringTokenizer st = new StringTokenizer(stringList, File.pathSeparator + "\n\r");//$NON-NLS-1$ ArrayList<String> v = new ArrayList<String>(); while (st.hasMoreElements()) { v.add(st.nextToken()); } return v.toArray(new String[v.size()]); } /** * @deprecated as of CDT 5.0 */ @Deprecated static public IMakefile createMakefile(File file, boolean isGnuStyle, String[] makefileDirs) { IMakefile makefile; if (isGnuStyle) { GNUMakefile gnu = new GNUMakefile(); ArrayList<String> includeList = new ArrayList<String>(); includeList.add(new Path(file.getAbsolutePath()).removeLastSegments(1).toOSString()); includeList.addAll(Arrays.asList(gnu.getIncludeDirectories())); includeList.addAll(Arrays.asList(makefileDirs)); String[] includes = includeList.toArray(new String[includeList.size()]); gnu.setIncludeDirectories(includes); try { gnu.parse(file.getAbsolutePath(), new FileReader(file)); } catch (IOException e) { } makefile = gnu; } else { PosixMakefile posix = new PosixMakefile(); try { posix.parse(file.getAbsolutePath(), new FileReader(file)); } catch (IOException e) { } makefile = posix; } return makefile; } public static IMakefile createMakefile(IFileStore file, boolean isGnuStyle, String[] makefileDirs) throws CoreException { return createMakefile(file.toURI(), isGnuStyle, makefileDirs, (String) null); } static IMakefile createMakefile(IFileStore file, boolean isGnuStyle, String[] makefileDirs, String encoding) throws CoreException { return createMakefile(file.toURI(), isGnuStyle, makefileDirs, encoding); } static IMakefile createMakefile(URI fileURI, boolean isGnuStyle, String[] makefileDirs, String encoding) { return createMakefile(fileURI, isGnuStyle, makefileDirs, new FileStoreReaderProvider(encoding)); } /** * Create an IMakefile using the given IMakefileReaderProvider to fetch * contents by name. * * @param fileURI URI of main file * @param makefileReaderProvider may be <code>null</code> for EFS IFileStore reading */ public static IMakefile createMakefile(URI fileURI, boolean isGnuStyle, String[] makefileDirs, IMakefileReaderProvider makefileReaderProvider) { IMakefile makefile; if (isGnuStyle) { GNUMakefile gnu = new GNUMakefile(); ArrayList<String> includeList = new ArrayList<String>(); includeList.add(new Path(fileURI.getPath()).removeLastSegments(1).toString()); includeList.addAll(Arrays.asList(gnu.getIncludeDirectories())); includeList.addAll(Arrays.asList(makefileDirs)); String[] includes = includeList.toArray(new String[includeList.size()]); gnu.setIncludeDirectories(includes); try { gnu.parse(fileURI, makefileReaderProvider); } catch (IOException e) { } makefile = gnu; } else { PosixMakefile posix = new PosixMakefile(); try { posix.parse(fileURI, makefileReaderProvider); } catch (IOException e) { } makefile = posix; } return makefile; } /** * Create an IMakefile using EFS to fetch contents. * * @param fileURI URI of main file */ public static IMakefile createMakefile(URI fileURI, boolean isGnuStyle, String[] makefileDirs) { return createMakefile(fileURI, isGnuStyle, makefileDirs, (String) null); } public IMakefile createMakefile(IFile file) throws CoreException { return createMakefile(EFS.getStore(file.getLocationURI()), isMakefileGNUStyle(), getMakefileDirs(), file.getCharset()); } @Override public void stop(BundleContext context) throws Exception { try { if ( fTargetManager != null) { fTargetManager.shutdown(); fTargetManager = null; } if (fDiscoveryPathManager != null) { fDiscoveryPathManager.shutdown(); fDiscoveryPathManager = null; } savePluginPreferences(); } finally { super.stop(context); } } /* * Following methods create IScannerConfigBuilderInfo * Delegating requests to ScannerConfigInfoFactory */ public static IScannerConfigBuilderInfo createScannerConfigBuildInfo( Preferences prefs, String builderID, boolean useDefaults) { return ScannerConfigInfoFactory.create(prefs, builderID, useDefaults); } public static IScannerConfigBuilderInfo createScannerConfigBuildInfo( IProject project, String builderID) throws CoreException { return ScannerConfigInfoFactory.create(project, builderID); } public static IScannerConfigBuilderInfo createScannerConfigBuildInfo( Map<String, String> args, String builderID) { return ScannerConfigInfoFactory.create(args, builderID); } public static IPath getWorkingDirectory() { return MakeCorePlugin.getDefault().getStateLocation(); } public IDiscoveredPathManager getDiscoveryManager() { if ( fDiscoveryPathManager == null) { fDiscoveryPathManager = new DiscoveredPathManager(); fDiscoveryPathManager.startup(); } return fDiscoveryPathManager; } /** * @param id - id specifying external scanner info provider * @return provider - new instance of an external scanner info provider */ public IExternalScannerInfoProvider getExternalScannerInfoProvider(String id) { try { IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(PLUGIN_ID, EXTERNAL_SI_PROVIDER_SIMPLE_ID); if (extension != null) { IExtension[] extensions = extension.getExtensions(); for (int i = 0; i < extensions.length; i++) { String tool = extensions[i].getUniqueIdentifier(); if (tool != null && tool.equals(id)) { IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); for (int j = 0; j < configElements.length; j++) { IConfigurationElement[] runElement = configElements[j].getChildren("run"); //$NON-NLS-1$ if (runElement.length > 0) { IExternalScannerInfoProvider builder = (IExternalScannerInfoProvider) runElement[0].createExecutableExtension("class"); //$NON-NLS-1$ return builder; } } } } } } catch (CoreException e) { log(e); } return null; } /** * @return String[] - array of parserIds associated with the commandId or 'all' */ public String[] getScannerInfoConsoleParserIds(String commandId) { String[] empty = new String[0]; if (commandId == null || commandId.length() == 0) { commandId = "all"; //$NON-NLS-1$ } IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(PLUGIN_ID, SI_CONSOLE_PARSER_SIMPLE_ID); if (extension != null) { IExtension[] extensions = extension.getExtensions(); List<String> parserIds = new ArrayList<String>(extensions.length); for (int i = 0; i < extensions.length; i++) { String parserId = extensions[i].getUniqueIdentifier(); if (parserId != null) { IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); String id = configElements[0].getAttribute("commandId");//$NON-NLS-1$ if (id != null && (id.equals(commandId) || id.equals("all"))) { //$NON-NLS-1$ parserIds.add(parserId); } } } return parserIds.toArray(empty); } return empty; } /** * @return parser - parser object identified by the parserId */ public IScannerInfoConsoleParser getScannerInfoConsoleParser(String parserId) { try { IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(PLUGIN_ID, SI_CONSOLE_PARSER_SIMPLE_ID); if (extension != null) { IExtension[] extensions = extension.getExtensions(); for (int i = 0; i < extensions.length; i++) { String id = extensions[i].getUniqueIdentifier(); if (id != null && id.equals(parserId)) { IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); IScannerInfoConsoleParser parser = (IScannerInfoConsoleParser)configElements[0].createExecutableExtension("class");//$NON-NLS-1$ return parser; } } } } catch (CoreException e) { log(e); } return null; } /* (non-Javadoc) * @see org.eclipse.core.runtime.Plugin#startup() */ @Override public void start(BundleContext context) throws Exception { super.start(context); //Set debug tracing options configurePluginDebugOptions(); // Scanner config discovery setup GCCScannerConfigUtil.createSpecs(); } private static final String SCANNER_CONFIG = MakeCorePlugin.getUniqueIdentifier() + "/debug/scdiscovery"; //$NON-NLS-1$ /** * */ private void configurePluginDebugOptions() { if (isDebugging()) { String option = Platform.getDebugOption(SCANNER_CONFIG); if (option != null) { TraceUtil.SCANNER_CONFIG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ } } } }