Package org.eclipse.cdt.managedbuilder.llvm.util

Source Code of org.eclipse.cdt.managedbuilder.llvm.util.LlvmToolOptionPathUtil

/*******************************************************************************
* Copyright (c) 2010-2013 Nokia Siemens Networks Oyj, Finland.
* 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:
*      Nokia Siemens Networks - initial implementation
*      Petri Tuononen - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.llvm.util;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.resources.RefreshScopeManager;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.managedbuilder.core.BuildException;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
import org.eclipse.cdt.managedbuilder.core.IManagedProject;
import org.eclipse.cdt.managedbuilder.core.IOption;
import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable;
import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier;
import org.eclipse.cdt.managedbuilder.gnu.mingw.MingwEnvironmentVariableSupplier;
import org.eclipse.cdt.managedbuilder.llvm.ui.LlvmEnvironmentVariableSupplier;
import org.eclipse.cdt.managedbuilder.llvm.ui.preferences.LlvmPreferenceStore;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;

/**
* The main purpose of this class is to add include paths and libraries and library search paths
* for LLVM compiler and linker Tools which are added in Preferences->LLVM to all projects
* and build configurations that use LLVM ToolChain. Values added in Preferences->LLVM will
* show in Project->Properties->C/C++ General->Paths and Symbols tabs.
*
*/
public class LlvmToolOptionPathUtil {

  //tool input extensions
  private static final String linkerInputType = "bc"; //$NON-NLS-1$
  private static final String[] inputTypes = {"cpp", "c"}//$NON-NLS-1$ //$NON-NLS-2$
  //tool option values
  public static final int INCLUDE = 1;
  public static final int LIB = 2;
  public static final int LIB_PATH = 3;

  /**
   * Adds new include path to LLVM front-end's Include path option for every project
   * in the workspace that uses LLVM Toolchain and for for every build configuration.
   *
   * @param includePath Include path for LLVM front-end's Include Option
   */
  public static void addLlvmIncludePath(String includePath) {
    addPathToToolOption(includePath, INCLUDE);
  }

  /**
   * Removes an include path from LLVM front-end's Include path option for every project
   * in the workspace that uses LLVM Toolchain and for for every build configuration.
   *
   * @param includePath Include path for LLVM front-end's Include Option
   */
  public static void removeLlvmIncludePath(String includePath) {
    removePathFromToolOption(includePath, INCLUDE);
  }

  /**
   * Adds a new Library to LLVM linker's Libraries Option for every project
   * in the workspace that use LLVM Toolchain and for for every build configuration.
   *
   * @param lib Library name for the LLVM linker's Libraries Option
   */
  public static void addLlvmLib(String lib) {
    addPathToToolOption(lib, LIB);
  }

  /**
   * Removes a Library to LLVM linker's Libraries Option for every project
   * in the workspace that use LLVM Toolchain and for for every build configuration.
   *
   * @param lib Library name for the LLVM linker's Libraries Option
   */
  public static void removeLlvmLib(String lib) {
    removePathFromToolOption(lib, LIB);
  }

  /**
   * Adds a new Library search path directory to LLVM linker's Library search path Option
   * for every project in the workspace that use LLVM Toolchain and for for every
   * build configuration.
   *
   * @param libDir Library search path directory for LLVM linker's Library search path Option
   */
  public static void addLlvmLibraryPath(String libDir) {
    addPathToToolOption(libDir, LIB_PATH);
  }

  /**
   * Removes a Library search path directory from LLVM linker's Library search path Option
   * for every project in the workspace that use LLVM Toolchain and for for every
   * build configuration.
   *
   * @param libDir Library search path directory for LLVM linker's Library search path Option
   */ 
  public static void removeLlvmLibraryPath(String libDir) {
    removePathFromToolOption(libDir, LIB_PATH);
  }

