blob: 8e9f76a92091a0dd1501616d0a55f6e4460d208d [file] [log] [blame]
/**********************************************************************
* Copyright (c) 2002,2003 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.core;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Map.Entry;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.make.core.IMakeBuilderInfo;
import org.eclipse.cdt.make.core.MakeCorePlugin;
import org.eclipse.cdt.make.core.MakeProjectNature;
import org.eclipse.core.resources.ICommand;
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.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status;
public class BuildInfoFactory {
private static final String PREFIX = MakeCorePlugin.getUniqueIdentifier();
static final String BUILD_COMMAND = PREFIX + ".buildCommand"; //$NON-NLS-1$
static final String BUILD_LOCATION = PREFIX + ".buildLocation"; //$NON-NLS-1$
static final String STOP_ON_ERROR = PREFIX + ".stopOnError"; //$NON-NLS-1$
static final String USE_DEFAULT_BUILD_CMD = PREFIX + ".useDefaultBuildCmd"; //$NON-NLS-1$
static final String BUILD_TARGET_AUTO = PREFIX + ".autoBuildTarget"; //$NON-NLS-1$
static final String BUILD_TARGET_INCREMENTAL = PREFIX + ".incrementalBuildTarget"; //$NON-NLS-1$
static final String BUILD_TARGET_FULL = PREFIX + ".fullBuildTarget"; //$NON-NLS-1$
static final String BUILD_FULL_ENABLED = PREFIX + ".enableFullBuild"; //$NON-NLS-1$
static final String BUILD_INCREMENTAL_ENABLED = PREFIX + ".enabledIncrementalBuild"; //$NON-NLS-1$
static final String BUILD_AUTO_ENABLED = PREFIX + ".enableAutoBuild"; //$NON-NLS-1$
static final String BUILD_ARGUMENTS = PREFIX + ".buildArguments"; //$NON-NLS-1$
static final String ENVIRONMENT = PREFIX + ".environment"; //$NON-NLS-1$
private abstract static class Store implements IMakeBuilderInfo {
public void setUseDefaultBuildCmd(boolean on) throws CoreException {
putString(USE_DEFAULT_BUILD_CMD, new Boolean(on).toString());
}
public boolean isDefaultBuildCmd() {
if (getString(USE_DEFAULT_BUILD_CMD) == null) { // if no property then default to true
return true;
}
return getBoolean(USE_DEFAULT_BUILD_CMD);
}
public void setBuildCommand(IPath location) throws CoreException {
putString(BUILD_COMMAND, location.toString());
}
public IPath getBuildCommand() {
if (isDefaultBuildCmd()) {
String command = getBuildParameter("defaultCommand"); //$NON-NLS-1$
if (command == null) {
return new Path("make"); //$NON-NLS-1$
}
return new Path(command);
}
return new Path(getString(BUILD_COMMAND));
}
protected String getBuildParameter(String name) {
IExtension extension =
Platform.getPluginRegistry().getExtension(
ResourcesPlugin.PI_RESOURCES,
ResourcesPlugin.PT_BUILDERS,
getBuilderID());
if (extension == null)
return null;
IConfigurationElement[] configs = extension.getConfigurationElements();
if (configs.length == 0)
return null;
//The nature exists, or this builder doesn't specify a nature
IConfigurationElement[] runElement = configs[0].getChildren("run"); //$NON-NLS-1$
IConfigurationElement[] paramElement = runElement[0].getChildren("parameter"); //$NON-NLS-1$
for (int i = 0; i < paramElement.length; i++) {
if (paramElement[i].getAttribute("name").equals(name)) { //$NON-NLS-1$
return paramElement[i].getAttribute("value"); //$NON-NLS-1$
}
}
return null;
}
protected abstract String getBuilderID();
public void setBuildLocation(IPath location) throws CoreException {
putString(BUILD_LOCATION, location.toString());
}
public IPath getBuildLocation() {
String location = getString(BUILD_LOCATION);
return new Path(location == null ? "" : location); //$NON-NLS-1$
}
public void setStopOnError(boolean enabled) throws CoreException {
putString(STOP_ON_ERROR, new Boolean(enabled).toString());
}
public boolean isStopOnError() {
return getBoolean(STOP_ON_ERROR);
}
public void setAutoBuildTarget(String target) throws CoreException {
putString(BUILD_TARGET_AUTO, target);
}
public String getAutoBuildTarget() {
return getString(BUILD_TARGET_AUTO);
}
public void setIncrementalBuildTarget(String target) throws CoreException {
putString(BUILD_TARGET_INCREMENTAL, target);
}
public String getIncrementalBuildTarget() {
return getString(BUILD_TARGET_INCREMENTAL);
}
public void setFullBuildTarget(String target) throws CoreException {
putString(BUILD_TARGET_FULL, target);
}
public String getFullBuildTarget() {
return getString(BUILD_TARGET_FULL);
}
public boolean getBoolean(String property) {
return Boolean.valueOf(getString(property)).booleanValue();
}
protected abstract void putString(String name, String value) throws CoreException;
protected abstract String getString(String property);
public void setAutoBuildEnable(boolean enabled) throws CoreException {
putString(BUILD_AUTO_ENABLED, new Boolean(enabled).toString());
}
public boolean isAutoBuildEnable() {
return getBoolean(BUILD_AUTO_ENABLED);
}
public void setIncrementalBuildEnable(boolean enabled) throws CoreException {
putString(BUILD_INCREMENTAL_ENABLED, new Boolean(enabled).toString());
}
public boolean isIncrementalBuildEnabled() {
return getBoolean(BUILD_INCREMENTAL_ENABLED);
}
public void setFullBuildEnable(boolean enabled) throws CoreException {
putString(BUILD_FULL_ENABLED, new Boolean(enabled).toString());
}
public boolean isFullBuildEnabled() {
return getBoolean(BUILD_FULL_ENABLED);
}
public String getBuildArguments() {
return getString(BUILD_ARGUMENTS);
}
public void setBuildArguments(String args) throws CoreException {
putString(BUILD_ARGUMENTS, args);
}
public String[] getErrorParsers() {
String parsers = getString(ErrorParserManager.PREF_ERROR_PARSER);
if (parsers != null && parsers.length() > 0) {
StringTokenizer tok = new StringTokenizer(parsers, ";");
List list = new ArrayList(tok.countTokens());
while (tok.hasMoreElements()) {
list.add(tok.nextToken());
}
return (String[]) list.toArray(new String[list.size()]);
}
return new String[0];
}
public void setErrorParsers(String[] parsers) throws CoreException {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < parsers.length; i++) {
buf.append(parsers[i]).append(';');
}
putString(ErrorParserManager.PREF_ERROR_PARSER, buf.toString());
}
public Map getEnvironment() {
return decodeMap(getString(ENVIRONMENT));
}
public void setEnvironment(Map env) throws CoreException {
putString(ENVIRONMENT, encodeMap(env));
}
protected Map decodeMap(String value) {
Map map = new HashMap();
try {
while (value != null && value.length() > 0) {
int ndx = 0;
while (value.charAt(ndx) != '|' || (ndx != 0 && value.charAt(ndx - 1) == '\\')) {
ndx++;
}
StringBuffer line = new StringBuffer(value.substring(0, ndx));
int lndx = 0;
while (line.charAt(lndx) != '=' || (lndx != 0 && line.charAt(lndx - 1) == '\\')) {
lndx++;
}
map.put(line.substring(0, lndx), line.substring(lndx + 1));
value = value.substring(ndx+1);
}
} catch (StringIndexOutOfBoundsException e) {
}
return map;
}
protected String encodeMap(Map values) {
StringBuffer str = new StringBuffer();
Iterator entries = values.entrySet().iterator();
while (entries.hasNext()) {
Entry entry = (Entry) entries.next();
str.append(escapeChars((String) entry.getKey(), "=|"));
str.append("=");
str.append(escapeChars((String) entry.getValue(), "=|)"));
str.append("|");
}
return str.toString();
}
protected String escapeChars(String string, String escapeChars) {
StringBuffer str = new StringBuffer(string);
for(int i = 0; i < str.length(); i++) {
if ( escapeChars.indexOf(str.charAt(i)) != -1) {
str.insert(i-1, '\\');
}
}
return str.toString();
}
}
private static class Preference extends Store {
private Preferences prefs;
private String builderID;
private boolean useDefaults;
Preference(Preferences prefs, String builderID, boolean useDefaults) {
this.prefs = prefs;
this.builderID = builderID;
this.useDefaults = useDefaults;
}
protected void putString(String name, String value) {
if (useDefaults) {
prefs.setDefault(name, value);
} else {
prefs.setValue(name, value);
}
}
protected String getString(String property) {
if (useDefaults) {
return prefs.getDefaultString(property);
}
return prefs.getString(property);
}
protected String getBuilderID() {
return builderID;
}
}
private static class BuildProperty extends Store {
private IProject project;
private String builderID;
private Map args;
BuildProperty(IProject project, String builderID) throws CoreException {
this.project = project;
this.builderID = builderID;
ICommand builder;
builder = MakeProjectNature.getBuildSpec(project, builderID);
if (builder == null) {
throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1, MakeCorePlugin.getResourceString("BuildInfoFactory.Missing_Builder") + builderID, null)); //$NON-NLS-1$
}
args = builder.getArguments();
}
protected void putString(String name, String value) throws CoreException {
String curValue = (String) args.get(name);
if (curValue != null && curValue.equals(value)) {
return;
}
ICommand builder = MakeProjectNature.getBuildSpec(project, builderID);
args.put(name, value);
builder.setArguments(args);
project.setDescription(project.getDescription(), null);
}
protected String getString(String name) {
String value = (String) args.get(name);
return value == null ? "" : value; //$NON-NLS-1$
}
protected String getBuilderID() {
return builderID;
}
}
private static class BuildArguments extends Store {
private Map args;
private String builderID;
BuildArguments(Map args, String builderID) {
this.args = args;
this.builderID = builderID;
}
protected void putString(String name, String value) {
args.put(name, value);
}
protected String getString(String name) {
return (String) args.get(name);
}
protected String getBuilderID() {
return builderID;
}
}
public static IMakeBuilderInfo create(Preferences prefs, String builderID, boolean useDefaults) {
return new BuildInfoFactory.Preference(prefs, builderID, useDefaults);
}
public static IMakeBuilderInfo create(IProject project, String builderID) throws CoreException {
return new BuildInfoFactory.BuildProperty(project, builderID);
}
public static IMakeBuilderInfo create(Map args, String builderID) {
return new BuildInfoFactory.BuildArguments(args, builderID);
}
}