diff --git a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
index 29cf0b35e4a..04a7b1ced98 100644
--- a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
+++ b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
@@ -9,10 +9,6 @@ Bundle-Localization: plugin
Export-Package: org.eclipse.cdt.core,
org.eclipse.cdt.core.browser,
org.eclipse.cdt.core.cdtvariables,
- org.eclipse.cdt.utils.cdtvariables,
- org.eclipse.cdt.utils.envvar,
- org.eclipse.cdt.internal.core.cdtvariables,
- org.eclipse.cdt.internal.core.envvar,
org.eclipse.cdt.core.dom,
org.eclipse.cdt.core.dom.ast,
org.eclipse.cdt.core.dom.ast.c,
@@ -23,6 +19,7 @@ Export-Package: org.eclipse.cdt.core,
org.eclipse.cdt.core.envvar,
org.eclipse.cdt.core.formatter,
org.eclipse.cdt.core.index,
+ org.eclipse.cdt.core.index.export,
org.eclipse.cdt.core.model,
org.eclipse.cdt.core.model.util,
org.eclipse.cdt.core.parser,
@@ -37,12 +34,14 @@ Export-Package: org.eclipse.cdt.core,
org.eclipse.cdt.core.settings.model.util,
org.eclipse.cdt.internal.core;x-friends:="org.eclipse.cdt.ui",
org.eclipse.cdt.internal.core.browser.util;x-friends:="org.eclipse.cdt.ui",
+ org.eclipse.cdt.internal.core.cdtvariables,
org.eclipse.cdt.internal.core.dom;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.refactoring",
org.eclipse.cdt.internal.core.dom.parser;x-friends:="org.eclipse.cdt.refactoring",
org.eclipse.cdt.internal.core.dom.parser.c;x-friends:="org.eclipse.cdt.refactoring",
org.eclipse.cdt.internal.core.dom.parser.cpp;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.refactoring",
+ org.eclipse.cdt.internal.core.envvar,
org.eclipse.cdt.internal.core.index;x-internal:=true,
- org.eclipse.cdt.internal.core.language;x-friends:="org.eclipse.cdt.ui",
+ org.eclipse.cdt.internal.core.language,
org.eclipse.cdt.internal.core.model;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.refactoring",
org.eclipse.cdt.internal.core.model.ext;x-friends:="org.eclipse.cdt.ui",
org.eclipse.cdt.internal.core.parser;x-internal:=true,
@@ -71,6 +70,7 @@ Export-Package: org.eclipse.cdt.core,
org.eclipse.cdt.internal.formatter.align;x-internal:=true,
org.eclipse.cdt.internal.formatter.scanner,
org.eclipse.cdt.utils,
+ org.eclipse.cdt.utils.cdtvariables,
org.eclipse.cdt.utils.coff,
org.eclipse.cdt.utils.coff.parser,
org.eclipse.cdt.utils.debug,
@@ -79,6 +79,7 @@ Export-Package: org.eclipse.cdt.core,
org.eclipse.cdt.utils.debug.tools,
org.eclipse.cdt.utils.elf,
org.eclipse.cdt.utils.elf.parser,
+ org.eclipse.cdt.utils.envvar,
org.eclipse.cdt.utils.macho,
org.eclipse.cdt.utils.macho.parser,
org.eclipse.cdt.utils.pty,
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/AbstractExportProjectProvider.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/AbstractExportProjectProvider.java
new file mode 100644
index 00000000000..a763fe991ce
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/AbstractExportProjectProvider.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Symbian 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:
+ * Andrew Ferguson (Symbian) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.index.export;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.internal.core.pdom.export.CLIUtil;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+
+
+/**
+ * An IExportProjectProvider suitable for subclassing. It provides convenience methods
+ * for obtaining options and their parameters from the command-line.
+ *
+ * @see ExternalExportProjectProvider for usage scenarios
+ */
+public abstract class AbstractExportProjectProvider implements IExportProjectProvider {
+ public static final IProgressMonitor NPM= new NullProgressMonitor();
+
+ private Map arguments;
+ private String[] appArguments;
+
+ public AbstractExportProjectProvider() {}
+
+ /**
+ *
+ * @return
+ */
+ protected String[] getApplicationArguments() {
+ return (String[]) appArguments.clone();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.cdt.core.index.export.IExportProjectProvider#setApplicationArguments(java.lang.String[])
+ */
+ public void setApplicationArguments(String[] arguments) {
+ this.appArguments= (String[]) arguments.clone();
+ this.arguments= Collections.unmodifiableMap(CLIUtil.parseToMap(arguments));
+ }
+
+ /**
+ * Returns a mapping from string option to parameter string list
+ *
+ * For example, if -option p1 p2 p3 appears on the command line, then
+ * the mapping option=>[p1,p2,p3] will be present in the map
+ * @return a mapping from string option to parameter string list
+ */
+ protected Map getParsedArgs() {
+ return arguments;
+ }
+
+ /**
+ * Gets an option's single parameter, or throws a CoreException should the option
+ * not be present, or if it does not have exactly one parameter
+ * @param option
+ * @return an option's single parameter
+ * @throws CoreException should the specified option
+ * not be present, or if it does not have exactly one parameter
+ */
+ public String getSingleString(String option) throws CoreException {
+ return (String) CLIUtil.getArg(arguments, option, 1).get(0);
+ }
+
+ /**
+ *
+ * @param option
+ * @return
+ * @throws CoreException
+ */
+ public List getParameters(String option) {
+ return (List) arguments.get(option);
+ }
+
+ /**
+ * Returns whether the specified option appears in the application arguments
+ * @param option the option to check for
+ * @return whether the specified option appears in the application arguments
+ */
+ public boolean isPresent(String option) {
+ return arguments.containsKey(option);
+ }
+
+ /**
+ * Returns a list of strings representing the parameters to the specified option. If the number
+ * of parameters does not match the expected number, an command-line error message is shown to the
+ * user.
+ * @param option
+ * @param expected the number of parameters expected
+ * @return
+ * @throws CoreException
+ */
+ public List getParameters(String option, int expected) throws CoreException {
+ return CLIUtil.getArg(arguments, option, expected);
+ }
+
+ /**
+ * Produces an error in the application
+ * @param message an error message suitable for the user
+ * @return does not return
+ * @throws CoreException Throws a CoreException with an ERROR status
+ */
+ public IStatus fail(String message) throws CoreException {
+ throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, message));
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/ExternalExportProjectProvider.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/ExternalExportProjectProvider.java
new file mode 100644
index 00000000000..26c1cac4789
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/ExternalExportProjectProvider.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Symbian 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:
+ * Andrew Ferguson (Symbian) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.index.export;
+
+import java.io.File;
+import java.text.DateFormat;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.CCProjectNature;
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.CProjectNature;
+import org.eclipse.cdt.core.dom.IPDOMManager;
+import org.eclipse.cdt.core.index.IIndexLocationConverter;
+import org.eclipse.cdt.core.index.ResourceContainerRelativeLocationConverter;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.IPathEntry;
+import org.eclipse.cdt.internal.core.index.IIndexFragment;
+import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * An IExportProjectProvider suitable for indexing an external folder. The arguments understood by this provider
+ * are
+ *
+ * - -source what will become the root of the indexed content
+ *
- -include any preinclude files to configure the parser with
+ *
- -id the id to write to the produce fragment
+ *
+ */
+public class ExternalExportProjectProvider extends AbstractExportProjectProvider implements IExportProjectProvider {
+ private static final String ORG_ECLIPSE_CDT_CORE_INDEX_EXPORT_DATESTAMP = "org.eclipse.cdt.core.index.export.datestamp"; //$NON-NLS-1$
+ private static final String CONTENT = "content"; //$NON-NLS-1$
+ protected static final String ARG_SOURCE = "-source"; //$NON-NLS-1$
+ protected static final String ARG_INCLUDE = "-include"; //$NON-NLS-1$
+ protected static final String ARG_FRAGMENT_ID = "-id"; //$NON-NLS-1$
+
+ private IFolder content;
+ private String fragmentId;
+
+ public ExternalExportProjectProvider() {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.cdt.core.index.export.IProjectForExportManager#createProject(java.util.Map)
+ */
+ public ICProject createProject() throws CoreException {
+ // -source
+ File source= new File(getSingleString(ARG_SOURCE));
+ if(!source.exists()) {
+ fail(MessageFormat.format(Messages.ExternalContentPEM_LocationToIndexNonExistent, new Object[] {source}));
+ }
+
+ // -include
+ List includeFiles= new ArrayList();
+ if(isPresent(ARG_INCLUDE)) {
+ includeFiles.addAll(getParameters(ARG_INCLUDE));
+ }
+
+ // -id
+ fragmentId= getSingleString(ARG_FRAGMENT_ID);
+
+ return createCProject("__"+System.currentTimeMillis(), source, IPDOMManager.ID_FAST_INDEXER, includeFiles); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the project folder the external content is stored in
+ * @return the project folder the external content is stored in
+ */
+ protected IFolder getContentFolder() {
+ return content;
+ }
+
+ /**
+ * Convenience method for creating a cproject
+ * @param projectName the name for the new project
+ * @param location the absolute path of some external content
+ * @param indexerID the indexer to use
+ * @param includeFiles a list of include paths to add to the project scanner
+ * @return a new project
+ * @throws CoreException
+ */
+ private ICProject createCProject(
+ final String projectName,
+ final File location,
+ final String indexerID,
+ final List includeFiles
+ ) throws CoreException {
+ final IWorkspace ws = ResourcesPlugin.getWorkspace();
+ final ICProject newProject[] = new ICProject[1];
+
+ ws.run(new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ IWorkspaceRoot root = ws.getRoot();
+
+ IProject project = root.getProject(projectName);
+ if (!project.exists()) {
+ project.create(NPM);
+ } else {
+ project.refreshLocal(IResource.DEPTH_INFINITE, NPM);
+ }
+ if (!project.isOpen()) {
+ project.open(NPM);
+ }
+ if (!project.hasNature(CProjectNature.C_NATURE_ID)) {
+ addNatureToProject(project, CProjectNature.C_NATURE_ID, NPM);
+ }
+ if (!project.hasNature(CCProjectNature.CC_NATURE_ID)) {
+ addNatureToProject(project, CCProjectNature.CC_NATURE_ID, NPM);
+ }
+
+ ICProject cproject = CCorePlugin.getDefault().getCoreModel().create(project);
+
+ // External content appears under a linked folder
+ content= cproject.getProject().getFolder(CONTENT);
+ content.createLink(new Path(location.getAbsolutePath()), IResource.NONE, null);
+
+ // Setup path entries
+ List entries= new ArrayList(Arrays.asList(CoreModel.getRawPathEntries(cproject)));
+ for(Iterator j= includeFiles.iterator(); j.hasNext(); ) {
+ entries.add(
+ CoreModel.newIncludeFileEntry(
+ cproject.getProject().getFullPath(),
+ new Path((String) j.next())
+ ));
+ }
+ entries.add(CoreModel.newSourceEntry(content.getProjectRelativePath()));
+ cproject.setRawPathEntries(
+ (IPathEntry[]) entries.toArray(new IPathEntry[includeFiles.size()]),
+ new NullProgressMonitor()
+ );
+
+ newProject[0]= cproject;
+ }
+ }, null);
+
+ if (indexerID != null) {
+ IndexerPreferences.set(newProject[0].getProject(), IndexerPreferences.KEY_INDEX_ALL_FILES, Boolean.TRUE.toString());
+ IndexerPreferences.set(newProject[0].getProject(), IndexerPreferences.KEY_INDEXER_ID, indexerID);
+ }
+
+ return newProject[0];
+ }
+
+ /*
+ * This should be a platform/CDT API
+ */
+ private static void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException {
+ IProjectDescription description = proj.getDescription();
+ String[] prevNatures = description.getNatureIds();
+ String[] newNatures = new String[prevNatures.length + 1];
+ System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
+ newNatures[prevNatures.length] = natureId;
+ description.setNatureIds(newNatures);
+ proj.setDescription(description, monitor);
+ }
+
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.cdt.core.index.export.IExportProjectProvider#getLocationConverter(org.eclipse.cdt.core.model.ICProject)
+ */
+ public IIndexLocationConverter getLocationConverter(final ICProject cproject) {
+ return new ResourceContainerRelativeLocationConverter(content);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.cdt.core.index.export.IExportProjectProvider#getExportProperties()
+ */
+ public Map getExportProperties() {
+ Map properties= new HashMap();
+ Date now= Calendar.getInstance().getTime();
+ properties.put(ORG_ECLIPSE_CDT_CORE_INDEX_EXPORT_DATESTAMP,
+ DateFormat.getDateInstance().format(now)
+ +" "+DateFormat.getTimeInstance().format(now)); //$NON-NLS-1$
+ properties.put(IIndexFragment.PROPERTY_FRAGMENT_ID, fragmentId);
+ return properties;
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/IExportProjectProvider.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/IExportProjectProvider.java
new file mode 100644
index 00000000000..dcd8742817f
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/IExportProjectProvider.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Symbian 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:
+ * Andrew Ferguson (Symbian) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.index.export;
+
+import java.util.Map;
+
+import org.eclipse.cdt.core.index.IIndexLocationConverter;
+import org.eclipse.cdt.core.index.ResourceContainerRelativeLocationConverter;
+import org.eclipse.cdt.core.index.URIRelativeLocationConverter;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * An IExportProjectProvider provides a configured ICProject suitable set up for
+ * indexing. It is used via the org.eclipse.cdt.core.GeneratePDOM application.
+ *
+ * In general, ISV's may have very specific configuration requirements, and it is
+ * expected that they subclass {@link AbstractExportProjectProvider} or {@link ExternalExportProjectProvider}
+ * in order to do so.
+ *
+ * If your requirements are very simple, then {@link ExternalExportProjectProvider} may
+ * be sufficient for direct usage.
+ */
+public interface IExportProjectProvider {
+ /**
+ * This method will be called by the export framework before any other method
+ * in this class. It passes the application argument received by the export
+ * application
+ * @param arguments the application arguments
+ * @see Platform#getApplicationArgs()
+ */
+ public void setApplicationArguments(String[] arguments);
+
+ /**
+ * Creates, configures and returns a project for the indexer to index
+ * May not return null.
+ * @return
+ */
+ public ICProject createProject() throws CoreException;
+
+ /**
+ * The location converter to use on export. This converter will be called to convert
+ * IIndexFileLocation's to an external form. The external form is implementation dependent.
+ * @param cproject
+ * @return
+ * @see URIRelativeLocationConverter
+ * @see ResourceContainerRelativeLocationConverter
+ */
+ public IIndexLocationConverter getLocationConverter(ICProject cproject);
+
+ /**
+ * Get a String to String map of properties to store with the index
+ * content. The export framework may ignore this if the index format does
+ * not support this. The PDOM format does support properties.
+ * @return a Map of String typed key value pairs representing ISV specific properties. This
+ * may return null.
+ */
+ public Map/**/ getExportProperties();
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/Messages.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/Messages.java
new file mode 100644
index 00000000000..abbf8383ee5
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/Messages.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Symbian 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:
+ * Andrew Ferguson (Symbian) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.index.export;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.cdt.core.index.export.messages"; //$NON-NLS-1$
+ public static String CLIUtil_OptionParametersMismatch;
+ public static String ExternalContentPEM_LocationToIndexNonExistent;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/messages.properties b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/messages.properties
new file mode 100644
index 00000000000..4019cc4a344
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/export/messages.properties
@@ -0,0 +1,2 @@
+ExternalContentPEM_LocationToIndexNonExistent=Location to index {0} does not exist
+CLIUtil_OptionParametersMismatch=Option {0} takes exactly {1} parameters
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
index 853eadf9c58..6a969a85557 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
@@ -51,6 +51,12 @@ public interface IIndexFragment {
*/
final int FIND_ALL_OCCURENCES = IIndex.FIND_ALL_OCCURENCES;
+ /**
+ * Property key constant for the fragment ID. The fragment ID should uniquely identify the fragments usage within
+ * a logical index.
+ */
+ public static final String PROPERTY_FRAGMENT_ID= "org.eclipse.cdt.internal.core.index.fragment.id"; //$NON-NLS-1$
+
/**
* Returns the file for the given location. May return null
, if no such file exists.
* This method may only return files that are actually managed by this fragement.
@@ -159,10 +165,12 @@ public interface IIndexFragment {
IIndexLinkage[] getLinkages();
/**
- * Read the named property in this fragment
+ * Read the named property in this fragment. All fragments are expected to return a non-null value for
+ * PROPERTY_FRAGMENT_ID
* @param key a case-sensitive identifier for a property, or null
* @return the value associated with the key, or null if either no such property is set, or the specified key was null
* @throws CoreException
+ * @see IIndexFragment#PROPERTY_FRAGMENT_ID
*/
- public String getProperty(String propertyName) throws CoreException;
+ public String getProperty(String propertyName) throws CoreException;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/Messages.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/Messages.java
index 68975c42b18..1b6d76c8c62 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/Messages.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/Messages.java
@@ -15,6 +15,7 @@ import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.core.pdom.messages"; //$NON-NLS-1$
+ public static String PDOMManager_ExistingFileCollides;
public static String PDOMManager_indexMonitorDetail;
public static String PDOMManager_JoinIndexerTask;
public static String PDOMManager_notifyJob_label;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java
index a468dd6b545..91813fc4a61 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java
@@ -13,10 +13,15 @@
package org.eclipse.cdt.internal.core.pdom;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -27,18 +32,21 @@ import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexChangeListener;
+import org.eclipse.cdt.core.index.IIndexLocationConverter;
import org.eclipse.cdt.core.index.IIndexerStateListener;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IElementChangedListener;
import org.eclipse.cdt.internal.core.CCoreInternals;
+import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IWritableIndex;
import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
import org.eclipse.cdt.internal.core.index.IndexChangeEvent;
import org.eclipse.cdt.internal.core.index.IndexFactory;
import org.eclipse.cdt.internal.core.index.IndexerStateEvent;
import org.eclipse.cdt.internal.core.pdom.PDOM.IListener;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMProjectIndexLocationConverter;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMImportTask;
@@ -197,6 +205,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
}
pdom = new WritablePDOM(dbFile, new PDOMProjectIndexLocationConverter(rproject));
+ pdom.setProperty(IIndexFragment.PROPERTY_FRAGMENT_ID, "org.eclipse.cdt.internal.pdom["+rproject.getName()+"]"); //$NON-NLS-1$ //$NON-NLS-2$
pdom.addListener(this);
}
@@ -704,5 +713,62 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
public IIndex getIndex(ICProject[] projects, int options) throws CoreException {
return fIndexFactory.getIndex(projects, options);
}
+
+ /**
+ * Exports the project PDOM to the specified location, rewriting locations with
+ * the specified location converter.
+ *
+ * Note. this method does not acquire or release any locks. It is expected
+ * that this will be done by the caller.
+ * @param targetLocation a location that does not currently exist
+ * @param newConverter
+ * @throws CoreException
+ * @throws IllegalArgumentException if a file exists at targetLocation
+ */
+ public void exportProjectPDOM(ICProject cproject, File targetLocation, final IIndexLocationConverter newConverter) throws CoreException {
+ if(targetLocation.exists()) {
+ boolean deleted= targetLocation.delete();
+ if(!deleted) {
+ throw new IllegalArgumentException(
+ MessageFormat.format(Messages.PDOMManager_ExistingFileCollides,
+ new Object[] {targetLocation})
+ );
+ }
+ }
+ try {
+ // copy it
+ PDOM pdom= (PDOM) getPDOM(cproject);
+ pdom.acquireWriteLock();
+ try {
+ File db = pdom.getDB().getLocation();
+ FileChannel from = new FileInputStream(db).getChannel();
+ FileChannel to = new FileOutputStream(targetLocation).getChannel();
+ from.transferTo(0, from.size(), to);
+ to.close();
+ from.close();
+ } finally {
+ pdom.releaseWriteLock();
+ }
+ // overwrite internal location representations
+ final WritablePDOM newPDOM = new WritablePDOM(targetLocation, pdom.getLocationConverter());
+
+ newPDOM.acquireWriteLock();
+ try {
+ List notConverted= newPDOM.rewriteLocations(newConverter);
+
+ // remove content where converter returns null
+ for(Iterator i = notConverted.iterator(); i.hasNext(); ) {
+ PDOMFile file = (PDOMFile) i.next();
+ file.clear();
+ }
+ } finally {
+ newPDOM.releaseWriteLock();
+ }
+ } catch(IOException ioe) {
+ throw new CoreException(CCorePlugin.createStatus(ioe.getMessage()));
+ } catch(InterruptedException ie) {
+ throw new CoreException(CCorePlugin.createStatus(ie.getMessage()));
+ }
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
index 90882d23f3d..28e4e05bc33 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
@@ -14,6 +14,9 @@ package org.eclipse.cdt.internal.core.pdom;
import java.io.File;
import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTName;
@@ -24,6 +27,7 @@ import org.eclipse.cdt.core.index.IIndexLocationConverter;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
import org.eclipse.cdt.internal.core.pdom.db.DBProperties;
+import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
@@ -74,4 +78,45 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
public void setProperty(String propertyName, String value) throws CoreException {
new DBProperties(db, PROPERTIES).setProperty(propertyName, value);
}
+
+
+ /**
+ * Use the specified location converter to update each internal representation of a file location.
+ * The file index is rebuilt with the new representations. Individual PDOMFile records are unmoved so
+ * as to maintain referential integrity with other PDOM records.
+ *
+ * A write-lock must be obtained before calling this method
+ *
+ * @param newConverter the converter to use to update internal file representations
+ * @return a list of PDOMFiles for which the location converter returned null when queried for the new internal representation
+ * @throws CoreException
+ */
+ public List/**/ rewriteLocations(final IIndexLocationConverter newConverter) throws CoreException {
+ final List pdomfiles = new ArrayList();
+ getFileIndex().accept(new IBTreeVisitor(){
+ public int compare(int record) throws CoreException {
+ return 0;
+ }
+ public boolean visit(int record) throws CoreException {
+ PDOMFile file = new PDOMFile(WritablePDOM.this, record);
+ pdomfiles.add(file);
+ return true;
+ }
+ });
+
+ clearFileIndex();
+ final List notConverted = new ArrayList();
+ for(Iterator i= pdomfiles.iterator(); i.hasNext(); ) {
+ PDOMFile file= (PDOMFile) i.next();
+ String internalFormat = newConverter.toInternalFormat(file.getLocation());
+ if(internalFormat!=null) {
+ file.setInternalLocation(internalFormat);
+ } else {
+ notConverted.add(file);
+ }
+ getFileIndex().insert(file.getRecord());
+ }
+
+ return notConverted;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/CLIUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/CLIUtil.java
new file mode 100644
index 00000000000..8a9a6a4d47f
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/CLIUtil.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Symbian 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:
+ * Andrew Ferguson (Symbian) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.pdom.export;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.index.export.Messages;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * Helper methods for command-line options
+ *
+ * Non-API Should a more suitable way for manipulating command-line arguments become usable
+ * in the future we will switch to that.
+ */
+public class CLIUtil {
+ public static final String UNQUALIFIED_PARAMETERS= "UNQUALIFIED_PARAMETERS"; //$NON-NLS-1$
+
+ /**
+ * Returns the list of options associated with the specified option
+ * @param arguments the arguments map
+ * @param opt the option name to check
+ * @param number the number of parameters
+ * @return
+ * @throws CoreException if the number of parameters is not the specified expected number
+ */
+ public static List getArg(Map arguments, String opt, int number) throws CoreException {
+ List list = (List) arguments.get(opt);
+ if(list==null || list.size()!=number) {
+ String msg= MessageFormat.format(Messages.CLIUtil_OptionParametersMismatch, new Object[] {opt, ""+number}); //$NON-NLS-1$
+ throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, msg));
+ }
+ return list;
+ }
+
+ /**
+ * Returns a map of String option to List of String parameters.
+ *
+ * @param args
+ * @return
+ */
+ public static Map/*>*/ parseToMap(String[] args) {
+ Map result = new HashMap();
+ String current = null;
+ for(int i=0; i
+ * Creates a project for export
+ * Exports the pdom
+ * Writes new properties to the pdom
+ *
+ */
+public class GeneratePDOM implements ISafeRunnable {
+ protected IExportProjectProvider pm;
+ protected String[] applicationArguments;
+ protected File targetLocation;
+
+ public GeneratePDOM(IExportProjectProvider pm, String[] applicationArguments, File targetLocation) {
+ this.pm = pm;
+ this.applicationArguments= applicationArguments;
+ this.targetLocation = targetLocation;
+ }
+
+ public final void run() throws CoreException {
+ pm.setApplicationArguments(applicationArguments);
+ final ICProject cproject = pm.createProject();
+ if(cproject==null) {
+ throw new CoreException(CCorePlugin.createStatus(Messages.GeneratePDOM_ProjectProviderReturnedNullCProject));
+ }
+ CCorePlugin.getIndexManager().joinIndexer(Integer.MAX_VALUE, new NullProgressMonitor());
+ IIndexLocationConverter converter= pm.getLocationConverter(cproject);
+ try {
+ PDOM pdom = (PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject);
+ pdom.acquireWriteLock(0);
+ try {
+ CCoreInternals.getPDOMManager().exportProjectPDOM(cproject, targetLocation, converter);
+ WritablePDOM exportedPDOM= new WritablePDOM(targetLocation, converter);
+ Map exportProperties= pm.getExportProperties();
+ if(exportProperties!=null) {
+ for(Iterator i = exportProperties.entrySet().iterator(); i.hasNext(); ) {
+ Map.Entry entry = (Map.Entry) i.next();
+ exportedPDOM.setProperty((String) entry.getKey(), (String) entry.getValue());
+ }
+ }
+ } finally {
+ pdom.releaseWriteLock(0);
+ }
+ } catch(InterruptedException ie) {
+ String msg= MessageFormat.format(Messages.GeneratePDOM_GenericGenerationFailed, new Object[] {ie.getMessage()});
+ throw new CoreException(CCorePlugin.createStatus(msg, ie));
+ }
+ }
+
+ public void handleException(Throwable exception) {
+ // subclass for custom behaviour
+ CCorePlugin.log(exception);
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOMApplication.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOMApplication.java
new file mode 100644
index 00000000000..c284bad4945
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOMApplication.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Symbian 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:
+ * Andrew Ferguson (Symbian) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.pdom.export;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
+import org.eclipse.cdt.core.index.export.ExternalExportProjectProvider;
+import org.eclipse.cdt.core.index.export.IExportProjectProvider;
+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.IExtensionRegistry;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.ProgressProvider;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+
+/**
+ * An eclipse application for generating PDOM's without starting the Workbench
+ */
+public class GeneratePDOMApplication implements IApplication {
+ private static final String EXPORT_PROJECT_PROVIDER = "ExportProjectProvider"; //$NON-NLS-1$
+ private static final String DEFAULT_PROJECT_PROVIDER = ExternalExportProjectProvider.class.getName();
+ private static final String OPT_PROJECTPROVIDER= "-pprovider"; //$NON-NLS-1$
+ private static final String OPT_TARGET= "-target"; //$NON-NLS-1$
+ private static final String OPT_QUIET= "-quiet"; //$NON-NLS-1$
+
+ private static Map/**/ projectInitializers;
+
+ /**
+ * Starts this application
+ */
+ public Object start(IApplicationContext context) throws CoreException {
+ Map arguments= CLIUtil.parseToMap(Platform.getApplicationArgs());
+ output(Messages.GeneratePDOMApplication_Initializing);
+
+ setupCLIProgressProvider();
+
+ String pproviderFQN;
+ if(!arguments.containsKey(OPT_PROJECTPROVIDER)) {
+ output(MessageFormat.format(Messages.GeneratePDOMApplication_UsingDefaultProjectProvider, new Object[] {DEFAULT_PROJECT_PROVIDER}));
+ pproviderFQN= DEFAULT_PROJECT_PROVIDER;
+ } else {
+ pproviderFQN= (String) CLIUtil.getArg(arguments, OPT_PROJECTPROVIDER, 1).get(0);
+ }
+ String target= (String) CLIUtil.getArg(arguments, OPT_TARGET, 1).get(0);
+ boolean quiet= arguments.get(OPT_QUIET)!=null;
+
+ if(!quiet) {
+ System.setProperty(IPDOMIndexerTask.TRACE_ACTIVITY, Boolean.TRUE.toString());
+ System.setProperty(IPDOMIndexerTask.TRACE_PROBLEMS, Boolean.TRUE.toString());
+ System.setProperty(IPDOMIndexerTask.TRACE_STATISTICS, Boolean.TRUE.toString());
+ }
+
+ IExportProjectProvider pprovider = getDescription(pproviderFQN);
+ if(pprovider==null) {
+ output(MessageFormat.format(Messages.GeneratePDOMApplication_CouldNotFindInitializer, new Object[]{pproviderFQN}));
+ return null;
+ }
+ File targetLocation = new File(target);
+
+ GeneratePDOM generate = new GeneratePDOM(pprovider, Platform.getApplicationArgs(), targetLocation);
+ output(Messages.GeneratePDOMApplication_GenerationStarts);
+ generate.run();
+ output(Messages.GeneratePDOMApplication_GenerationEnds);
+ return null;
+ }
+
+ protected void output(String s) {
+ System.out.println(s);
+ }
+
+ public void stop() {
+ // do nothing
+ }
+
+ /**
+ * Returns the IProjectForExportManager registed in the plug-in registry under the
+ * specified fully qualified class name
+ * May return null
+ * @param fqn
+ * @return
+ */
+ private static synchronized IExportProjectProvider getDescription(String fqn) {
+ if(projectInitializers==null) {
+ projectInitializers = new HashMap();
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint indexExtensions = registry.getExtensionPoint(CCorePlugin.INDEX_UNIQ_ID);
+ IExtension[] extensions = indexExtensions.getExtensions();
+ for(int i=0; i
+
@@ -222,6 +223,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -579,6 +602,20 @@
id="org.eclipse.cdt.core.CFG_BASED_CONTAINER">
+
+
+
+
+
+
+
+
+
+
diff --git a/core/org.eclipse.cdt.core/schema/CIndex.exsd b/core/org.eclipse.cdt.core/schema/CIndex.exsd
new file mode 100644
index 00000000000..32f42420e9c
--- /dev/null
+++ b/core/org.eclipse.cdt.core/schema/CIndex.exsd
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
+
+ This extension point groups extensions to the index functionality in CDT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This element allows contribution of alternate IExportProjectProvider implementations. These can then be referenced by fully qualified class name in the command line tool (see option -pprovider).
+<p>
+<b>Invoking the application as a headless application</b>
+
+This example ant file shows how to invoke the tool headlessly, the same approach would work from a shell or batch file.
+
+<pre>
+<!-- Test script. This would be part of the documentation, rather than submitted to CVS -->
+<project name="Generate PDOM" default="generate">
+ <target name="generate">
+ <!-- This script shows how to invoke the default project provider (ExternalExportProjectProvider) -->
+ <property name="pprovider" value="org.eclipse.cdt.core.index.export.ExternalExportProjectProvider"/>
+ <property name="target" value="C:\ExportedPDOMs\acmeSDK_2_5.pdom"/> <!-- Where the output pdom is to go -->
+ <property name="source" value="E:\AcmeSDK\v2.5\inc"/> <!-- e.g. the directory to source content from -->
+ <property name="id" value="com.acme.mysdk.v2.5"/> <!-- the id to store in the generate pdom -->
+
+ <property name="eclipse.home" value="C:\eclipse"/> <!-- e.g. The eclipse installation to use. This installation must contain CDT 4.0+ plugins -->
+
+ <java classname="org.eclipse.equinox.launcher.Main">
+ <classpath>
+ <fileset dir="${eclipse.home}/plugins">
+ <include name="*equinox.launcher*.jar"/>
+ </fileset>
+ </classpath>
+ <arg value="-nosplash"/>
+ <arg value="-exitdata"/>
+ <arg value="-application"/><arg value="org.eclipse.cdt.core.GeneratePDOM"/>
+ <arg value="-pprovider"/><arg value="${pprovider}"/>
+ <arg value="-source"/><arg value="${source}"/>
+ <arg value="-target"/><arg value="${target}"/>
+ <arg value="-id"/><arg value="${id}"/>
+ </java>
+ </target>
+</project>
+</pre>
+<p>
+<b>Invoking the tool via an Eclipse Launch Configuration</b>
+<p>
+Specify "org.eclipse.cdt.core.GeneratePDOM" as the application to launch
+<p>
+In the Argument tabs provide (for example)
+ -target C:\ExportedPDOMs\acmeSDK_2_5.pdom -source E:\AcmeSDK\v2.5\inc -include E:\this.h -id com.acme.mysdk.v2.5
+<p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4.0
+
+
+
+
+
+
+
+
+ See subelement documentation
+
+
+
+
+
+
+
+
+ Index content provided by ISVs under this extension point will be accessible via the logical index org.eclipse.core.index.IIndex API
+
+For export functionality, see package org.eclipse.cdt.core.index.export
+
+
+
+
+
+
+
+
+ [Enter information about supplied implementation of this extension point.]
+
+
+
+
+
+
+
+
+ Copyright (c) 2007 Symbian 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
+
+
+
+
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
index 2b6987c2766..4bcecf0e5e7 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Markus Schorn (Wind River Systems)
+ * Andrew Ferguson (Symbian)
*******************************************************************************/
package org.eclipse.cdt.core;
@@ -91,6 +92,9 @@ public class CCorePlugin extends Plugin {
public final static String PREF_USE_STRUCTURAL_PARSE_MODE = "useStructualParseMode"; //$NON-NLS-1$
public final static String PREF_USE_NEW_MODEL_BUILDER = "useNewModelBuilder"; //$NON-NLS-1$
+ public static final String INDEX_SIMPLE_ID = "CIndex"; //$NON-NLS-1$
+ public static final String INDEX_UNIQ_ID = PLUGIN_ID + "." + INDEX_SIMPLE_ID; //$NON-NLS-1$
+
public static final String INDEXER_SIMPLE_ID = "CIndexer"; //$NON-NLS-1$
public static final String INDEXER_UNIQ_ID = PLUGIN_ID + "." + INDEXER_SIMPLE_ID; //$NON-NLS-1$
public static final String PREF_INDEXER = "indexer"; //$NON-NLS-1$