  /**
   * Adds a path to Tool option.
   *
   * @param path Path to add to Tool option
   * @param var Tool option's value
   */
  private static void addPathToToolOption(String path, int var) {
    //check if the given path exists
    if (path.length()>0 && (pathExists(path) || var==LIB)) {
      boolean success = false;
      //get all projects in the workspace
      IProject[] projects = getProjectsInWorkspace();
      IConfiguration[] configs;
      for (IProject proj : projects) {
       
        //get all build configurations of the IProject
        configs = getAllBuildConfigs(proj);
        //if build configurations found
        if (configs.length>0) {
          for (IConfiguration cf : configs) {
            //Add path for the Tool's option
            if (addPathToSelectedToolOptionBuildConf(cf, path, var)) {
              success = true;
            } else {
              success = false;
            }
          }
          //if the path was added successfully
          if (success) {
            //save project build info
            ManagedBuildManager.saveBuildInfo(proj, true);         
          }
        }
      }     
    }
  }

  /**
   * Adds a path to Tool option. Only for C++ projects.
   *
   * @param path Path to add to Tool option
   * @param var Tool option's value
   */
  private static void addPathToToolOptionCppProjects(String path, int var) {
    //check if the given path exists
    if (path.length()>0 && (pathExists(path) || var==LIB)) {
      boolean success = false;
      //get all projects in the workspace
      IProject[] projects = getProjectsInWorkspace();
      IConfiguration[] configs;
      String projectPath = null;
      for (IProject proj : projects) {
        projectPath = proj.getLocation().toOSString();
        if (projectPath!=null) {
          //only apply to C++ projects
          if (FileUtil.containsCppFile(new File(projectPath))) {
            //get all build configurations of the IProject
            configs = getAllBuildConfigs(proj);
            //if build configurations found
            if (configs.length>0) {
              for (IConfiguration cf : configs) {
                //Add path for the Tool's option
                if (addPathToSelectedToolOptionBuildConf(cf, path, var)) {
                  success = true;
                } else {
                  success = false;
                }
              }
              //if the path was added successfully
              if (success) {
                //save project build info
                ManagedBuildManager.saveBuildInfo(proj, true);   
                ICProjectDescription projectDescription = CoreModel.getDefault().getProjectDescription(proj);
                try {
                  CoreModel.getDefault().setProjectDescription(proj, projectDescription);
                } catch (CoreException e) {
                  e.printStackTrace();
                }
                //use refresh scope manager to refresh
                  RefreshScopeManager manager = RefreshScopeManager.getInstance();
                  IWorkspaceRunnable runnable = manager.getRefreshRunnable(proj);
                  try {
                  ResourcesPlugin.getWorkspace().run(runnable, null, IWorkspace.AVOID_UPDATE, new NullProgressMonitor());
                } catch (CoreException e) {
                  e.printStackTrace();
                }
                  //rebuilt the project index
                ProjectIndex.rebuiltIndex(proj);
              }
            }
          }
        }
      }     
    }
  }
 
  /**
   * Removes a path from Tool option.
   *
   * @param path Path to remove from Tool option
   * @param var Tool option's value
   */
  private static void removePathFromToolOption(String path, int var) {
    //check if the given path exists
    if (path.length()>0 && pathExists(path) || var==LIB) {
      boolean success = false;
      //get all projects in the workspace
      IProject[] projects = getProjectsInWorkspace();
      IConfiguration[] configs;
      for (IProject proj : projects) {
        //get all build configurations of the IProject
        configs = getAllBuildConfigs(proj);
        //if build configurations found
        if (configs.length>0) {
          for (IConfiguration cf : configs) {
            //remove a path from the Tool's option
            if (removePathFromSelectedToolOptionBuildConf(cf, path, var)) {
              success = true;
            } else {
              success = false;
            }
          }
          //if the path was removed successfully
          if (success) {
            //save project build info
            ManagedBuildManager.saveBuildInfo(proj, true);         
          }
        }
      }     
    }
  }

  /**
   * Add a path to specific build configuration's Tool option.
   *
   * @param cf Build configuration
   * @param path Path or file name to add
   * @param var Value of the option type
   * @return boolean True if path was added successfully
   */
  private static boolean addPathToSelectedToolOptionBuildConf(IConfiguration cf, String path, int var) {
    switch (var) {
    case INCLUDE:
      return addLlvmIncludePathToToolOption(cf, path);
    case LIB:
      return addLlvmLibToToolOption(cf, path);
    case LIB_PATH:
      return addLlvmLibSearchPathToToolOption(cf, path);
    default:
      return false;
    }
  }

