/******************************************************************************* * Copyright (c) 2005, 2016 Intel 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: * Intel Corporation - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.core.cdtvariables; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.regex.Pattern; import org.eclipse.cdt.core.cdtvariables.CdtVariable; import org.eclipse.cdt.core.cdtvariables.CdtVariableException; import org.eclipse.cdt.core.cdtvariables.ICdtVariable; import org.eclipse.cdt.core.cdtvariables.ICdtVariableStatus; import org.eclipse.cdt.utils.cdtvariables.ICdtVariableSupplier; import org.eclipse.cdt.utils.cdtvariables.IVariableContextInfo; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.variables.IDynamicVariable; import org.eclipse.core.variables.IStringVariable; import org.eclipse.core.variables.IStringVariableManager; import org.eclipse.core.variables.IValueVariable; import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.osgi.util.NLS; /** * This supplier suplies the macros that represent the Eclipse variables * * @since 3.0 */ public class EclipseVariablesVariableSupplier implements ICdtVariableSupplier { private static final Pattern RESOURCE_VARIABLE_PATTERN= Pattern.compile("(project|resource|container)_(loc|path|name)"); //$NON-NLS-1$ // private static final String VAR_PREFIX = "${"; //$NON-NLS-1$ // private static final char VAR_SUFFIX = '}'; private static final char COLON = ':'; private static EclipseVariablesVariableSupplier fInstance; private EclipseVariablesVariableSupplier(){ } public static EclipseVariablesVariableSupplier getInstance(){ if(fInstance == null) fInstance = new EclipseVariablesVariableSupplier(); return fInstance; } public class EclipseVarMacro extends CdtVariable { private IStringVariable fVariable; private String fArgument; private boolean fInitialized; private EclipseVarMacro(IStringVariable var){ this(var,null); } private EclipseVarMacro(IStringVariable var, String argument){ fVariable = var; fType = VALUE_TEXT; fName = var.getName(); if(argument != null) fName += COLON + argument; fArgument = argument; } /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacro#getStringValue() */ @Override public String getStringValue() throws CdtVariableException { if(!fInitialized){ try { if (!canExpandVariable(fVariable.getName(), fArgument)) { final String expression= "${"+fName+"}"; //$NON-NLS-1$//$NON-NLS-2$ throw new CdtVariableException(ICdtVariableStatus.TYPE_MACRO_REFERENCE_INCORRECT, NLS.bind(Messages.EclipseVariablesVariableSupplier_illegal_variable, expression), null, fVariable.getName(), expression, null); } loadValue(fVariable); } finally { fInitialized = true; } } return fStringValue; } private void loadValue(IStringVariable var) throws CdtVariableException { if(var instanceof IDynamicVariable){ IDynamicVariable dynamicVar = (IDynamicVariable)var; if(fArgument == null || dynamicVar.supportsArgument()){ try{ fStringValue = dynamicVar.getValue(fArgument); }catch(CoreException e){ fStringValue = null; } }else fStringValue = null; }else if(var instanceof IValueVariable){ if(fArgument == null) fStringValue = ((IValueVariable)var).getValue(); else fStringValue = null; } } public IStringVariable getVariable(){ return fVariable; } } /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacro(java.lang.String, int, java.lang.Object) */ @Override public ICdtVariable getVariable(String macroName, IVariableContextInfo info) { return getVariable(macroName); } public ICdtVariable getVariable(String macroName) { // if(contextType != DefaultMacroContextInfo.CONTEXT_WORKSPACE) // return null; if(macroName == null || macroName.isEmpty()) return null; String varName = null; String param = null; IStringVariable var = null; int index = macroName.indexOf(COLON); if(index == -1) varName = macroName; else if(index > 0){ varName = macroName.substring(0,index); param = macroName.substring(index+1); } if(varName != null){ IStringVariableManager mngr = VariablesPlugin.getDefault().getStringVariableManager(); var = mngr.getValueVariable(varName); if(var == null) var = mngr.getDynamicVariable(varName); } if(var != null) return new EclipseVarMacro(var,param); return null; } /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacros(int, java.lang.Object) */ @Override public ICdtVariable[] getVariables(IVariableContextInfo info) { return getVariables(); } public ICdtVariable[] getVariables() { // if(contextType != DefaultMacroContextInfo.CONTEXT_WORKSPACE) // return null; IStringVariableManager mngr = VariablesPlugin.getDefault().getStringVariableManager(); IDynamicVariable vars[] = mngr.getDynamicVariables(); Map<String, IStringVariable> map = new HashMap<String, IStringVariable>(); for (IDynamicVariable var : vars) { final String name= var.getName(); if (!isDeadlockProneVariable(name)) { map.put(name,var); } } IValueVariable valVars[] = mngr.getValueVariables(); for (IValueVariable valVar : valVars) map.put(valVar.getName(),valVar); Collection<IStringVariable> collection = map.values(); EclipseVarMacro macros[] = new EclipseVarMacro[collection.size()]; Iterator<IStringVariable> iter = collection.iterator(); for(int i = 0; i < macros.length ; i++) macros[i] = new EclipseVarMacro(iter.next()); return macros; } /** * Test for Eclipse variables with known deadlock issues. * @param name variable name * @return whether the variable is prone to deadlocks */ private static boolean isDeadlockProneVariable(String name) { return RESOURCE_VARIABLE_PATTERN.matcher(name).matches() || name.endsWith("_prompt") //$NON-NLS-1$ || name.equals("selected_text"); //$NON-NLS-1$ } private static boolean canExpandVariable(String name, String argument) { if (argument == null && RESOURCE_VARIABLE_PATTERN.matcher(name).matches()) { return false; } if (name.endsWith("_prompt") || name.equals("selected_text")) { //$NON-NLS-1$//$NON-NLS-2$ return false; } return true; } // private String getMacroValue(String name){ // IStringVariableManager mngr = VariablesPlugin.getDefault().getStringVariableManager(); // try{ // return mngr.performStringSubstitution(VAR_PREFIX + name + VAR_SUFFIX); // }catch (CoreException e){ // } // // return null; // } }