logic: source groups for project settings
* project can not have multiple source groups with different types * language of a project is now inferred from source groups * setting global NameHierarchy delimiter of first sourceGroup in project * added project settings migrations for source groups * Add Settings Migration classes (MoveKey, DeleteKey, Lambda) * Update sample projects with migrations * added method to config to retrieve sublevel key names * implemented recursive removing of keys in settings * moved project files out of top level * removed solution parsing code as it is not used anymore fortune cookie message = The secret of getting ahead is getting started.
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
#include "utility/ConfigManager.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "tinyxml/tinyxml.h"
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
#include "utility/utility.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
std::shared_ptr<ConfigManager> ConfigManager::createEmpty()
|
||||
@@ -222,6 +225,10 @@ void ConfigManager::setValues(const std::string& key, const std::vector<bool>& v
|
||||
|
||||
void ConfigManager::removeValues(const std::string& key)
|
||||
{
|
||||
for (const std::string& sublevelKey: getSublevelKeys(key))
|
||||
{
|
||||
removeValues(sublevelKey);
|
||||
}
|
||||
m_values.erase(key);
|
||||
}
|
||||
|
||||
@@ -232,6 +239,24 @@ bool ConfigManager::isValueDefined(const std::string& key) const
|
||||
return (it != m_values.end());
|
||||
}
|
||||
|
||||
std::vector<std::string> ConfigManager::getSublevelKeys(const std::string& key) const
|
||||
{
|
||||
std::set<std::string> keys;
|
||||
for (std::multimap<std::string, std::string>::const_iterator it = m_values.begin(); it != m_values.end(); it++)
|
||||
{
|
||||
if (utility::isPrefix(key, it->first))
|
||||
{
|
||||
size_t startPos = it->first.find("/", key.size());
|
||||
if (startPos == key.size())
|
||||
{
|
||||
std::string sublevelKey = it->first.substr(0, it->first.find("/", startPos + 1));
|
||||
keys.insert(sublevelKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
return utility::toVector(keys);
|
||||
}
|
||||
|
||||
bool ConfigManager::load(const std::shared_ptr<TextAccess> textAccess)
|
||||
{
|
||||
std::string text = textAccess->getText();
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
void removeValues(const std::string& key);
|
||||
|
||||
bool isValueDefined(const std::string& key) const;
|
||||
std::vector<std::string> getSublevelKeys(const std::string& key) const;
|
||||
|
||||
bool load(const std::shared_ptr<TextAccess> textAccess);
|
||||
void save(const std::string filepath);
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
#include "utility/file/FileManager.h"
|
||||
|
||||
#include <functional>
|
||||
#include <set>
|
||||
|
||||
#include "utility/file/FileSystem.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/utility.h"
|
||||
|
||||
FileManager::FileManager()
|
||||
@@ -15,51 +13,18 @@ FileManager::~FileManager()
|
||||
{
|
||||
}
|
||||
|
||||
void FileManager::setPaths(
|
||||
std::vector<FilePath> sourcePaths,
|
||||
std::vector<FilePath> headerPaths,
|
||||
std::vector<FilePath> excludePaths,
|
||||
std::vector<std::string> sourceExtensions
|
||||
void FileManager::update(
|
||||
const std::vector<FilePath>& sourcePaths,
|
||||
const std::vector<FilePath>& excludePaths,
|
||||
const std::vector<std::string>& sourceExtensions
|
||||
){
|
||||
m_sourcePaths = sourcePaths;
|
||||
m_headerPaths = makeCanonical(headerPaths);
|
||||
m_excludePaths = makeCanonical(excludePaths);
|
||||
m_sourceExtensions = sourceExtensions;
|
||||
}
|
||||
|
||||
FileManager::FileSets FileManager::fetchFilePaths(const std::vector<FileInfo>& oldFileInfos)
|
||||
{
|
||||
m_filesInfos.clear();
|
||||
for (FileInfo oldFileInfo: oldFileInfos)
|
||||
{
|
||||
m_filesInfos.emplace(oldFileInfo.path, oldFileInfo);
|
||||
}
|
||||
m_allSourceFilePaths.clear();
|
||||
|
||||
FileSets fileSets;
|
||||
|
||||
// update old files that have been modified
|
||||
// remove old files that don't exist anymore
|
||||
for (std::map<FilePath, FileInfo>::iterator it = m_filesInfos.begin(); it != m_filesInfos.end(); it++)
|
||||
{
|
||||
const FilePath& filePath = it->first;
|
||||
if (filePath.exists() && !hasSourceFilePath(filePath))
|
||||
{
|
||||
FileInfo newFileInfo = FileSystem::getFileInfoForPath(filePath);
|
||||
|
||||
if (newFileInfo.lastWriteTime > it->second.lastWriteTime)
|
||||
{
|
||||
it->second.lastWriteTime = newFileInfo.lastWriteTime;
|
||||
fileSets.updatedFiles.insert(filePath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fileSets.removedFiles.insert(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<FileInfo> fileInfos = FileSystem::getFileInfosFromPaths(m_sourcePaths, m_sourceExtensions);
|
||||
for (FileInfo fileInfo: fileInfos)
|
||||
for (FileInfo fileInfo: FileSystem::getFileInfosFromPaths(m_sourcePaths, m_sourceExtensions))
|
||||
{
|
||||
const FilePath& filePath = fileInfo.path;
|
||||
if (isExcluded(filePath))
|
||||
@@ -67,33 +32,8 @@ FileManager::FileSets FileManager::fetchFilePaths(const std::vector<FileInfo>& o
|
||||
continue;
|
||||
}
|
||||
|
||||
fileSets.allSourceFilePaths.insert(filePath);
|
||||
|
||||
std::map<FilePath, FileInfo>::iterator it = m_filesInfos.find(filePath);
|
||||
if (it != m_filesInfos.end())
|
||||
{
|
||||
fileSets.removedFiles.erase(filePath);
|
||||
if (fileInfo.lastWriteTime > it->second.lastWriteTime)
|
||||
{
|
||||
it->second.lastWriteTime = fileInfo.lastWriteTime;
|
||||
fileSets.updatedFiles.insert(filePath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_filesInfos.insert(std::pair<FilePath, FileInfo>(filePath, fileInfo));
|
||||
fileSets.addedFiles.insert(filePath);
|
||||
}
|
||||
m_allSourceFilePaths.insert(filePath);
|
||||
}
|
||||
|
||||
for (const FilePath& filePath : fileSets.removedFiles)
|
||||
{
|
||||
m_filesInfos.erase(filePath);
|
||||
}
|
||||
|
||||
m_sourceFilePaths = fileSets.allSourceFilePaths;
|
||||
|
||||
return fileSets;
|
||||
}
|
||||
|
||||
std::vector<FilePath> FileManager::getSourcePaths() const
|
||||
@@ -101,48 +41,21 @@ std::vector<FilePath> FileManager::getSourcePaths() const
|
||||
return m_sourcePaths;
|
||||
}
|
||||
|
||||
std::set<FilePath> FileManager::getSourceFilePaths() const
|
||||
{
|
||||
std::set<FilePath> sourceFilePaths;
|
||||
for (const FileInfo& fileInfo: FileSystem::getFileInfosFromPaths(m_sourcePaths, m_sourceExtensions))
|
||||
{
|
||||
const FilePath& path = fileInfo.path;
|
||||
bool excluded = false;
|
||||
for (FilePath p: m_excludePaths)
|
||||
{
|
||||
if (p == path || p.contains(path))
|
||||
{
|
||||
excluded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!excluded)
|
||||
{
|
||||
sourceFilePaths.emplace(path);
|
||||
}
|
||||
}
|
||||
return sourceFilePaths;
|
||||
}
|
||||
|
||||
bool FileManager::hasSourceFilePath(const FilePath& filePath) const
|
||||
{
|
||||
if (m_sourceFilePaths.find(filePath) != m_sourceFilePaths.end())
|
||||
if (m_allSourceFilePaths.find(filePath) != m_allSourceFilePaths.end())
|
||||
{
|
||||
for (FilePath p: m_excludePaths)
|
||||
{
|
||||
if (p == filePath || p.contains(filePath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::set<FilePath> FileManager::getAllSourceFilePaths() const
|
||||
{
|
||||
return m_allSourceFilePaths;
|
||||
}
|
||||
|
||||
std::vector<FilePath> FileManager::makeCanonical(const std::vector<FilePath>& filePaths)
|
||||
{
|
||||
std::vector<FilePath> ret;
|
||||
|
||||
@@ -10,47 +10,33 @@
|
||||
class FileManager
|
||||
{
|
||||
public:
|
||||
struct FileSets
|
||||
{
|
||||
std::set<FilePath> addedFiles;
|
||||
std::set<FilePath> updatedFiles;
|
||||
std::set<FilePath> removedFiles;
|
||||
std::set<FilePath> allSourceFilePaths;
|
||||
};
|
||||
|
||||
FileManager();
|
||||
virtual ~FileManager();
|
||||
|
||||
void setPaths(
|
||||
std::vector<FilePath> sourcePaths,
|
||||
std::vector<FilePath> headerPaths,
|
||||
std::vector<FilePath> excludePaths,
|
||||
std::vector<std::string> sourceExtensions
|
||||
void update(
|
||||
const std::vector<FilePath>& sourcePaths,
|
||||
const std::vector<FilePath>& excludePaths,
|
||||
const std::vector<std::string>& sourceExtensions
|
||||
);
|
||||
|
||||
FileSets fetchFilePaths(const std::vector<FileInfo>& oldFileInfos);
|
||||
|
||||
// returns a list of source paths (can be directories) specified in the project settings
|
||||
std::vector<FilePath> getSourcePaths() const;
|
||||
|
||||
// returns a list of paths to all files that reside in the non-excluded source paths
|
||||
std::set<FilePath> getSourceFilePaths() const;
|
||||
|
||||
// checks if file is in non-excluded source directory
|
||||
bool hasSourceFilePath(const FilePath& filePath) const;
|
||||
|
||||
// returns a list of paths to all files that reside in the non-excluded source paths
|
||||
std::set<FilePath> getAllSourceFilePaths() const;
|
||||
|
||||
private:
|
||||
std::vector<FilePath> makeCanonical(const std::vector<FilePath>& filePaths);
|
||||
bool isExcluded(const FilePath& filePath) const;
|
||||
|
||||
std::vector<FilePath> m_sourcePaths;
|
||||
std::vector<FilePath> m_headerPaths;
|
||||
std::vector<FilePath> m_excludePaths;
|
||||
std::vector<std::string> m_sourceExtensions;
|
||||
|
||||
std::map<FilePath, FileInfo> m_filesInfos;
|
||||
|
||||
std::set<FilePath> m_sourceFilePaths;
|
||||
std::set<FilePath> m_allSourceFilePaths;
|
||||
};
|
||||
|
||||
#endif // FILE_MANAGER_H
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
#include "ISolutionParser.h"
|
||||
|
||||
std::string ISolutionParser::getSolutionPath()
|
||||
{
|
||||
return m_solutionPath;
|
||||
}
|
||||
|
||||
std::string ISolutionParser::getToolID() const
|
||||
{
|
||||
return "NONE";
|
||||
}
|
||||
|
||||
void ISolutionParser::openSolutionFile(const std::string& solutionFilePath)
|
||||
{
|
||||
m_solution = loadFile(solutionFilePath);
|
||||
|
||||
size_t pos = solutionFilePath.find_last_of("/");
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
pos = solutionFilePath.find_last_of("\\");
|
||||
}
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
if (pos > 0)
|
||||
{
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
m_solutionPath = solutionFilePath.substr(0, pos);
|
||||
m_solutionName = solutionFilePath.substr(pos);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int ISolutionParser::getSolutionCharCount() const
|
||||
{
|
||||
return m_solution.size();
|
||||
}
|
||||
|
||||
std::string ISolutionParser::loadFile(const std::string& filePath)
|
||||
{
|
||||
std::string file = "";
|
||||
|
||||
std::ifstream ifstream;
|
||||
ifstream.open(filePath);
|
||||
|
||||
if (ifstream.is_open())
|
||||
{
|
||||
file = std::string(std::istreambuf_iterator<char>(ifstream), std::istreambuf_iterator<char>());
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
std::vector<std::string> ISolutionParser::makePathsAbsolute(const std::vector<std::string>& paths)
|
||||
{
|
||||
std::vector<std::string> absolutePaths;
|
||||
|
||||
for (unsigned int i = 0; i < paths.size(); i++)
|
||||
{
|
||||
std::string path = paths[i];
|
||||
|
||||
boost::filesystem::path boostPath(path);
|
||||
if (boostPath.is_relative())
|
||||
{
|
||||
path = m_solutionPath + path;
|
||||
}
|
||||
|
||||
absolutePaths.push_back(path);
|
||||
}
|
||||
|
||||
return absolutePaths;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
#ifndef I_SOLUTION_PARSER_H
|
||||
#define I_SOLUTION_PARSER_H
|
||||
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include "settings/ProjectSettings.h"
|
||||
|
||||
class ISolutionParser
|
||||
{
|
||||
public:
|
||||
ISolutionParser()
|
||||
: m_solutionPath("")
|
||||
, m_solution("")
|
||||
{};
|
||||
virtual ~ISolutionParser(){};
|
||||
|
||||
virtual std::string getToolID() const;
|
||||
|
||||
void openSolutionFile(const std::string& solutionFilePath);
|
||||
unsigned int getSolutionCharCount() const;
|
||||
|
||||
virtual std::string getSolutionName() = 0; // to be overwritten to account for different file endings
|
||||
std::string getSolutionPath();
|
||||
|
||||
virtual std::vector<std::string> getProjects() = 0;
|
||||
virtual std::vector<std::string> getProjectFiles() = 0;
|
||||
virtual std::vector<std::string> getProjectItems() = 0;
|
||||
virtual std::vector<std::string> getCompileFlags() = 0;
|
||||
|
||||
virtual std::shared_ptr<ProjectSettings> getProjectSettings(const std::string& solutionFilePath) = 0;
|
||||
|
||||
virtual std::string getIdeName() const = 0;
|
||||
virtual std::string getButtonText() const = 0;
|
||||
virtual std::string getDescription() const = 0;
|
||||
virtual std::string getIconPath() const = 0;
|
||||
virtual std::string getFileExtension() const = 0;
|
||||
|
||||
protected:
|
||||
std::string loadFile(const std::string& filePath);
|
||||
|
||||
std::vector<std::string> makePathsAbsolute(const std::vector<std::string>& paths);
|
||||
|
||||
std::string m_solutionName;
|
||||
std::string m_solutionPath;
|
||||
std::string m_solution;
|
||||
};
|
||||
|
||||
#endif // I_SOLUTION_PARSER_H
|
||||
@@ -1,18 +0,0 @@
|
||||
#include "SolutionParserCMake.h"
|
||||
|
||||
SolutionParserCMake::SolutionParserCMake()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SolutionParserCMake::~SolutionParserCMake()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserCMake::getProjects()
|
||||
{
|
||||
std::vector<std::string> projects;
|
||||
|
||||
return projects;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#ifndef SOLUTION_PARSER_C_MAKE_H
|
||||
#define SOLUTION_PARSER_C_MAKE_H
|
||||
|
||||
#include "ISolutionParser.h"
|
||||
|
||||
class SolutionParserCMake : public ISolutionParser
|
||||
{
|
||||
public:
|
||||
SolutionParserCMake();
|
||||
virtual ~SolutionParserCMake();
|
||||
|
||||
virtual std::vector<std::string> getProjects();
|
||||
virtual std::vector<std::string> getProjectFiles();
|
||||
};
|
||||
|
||||
#endif // SOLUTION_PARSER_C_MAKE_H
|
||||
@@ -1,228 +0,0 @@
|
||||
#include "SolutionParserCodeBlocks.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "SolutionParserUtility.h"
|
||||
|
||||
#include "settings/CxxProjectSettings.h"
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
SolutionParserCodeBlocks::SolutionParserCodeBlocks()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SolutionParserCodeBlocks::~SolutionParserCodeBlocks()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string SolutionParserCodeBlocks::getToolID() const
|
||||
{
|
||||
return "cb";
|
||||
}
|
||||
|
||||
std::string SolutionParserCodeBlocks::getSolutionName()
|
||||
{
|
||||
std::string result = "";
|
||||
|
||||
if (m_solutionName.size() > 0)
|
||||
{
|
||||
size_t pos = m_solutionName.find(".cbp");
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
result = m_solutionName.substr(0, pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = m_solution;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserCodeBlocks::getProjects()
|
||||
{
|
||||
std::vector<std::string> projectFiles;
|
||||
|
||||
projectFiles.push_back(m_solutionName);
|
||||
|
||||
return projectFiles;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserCodeBlocks::getProjectFiles()
|
||||
{
|
||||
std::vector<std::string> projectFiles;
|
||||
std::vector<std::string> projectFilesNames = getProjects();
|
||||
|
||||
projectFiles.push_back(loadFile(m_solutionPath + m_solutionName));
|
||||
|
||||
return projectFiles;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserCodeBlocks::getProjectItems()
|
||||
{
|
||||
std::vector<std::string> projectItems;
|
||||
|
||||
std::vector<std::string> projectFilesNames = getProjects();
|
||||
std::vector<std::string> projectFiles = getProjectFiles();
|
||||
|
||||
std::vector<std::string> validFileExtensions;
|
||||
validFileExtensions.push_back(".c");
|
||||
validFileExtensions.push_back(".cpp");
|
||||
validFileExtensions.push_back(".h");
|
||||
validFileExtensions.push_back(".hpp");
|
||||
|
||||
for (unsigned int i = 0; i < projectFiles.size(); i++)
|
||||
{
|
||||
TiXmlDocument doc;
|
||||
doc.Parse(projectFiles[i].c_str(), 0, TIXML_ENCODING_UTF8);
|
||||
|
||||
std::string error = doc.ErrorDesc();
|
||||
|
||||
if (error.length() > 0)
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to parse project file " << i << ": " << error);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<TiXmlElement*> nodes = SolutionParserUtility::getAllTagsByNameWithAttribute(doc.RootElement(), "Unit", "filename");
|
||||
|
||||
if (nodes.size() > 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < nodes.size(); i++)
|
||||
{
|
||||
std::string text = nodes[i]->Attribute("filename");
|
||||
|
||||
if (SolutionParserUtility::checkValidFileExtension(text, validFileExtensions))
|
||||
{
|
||||
if (boost::filesystem::exists(text))
|
||||
{
|
||||
projectItems.push_back(text);
|
||||
continue;
|
||||
}
|
||||
|
||||
text = m_solutionPath + "/" + text;
|
||||
|
||||
projectItems.push_back(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::set<std::string> s(projectItems.begin(), projectItems.end());
|
||||
projectItems.assign(s.begin(), s.end());
|
||||
|
||||
projectItems = SolutionParserUtility::resolveEnvironmentVariables(projectItems);
|
||||
projectItems = makePathsAbsolute(projectItems);
|
||||
|
||||
return projectItems;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserCodeBlocks::getIncludePaths()
|
||||
{
|
||||
std::vector<std::string> includePaths;
|
||||
|
||||
std::vector<std::string> projectFiles = getProjectFiles();
|
||||
|
||||
std::vector<std::string> validExtensions;
|
||||
validExtensions.push_back(".c");
|
||||
validExtensions.push_back(".cpp");
|
||||
validExtensions.push_back(".h");
|
||||
validExtensions.push_back(".hpp");
|
||||
|
||||
for (unsigned int i = 0; i < projectFiles.size(); i++)
|
||||
{
|
||||
TiXmlDocument doc;
|
||||
doc.Parse(projectFiles[i].c_str(), 0, TIXML_ENCODING_UTF8);
|
||||
|
||||
std::string error = doc.ErrorDesc();
|
||||
|
||||
if (error.length() > 0)
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to parse project file " << i << ": " << error);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<TiXmlElement*> nodes = SolutionParserUtility::getAllTagsByNameWithAttribute(doc.RootElement(), "Add", "directory");
|
||||
|
||||
if (nodes.size() > 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < nodes.size(); i++)
|
||||
{
|
||||
std::string text = nodes[i]->Attribute("directory");
|
||||
|
||||
includePaths.push_back(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::set<std::string> s(includePaths.begin(), includePaths.end());
|
||||
includePaths.assign(s.begin(), s.end());
|
||||
|
||||
includePaths = SolutionParserUtility::resolveEnvironmentVariables(includePaths);
|
||||
includePaths = makePathsAbsolute(includePaths);
|
||||
|
||||
return includePaths;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserCodeBlocks::getCompileFlags()
|
||||
{
|
||||
std::vector<std::string> compilerFlags;
|
||||
|
||||
return compilerFlags;
|
||||
}
|
||||
|
||||
std::shared_ptr<ProjectSettings> SolutionParserCodeBlocks::getProjectSettings(const std::string& solutionFilePath)
|
||||
{
|
||||
openSolutionFile(solutionFilePath);
|
||||
|
||||
std::shared_ptr<CxxProjectSettings> settings = std::make_shared<CxxProjectSettings>(getSolutionName(), getSolutionPath());
|
||||
settings->setVisualStudioSolutionPath(solutionFilePath); // why is it called vs solution if it is used for codeblocks as well?
|
||||
|
||||
std::vector<std::string> sourceFiles = getProjectItems();
|
||||
std::vector<FilePath> sourcePaths;
|
||||
for (const std::string& p : sourceFiles)
|
||||
{
|
||||
sourcePaths.push_back(FilePath(p));
|
||||
}
|
||||
|
||||
std::vector<std::string> includePaths = getIncludePaths();
|
||||
std::vector<FilePath> headerPaths;
|
||||
for (const std::string& p : includePaths)
|
||||
{
|
||||
headerPaths.push_back(FilePath(p));
|
||||
}
|
||||
|
||||
settings->setSourcePaths(sourcePaths);
|
||||
settings->setHeaderSearchPaths(headerPaths);
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
std::string SolutionParserCodeBlocks::getIdeName() const
|
||||
{
|
||||
return "Code Blocks";
|
||||
}
|
||||
|
||||
std::string SolutionParserCodeBlocks::getButtonText() const
|
||||
{
|
||||
return "from Code\nBlocks Project";
|
||||
}
|
||||
|
||||
std::string SolutionParserCodeBlocks::getDescription() const
|
||||
{
|
||||
return "idunno";
|
||||
}
|
||||
|
||||
std::string SolutionParserCodeBlocks::getIconPath() const
|
||||
{
|
||||
return "icon/project_vs_256_256.png";
|
||||
}
|
||||
|
||||
std::string SolutionParserCodeBlocks::getFileExtension() const
|
||||
{
|
||||
return ".cbp";
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#ifndef SOLUTION_PARSER_CODE_BLOCKS_H
|
||||
#define SOLUTION_PARSER_CODE_BLOCKS_H
|
||||
|
||||
#include "ISolutionParser.h"
|
||||
|
||||
#include "tinyxml/tinyxml.h"
|
||||
|
||||
class SolutionParserCodeBlocks : public ISolutionParser
|
||||
{
|
||||
public:
|
||||
SolutionParserCodeBlocks();
|
||||
virtual ~SolutionParserCodeBlocks();
|
||||
|
||||
virtual std::string getToolID() const;
|
||||
|
||||
virtual std::string getSolutionName();
|
||||
|
||||
virtual std::vector<std::string> getProjects();
|
||||
virtual std::vector<std::string> getProjectFiles();
|
||||
virtual std::vector<std::string> getProjectItems();
|
||||
virtual std::vector<std::string> getIncludePaths();
|
||||
virtual std::vector<std::string> getCompileFlags();
|
||||
|
||||
virtual std::shared_ptr<ProjectSettings> getProjectSettings(const std::string& solutionFilePath);
|
||||
|
||||
virtual std::string getIdeName() const;
|
||||
virtual std::string getButtonText() const;
|
||||
virtual std::string getDescription() const;
|
||||
virtual std::string getIconPath() const;
|
||||
virtual std::string getFileExtension() const;
|
||||
};
|
||||
|
||||
#endif // SOLUTION_PARSER_CODE_BLOCKS_H
|
||||
@@ -1,143 +0,0 @@
|
||||
#include "SolutionParserManager.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
SolutionParserManager::SolutionParserManager()
|
||||
: m_solutionParsers()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SolutionParserManager::~SolutionParserManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SolutionParserManager::pushSolutionParser(const std::shared_ptr<ISolutionParser>& solutionParser)
|
||||
{
|
||||
m_solutionParsers.push_back(solutionParser);
|
||||
}
|
||||
|
||||
bool SolutionParserManager::canParseSolution(const std::string& ideId) const
|
||||
{
|
||||
std::string lIdeId = ideId;
|
||||
boost::algorithm::to_lower(lIdeId);
|
||||
|
||||
for (unsigned int i = 0; i < m_solutionParsers.size(); i++)
|
||||
{
|
||||
std::string parserIdeId = m_solutionParsers[i]->getToolID();
|
||||
boost::algorithm::to_lower(parserIdeId);
|
||||
|
||||
if (lIdeId == parserIdeId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<ProjectSettings> SolutionParserManager::getProjectSettings(const std::string& ideId, const std::string& solutionFilePath) const
|
||||
{
|
||||
std::string lIdeId = ideId;
|
||||
boost::algorithm::to_lower(lIdeId);
|
||||
|
||||
for (unsigned int i = 0; i < m_solutionParsers.size(); i++)
|
||||
{
|
||||
std::string parserIdeId = m_solutionParsers[i]->getToolID();
|
||||
boost::algorithm::to_lower(parserIdeId);
|
||||
|
||||
if (lIdeId == parserIdeId)
|
||||
{
|
||||
return m_solutionParsers[i]->getProjectSettings(solutionFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR_STREAM(<< "Solution type is unknown");
|
||||
|
||||
return std::shared_ptr<ProjectSettings>();
|
||||
}
|
||||
|
||||
unsigned int SolutionParserManager::getParserCount() const
|
||||
{
|
||||
return m_solutionParsers.size();
|
||||
}
|
||||
|
||||
std::string SolutionParserManager::getParserName(const unsigned int idx) const
|
||||
{
|
||||
if (checkIndex(idx))
|
||||
{
|
||||
return m_solutionParsers[idx]->getIdeName();
|
||||
}
|
||||
|
||||
LOG_WARNING_STREAM(<< "Index is out of range, was " << idx << ". Max is " << m_solutionParsers.size() - 1);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string SolutionParserManager::getParserButtonText(const unsigned int idx) const
|
||||
{
|
||||
if (checkIndex(idx))
|
||||
{
|
||||
return m_solutionParsers[idx]->getButtonText();
|
||||
}
|
||||
|
||||
LOG_WARNING_STREAM(<< "Index is out of range, was " << idx << ". Max is " << m_solutionParsers.size() - 1);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string SolutionParserManager::getParserDescription(const unsigned int idx) const
|
||||
{
|
||||
if (checkIndex(idx))
|
||||
{
|
||||
return m_solutionParsers[idx]->getDescription();
|
||||
}
|
||||
|
||||
LOG_WARNING_STREAM(<< "Index is out of range, was " << idx << ". Max is " << m_solutionParsers.size() - 1);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string SolutionParserManager::getParserFileEnding(const unsigned int idx) const
|
||||
{
|
||||
if (checkIndex(idx))
|
||||
{
|
||||
return m_solutionParsers[idx]->getFileExtension();
|
||||
}
|
||||
|
||||
LOG_WARNING_STREAM(<< "Index is out of range, was " << idx << ". Max is " << m_solutionParsers.size() - 1);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string SolutionParserManager::getParserIdeId(const unsigned int idx) const
|
||||
{
|
||||
if (checkIndex(idx))
|
||||
{
|
||||
return m_solutionParsers[idx]->getToolID();
|
||||
}
|
||||
|
||||
LOG_WARNING_STREAM(<< "Index is out of range, was " << idx << ". Max is " << m_solutionParsers.size() - 1);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string SolutionParserManager::getIconPath(const unsigned int idx) const
|
||||
{
|
||||
if (checkIndex(idx))
|
||||
{
|
||||
return m_solutionParsers[idx]->getIconPath();
|
||||
}
|
||||
|
||||
LOG_WARNING_STREAM(<< "Index is out of range, was " << idx << ". Max is " << m_solutionParsers.size() - 1);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool SolutionParserManager::checkIndex(const unsigned int idx) const
|
||||
{
|
||||
return (idx < m_solutionParsers.size());
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#ifndef SOLUTION_PARSER_MANAGER_H
|
||||
#define SOLUTION_PARSER_MANAGER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "ISolutionParser.h"
|
||||
|
||||
class SolutionParserManager
|
||||
{
|
||||
public:
|
||||
SolutionParserManager();
|
||||
~SolutionParserManager();
|
||||
|
||||
void pushSolutionParser(const std::shared_ptr<ISolutionParser>& solutionParser);
|
||||
|
||||
bool canParseSolution(const std::string& ideId) const;
|
||||
|
||||
std::shared_ptr<ProjectSettings> getProjectSettings(const std::string& ideId, const std::string& solutionFilePath) const;
|
||||
|
||||
unsigned int getParserCount() const;
|
||||
|
||||
std::string getParserName(const unsigned int idx) const;
|
||||
std::string getParserButtonText(const unsigned int idx) const;
|
||||
std::string getParserDescription(const unsigned int idx) const;
|
||||
std::string getParserFileEnding(const unsigned int idx) const;
|
||||
std::string getParserIdeId(const unsigned int idx) const;
|
||||
std::string getIconPath(const unsigned int idx) const;
|
||||
|
||||
private:
|
||||
bool checkIndex(const unsigned int idx) const;
|
||||
|
||||
std::vector<std::shared_ptr<ISolutionParser>> m_solutionParsers;
|
||||
};
|
||||
|
||||
#endif // SOLUTION_PARSER_MANAGER_H
|
||||
@@ -1,328 +0,0 @@
|
||||
#include "SolutionParserUtility.h"
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
#include "utility/messaging/type/MessageStatus.h"
|
||||
|
||||
#include "boost/filesystem/path.hpp"
|
||||
#include "boost/filesystem.hpp"
|
||||
|
||||
std::vector<std::string> SolutionParserUtility::m_ideMacros;
|
||||
std::map<std::string, std::string> SolutionParserUtility::m_ideMacroValues;
|
||||
|
||||
TiXmlElement* SolutionParserUtility::getFirstTagByName(TiXmlElement* root, const std::string& tag)
|
||||
{
|
||||
TiXmlElement* element = root;
|
||||
|
||||
while (element)
|
||||
{
|
||||
if (element == NULL)
|
||||
{
|
||||
}
|
||||
|
||||
std::string value = element->Value();
|
||||
|
||||
if (value == tag) // "ClInclude") // || value == "ClCompile")
|
||||
{
|
||||
if (element->Parent() != NULL)
|
||||
{
|
||||
return element; // ->Parent()->ToElement();
|
||||
}
|
||||
}
|
||||
|
||||
if (element->FirstChildElement() != NULL)
|
||||
{
|
||||
element = element->FirstChildElement();
|
||||
}
|
||||
else if (element->NextSiblingElement() != NULL)
|
||||
{
|
||||
element = element->NextSiblingElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (element == NULL)
|
||||
{
|
||||
}
|
||||
|
||||
while (element->Parent()->ToElement() != NULL && element->Parent()->NextSiblingElement() == NULL)
|
||||
{
|
||||
TiXmlElement* newElement = element->Parent()->ToElement();
|
||||
|
||||
if (newElement == NULL)
|
||||
{
|
||||
}
|
||||
|
||||
element = newElement;
|
||||
}
|
||||
if (element->Parent() != NULL && element->Parent()->NextSiblingElement() != NULL)
|
||||
{
|
||||
element = element->Parent()->NextSiblingElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TiXmlElement* SolutionParserUtility::getFirstTagByNameWithAttribute(TiXmlElement* root, const std::string& tag, const std::string& attribute)
|
||||
{
|
||||
TiXmlElement* element = root;
|
||||
|
||||
while (element)
|
||||
{
|
||||
if (element == NULL)
|
||||
{
|
||||
}
|
||||
|
||||
std::string value = element->Value();
|
||||
|
||||
bool hasAttribute = false;
|
||||
if (element->Attribute(attribute.c_str()) != NULL)
|
||||
{
|
||||
hasAttribute = true;
|
||||
}
|
||||
|
||||
if (value == tag && hasAttribute) // "ClInclude") // || value == "ClCompile")
|
||||
{
|
||||
if (element->Parent() != NULL)
|
||||
{
|
||||
return element; // ->Parent()->ToElement();
|
||||
}
|
||||
}
|
||||
|
||||
if (element->FirstChildElement() != NULL)
|
||||
{
|
||||
element = element->FirstChildElement();
|
||||
}
|
||||
else if (element->NextSiblingElement() != NULL)
|
||||
{
|
||||
element = element->NextSiblingElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (element->Parent()->ToElement() != NULL && element->Parent()->NextSiblingElement() == NULL)
|
||||
{
|
||||
TiXmlElement* newElement = element->Parent()->ToElement();
|
||||
|
||||
element = newElement;
|
||||
}
|
||||
if (element->Parent() != NULL && element->Parent()->NextSiblingElement() != NULL)
|
||||
{
|
||||
element = element->Parent()->NextSiblingElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::vector<TiXmlElement*> SolutionParserUtility::getAllTagsByNameWithAttribute(TiXmlElement* root, const std::string& tag, const std::string& attribute)
|
||||
{
|
||||
std::vector<TiXmlElement*> nodes;
|
||||
|
||||
TiXmlElement* element = root;
|
||||
|
||||
while (element)
|
||||
{
|
||||
std::string value = element->Value();
|
||||
|
||||
bool hasAttribute = false;
|
||||
if (element->Attribute(attribute.c_str()) != NULL)
|
||||
{
|
||||
hasAttribute = true;
|
||||
}
|
||||
|
||||
if (value == tag && hasAttribute)
|
||||
{
|
||||
nodes.push_back(element);
|
||||
}
|
||||
|
||||
if (element->FirstChildElement() != NULL)
|
||||
{
|
||||
element = element->FirstChildElement();
|
||||
}
|
||||
else if (element->NextSiblingElement() != NULL)
|
||||
{
|
||||
element = element->NextSiblingElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (element->Parent()->ToElement() != NULL && element->Parent()->NextSiblingElement() == NULL)
|
||||
{
|
||||
TiXmlElement* newElement = element->Parent()->ToElement();
|
||||
|
||||
element = newElement;
|
||||
}
|
||||
if (element->Parent() != NULL && element->Parent()->NextSiblingElement() != NULL)
|
||||
{
|
||||
element = element->Parent()->NextSiblingElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
bool SolutionParserUtility::checkValidFileExtension(const std::string& file, const std::vector<std::string>& validExtensions)
|
||||
{
|
||||
for (unsigned int i = 0; i < validExtensions.size(); i++)
|
||||
{
|
||||
size_t pos = file.find(validExtensions[i]);
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserUtility::resolveEnvironmentVariables(const std::vector<std::string>& paths)
|
||||
{
|
||||
std::vector<std::string> resolvedPaths;
|
||||
|
||||
for (unsigned int i = 0; i < paths.size(); i++)
|
||||
{
|
||||
std::string resolvedPath = "";
|
||||
|
||||
try
|
||||
{
|
||||
resolvedPath = findAndResolveEnvironmentVariable(paths[i]);
|
||||
|
||||
resolvedPaths.push_back(resolvedPath);
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to resolve environment variable, exception was: \"" << e.what() << "\"");
|
||||
}
|
||||
}
|
||||
|
||||
return resolvedPaths;
|
||||
}
|
||||
|
||||
std::string SolutionParserUtility::findAndResolveEnvironmentVariable(const std::string& path)
|
||||
{
|
||||
std::string resolvedPath;
|
||||
|
||||
size_t pos = path.find("$(");
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
size_t endPos = path.substr(pos).find(")");
|
||||
|
||||
std::string envVariable = path.substr(pos + 2, (endPos - 2) - pos);
|
||||
|
||||
std::string envPath = "";
|
||||
|
||||
std::string macro = checkIsIdeMacro(envVariable);
|
||||
if (macro != "")
|
||||
{
|
||||
LOG_WARNING_STREAM(<< "Encountered IDE macro \"" << macro << "\"");
|
||||
|
||||
if (m_ideMacroValues.find(macro) == m_ideMacroValues.end())
|
||||
{
|
||||
LOG_WARNING_STREAM(<< "Could not resolve IDE macro \"" << macro << "\"");
|
||||
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
envPath = m_ideMacroValues[macro];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
envPath = getenv(envVariable.c_str());
|
||||
}
|
||||
|
||||
std::string prePath = path.substr(0, pos);
|
||||
std::string postPath = path.substr(endPos + 1);
|
||||
|
||||
resolvedPath = prePath + envPath + postPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
resolvedPath = path;
|
||||
}
|
||||
|
||||
return resolvedPath;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserUtility::makePathsCanonical(const std::vector<std::string>& paths)
|
||||
{
|
||||
std::vector<std::string> canonicalPaths;
|
||||
|
||||
int errorCount = 0;
|
||||
|
||||
for (unsigned int i = 0; i < paths.size(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::filesystem::path canonicalPath = boost::filesystem::canonical(boost::filesystem::path(paths[i]));
|
||||
canonicalPaths.push_back(canonicalPath.string());
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::string what = e.what();
|
||||
LOG_WARNING_STREAM(<< e.what());
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (errorCount > 0)
|
||||
{
|
||||
std::stringstream errorMessage;
|
||||
errorMessage << "Detected " << errorCount << " invalid include file paths. Check if the include paths of your VS project exist.";
|
||||
MessageStatus(errorMessage.str(), true).dispatch();
|
||||
}
|
||||
|
||||
return canonicalPaths;
|
||||
}
|
||||
|
||||
std::string SolutionParserUtility::makePathCanonical(const std::string& path)
|
||||
{
|
||||
std::string result = "";
|
||||
|
||||
try
|
||||
{
|
||||
boost::filesystem::path canonicalPath = boost::filesystem::canonical(boost::filesystem::path(path));
|
||||
result = canonicalPath.string();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::string what = e.what();
|
||||
LOG_WARNING_STREAM(<< e.what());
|
||||
|
||||
std::stringstream errorMessage;
|
||||
errorMessage << "Could not make path \"" << path << "\" canonical. Check if it really exists.";
|
||||
MessageStatus(errorMessage.str(), true).dispatch();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string SolutionParserUtility::checkIsIdeMacro(const std::string& text)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_ideMacros.size(); i++)
|
||||
{
|
||||
if (text == m_ideMacros[i])
|
||||
{
|
||||
return m_ideMacros[i];
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef SOLUTION_PARSER_UTILITY_H
|
||||
#define SOLUTION_PARSER_UTILITY_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "tinyxml/tinyxml.h"
|
||||
|
||||
class SolutionParserUtility
|
||||
{
|
||||
public:
|
||||
static TiXmlElement* getFirstTagByName(TiXmlElement* root, const std::string& tag);
|
||||
|
||||
static TiXmlElement* getFirstTagByNameWithAttribute(TiXmlElement* root, const std::string& tag, const std::string& attribute);
|
||||
static std::vector<TiXmlElement*> getAllTagsByNameWithAttribute(TiXmlElement* root, const std::string& tag, const std::string& attribute);
|
||||
|
||||
static bool checkValidFileExtension(const std::string& file, const std::vector<std::string>& validExtensions);
|
||||
|
||||
static std::vector<std::string> resolveEnvironmentVariables(const std::vector<std::string>& paths);
|
||||
static std::string findAndResolveEnvironmentVariable(const std::string& path);
|
||||
static std::vector<std::string> makePathsCanonical(const std::vector<std::string>& paths);
|
||||
static std::string makePathCanonical(const std::string& path);
|
||||
|
||||
static std::string checkIsIdeMacro(const std::string& text); // returns matching macro or empty string if no match was found
|
||||
|
||||
static std::vector<std::string> m_ideMacros;
|
||||
static std::map<std::string, std::string> m_ideMacroValues; // to replace macros with known values
|
||||
};
|
||||
|
||||
#endif // SOLUTION_PARSER_UTILITY_H
|
||||
@@ -147,22 +147,6 @@ namespace utility
|
||||
return text.size() >= postfix.size() && text.rfind(postfix) == (text.size() - postfix.size());
|
||||
}
|
||||
|
||||
std::string switchCases(std::string s)
|
||||
{
|
||||
for (char& c: s)
|
||||
{
|
||||
if (islower(c))
|
||||
{
|
||||
c = toupper(c);
|
||||
}
|
||||
else if (isupper(c))
|
||||
{
|
||||
c = tolower(c);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string toUpperCase(const std::string& in)
|
||||
{
|
||||
std::string out;
|
||||
|
||||
@@ -38,7 +38,6 @@ namespace utility
|
||||
bool isPrefix(const std::string& prefix, const std::string& text);
|
||||
bool isPostfix(const std::string& postfix, const std::string& text);
|
||||
|
||||
std::string switchCases(std::string s);
|
||||
std::string toUpperCase(const std::string& in);
|
||||
std::string toLowerCase(const std::string& in);
|
||||
bool equalsCaseInsensitive(const std::string& a, const std::string& b);
|
||||
|
||||
Reference in New Issue
Block a user