  /**
   * Removes a path from specific build configuration's Tool option.
   *
   * @param cf Build configuration
   * @param path Path or file name to remove
   * @param var Value of the option type
   * @return boolean True if path was removed successfully
   */
  private static boolean removePathFromSelectedToolOptionBuildConf(IConfiguration cf, String path, int var) {
    switch (var) {
    case INCLUDE:
      return removeLlvmIncludePathFromToolOption(cf, path);
    case LIB:
      return removeLlvmLibFromToolOption(cf, path);
    case LIB_PATH:
      return removeLlvmLibSearchPathFromToolOption(cf, path);
    default:
      return false;
    }
  }

  /**
   * Returns all projects in the workspace.
   *
   * @return IProject[]
   */
  public static IProject[] getProjectsInWorkspace() {
    //get workspace
    IWorkspace root = ResourcesPlugin.getWorkspace();
    //get all projects in the workspace
    return root.getRoot().getProjects();
  }

  /**
   * Returns all build configurations of the project.
   *
   * @param proj IProject Project
   * @return IConfiguration[] Build configurations
   */
  private static IConfiguration[] getAllBuildConfigs(IProject proj) {
    IConfiguration[] configurations = new IConfiguration[] {};
    IManagedBuildInfo info = null;
    //try to get Managed build info
    try {
      info = ManagedBuildManager.getBuildInfo(proj); //null if doesn't exists
    } catch (Exception e) { //if not a managed build project
      //print error
      e.printStackTrace();
      return configurations;
    }
    //info can be null for projects without build info. For example, when creating a project
    //from Import >�C/C++ Executable
    if(info == null) {
      return configurations;
    }
    //get ManagedProject associated with build info
    IManagedProject mProj = info.getManagedProject();

    //get all build configurations of the project
    configurations = mProj.getConfigurations();
    return configurations;
  }

  /**
   * Adds an include path to LLVM front-end's include path option.
   *
   * @param cf IConfiguration Build configuration
   * @param newIncludePath Include path to be added to LLVM front-end's Include path option
   */
  private static boolean addLlvmIncludePathToToolOption(IConfiguration cf, String newIncludePath) {
    //get LLVM front-end
    ITool llvmFrontEnd = getLlvmFrontEnd(cf);
    //If the LLVM front-end is found from the given build configuration
    if (llvmFrontEnd != null) {
      //get LLVM front-end Include paths option.
      IOption llvmFrontEndIncPathOption = getLlvmFrontEndIncludePathOption(cf);
      //add a new include path to front-end's Include paths option.
      boolean val = addIncludePathToToolOption(cf, llvmFrontEnd, llvmFrontEndIncPathOption, newIncludePath);
      return val;
    }
    return false;
  }

  /**
   * Removes an include path from LLVM front-end's include path option.
   *
   * @param cf IConfiguration Build configuration
   * @param removeIncludePath Include path to be removed from LLVM front-end's Include path option
   */
  private static boolean removeLlvmIncludePathFromToolOption(IConfiguration cf, String removeIncludePath) {
    //get LLVM front-end
    ITool llvmFrontEnd = getLlvmFrontEnd(cf);
    //If the LLVM front-end is found from the given build configuration
    if (llvmFrontEnd != null) {
      //get LLVM front-end Include paths option.
      IOption llvmFrontEndIncPathOption = getLlvmFrontEndIncludePathOption(cf);
      //remove an include path from front-end's Include paths option.
      removeIncludePathFromToolOption(cf, llvmFrontEnd, llvmFrontEndIncPathOption, removeIncludePath);
      return true;
    }
    return false;
  }

