/******************************************************************************* * Copyright (c) 2005, 2011 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 * Miwako Tokugawa (Intel Corporation) - bug 222817 (OptionCategoryApplicability) *******************************************************************************/ package org.eclipse.cdt.managedbuilder.internal.enablement; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.cdt.core.cdtvariables.CdtVariableException; import org.eclipse.cdt.managedbuilder.core.BuildException; import org.eclipse.cdt.managedbuilder.core.IBuildObject; import org.eclipse.cdt.managedbuilder.core.IFileInfo; import org.eclipse.cdt.managedbuilder.core.IFolderInfo; import org.eclipse.cdt.managedbuilder.core.IHoldsOptions; import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; import org.eclipse.cdt.managedbuilder.core.IOption; import org.eclipse.cdt.managedbuilder.core.IOptionCategory; import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; import org.eclipse.cdt.managedbuilder.core.IResourceInfo; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroProvider; import org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo; import org.eclipse.cdt.managedbuilder.internal.macros.OptionContextData; import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; import org.eclipse.cdt.utils.cdtvariables.CdtVariableResolver; import org.eclipse.cdt.utils.cdtvariables.SupplierBasedCdtVariableSubstitutor; public class CheckOptionExpression implements IBooleanExpression { public static final String NAME = "checkOption"; //$NON-NLS-1$ public static final String OPTION_ID = "optionId"; //$NON-NLS-1$ public static final String HOLDER_ID = "holderId"; //$NON-NLS-1$ public static final String VALUE = "value"; //$NON-NLS-1$ public static final String IS_REGEX = "isRegex"; //$NON-NLS-1$ public static final String OTHER_OPTION_ID = "otherOptionId"; //$NON-NLS-1$ public static final String OTHER_HOLDER_ID = "otherHolderId"; //$NON-NLS-1$ private String fOptionId; private String fHolderId; private String fValue; private boolean fIsRegex; private String fOtherOptionId; private String fOtherHolderId; public CheckOptionExpression(IManagedConfigElement element){ fOptionId = element.getAttribute(OPTION_ID); fHolderId = element.getAttribute(HOLDER_ID); fValue = element.getAttribute(VALUE); fIsRegex = OptionEnablementExpression.getBooleanValue(element.getAttribute(IS_REGEX)); fOtherOptionId = element.getAttribute(OTHER_OPTION_ID); fOtherHolderId = element.getAttribute(OTHER_HOLDER_ID); } public boolean evaluate(IResourceInfo rcInfo, IHoldsOptions holder, IOption option) { boolean result = false; IBuildObject ho[] = getHolderAndOption(fOptionId, fHolderId, rcInfo, holder, option); if(ho != null){ if(fValue != null) result = evaluate((IOption)ho[1],((IHoldsOptions)ho[0]),fValue); else { IBuildObject otherHo[] = getHolderAndOption(fOtherOptionId, fOtherHolderId, rcInfo, holder, option); if(otherHo != null) result = evaluate((IOption)ho[1],((IHoldsOptions)ho[0]), (IOption)otherHo[1],((IHoldsOptions)otherHo[0])); } } return result; } public boolean evaluate(IResourceInfo rcInfo, IHoldsOptions holder, IOptionCategory category) { boolean result = false; IBuildObject ho[] = getHolderAndOption(fOptionId, fHolderId, rcInfo, holder); if(ho != null){ if(fValue != null) result = evaluate((IOption)ho[1],((IHoldsOptions)ho[0]),fValue); // otherOptionId shouldn't be set when enabling optionCategory } return result; } public boolean evaluate(IOption option, IHoldsOptions holder, String value){ IBuildMacroProvider provider = ManagedBuildManager.getBuildMacroProvider(); String delimiter = ManagedBuildManager.getEnvironmentVariableProvider().getDefaultDelimiter(); String inexVal = " "; //$NON-NLS-1$ try { String resolvedValue = provider.resolveValue(value, inexVal, delimiter, IBuildMacroProvider.CONTEXT_OPTION, new OptionContextData(option,holder)); switch(option.getValueType()){ case IOption.STRING: case IOption.ENUMERATED:{ String stringValue = option.getStringValue(); stringValue = provider.resolveValue(stringValue, inexVal, delimiter, IBuildMacroProvider.CONTEXT_OPTION, new OptionContextData(option,holder)); if(fIsRegex){ Pattern pattern = Pattern.compile(resolvedValue); Matcher matcher = pattern.matcher(stringValue); return matcher.matches(); } return stringValue.equals(resolvedValue); } case IOption.BOOLEAN: return option.getBooleanValue() == OptionEnablementExpression.getBooleanValue(resolvedValue); case IOption.INCLUDE_PATH: case IOption.STRING_LIST: case IOption.PREPROCESSOR_SYMBOLS: case IOption.LIBRARIES: case IOption.OBJECTS: case IOption.INCLUDE_FILES: case IOption.LIBRARY_PATHS: case IOption.LIBRARY_FILES: case IOption.MACRO_FILES: case IOption.UNDEF_INCLUDE_PATH: case IOption.UNDEF_PREPROCESSOR_SYMBOLS: case IOption.UNDEF_INCLUDE_FILES: case IOption.UNDEF_LIBRARY_PATHS: case IOption.UNDEF_LIBRARY_FILES: case IOption.UNDEF_MACRO_FILES:{ @SuppressWarnings("unchecked") List<String> list = (List<String>)option.getValue(); String listValue = provider.convertStringListToString(list.toArray(new String[list.size()]),delimiter); listValue = provider.resolveValue(listValue, inexVal, delimiter, IBuildMacroProvider.CONTEXT_OPTION, new OptionContextData(option,holder)); if(fIsRegex){ Pattern pattern = Pattern.compile(resolvedValue); Matcher matcher = pattern.matcher(listValue); return matcher.matches(); } return listValue.equals(resolvedValue); } default: break; } } catch (BuildException e) { } catch (BuildMacroException e) { } return false; } public boolean evaluate(IOption option, IHoldsOptions holder, IOption otherOption, IHoldsOptions otherHolder){ try { if(option.getValueType() != otherOption.getValueType()) return false; BuildMacroProvider provider = (BuildMacroProvider)ManagedBuildManager.getBuildMacroProvider(); String delimiter = ManagedBuildManager.getEnvironmentVariableProvider().getDefaultDelimiter(); String inexVal = " "; //$NON-NLS-1$ switch(option.getValueType()){ case IOption.STRING: case IOption.ENUMERATED:{ String stringValue = option.getStringValue(); stringValue = provider.resolveValue(stringValue, inexVal, delimiter, IBuildMacroProvider.CONTEXT_OPTION, new OptionContextData(option,holder)); String str = otherOption.getStringValue(); str = provider.resolveValue(str, inexVal, delimiter, IBuildMacroProvider.CONTEXT_OPTION, new OptionContextData(otherOption,otherHolder)); return stringValue.equals(str); } case IOption.BOOLEAN: return option.getBooleanValue() == otherOption.getBooleanValue(); case IOption.INCLUDE_PATH: case IOption.STRING_LIST: case IOption.PREPROCESSOR_SYMBOLS: case IOption.LIBRARIES: case IOption.OBJECTS: case IOption.INCLUDE_FILES: case IOption.LIBRARY_PATHS: case IOption.LIBRARY_FILES: case IOption.MACRO_FILES: case IOption.UNDEF_INCLUDE_PATH: case IOption.UNDEF_PREPROCESSOR_SYMBOLS: case IOption.UNDEF_INCLUDE_FILES: case IOption.UNDEF_LIBRARY_PATHS: case IOption.UNDEF_LIBRARY_FILES: case IOption.UNDEF_MACRO_FILES:{ @SuppressWarnings("unchecked") List<String> list = (List<String>)option.getValue(); String listValue[] = list.toArray(new String[list.size()]); @SuppressWarnings("unchecked") List<String> otherList = (List<String>)otherOption.getValue(); String otherValue[] = otherList.toArray(new String[otherList.size()]); IMacroContextInfo info = provider.getMacroContextInfo(IBuildMacroProvider.CONTEXT_OPTION, new OptionContextData(option,holder)); SupplierBasedCdtVariableSubstitutor subst = provider.getMacroSubstitutor(info,inexVal,delimiter); listValue = CdtVariableResolver.resolveStringListValues(listValue,subst,false); info = provider.getMacroContextInfo(IBuildMacroProvider.CONTEXT_OPTION, new OptionContextData(otherOption,otherHolder)); subst = provider.getMacroSubstitutor(info,inexVal,delimiter); otherValue = CdtVariableResolver.resolveStringListValues(otherValue,subst,false); if(listValue.length == otherValue.length){ for(int i = 0; i < listValue.length; i++){ if(!listValue[i].equals(otherValue[i])) return false; } return true; } return false; } default: break; } } catch (BuildException e) { } catch (CdtVariableException e) { } catch (ClassCastException e) { } return false; } protected IBuildObject[] getHolderAndOption(String optionId, String holderId, IResourceInfo rcInfo, IHoldsOptions holder, IOption option ){ IBuildObject result[] = null; if(optionId == null) result = new IBuildObject[]{holder,option}; else { IHoldsOptions hld = null; if(holderId == null) hld = holder; else hld = getHolder(holderId,rcInfo); if(hld != null) { IOption opt = getOption(optionId,hld); if(opt != null) result = new IBuildObject[]{hld,opt}; } } return result; } /* This is called for optionCategory */ protected IBuildObject[] getHolderAndOption(String optionId, String holderId, IResourceInfo rcInfo, IHoldsOptions holder ){ IBuildObject result[] = null; if(optionId != null) { IHoldsOptions hld = null; if(holderId == null) hld = holder; else hld = getHolder(holderId,rcInfo); if(hld != null) { IOption opt = getOption(optionId,hld); if(opt != null) result = new IBuildObject[]{hld,opt}; } } return result; } protected IOption getOption(String optionId, IHoldsOptions holder){ return holder.getOptionBySuperClassId(optionId); } protected IHoldsOptions getHolder(String id, IResourceInfo rcInfo){ IHoldsOptions holder = null; if(rcInfo instanceof IFileInfo){ IHoldsOptions holders[] = ((IResourceConfiguration)rcInfo).getTools(); for(int i = 0; i < holders.length; i++){ if(isHolder(id,holders[i])){ holder = holders[i]; break; } } } else if (rcInfo instanceof IFolderInfo){ IToolChain tc = ((IFolderInfo)rcInfo).getToolChain(); if(isHolder(id,tc)) holder = tc; else { IHoldsOptions holders[] = tc.getTools(); for(int i = 0; i < holders.length; i++){ if(isHolder(id,holders[i])){ holder = holders[i]; break; } } } } return holder; } protected boolean isHolder(String id, IHoldsOptions holder){ do { if(id.equals(holder.getId())) return true; if(holder instanceof IToolChain) holder = ((IToolChain)holder).getSuperClass(); else if(holder instanceof ITool) holder = ((ITool)holder).getSuperClass(); else holder = null; } while(holder != null); return false; } }