ui: Added user interface for auto system header search paths detection

* moved detection files to lib_gui
* added ui to global header search and framework search ui in project wizzard and preferences
* detecting the search paths will add them to the list if not added yet
* only detected compilers are shown in the dropdown list
This commit is contained in:
Eberhard Graether
2016-04-06 11:23:20 +02:00
parent 93f21283f6
commit 5e6714d95a
26 changed files with 345 additions and 243 deletions
-12
View File
@@ -6,18 +6,6 @@ add_files(
utility/commandline/CommandLineParser.cpp
utility/commandline/CommandLineParser.h
utility/headerSearch/CompilerDetector.cpp
utility/headerSearch/CompilerDetector.h
utility/headerSearch/DetectorBase.cpp
utility/headerSearch/DetectorBase.h
utility/headerSearch/StandardHeaderDetection.cpp
utility/headerSearch/StandardHeaderDetection.h
utility/headerSearch/VisualStudioDetector.cpp
utility/headerSearch/VisualStudioDetector.h
utility/utilityApp.cpp
utility/utilityApp.h
isTrial.cpp
LicenseChecker.h
main.cpp
-7
View File
@@ -20,9 +20,6 @@
#include "settings/ProjectSettings.h"
#include "utility/headerSearch/StandardHeaderDetection.h"
void init()
{
std::shared_ptr<ConsoleLogger> consoleLogger = std::make_shared<ConsoleLogger>();
@@ -86,10 +83,6 @@ int main(int argc, char *argv[])
LicenseChecker checker;
StandardHeaderDetection detection;
detection.printdetectedCompilers();
detection.printAvailableDetectors();
utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".otf");
std::shared_ptr<Application> app = Application::create(version, &viewFactory, &networkFactory);
@@ -1,37 +0,0 @@
#include "utility/headerSearch/CompilerDetector.h"
#include "utility/utilityApp.h"
#include "utility/utilityString.h"
CompilerDetector::CompilerDetector(const std::string& name)
: DetectorBase(name)
{
}
CompilerDetector::~CompilerDetector()
{
}
std::vector<FilePath> CompilerDetector::getStandardHeaderPaths()
{
std::string command = m_name + " -x c++ -v -E /dev/null";
std::string clangOutput = utility::executeProcess(command.c_str());
std::string standardHeaders = utility::substrBetween(clangOutput, "#include <...> search starts here:\n","\nEnd of search list");
std::vector<FilePath> paths;
if (!standardHeaders.empty())
{
for (std::string s : utility::splitToVector(standardHeaders, '\n'))
{
paths.push_back(s);
}
}
return paths;
}
// Add Gcc to Available Detectors
static StandardHeaderDetection::Add<CompilerDetector> gcc("gcc");
// Add Clang to Available Detectors
static StandardHeaderDetection::Add<CompilerDetector> clang("clang");
@@ -1,13 +0,0 @@
#ifndef DETECTOR_PROXY_H
#define DETECTOR_PROXY_H
class DetectorProxyBase
{
public:
};
#endif // DETECTOR_PROXY_H
@@ -1,87 +0,0 @@
#include "utility/headerSearch/StandardHeaderDetection.h"
#include <cstdlib>
#include <map>
#include <string>
#include <vector>
#include <utility>
#include <iostream>
#include "utility/file/FilePath.h"
#include "utility/logging/logging.h"
#include "utility/utilityApp.h"
#include "utility/utilityString.h"
#include "clang/Driver/ToolChain.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/Tool.h"
#include "clang/Driver/DriverDiagnostic.h"
typedef std::pair<std::string, std::shared_ptr<DetectorBase>> DetectorPair;
DetectorMap* StandardHeaderDetection::s_availableDetectors;
StandardHeaderDetection::StandardHeaderDetection()
{
detectHeaders();
}
StandardHeaderDetection::~StandardHeaderDetection()
{
if ( s_availableDetectors != nullptr )
{
delete s_availableDetectors;
}
}
void StandardHeaderDetection::detectHeaders()
{
for ( DetectorPair detector : *s_availableDetectors)
{
if ( detector.second->detect() )
{
m_detectedCompilers.insert(detector);
}
}
}
std::vector<std::string> StandardHeaderDetection::getDetectedCompilers()
{
std::vector<std::string> v;
for ( DetectorPair detector : m_detectedCompilers)
{
v.push_back(detector.first);
}
return v;
}
std::vector<FilePath> StandardHeaderDetection::getStandardHeaderPaths(std::string compiler)
{
auto it = m_detectedCompilers.find(compiler);
if(it != m_detectedCompilers.end())
{
return it->second->getStandardHeaderPaths();
}
return std::vector<FilePath>();
}
void StandardHeaderDetection::printdetectedCompilers()
{
std::cout << "Detected Compilers: " << std::endl;
std::vector<std::string> compilers = getDetectedCompilers();
for ( std::string compiler : compilers)
{
std::cout << compiler << std::endl;
}
}
void StandardHeaderDetection::printAvailableDetectors()
{
std::cout << "printAvailableDetectors: " << std::endl;
for ( DetectorPair detector : *s_availableDetectors)
{
std::cout << detector.first << std::endl;
}
}
@@ -1,53 +0,0 @@
#ifndef STANDARDHEADER_DETECTION_H
#define STANDARDHEADER_DETECTION_H
#include <map>
#include <memory>
#include <string>
#include "utility/headerSearch/DetectorBase.h"
typedef std::map<std::string, std::shared_ptr<DetectorBase>> DetectorMap;
class FilePath;
class StandardHeaderDetection
{
public:
StandardHeaderDetection();
~StandardHeaderDetection();
/// Checks all availabe detectors and saves found Compilers
void detectHeaders();
/// Returns alls found compilers
std::vector<std::string> getDetectedCompilers();
/// Returns the headerpaths from a found compiler
std::vector<FilePath> getStandardHeaderPaths(std::string compiler);
/// Declare a instance of this class to add a detector
template <typename U>
class Add
{
public:
Add(const std::string& name)
{
std::shared_ptr<DetectorBase> detector = std::shared_ptr<U>(new U(name));
if (!s_availableDetectors)
{
s_availableDetectors = new DetectorMap();
}
s_availableDetectors->insert(std::make_pair(detector->getName(), detector));
}
};
/// Debugging Output
void printAvailableDetectors();
void printdetectedCompilers();
private:
static DetectorMap* s_availableDetectors;
DetectorMap m_detectedCompilers;
};
#endif //STANDARDHEADER_DETECTION_H
+7 -2
View File
@@ -122,12 +122,17 @@ namespace utility
bool isPrefix(const std::string& prefix, const std::string& text)
{
typedef std::pair<std::string::const_iterator, std::string::const_iterator> ResType;
ResType res = std::mismatch(prefix.begin(), prefix.end(), text.begin());
std::pair<std::string::const_iterator, std::string::const_iterator> res =
std::mismatch(prefix.begin(), prefix.end(), text.begin());
return res.first == prefix.end();
}
bool isPostfix(const std::string& postfix, const std::string& text)
{
return text.size() >= postfix.size() && text.rfind(postfix) == (text.size() - postfix.size());
}
std::string toUpperCase(const std::string& in)
{
std::string out;
+1
View File
@@ -35,6 +35,7 @@ namespace utility
std::string substrBetween(const std::string& str, const std::string& delimiter1, const std::string& delimiter2);
bool isPrefix(const std::string& prefix, const std::string& text);
bool isPostfix(const std::string& postfix, const std::string& text);
std::string toUpperCase(const std::string& in);
std::string toLowerCase(const std::string& in);
+12
View File
@@ -151,4 +151,16 @@ add_files(
qt/QtApplication.h
qt/QtCoreApplication.cpp
qt/QtCoreApplication.h
utility/headerSearch/CompilerDetector.cpp
utility/headerSearch/CompilerDetector.h
utility/headerSearch/DetectorBase.cpp
utility/headerSearch/DetectorBase.h
utility/headerSearch/StandardHeaderDetection.cpp
utility/headerSearch/StandardHeaderDetection.h
utility/headerSearch/VisualStudioDetector.cpp
utility/headerSearch/VisualStudioDetector.h
utility/utilityApp.cpp
utility/utilityApp.h
)
@@ -92,7 +92,7 @@ void QtProjectWizzard::newProjectFromSolution(const std::string& ideId, const st
std::string title = "NEW PROJECT FROM ";
title += ideId;
title += " SOLUTION";
boost::algorithm::to_upper(title);
window->updateTitle(QString(title.c_str()));
@@ -232,8 +232,8 @@ QtProjectWizzardWindow* QtProjectWizzard::createWindowWithContent<QtProjectWizza
connect(window, SIGNAL(canceled()), this, SLOT(cancelWizzard()));
QtProjectWizzardContentSelect* content = new QtProjectWizzardContentSelect(&m_settings, window, m_parserManager);
window->setContent(content);
window->setup();
@@ -7,6 +7,7 @@
#include "qt/element/QtDirectoryListBox.h"
#include "settings/ApplicationSettings.h"
#include "utility/file/FileSystem.h"
#include "utility/headerSearch/StandardHeaderDetection.h"
#include "utility/utility.h"
QtProjectWizzardContentPaths::QtProjectWizzardContentPaths(ProjectSettings* settings, QtProjectWizzardWindow* window)
@@ -47,6 +48,11 @@ void QtProjectWizzardContentPaths::populateWindow(QGridLayout* layout, int& row)
addFilesButton(m_showFilesString, layout, row);
}
if (m_detectionString.size() > 0)
{
addDetection(m_detectionString, layout, row);
}
row++;
layout->setColumnStretch(QtProjectWizzardWindow::FRONT_COL, 1);
@@ -72,6 +78,12 @@ void QtProjectWizzardContentPaths::populateForm(QGridLayout* layout, int& row)
addFilesButton(m_showFilesString, layout, row);
row++;
}
if (m_detectionString.size() > 0)
{
addDetection(m_detectionString, layout, row);
row++;
}
}
QSize QtProjectWizzardContentPaths::preferredWindowSize() const
@@ -101,6 +113,60 @@ void QtProjectWizzardContentPaths::setHelpString(const QString& help)
m_helpString = help;
}
void QtProjectWizzardContentPaths::addDetection(QString name, QGridLayout* layout, int row)
{
StandardHeaderDetection detection;
std::vector<std::string> compilers = detection.getDetectedCompilers();
if (!compilers.size())
{
return;
}
QLabel* label = new QLabel("Auto detection from:");
m_detectorBox = new QComboBox();
for (const std::string& compiler : compilers)
{
m_detectorBox->addItem(compiler.c_str());
}
QPushButton* button = new QPushButton("detect");
button->setObjectName("windowButton");
connect(button, SIGNAL(clicked()), this, SLOT(detectionClicked()));
QHBoxLayout* hlayout = new QHBoxLayout();
hlayout->addWidget(label);
hlayout->addWidget(m_detectorBox);
hlayout->addWidget(button);
layout->addLayout(hlayout, row, QtProjectWizzardWindow::BACK_COL, Qt::AlignLeft | Qt::AlignTop);
}
void QtProjectWizzardContentPaths::detectionClicked()
{
StandardHeaderDetection detection;
std::vector<FilePath> paths;
if (m_detectionString == "headers")
{
paths = detection.getStandardHeaderPaths(m_detectorBox->currentText().toStdString());
}
else if (m_detectionString == "frameworks")
{
paths = detection.getStandardFrameworkPaths(m_detectorBox->currentText().toStdString());
}
std::vector<FilePath> oldPaths = m_list->getList();
std::set<FilePath> uniquePaths;
uniquePaths.insert(oldPaths.begin(), oldPaths.end());
uniquePaths.insert(paths.begin(), paths.end());
m_list->setList(utility::toVector(uniquePaths));
}
QtProjectWizzardContentPathsSource::QtProjectWizzardContentPathsSource(
ProjectSettings* settings, QtProjectWizzardWindow* window
)
@@ -291,14 +357,16 @@ QtProjectWizzardContentPathsHeaderSearchGlobal::QtProjectWizzardContentPathsHead
{
setInfo(
"Global Header Search Paths",
"These header search paths will be used in all your projects. Use it to add system header and Standard Library "
"header paths (See <a href=\"https://coati.io/documentation/#FindingSystemHeaderLocations\">Finding "
"System Header Locations</a>).",
"These header search paths will be used in all your projects. Use it to add system header paths "
"(See <a href=\"https://coati.io/documentation/#FindingSystemHeaderLocations\">Finding System Header Locations</a> "
"or use the auto detection below).",
"Header Search Paths define where additional headers, that your project depends on, are found. Usually they are "
"header files of frameworks or libraries that your project uses. These files won't be analyzed, but Coati needs "
"them for correct analysis.\n\n"
"Header Search Paths defined here will be used for all projects."
);
m_detectionString = "headers";
}
void QtProjectWizzardContentPathsHeaderSearchGlobal::load()
@@ -350,11 +418,13 @@ QtProjectWizzardContentPathsFrameworkSearchGlobal::QtProjectWizzardContentPathsF
"Global Framework Search Paths",
"These framework search paths will be used in all your projects. Use it to add system frameworks "
"(See <a href=\"https://coati.io/documentation/#FindingSystemHeaderLocations\">"
"Finding System Header Locations</a>).",
"Finding System Header Locations</a> or use the auto detection below).",
"Framework Search Paths define where MacOS framework containers (.framework), that your project depends on, are "
"found.\n\n"
"Framework Search Paths defined here will be used for all projects."
);
m_detectionString = "frameworks";
}
void QtProjectWizzardContentPathsFrameworkSearchGlobal::load()
@@ -1,6 +1,7 @@
#ifndef QT_PROJECT_WIZZARD_CONTENT_PATHS_H
#define QT_PROJECT_WIZZARD_CONTENT_PATHS_H
#include <QComboBox>
#include <QPushButton>
#include "qt/window/project_wizzard/QtProjectWizzardContent.h"
@@ -31,14 +32,22 @@ protected:
void setDescriptionString(const QString& description);
void setHelpString(const QString& help);
void addDetection(QString name, QGridLayout* layout, int row);
QtDirectoryListBox* m_list;
QString m_showFilesString;
QString m_detectionString;
private slots:
void detectionClicked();
private:
QString m_titleString;
QString m_descriptionString;
QString m_helpString;
QComboBox* m_detectorBox;
};
@@ -0,0 +1,62 @@
#include "utility/headerSearch/CompilerDetector.h"
#include "utility/utilityApp.h"
#include "utility/utilityString.h"
CompilerDetector::CompilerDetector(const std::string& name)
: DetectorBase(name)
{
}
CompilerDetector::~CompilerDetector()
{
}
std::vector<std::string> CompilerDetector::getHeaderPaths()
{
std::string command = m_name + " -x c++ -v -E /dev/null";
std::string clangOutput = utility::executeProcess(command.c_str());
std::string standardHeaders =
utility::substrBetween(clangOutput, "#include <...> search starts here:\n","\nEnd of search list");
std::vector<std::string> paths;
if (!standardHeaders.empty())
{
for (std::string s : utility::splitToVector(standardHeaders, '\n'))
{
paths.push_back(utility::trim(s));
}
}
return paths;
}
std::vector<FilePath> CompilerDetector::getStandardHeaderPaths()
{
std::vector<std::string> paths = getHeaderPaths();
std::vector<FilePath> headerPaths;
for (const std::string& path : paths)
{
if (!utility::isPostfix(" (framework directory)", path))
{
headerPaths.push_back(FilePath(path).canonical());
}
}
return headerPaths;
}
std::vector<FilePath> CompilerDetector::getStandardFrameworkPaths()
{
std::vector<std::string> paths = getHeaderPaths();
std::vector<FilePath> frameworkPaths;
for (const std::string& path : paths)
{
if (utility::isPostfix(" (framework directory)", path))
{
frameworkPaths.push_back(FilePath(utility::replace(path, " (framework directory)", "")).canonical());
}
}
return frameworkPaths;
}
@@ -2,16 +2,19 @@
#define COMPILER_DETECTOR_H
#include "utility/headerSearch/DetectorBase.h"
#include "utility/headerSearch/StandardHeaderDetection.h"
class CompilerDetector : public DetectorBase
class CompilerDetector
: public DetectorBase
{
public:
CompilerDetector(const std::string& name);
virtual ~CompilerDetector();
std::vector<std::string> getHeaderPaths();
virtual std::vector<FilePath> getStandardHeaderPaths();
private:
virtual std::vector<FilePath> getStandardFrameworkPaths();
};
#endif // COMPILER_DETECTOR_H
@@ -1,7 +1,5 @@
#include "utility/headerSearch/DetectorBase.h"
#include <iostream>
DetectorBase::DetectorBase(const std::string name)
{
setName(name);
@@ -12,6 +10,11 @@ bool DetectorBase::detect()
return !getStandardHeaderPaths().empty();
}
std::vector<FilePath> DetectorBase::getStandardFrameworkPaths()
{
return std::vector<FilePath>();
}
std::string DetectorBase::getName() const
{
return m_name;
@@ -2,6 +2,7 @@
#define DETECTOR_BASE_H
#include <vector>
#include "utility/file/FilePath.h"
class DetectorBase
@@ -11,19 +12,11 @@ public:
virtual ~DetectorBase(){};
virtual bool detect();
virtual std::vector<FilePath> getStandardHeaderPaths() = 0;
virtual std::vector<FilePath> getStandardFrameworkPaths();
virtual std::string getName() const;
virtual void setName(const std::string& name);
protected:
std::string m_name;
};
class Detector
{
public:
virtual ~Detector();
};
#endif // DETECTOR_BASE_H
@@ -0,0 +1,106 @@
#include "utility/headerSearch/StandardHeaderDetection.h"
#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "utility/file/FilePath.h"
#include "utility/headerSearch/CompilerDetector.h"
#include "utility/headerSearch/VisualStudioDetector.h"
#include "utility/logging/logging.h"
#include "utility/utilityApp.h"
#include "utility/utilityString.h"
StandardHeaderDetection::DetectorMap StandardHeaderDetection::s_availableDetectors;
StandardHeaderDetection::DetectorMap StandardHeaderDetection::s_detectedCompilers;
StandardHeaderDetection::StandardHeaderDetection()
{
if (!s_availableDetectors.size())
{
addDetector(std::make_shared<CompilerDetector>("gcc"));
addDetector(std::make_shared<CompilerDetector>("clang"));
addDetector(std::make_shared<VisualStudioDetector>("14"));
addDetector(std::make_shared<VisualStudioDetector>("12"));
addDetector(std::make_shared<VisualStudioDetector>("11"));
addDetector(std::make_shared<VisualStudioDetector>("9"));
detectHeaders();
}
}
StandardHeaderDetection::~StandardHeaderDetection()
{
}
void StandardHeaderDetection::addDetector(std::shared_ptr<DetectorBase> detector)
{
s_availableDetectors.emplace(detector->getName(), detector);
}
void StandardHeaderDetection::detectHeaders()
{
for ( DetectorPair detector : s_availableDetectors)
{
if ( detector.second->detect() )
{
s_detectedCompilers.insert(detector);
}
}
}
std::vector<std::string> StandardHeaderDetection::getDetectedCompilers()
{
std::vector<std::string> v;
for ( DetectorPair detector : s_detectedCompilers)
{
v.push_back(detector.first);
}
return v;
}
std::vector<FilePath> StandardHeaderDetection::getStandardHeaderPaths(std::string compiler)
{
auto it = s_detectedCompilers.find(compiler);
if (it != s_detectedCompilers.end())
{
return it->second->getStandardHeaderPaths();
}
return std::vector<FilePath>();
}
std::vector<FilePath> StandardHeaderDetection::getStandardFrameworkPaths(std::string compiler)
{
auto it = s_detectedCompilers.find(compiler);
if (it != s_detectedCompilers.end())
{
return it->second->getStandardFrameworkPaths();
}
return std::vector<FilePath>();
}
void StandardHeaderDetection::printDetectedCompilers()
{
std::cout << "Detected Compilers: " << std::endl;
std::vector<std::string> compilers = getDetectedCompilers();
for ( std::string compiler : compilers)
{
std::cout << compiler << std::endl;
}
}
void StandardHeaderDetection::printAvailableDetectors()
{
std::cout << "Available Detectors: " << std::endl;
for ( DetectorPair detector : s_availableDetectors)
{
std::cout << detector.first << std::endl;
}
}
@@ -0,0 +1,43 @@
#ifndef STANDARD_HEADER_DETECTION_H
#define STANDARD_HEADER_DETECTION_H
#include <map>
#include <memory>
#include <string>
#include <iostream>
#include "utility/headerSearch/DetectorBase.h"
class FilePath;
class StandardHeaderDetection
{
public:
StandardHeaderDetection();
~StandardHeaderDetection();
void addDetector(std::shared_ptr<DetectorBase> detector);
/// Checks all availabe detectors and saves found Compilers
void detectHeaders();
/// Returns alls found compilers
std::vector<std::string> getDetectedCompilers();
/// Returns the headerpaths from a found compiler
std::vector<FilePath> getStandardHeaderPaths(std::string compiler);
std::vector<FilePath> getStandardFrameworkPaths(std::string compiler);
/// Debugging Output
void printAvailableDetectors();
void printDetectedCompilers();
private:
typedef std::map<std::string, std::shared_ptr<DetectorBase>> DetectorMap;
typedef std::pair<std::string, std::shared_ptr<DetectorBase>> DetectorPair;
static DetectorMap s_availableDetectors;
static DetectorMap s_detectedCompilers;
};
#endif // STANDARD_HEADER_DETECTION_H
@@ -1,14 +1,13 @@
#include "utility/headerSearch/VisualStudioDetector.h"
#include <string>
#include <QSettings>
#include <QSysInfo>
#include <QDir>
#include <string>
#include "utility/file/FilePath.h"
#include "utility/logging/logging.h"
#include "utility/headerSearch/StandardHeaderDetection.h"
#include <iostream>
VisualStudioDetector::VisualStudioDetector(const std::string name)
: DetectorBase("")
@@ -116,10 +115,3 @@ bool VisualStudioDetector::getStanardHeaderPathsUsingRegistry(std::vector<FilePa
return false;
}
// Add Visual Studio Version to the available detectors
static StandardHeaderDetection::Add<VisualStudioDetector> vs2015("14");
static StandardHeaderDetection::Add<VisualStudioDetector> vs2013("12");
static StandardHeaderDetection::Add<VisualStudioDetector> vs2012("11");
static StandardHeaderDetection::Add<VisualStudioDetector> vs2010("9");
@@ -2,6 +2,7 @@
#define VISUAL_STUDIO_DETECTOR_H
#include <vector>
#include "utility/headerSearch/DetectorBase.h"
class FilePath;