  /**
   * Adds a Library to LLVM linker's Libraries Option.
   *
   * @param cf IConfiguration Build configuration
   * @param lib Library name
   * @return boolean Returns true if Library Option was added successfully for the LLVM Linker.
   */
  private static boolean addLlvmLibToToolOption(IConfiguration cf, String lib) {
    //get LLVM linker
    ITool llvmLinker = getLlvmLinker(cf);
    //If the LLVM linker is found from the given build configuration
    if (llvmLinker != null) {
      //get LLVM Linker Libraries option
      IOption librariesOption = getLlvmLinkerLibrariesOption(cf);
      //add library to LLVM linker's Libraries Option type
      boolean val = addLibraryToToolOption(cf, llvmLinker, librariesOption, lib);
      return val;
    }
    //adding the library failed
    return false;
  }

  /**
   * Removes a Library from LLVM linker's Libraries Option.
   *
   * @param cf IConfiguration Build configuration
   * @param removeLib Library name
   * @return boolean Returns true if Library Option was removed successfully from the LLVM Linker.
   */
  private static boolean removeLlvmLibFromToolOption(IConfiguration cf, String removeLib) {
    //get LLVM linker
    ITool llvmLinker = getLlvmLinker(cf);
    //If the LLVM linker is found from the given build configuration
    if (llvmLinker != null) {
      //get LLVM Linker Libraries option
      IOption librariesOption = getLlvmLinkerLibrariesOption(cf);
      //remove a library from LLVM linker's Libraries Option type
      removeLibraryFromToolOption(cf, llvmLinker, librariesOption, removeLib);
      return true;
    }
    //removing the library failed
    return false;
  }

  /**
   * Adds a Library search path to LLVM linker's Library search path Option.
   *
   * @param cf IConfiguration Build configuration
   * @param libDir Library search path
   * @return boolean Returns true if Library search path Option was added successfully for the LLVM Linker.
   */
  private static boolean addLlvmLibSearchPathToToolOption(IConfiguration cf, String libDir) {
    //get LLVM linker
    ITool llvmLinker = getLlvmLinker(cf);
    //If the LLVM linker is found from the given build configuration
    if (llvmLinker != null) {
      //get LLVM Linker Library search path option
      IOption libDirOption = getLlvmLinkerLibrarySearchPathOption(cf);
      //add library search path to LLVM linker's Library Search Path Option type
      boolean val = addLibrarySearchPathToToolOption(cf, llvmLinker, libDirOption, libDir);
      return val;
    }
    //adding library failed
    return false;
  }

  /**
   * Removes a Library search path from LLVM linker's Library search path Option.
   *
   * @param cf IConfiguration Build configuration
   * @param removeLibDir Library search path
   * @return boolean Returns true if Library search path Option was removed successfully from the LLVM Linker.
   */
  private static boolean removeLlvmLibSearchPathFromToolOption(IConfiguration cf, String removeLibDir) {
    //get LLVM linker
    ITool llvmLinker = getLlvmLinker(cf);
    //If the LLVM linker is found from the given build configuration
    if (llvmLinker != null) {
      //get LLVM Linker Library search path option
      IOption libDirOption = getLlvmLinkerLibrarySearchPathOption(cf);
      //remove a library search path from LLVM linker's Library Search Path Option type
      removeLibrarySearchPathFromToolOption(cf, llvmLinker, libDirOption, removeLibDir);
      return true;
    }
    //removing the library search path failed
    return false;
  }

  /**
   * Adds include path for given Build configuration's Tool's Include path Option.
   *
   * @param cf IConfiguration Build configuration
   * @param cfTool ITool Tool
   * @param option Tool Option type
   * @param newIncludePath Include path to be added to Tool's Include path option
   */
  private static boolean addIncludePathToToolOption(IConfiguration cf, ITool cfTool, IOption option, String newIncludePath) {
    try {
      //add path only if it does not exists
      String[] incPaths = option.getIncludePaths();
      for (String inc : incPaths) {
        if (inc.equalsIgnoreCase(newIncludePath)) {
          return false;
        }
      }
      //add a new include path to linker's Include paths option.
      addInputToToolOption(cf, cfTool, option, newIncludePath, incPaths);
    } catch (BuildException e) {
      //show error
      e.printStackTrace();
    }
    return true;
  }

  /**
   * Removes an include path from given Build configuration's Tool's Include path Option.
   *
   * @param cf IConfiguration Build configuration
   * @param cfTool ITool Tool
   * @param option Tool Option type
   * @param removeIncludePath Include path to be removed from Tool's Include path option
   */
  private static void removeIncludePathFromToolOption(IConfiguration cf, ITool cfTool, IOption option, String removeIncludePath) {
    try {
      //remove an include path from linker's Include paths option.
      removeInputFromToolOption(cf, cfTool, option, removeIncludePath, option.getIncludePaths());
    } catch (BuildException e) {
      //show error
      e.printStackTrace();
    }
  }

  /**
   * Adds new Library for the Linker's Libraries Option.
   *
   * @param cf IConfiguration Build configuration
   * @param cfTool ITool Tool
   * @param option Tool Option type
   * @param newLibrary Library
   */
  private static boolean addLibraryToToolOption(IConfiguration cf, ITool cfTool, IOption option, String newLibrary) {
    try {
      if(option != null) {
        //add library only if it does not exists
        String[] libraries = option.getLibraries();
        for (String lib : libraries) {
          if (lib.equalsIgnoreCase(newLibrary)) {
            return false;
          }
        }
        //add a new library to linker's Libraries option.
        addInputToToolOption(cf, cfTool, option, newLibrary, libraries);
      }
    } catch (BuildException e) {
      //show error
      e.printStackTrace();
    }
    return true;
  }

  /**
   * Removes a new Library from the Linker's Libraries Option.
   *
   * @param cf IConfiguration Build configuration
   * @param cfTool ITool Tool
   * @param option Tool Option type
   * @param removeLibrary Library
   */
  private static void removeLibraryFromToolOption(IConfiguration cf, ITool cfTool, IOption option, String removeLibrary) {
    try {
      //remove a library from linker's Libraries option.
      removeInputFromToolOption(cf, cfTool, option, removeLibrary, option.getLibraries());
    } catch (BuildException e) {
      //show error
      e.printStackTrace();
    }
  }

  //Works only if Eclipse Bugzilla Bug 321040 fix is applied
  /**
   * Adds new Library search path for the Linker's Library search path Option.
   *
   * @param cf IConfiguration Build configuration
   * @param cfTool ITool Tool
   * @param option Tool Option type
   * @param newLibraryPath Library search path
   */
  private static boolean addLibrarySearchPathToToolOption(IConfiguration cf, ITool cfTool, IOption option, String newLibraryPath) {
    try {
      if(option != null) {
        //add path only if it does not exists
        String[] libPaths = option.getLibraryPaths();
        for (String libPath : libPaths) {
          if (libPath.equalsIgnoreCase(newLibraryPath)) {
            return false;
          }
        }
        //add a new library path to linker's Library search path option.
        addInputToToolOption(cf, cfTool, option, newLibraryPath, libPaths);
      }
    } catch (BuildException e) {
      //show error
      e.printStackTrace();
    }
    return true;
  }

  /**
   * Removes a Library search path from the Linker's Library search path Option.
   * Since CDT 8.0 (Bugzilla Bug 321040)
   *
   * @param cf IConfiguration Build configuration
   * @param cfTool ITool Tool
   * @param option Tool Option type
   * @param removeSearchPath Library search path
   */
  private static void removeLibrarySearchPathFromToolOption(IConfiguration cf, ITool cfTool, IOption option, String removeSearchPath) {
    try {
      //remove a library path from linker's Library search path option.
      removeInputFromToolOption(cf, cfTool, option, removeSearchPath, option.getLibraryPaths());
    } catch (BuildException e) {
      //show error
      e.printStackTrace();
    }
  }

  /**
   * Adds a new value to specific Option.
   *
   * @param cf IConfiguration Build configuration
   * @param cfTool ITool Tool
   * @param option Tool Option type
   * @param newValue New value to be added to the Option type
   * @param existingValues Existing Option type values
   */
  private static void addInputToToolOption(IConfiguration cf, ITool cfTool, IOption option, String newValue, String[] existingValues) {
    //if Option type is found
    if (option != null) {
      //append new value with existing values
      String[] newValues = addNewPathToExistingPathList(existingValues, newValue);
      //set new values array for the option for the given build configuration
      ManagedBuildManager.setOption(cf, cfTool, option, newValues);
    }
    else{
      //log error
    }
  }

  /**
   * Removes a value from a specific Option.
   *
   * @param cf IConfiguration Build configuration
   * @param cfTool ITool Tool
   * @param option Tool Option type
   * @param removeValue Value to be removed from the Option type
   * @param existingValues Existing Option type values
   */
  private static void removeInputFromToolOption(IConfiguration cf, ITool cfTool, IOption option, String removeValue, String[] existingValues) {
    //if Option type is found
    if (option != null) {
      //check that list has values
      if(existingValues.length>0) {
        //remove value from existing values
        String[] newValues = removePathFromExistingPathList(existingValues, removeValue);
        //set new values array for the option for the given build configuration
        ManagedBuildManager.setOption(cf, cfTool, option, newValues);
      }
    }
    else{
      //log error
    }
  }

  /**
   * Return LLVM front-end according to the input type.
   * @param cf IConfiguration Build configuration
   * @return ITool LLVM front-end
   */
  private static ITool getLlvmFrontEnd(IConfiguration cf) {
    //get LLVM front-end according to the input type
    for(int i=0; i<inputTypes.length; i++) {
      ITool tool = getIToolByInputType(cf, inputTypes[i]);
      if (tool != null) {
        return tool;
      }
    }
    return null;
  }

  /**
   * Returns LLVM linker.
   *
   * @param cf IConfiguration Build configuration
   * @return ITool LLVM linker
   */
  private static ITool getLlvmLinker(IConfiguration cf) {
    //get LLVM linker
    return getIToolByInputType(cf, linkerInputType);
  }

  /**
   * Returns ITool associated with the input extension.
   *
   * @param cf IConfiguration Build configuration
   * @param ext input extension associated with ITool
   * @return ITool Tool that matches input extension
   */
  private static ITool getIToolByInputType(IConfiguration cf, String ext) {
    //get ITool associated with the input extension
    return cf.getToolFromInputExtension(ext);
  }

  /**
   * Returns LLVM front-end Include path Option type.
   *
   * @param cf IConfiguration Project build configuration
   * @return IOption Tool option type
   */
  private static IOption getLlvmFrontEndIncludePathOption(IConfiguration cf) {
    //get llvm front-end
    ITool cfTool = getLlvmFrontEnd(cf);
    //get option id for include paths
    String includeOptionId = getOptionId(cfTool, IOption.INCLUDE_PATH);
    return getIToolPathOption(cfTool, includeOptionId);
  }

  /**
   * Returns LLVM Linker Libraries Option type.
   *
   * @param cf IConfiguration Project build configuration
   * @return IOption Tool option type
   */
  private static IOption getLlvmLinkerLibrariesOption(IConfiguration cf) {
    //get llvm linker
    ITool cfTool = getLlvmLinker(cf);
    //get option id for libraries
    String libOptionId = getOptionId(cfTool, IOption.LIBRARIES);
    return getIToolPathOption(cfTool, libOptionId);
  }

  /**
   * Returns LLVM Linker Library search path Option type.
   *
   * @param cf IConfiguration Project build configuration
   * @return IOption Tool option type
   */
  private static IOption getLlvmLinkerLibrarySearchPathOption(IConfiguration cf) {
    //get ITool associated with the input extension
    ITool cfTool = cf.getToolFromInputExtension(linkerInputType);
    //get option id for library paths
    String libDirOptionId = getOptionId(cfTool, IOption.LIBRARY_PATHS);
    return getIToolPathOption(cfTool, libDirOptionId);
  }

  /**
   * Returns Tool's option id.
   *
   * @param cfTool ITool Tool
   * @param optionValueType Option's value type.
   * @return optionId Tool's option id.
   */
  private static String getOptionId(ITool cfTool, int optionValueType) {
    String optionId = null;
    //get all Tool options.
    IOption[] options = cfTool.getOptions();
    for (IOption opt : options) {
      try {
        //try to match option value type
        if(opt.getValueType()==optionValueType) {
          //get option id
          optionId = opt.getId();
          break;
        }
      } catch (BuildException e) {
        //log error
      }
    } 
    return optionId;
  }

  /**
   * Returns Tool's Option type by Id.
   *
   * @param cfTool ITool Tool
   * @param optionId String Tool option type id
   * @return IOption Tool option type
   */
  private static IOption getIToolPathOption(ITool cfTool, String optionId) {
    //get path option with specific id for the ITool
    return cfTool.getOptionById(optionId);
  }

  /**
   * Adds one or more paths to the list of paths.
   *
   * @param existingPaths Existing list of paths to add to
   * @param newPath New path to add. May include multiple directories with a path delimiter java.io.File.pathSeparator
   * (usually semicolon (Win) or colon (Linux/Mac), OS specific)
   * @return String[] List that includes existing paths as well as new paths.
   */
  public static String[] addNewPathToExistingPathList(String[] existingPaths, String newPath) {
    String pathSep = java.io.File.pathSeparator;  // semicolon for windows, colon for Linux/Mac
    List<String> newPathList = new ArrayList<String>();
    String path;
    //adds existing paths to new paths list
    for (int i = 0; i < existingPaths.length; i++) {
      path = existingPaths[i];
      newPathList.add(path);
    }
    //separates new path if it has multiple paths separated by a path separator
    String[] newPathArray = newPath.split(pathSep);
    for (int i = 0; i < newPathArray.length; i++) {
      path = newPathArray[i];
      newPathList.add(path);
    }
    //creates a new list that includes all existing paths as well as new paths
    String[] newArray = newPathList.toArray(new String[0]);
    return newArray;
  }

  /**
   * Removes one path from the list of paths.
   *
   * @param existingPaths Existing list of paths to remove from
   * @param removePath Path to be removed.
   * @return String[] List that includes existing paths without the path that was removed.
   */
  public static String[] removePathFromExistingPathList(String[] existingPaths, String removePath) {
    List<String> newPathList = new ArrayList<String>();
    String path;
    //adds existing paths to new paths list
    for (int i = 0; i < existingPaths.length; i++) {
      path = existingPaths[i];
      newPathList.add(path);
    }
    newPathList.remove(removePath);
    //creates a new list that includes all existing paths except the removed path
    String[] newArray = newPathList.toArray(new String[0]);
    return newArray;
  }

  /**
   * Split paths to a String array.
   *
   * @param str String of paths separated by a path separator.
   * @return String array containing multiple paths.
   */
  public static String[] stringToArray(String str) {
    return str.split(System.getProperty("path.separator")); //$NON-NLS-1$
  }

  /**
   * Append an array of Strings to a String separated by a path separator.
   *
   * @param array An array of Strings.
   * @return string which contains all indexes of
   * a String array separated by a path separator.
   */
  public static String arrayToString(String[] array) {
    StringBuffer sB = new StringBuffer();
    //if array isn't empty and doesn't contain an empty String
    if (array.length>0 /*&& !array[0].equals("")*/) {
      for (String i : array) {
        sB.append(i);
        sB.append(System.getProperty("path.separator")); //$NON-NLS-1$
      }     
    }
    return sB.toString();
  }

  /**
   * Checks if a file path exists.
   *
   * @return boolean True if the file exists.
   */
  private static boolean pathExists(String path) {
    //return true if path exists.
    return new File(path).exists();
  }

  /**
   * Get all include paths in a String array.
   *
   * @return String[] A String array of include paths
   */
  private static String[] getAllIncludePaths() {
    //get all include paths
    String includePathList = LlvmPreferenceStore.getIncludePath();
    //split paths to String array
    String[] incPaths = includePathList.split(Separators.getPathSeparator());
    return incPaths;
  }

  /**
   * Get all libraries in a String array.
   *
   * @return String[] A String array of libraries
   */
  private static String[] getAllLibraries() {
    //get all libraries
    String libList = LlvmPreferenceStore.getLibraries();
    //split values to String array
    String[] libs = libList.split(Separators.getPathSeparator());
    return libs;
  }

  /**
   * Get all library paths in a String array.
   *
   * @return String[] A String array of library paths
   */
  private static String[] getAllLibraryPaths() {
    //get all library paths
    String libPathList = LlvmPreferenceStore.getLibraryPath();
    //split paths to String array
    String[] libPaths = libPathList.split(Separators.getPathSeparator());
    return libPaths;
  }
 
  /**
   * Add all include paths found in LLVM preference page to
   * every project's build configurations.
   */
  public static void addAllIncludesToBuildConf() {
    String[] includes = getAllIncludePaths();
    for(String inc : includes) {
      addLlvmIncludePath(inc);     
    }
  }
 
  /**
   * Add all libraries found in LLVM preference page to
   * every project's build configurations.
   */
  public static void addAllLibsToBuildConf() {
    String[] libs = getAllLibraries();
    for(String lib : libs) {
//      if (!lib.equalsIgnoreCase("stdc++")) { //$NON-NLS-1$ //C++ specific
        addLlvmLib(lib);
//      }
    }
  }
 
  /**
   * Add all library paths found in LLVM preference page to
   * every project's build configurations.
   */
  public static void addAllLibPathsToBuildConf() {
    String[] libPaths = getAllLibraryPaths();
    for(String libPath : libPaths) {
//      if (!libPath.equalsIgnoreCase(LlvmEnvironmentVariableSupplier.getMinGWStdLib())) { //C++ specific
        addLlvmLibraryPath(libPath)
//      }
    }
  }

  //temporary hack until scanner discovery works
  public static void addMissingCppIncludesForMingw() {
    //try to find mingw path from MingwEnvironmentVariableSupplier
    IConfigurationEnvironmentVariableSupplier mingwEnvironmentVariables =
      new MingwEnvironmentVariableSupplier();
    IBuildEnvironmentVariable mingwPath = mingwEnvironmentVariables.getVariable(
        "PATH", null, null); //$NON-NLS-1$
    //may contain multiple paths therefore must be separated
    String[] mingwPaths = mingwPath.getValue().split(Separators.getPathSeparator());
    //bin folder is appended so it must be removed
    for(int i=0; i<mingwPaths.length; i++) {
      if(mingwPaths[i].contains("bin")) { //$NON-NLS-1$
        mingwPaths[i] = mingwPaths[i].replace("bin", ""); //$NON-NLS-1$ //$NON-NLS-2$
      }
    }
    //find the correct path
    File f1 = null;
    String rightPath = null;
    findPath: for(int i=0; i<mingwPaths.length; i++) {
      f1 = new File(mingwPaths[i]+"lib/gcc/mingw32"); //$NON-NLS-1$
      if (f1.exists()) {
        rightPath = f1.getAbsolutePath();
        break findPath;
      }
    }
    if (rightPath!=null && f1!=null) {
      //get the first directory (mingw version)
      f1 = f1.listFiles()[0];
      //add three includes if they exist
      File testFile = new File(f1.getAbsolutePath()+"/include/c++"); //$NON-NLS-1$
      if (testFile.exists()) {
        LlvmPreferenceStore.appendIncludePath(testFile.getAbsolutePath());
        addPathToToolOptionCppProjects(testFile.getAbsolutePath(), INCLUDE);
      }
      testFile = new File(f1.getAbsolutePath()+"/include/c++/mingw32"); //$NON-NLS-1$
      if (testFile.exists()) {
        LlvmPreferenceStore.appendIncludePath(testFile.getAbsolutePath());
        addPathToToolOptionCppProjects(testFile.getAbsolutePath(), INCLUDE);
      }
      testFile = new File(f1.getAbsolutePath()+"/include/c++/backward"); //$NON-NLS-1$
      if (testFile.exists()) {
        LlvmPreferenceStore.appendIncludePath(testFile.getAbsolutePath());
        addPathToToolOptionCppProjects(testFile.getAbsolutePath(), INCLUDE);
      }
        //inform LLVM environment variable supplier that there has been a change
        LlvmEnvironmentVariableSupplier.notifyPreferenceChange();
    }
  }
 
}
TOP

Related Classes of org.eclipse.cdt.managedbuilder.llvm.util.LlvmToolOptionPathUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.