Refactor ConfigFile.cpp to be simpler
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# This Makefile was generated using MakeGen v1.3.9 made by Tim Håkansson
|
||||
# This Makefile was generated using MakeGen v1.3.10 made by Tim Håkansson
|
||||
# and is licensed under MIT. Full source of the project can be found at
|
||||
# https://gitea.timha.se/Thraix/MakeGen
|
||||
CC=@g++
|
||||
@@ -34,33 +34,33 @@ $(OUTPUT): $(OBJECTS)
|
||||
install: all
|
||||
$(info Installing MakeGen to /usr/bin/)
|
||||
@cp $(OUTPUT) /usr/bin/makegen
|
||||
$(OBJPATH)/src/ConfigCLI.o: src/ConfigCLI.cpp src/Common.h src/ConfigCLI.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h
|
||||
$(OBJPATH)/src/ConfigCLI.o: src/ConfigCLI.cpp src/Common.h src/AssertException.h src/ConfigCLI.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h
|
||||
$(info -[10%]- $<)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
$(OBJPATH)/src/ConfigFile.o: src/ConfigFile.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/FileUtils.h src/Utils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h src/compatibility/ConfigFileConf.h src/xml/XML.h
|
||||
$(OBJPATH)/src/ConfigFile.o: src/ConfigFile.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/AssertException.h src/FileUtils.h src/Utils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h src/compatibility/ConfigFileConf.h src/xml/XML.h
|
||||
$(info -[20%]- $<)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
$(OBJPATH)/src/HFileGen.o: src/HFileGen.cpp src/FileUtils.h src/Common.h src/Utils.h src/HFileGen.h src/ConfigFile.h src/ConfigUtils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h
|
||||
$(OBJPATH)/src/HFileGen.o: src/HFileGen.cpp src/FileUtils.h src/Common.h src/AssertException.h src/Utils.h src/HFileGen.h src/ConfigFile.h src/ConfigUtils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h
|
||||
$(info -[30%]- $<)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
$(OBJPATH)/src/IncludeDeps.o: src/IncludeDeps.cpp src/Common.h src/IncludeDeps.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h
|
||||
$(OBJPATH)/src/IncludeDeps.o: src/IncludeDeps.cpp src/Common.h src/AssertException.h src/IncludeDeps.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h
|
||||
$(info -[40%]- $<)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
$(OBJPATH)/src/Makefile.o: src/Makefile.cpp src/Common.h src/IncludeDeps.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h src/Makefile.h
|
||||
$(OBJPATH)/src/Makefile.o: src/Makefile.cpp src/Common.h src/AssertException.h src/IncludeDeps.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h src/Makefile.h
|
||||
$(info -[50%]- $<)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
$(OBJPATH)/src/Utils.o: src/Utils.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/FileUtils.h src/Utils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h
|
||||
$(OBJPATH)/src/Utils.o: src/Utils.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/AssertException.h src/FileUtils.h src/Utils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h
|
||||
$(info -[60%]- $<)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
$(OBJPATH)/src/compatibility/ConfigFileConf.o: src/compatibility/ConfigFileConf.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/FileUtils.h src/Utils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h src/compatibility/ConfigFileConf.h
|
||||
$(OBJPATH)/src/compatibility/ConfigFileConf.o: src/compatibility/ConfigFileConf.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/AssertException.h src/FileUtils.h src/Utils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h src/compatibility/ConfigFileConf.h
|
||||
$(info -[70%]- $<)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
$(OBJPATH)/src/main.o: src/main.cpp src/Common.h src/ConfigCLI.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h src/HFileGen.h src/Makefile.h src/Timer.h
|
||||
$(OBJPATH)/src/main.o: src/main.cpp src/Common.h src/AssertException.h src/ConfigCLI.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h src/HFileGen.h src/Makefile.h src/Timer.h
|
||||
$(info -[80%]- $<)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
$(OBJPATH)/src/xml/XML.o: src/xml/XML.cpp src/xml/XML.h src/xml/XMLObject.h src/xml/XMLException.h
|
||||
$(info -[90%]- $<)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
$(OBJPATH)/src/xml/XMLObject.o: src/xml/XMLObject.cpp src/Common.h src/Utils.h src/xml/XMLException.h src/xml/XMLObject.h
|
||||
$(OBJPATH)/src/xml/XMLObject.o: src/xml/XMLObject.cpp src/Common.h src/AssertException.h src/Utils.h src/xml/XMLException.h src/xml/XMLObject.h
|
||||
$(info -[100%]- $<)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
+1
-3
@@ -1,6 +1,5 @@
|
||||
<makegen>
|
||||
<configuration name="Release">
|
||||
<generatehfile>false</generatehfile>
|
||||
<outputdir>bin/Release/</outputdir>
|
||||
<outputname>makegen</outputname>
|
||||
<outputtype>executable</outputtype>
|
||||
@@ -11,7 +10,6 @@
|
||||
<cflag>-g3</cflag>
|
||||
<cflag>-w</cflag>
|
||||
<define>_DEBUG</define>
|
||||
<generatehfile>false</generatehfile>
|
||||
<outputdir>bin/Debug/</outputdir>
|
||||
<outputname>makegen</outputname>
|
||||
<outputtype>executable</outputtype>
|
||||
@@ -19,5 +17,5 @@
|
||||
<srcdir>src/</srcdir>
|
||||
</configuration>
|
||||
<target>Release</target>
|
||||
<version>v1.3.9</version>
|
||||
<version>v1.3.10</version>
|
||||
</makegen>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
struct AssertException : public std::runtime_error
|
||||
{
|
||||
AssertException()
|
||||
: std::runtime_error{"assertion failed"}
|
||||
{
|
||||
}
|
||||
};
|
||||
+19
-2
@@ -4,6 +4,8 @@
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "AssertException.h"
|
||||
|
||||
#define BIT(x) (1 << x)
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
@@ -14,7 +16,7 @@
|
||||
// Release, should be backwards compatible with any minor version
|
||||
#define MAKEGEN_VERSION_RELEASE 3
|
||||
// Minor changes, generally bug fixes
|
||||
#define MAKEGEN_VERSION_MINOR 9
|
||||
#define MAKEGEN_VERSION_MINOR 10
|
||||
|
||||
#define MAKEGEN_VERSION ("v" STR(MAKEGEN_VERSION_MAJOR) "." STR(MAKEGEN_VERSION_RELEASE) "." STR(MAKEGEN_VERSION_MINOR))
|
||||
|
||||
@@ -33,7 +35,22 @@ const static unsigned int FLAG_TARGET = BIT(11);
|
||||
|
||||
#define LOG_INFO(...) LogHelper(__VA_ARGS__)
|
||||
#define LOG_WARNING(...) LogHelper(__VA_ARGS__)
|
||||
#define LOG_ERROR(...) LogHelper(__VA_ARGS__)
|
||||
#define LOG_ERROR(...) LogHelper("\033[1;31m[ERROR] ", __VA_ARGS__, "\033[0m")
|
||||
#define ASSERT(expr, ...) \
|
||||
if (!(expr)) \
|
||||
{ \
|
||||
LOG_ERROR(__VA_ARGS__); \
|
||||
throw AssertException{}; \
|
||||
} \
|
||||
{ \
|
||||
} \
|
||||
while (false)
|
||||
#define ABORT(...) \
|
||||
{ \
|
||||
LOG_ERROR(__VA_ARGS__); \
|
||||
throw AssertException{}; \
|
||||
} \
|
||||
while (false)
|
||||
|
||||
template <typename T>
|
||||
void Log(const T& var)
|
||||
|
||||
+32
-40
@@ -54,8 +54,8 @@ Valid settings are:
|
||||
dependency Project which current project depends on
|
||||
excludesource Exclude source file from compiling
|
||||
excludeheader Exclude header file from project h-file
|
||||
argument Command line argument for the executable
|
||||
preargument Command line argument before the executabe, e.g. gdb)");
|
||||
argument Command line argument for the executable
|
||||
preargument Command line argument before the executabe, e.g. gdb)");
|
||||
}
|
||||
|
||||
void ConfigCLI::DisplayRemoveHelp()
|
||||
@@ -75,8 +75,8 @@ Valid settings are
|
||||
dependency Project which current project depends on
|
||||
excludesource Exclude source file from compiling
|
||||
excludeheader Exclude header file from project h-file
|
||||
argument Command line argument for the executable
|
||||
preargument Command line argument before the executabe, e.g. gdb)");
|
||||
argument Command line argument for the executable
|
||||
preargument Command line argument before the executabe, e.g. gdb)");
|
||||
}
|
||||
|
||||
void ConfigCLI::DisplaySetHelp()
|
||||
@@ -151,8 +151,7 @@ ConfigSetting ConfigCLI::CLIStringToSetting(const std::string& s)
|
||||
{"genhfile", ConfigSetting::GenerateHFile},
|
||||
};
|
||||
auto it = map.find(s);
|
||||
if (it == map.end())
|
||||
return ConfigSetting::Invalid;
|
||||
ASSERT(it != map.end(), "Invalid config setting: ", s)
|
||||
return it->second;
|
||||
}
|
||||
|
||||
@@ -202,15 +201,8 @@ int ConfigCLI::Add(int argc, char** argv, ConfigFile& config)
|
||||
ConfigSetting setting = CLIStringToSetting(argv[1]);
|
||||
if (!ConfigUtils::IsVectorSetting(setting))
|
||||
{
|
||||
if (setting == ConfigSetting::Invalid)
|
||||
{
|
||||
LOG_ERROR("No such setting: ", argv[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Cannot remove setting which only supports one argument");
|
||||
LOG_ERROR("use set instead.");
|
||||
}
|
||||
LOG_ERROR("Cannot remove setting which only supports one argument");
|
||||
LOG_ERROR("use set instead.");
|
||||
return 1;
|
||||
}
|
||||
for (int i = 2; i < argc; ++i)
|
||||
@@ -238,15 +230,8 @@ int ConfigCLI::Remove(int argc, char** argv, ConfigFile& config)
|
||||
ConfigSetting setting = CLIStringToSetting(argv[1]);
|
||||
if (!ConfigUtils::IsVectorSetting(setting))
|
||||
{
|
||||
if (setting == ConfigSetting::Invalid)
|
||||
{
|
||||
LOG_ERROR("No such setting: ", argv[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Cannot remove setting which only supports one argument");
|
||||
LOG_ERROR("use set instead.");
|
||||
}
|
||||
LOG_ERROR("Cannot remove setting which only supports one argument");
|
||||
LOG_ERROR("use set instead.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -275,15 +260,8 @@ int ConfigCLI::Set(int argc, char** argv, ConfigFile& config)
|
||||
ConfigSetting setting = CLIStringToSetting(argv[1]);
|
||||
if (!ConfigUtils::IsStringSetting(setting) && !ConfigUtils::IsBoolSetting(setting))
|
||||
{
|
||||
if (setting == ConfigSetting::Invalid)
|
||||
{
|
||||
LOG_ERROR("No such setting: ", argv[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Cannot set setting which supports multiple arguments");
|
||||
LOG_ERROR("use add or remove instead.");
|
||||
}
|
||||
LOG_ERROR("Cannot set setting which supports multiple arguments");
|
||||
LOG_ERROR("use add or remove instead.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -321,8 +299,22 @@ int ConfigCLI::Main(int argc, char** argv)
|
||||
DisplayCLIHelp();
|
||||
return 0;
|
||||
}
|
||||
std::optional<ConfigFile> config = ConfigFile::GetConfigFile("./", FlagData{});
|
||||
std::string command = argv[1];
|
||||
std::string target = "";
|
||||
int commandIndex = 1;
|
||||
if (argc >= 1 && Utils::StartsWith(argv[1], "--target="))
|
||||
{
|
||||
std::string prefix("--target=");
|
||||
std::string flag(argv[1]);
|
||||
if (flag.size() < prefix.size() + 1)
|
||||
{
|
||||
LOG_ERROR("No target specified in --target=<target>");
|
||||
return 1;
|
||||
}
|
||||
target = flag.substr(std::string("--target=").size());
|
||||
commandIndex++;
|
||||
}
|
||||
std::optional<ConfigFile> config = ConfigFile::GetConfigFile("./", FlagData{target == "" ? 0 : FLAG_TARGET, target});
|
||||
std::string command = argv[commandIndex];
|
||||
if (command == "gen")
|
||||
{
|
||||
if (config)
|
||||
@@ -330,18 +322,18 @@ int ConfigCLI::Main(int argc, char** argv)
|
||||
LOG_ERROR("Config file already exist (", CONFIG_FILENAME, ")");
|
||||
return 1;
|
||||
}
|
||||
return Gen(argc - 1, &argv[1]);
|
||||
return Gen(argc - commandIndex, &argv[commandIndex]);
|
||||
}
|
||||
else if (config)
|
||||
{
|
||||
if (command == "add")
|
||||
return Add(argc - 1, &argv[1], *config);
|
||||
return Add(argc - commandIndex, &argv[commandIndex], *config);
|
||||
else if (command == "remove")
|
||||
return Remove(argc - 1, &argv[1], *config);
|
||||
return Remove(argc - commandIndex, &argv[commandIndex], *config);
|
||||
else if (command == "set")
|
||||
return Set(argc - 1, &argv[1], *config);
|
||||
return Set(argc - commandIndex, &argv[commandIndex], *config);
|
||||
else if (command == "get")
|
||||
return Get(argc - 1, &argv[1], *config);
|
||||
return Get(argc - commandIndex, &argv[commandIndex], *config);
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Unknown config command: ", command);
|
||||
|
||||
+545
-281
@@ -7,21 +7,20 @@
|
||||
#include "xml/XML.h"
|
||||
|
||||
ConfigFile::ConfigFile(const std::string& path, const FlagData& flagData, int)
|
||||
: configPath{path}
|
||||
: makegen{"makegen", {}, std::map<std::string, std::vector<XMLObject>>{}},
|
||||
configPath{std::filesystem::canonical(path)}
|
||||
{
|
||||
// Converts project name (current directory) to lowercase
|
||||
// and replace whitespace with underscore
|
||||
// Create xml
|
||||
XMLObject makegen("makegen", {}, std::map<std::string, std::vector<XMLObject>>{});
|
||||
|
||||
// Version, target and configuration is probably going to be used in the future
|
||||
makegen.AddXMLObject(XMLObject("version", {}, "v1.3.0"));
|
||||
makegen.AddXMLObject(XMLObject("version", {}, MAKEGEN_VERSION));
|
||||
std::string target;
|
||||
if (flagData.flags & FLAG_TARGET)
|
||||
makegen.AddXMLObject(XMLObject("target", {}, flagData.target));
|
||||
target = flagData.target;
|
||||
else
|
||||
makegen.AddXMLObject(XMLObject("target", {}, "Release"));
|
||||
target = "Release";
|
||||
|
||||
XMLObject configuration("configuration", {{"name", "Release"}}, std::map<std::string, std::vector<XMLObject>>{});
|
||||
makegen.AddXMLObject(XMLObject("target", {}, target));
|
||||
|
||||
XMLObject configuration("configuration", {{"name", target}}, std::map<std::string, std::vector<XMLObject>>{});
|
||||
configuration.AddXMLObject(XMLObject("projectname", {}, ConfigUtils::GetDefaultProjectName(configPath)));
|
||||
configuration.AddXMLObject(XMLObject("outputname", {}, ConfigUtils::GetDefaultOutputName(configPath)));
|
||||
configuration.AddXMLObject(XMLObject("srcdir", {}, "src/"));
|
||||
@@ -31,50 +30,109 @@ ConfigFile::ConfigFile(const std::string& path, const FlagData& flagData, int)
|
||||
configuration.AddXMLObject(XMLObject("generatehfile", {}, "false"));
|
||||
|
||||
makegen.AddXMLObject(configuration);
|
||||
config = makegen;
|
||||
Init(flagData);
|
||||
}
|
||||
|
||||
ConfigFile::ConfigFile(const std::string& path, const FlagData& flagData)
|
||||
: config{XML::FromFile(path + CONFIG_FILENAME)},
|
||||
configPath{path}
|
||||
: makegen{XML::FromFile(path + CONFIG_FILENAME)},
|
||||
configPath{std::filesystem::canonical(path)}
|
||||
{
|
||||
Init(flagData);
|
||||
}
|
||||
|
||||
ConfigFile::ConfigFile(XMLObject& config, const std::string& path, const FlagData& flagData)
|
||||
: config{config},
|
||||
configPath{path}
|
||||
: makegen{config},
|
||||
configPath{std::filesystem::canonical(path)}
|
||||
{
|
||||
Init(flagData);
|
||||
}
|
||||
|
||||
void ConfigFile::Init(const FlagData& flagData)
|
||||
{
|
||||
InitTarget(flagData);
|
||||
InitTargetConfig();
|
||||
InitDependencies();
|
||||
InitStringSetting("outputname", &outputName);
|
||||
InitStringSetting("outputtype", &outputType);
|
||||
InitStringSetting("outputdir", &outputDir);
|
||||
InitStringSetting("projectname", &projectName);
|
||||
InitOptionalStringSetting("srcdir", &sourceDir);
|
||||
InitOptionalStringSetting("hfilename", &hFileName);
|
||||
InitStringListSetting("librarydir", &libraryDirs);
|
||||
InitStringListSetting("includedir", &includeDirs);
|
||||
InitStringListSetting("library", &libraries);
|
||||
InitStringListSetting("define", &defines);
|
||||
InitStringListSetting("cflag", &cFlags);
|
||||
InitStringListSetting("lflag", &lFlags);
|
||||
InitStringListSetting("excludeheader", &excludeHeaders);
|
||||
InitStringListSetting("excludesource", &excludeSources);
|
||||
InitStringListSetting("sourcefile", &sourceFiles);
|
||||
InitStringListSetting("preargument", &preArguments);
|
||||
InitStringListSetting("argument", &arguments);
|
||||
InitStringListSetting("includedirexcldep", &includeDirExclDeps);
|
||||
InitBoolSetting("generatehfile", &generateHFile);
|
||||
|
||||
InitDir(outputDir);
|
||||
InitOptionalDir(sourceDir);
|
||||
InitDirs(libraryDirs);
|
||||
InitDirs(includeDirs);
|
||||
}
|
||||
|
||||
void ConfigFile::InitTarget(const FlagData& flagData)
|
||||
{
|
||||
if (flagData.flags & FLAG_TARGET)
|
||||
{
|
||||
target = flagData.target;
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
const std::vector<XMLObject>& targetXml = makegen.GetObjects("target");
|
||||
if (targetXml.empty())
|
||||
{
|
||||
const std::vector<XMLObject>* targetXml = config.GetObjectPtr("target");
|
||||
target = "Release";
|
||||
if (!targetXml || targetXml->size() == 0)
|
||||
{
|
||||
LOG_ERROR("No target found in config file. Using target=", target);
|
||||
return;
|
||||
}
|
||||
if (targetXml->size() > 1)
|
||||
LOG_ERROR("To many targets in config file. Using target=", (*targetXml)[0].GetText());
|
||||
if (targetXml->size() > 0)
|
||||
target = (*targetXml)[0].GetText();
|
||||
LOG_ERROR("No target found in makegen file. Using target=", target);
|
||||
return;
|
||||
}
|
||||
InitDependencies();
|
||||
|
||||
if (targetXml.size() > 1)
|
||||
LOG_ERROR("Too many targets in makegen file. Using target=", targetXml.front().GetText());
|
||||
|
||||
target = targetXml.front().GetText();
|
||||
}
|
||||
|
||||
void ConfigFile::InitTargetConfig()
|
||||
{
|
||||
config = GetTargetConfig();
|
||||
}
|
||||
|
||||
XMLObject& ConfigFile::GetTargetConfig()
|
||||
{
|
||||
std::vector<XMLObject>& configurations = makegen.GetObjects("configuration");
|
||||
ASSERT(!configurations.empty(), "No configuration in makegen.xml");
|
||||
|
||||
for (auto& configuration : configurations)
|
||||
{
|
||||
if (!configuration.HasAttribute("name"))
|
||||
{
|
||||
LOG_ERROR("No name attribute in configuration tag");
|
||||
continue;
|
||||
}
|
||||
if (configuration.GetAttribute("name") == target)
|
||||
{
|
||||
return configuration;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR("Couldn\'t find given target=",
|
||||
target,
|
||||
" in config file. Using target=",
|
||||
configurations.front().GetAttribute("name", ""));
|
||||
return configurations.front();
|
||||
}
|
||||
|
||||
void ConfigFile::InitDependencies()
|
||||
{
|
||||
const std::vector<XMLObject>& values = GetConfiguration().GetObjects("dependency");
|
||||
const std::vector<XMLObject>& values = config.GetObjects("dependency");
|
||||
|
||||
for (const auto& value : values)
|
||||
{
|
||||
@@ -83,275 +141,498 @@ void ConfigFile::InitDependencies()
|
||||
}
|
||||
}
|
||||
|
||||
std::string& ConfigFile::GetSettingString(ConfigSetting setting)
|
||||
void ConfigFile::InitStringSetting(const std::string& name, std::string* output)
|
||||
{
|
||||
// Adding it to the cache since we need to return a reference
|
||||
if (!ConfigUtils::IsStringSetting(setting))
|
||||
const std::vector<XMLObject>& values = config.GetObjects(name);
|
||||
ASSERT(!values.empty(), "No ", name, " defined in makegen.xml")
|
||||
|
||||
if (values.size() > 1)
|
||||
{
|
||||
LOG_ERROR("Invalid string setting");
|
||||
return cache.strings.emplace("invalid", "").first->second;
|
||||
LOG_ERROR("Only one instance of ", name, " allowed using ", values.front().GetText());
|
||||
}
|
||||
|
||||
std::string sSetting = ConfigUtils::GetSettingName(setting);
|
||||
auto it = cache.strings.find(sSetting);
|
||||
if (it != cache.strings.end())
|
||||
return it->second;
|
||||
|
||||
const std::vector<XMLObject>* values = GetConfiguration().GetObjectPtr(sSetting);
|
||||
|
||||
// No value found, using default
|
||||
if (values == nullptr)
|
||||
return cache.strings.emplace(sSetting, ConfigUtils::GetDefaultSettingString(setting, configPath)).first->second;
|
||||
|
||||
if (values->size() != 1)
|
||||
{
|
||||
LOG_ERROR("To many arguments for setting using first: ", (int)setting, "=", (*values)[0].GetText());
|
||||
}
|
||||
std::string s = (*values)[0].GetText();
|
||||
if (ConfigUtils::IsDirectory(setting) && !s.empty() && s[s.size() - 1] != '/')
|
||||
s += '/';
|
||||
return cache.strings.emplace(sSetting, s).first->second;
|
||||
*output = values.front().GetText();
|
||||
}
|
||||
|
||||
bool ConfigFile::GetSettingBool(ConfigSetting setting)
|
||||
void ConfigFile::InitOptionalStringSetting(const std::string& name, std::optional<std::string>* output)
|
||||
{
|
||||
if (setting == ConfigSetting::Invalid)
|
||||
const std::vector<XMLObject>& values = config.GetObjects(name);
|
||||
if (values.empty())
|
||||
{
|
||||
LOG_ERROR("Invalid config setting");
|
||||
return false;
|
||||
*output = std::nullopt;
|
||||
return;
|
||||
}
|
||||
std::string sSetting = ConfigUtils::GetSettingName(setting);
|
||||
auto it = cache.bools.find(sSetting);
|
||||
if (it != cache.bools.end())
|
||||
return it->second;
|
||||
|
||||
const std::vector<XMLObject>* values = GetConfiguration().GetObjectPtr(sSetting); //,
|
||||
|
||||
if (values == nullptr)
|
||||
return cache.bools.emplace(sSetting, ConfigUtils::GetDefaultSettingBool(setting)).first->second;
|
||||
|
||||
if (values->size() != 1)
|
||||
if (values.size() > 1)
|
||||
{
|
||||
LOG_ERROR("To many arguments for setting using first: ", (int)setting, "=", (*values)[0].GetText());
|
||||
LOG_ERROR("Only one instance of ", name, " allowed using ", values.front().GetText());
|
||||
}
|
||||
return cache.bools.emplace(sSetting, (*values)[0].GetText() == "true").first->second;
|
||||
|
||||
if (values.front().GetText().empty())
|
||||
{
|
||||
*output = std::nullopt;
|
||||
return;
|
||||
}
|
||||
|
||||
*output = values.front().GetText();
|
||||
}
|
||||
|
||||
std::vector<std::string>& ConfigFile::GetSettingVectorString(ConfigSetting setting)
|
||||
void ConfigFile::InitStringListSetting(const std::string& name, std::vector<std::string>* output)
|
||||
{
|
||||
std::string sSetting = ConfigUtils::GetSettingName(setting);
|
||||
auto it = cache.vecStrings.find(sSetting);
|
||||
if (it != cache.vecStrings.end())
|
||||
return it->second;
|
||||
|
||||
const std::vector<XMLObject>* values = GetConfiguration().GetObjectPtr(sSetting);
|
||||
if (values == nullptr)
|
||||
return cache.vecStrings.emplace(sSetting, std::vector<std::string>{}).first->second;
|
||||
|
||||
std::vector<std::string> strings;
|
||||
strings.reserve(values->size());
|
||||
for (auto it = values->begin(); it != values->end(); ++it)
|
||||
const std::vector<XMLObject>& objects = config.GetObjects(name);
|
||||
for (const auto& object : objects)
|
||||
{
|
||||
if (it->GetText() == "")
|
||||
continue;
|
||||
std::string s = it->GetText();
|
||||
if (ConfigUtils::IsDirectory(setting) && s[s.size() - 1] != '/')
|
||||
s += '/';
|
||||
strings.push_back(s);
|
||||
output->emplace_back(object.GetText());
|
||||
}
|
||||
|
||||
return cache.vecStrings.emplace(sSetting, strings).first->second;
|
||||
}
|
||||
|
||||
std::vector<std::string> ConfigFile::GetSetting(ConfigSetting setting)
|
||||
void ConfigFile::InitBoolSetting(const std::string& name, bool* output)
|
||||
{
|
||||
if (ConfigUtils::IsStringSetting(setting))
|
||||
return {GetSettingString(setting)};
|
||||
else if (ConfigUtils::IsVectorSetting(setting))
|
||||
return GetSettingVectorString(setting);
|
||||
else if (ConfigUtils::IsBoolSetting(setting))
|
||||
return {GetSettingBool(setting) ? "true" : "false"};
|
||||
const std::vector<XMLObject>& values = config.GetObjects(name);
|
||||
if (values.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (values.size() > 1)
|
||||
{
|
||||
LOG_ERROR("Only one instance of ", name, " allowed using ", values.front().GetText());
|
||||
}
|
||||
|
||||
if (values.front().GetText() == "true")
|
||||
*output = true;
|
||||
else if (values.front().GetText() == "false")
|
||||
*output = false;
|
||||
else
|
||||
LOG_ERROR("Invalid bool value: ", values.front().GetText(), " for ", name);
|
||||
}
|
||||
|
||||
void ConfigFile::InitDir(std::string& dir) const
|
||||
{
|
||||
if (!dir.empty() && dir.back() != '/')
|
||||
{
|
||||
LOG_ERROR("Invalid config setting");
|
||||
return {};
|
||||
dir += '/';
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigFile::InitOptionalDir(std::optional<std::string>& dir) const
|
||||
{
|
||||
if (dir.has_value() && !dir.value().empty() && dir.value().back() != '/')
|
||||
{
|
||||
dir.value() += '/';
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigFile::InitDirs(std::vector<std::string>& dirs) const
|
||||
{
|
||||
for (auto& dir : dirs)
|
||||
{
|
||||
InitDir(dir);
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& ConfigFile::GetOutputDir() const
|
||||
{
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
const std::string& ConfigFile::GetOutputName() const
|
||||
{
|
||||
return outputName;
|
||||
}
|
||||
|
||||
const std::string& ConfigFile::GetProjectName() const
|
||||
{
|
||||
return projectName;
|
||||
}
|
||||
|
||||
const std::string& ConfigFile::GetOutputType() const
|
||||
{
|
||||
return outputType;
|
||||
}
|
||||
|
||||
const std::optional<std::string>& ConfigFile::GetSourceDir() const
|
||||
{
|
||||
return sourceDir;
|
||||
}
|
||||
|
||||
const std::optional<std::string>& ConfigFile::GetHFileName() const
|
||||
{
|
||||
return hFileName;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& ConfigFile::GetLibraryDirs() const
|
||||
{
|
||||
return libraryDirs;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& ConfigFile::GetIncludeDirs() const
|
||||
{
|
||||
return includeDirs;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& ConfigFile::GetLibraries() const
|
||||
{
|
||||
return libraries;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& ConfigFile::GetDefines() const
|
||||
{
|
||||
return defines;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& ConfigFile::GetCFlags() const
|
||||
{
|
||||
return cFlags;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& ConfigFile::GetLFlags() const
|
||||
{
|
||||
return lFlags;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& ConfigFile::GetExcludeHeaders() const
|
||||
{
|
||||
return excludeHeaders;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& ConfigFile::GetExcludeSources() const
|
||||
{
|
||||
return excludeSources;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& ConfigFile::GetSourceFiles() const
|
||||
{
|
||||
return sourceFiles;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& ConfigFile::GetPreArguments() const
|
||||
{
|
||||
return preArguments;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& ConfigFile::GetArguments() const
|
||||
{
|
||||
return arguments;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& ConfigFile::GetIncludeDirExclDeps() const
|
||||
{
|
||||
return includeDirExclDeps;
|
||||
}
|
||||
|
||||
const std::vector<Dependency>& ConfigFile::GetDependencies() const
|
||||
{
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
bool ConfigFile::SetSettingString(ConfigSetting setting, const std::string& value)
|
||||
bool ConfigFile::IsGenerateHFile() const
|
||||
{
|
||||
return generateHFile;
|
||||
}
|
||||
|
||||
std::vector<std::string> ConfigFile::GetSetting(ConfigSetting setting) const
|
||||
{
|
||||
switch (setting)
|
||||
{
|
||||
case ConfigSetting::SourceDir:
|
||||
{
|
||||
if (sourceDir.has_value())
|
||||
return {sourceDir.value()};
|
||||
return {};
|
||||
}
|
||||
case ConfigSetting::OutputDir:
|
||||
return {outputDir};
|
||||
case ConfigSetting::OutputName:
|
||||
return {outputName};
|
||||
case ConfigSetting::OutputType:
|
||||
return {outputType};
|
||||
case ConfigSetting::ProjectName:
|
||||
return {projectName};
|
||||
case ConfigSetting::HFileName:
|
||||
{
|
||||
if (hFileName.has_value())
|
||||
return {hFileName.value()};
|
||||
return {};
|
||||
}
|
||||
case ConfigSetting::LibraryDir:
|
||||
return libraryDirs;
|
||||
case ConfigSetting::IncludeDir:
|
||||
return includeDirs;
|
||||
case ConfigSetting::Dependency:
|
||||
{
|
||||
std::vector<std::string> list;
|
||||
for (const auto& [path, target] : dependencies)
|
||||
{
|
||||
list.emplace_back(path);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
case ConfigSetting::Library:
|
||||
return libraries;
|
||||
case ConfigSetting::Define:
|
||||
return defines;
|
||||
case ConfigSetting::CFlag:
|
||||
return cFlags;
|
||||
case ConfigSetting::LFlag:
|
||||
return lFlags;
|
||||
case ConfigSetting::ExcludeSource:
|
||||
return excludeSources;
|
||||
case ConfigSetting::ExcludeHeader:
|
||||
return excludeHeaders;
|
||||
case ConfigSetting::ExecPreArgument:
|
||||
return preArguments;
|
||||
case ConfigSetting::ExecArgument:
|
||||
return arguments;
|
||||
case ConfigSetting::GenerateHFile:
|
||||
return {generateHFile ? "true" : "false"};
|
||||
case ConfigSetting::SourceFile:
|
||||
return sourceFiles;
|
||||
case ConfigSetting::IncludeDirExclDep:
|
||||
return includeDirExclDeps;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ConfigFile::SetSettingString(ConfigSetting setting, std::string value)
|
||||
{
|
||||
// Check if valid enum
|
||||
std::string s = value;
|
||||
std::string sSetting = ConfigUtils::GetSettingName(setting);
|
||||
if (ConfigUtils::IsStringSetting(setting))
|
||||
if (ConfigUtils::IsDirectory(setting))
|
||||
{
|
||||
if (ConfigUtils::IsDirectory(setting) && s[s.size() - 1] != '/')
|
||||
{
|
||||
s += '/';
|
||||
}
|
||||
auto it = cache.strings.find(sSetting);
|
||||
// Update cache
|
||||
if (it != cache.strings.end())
|
||||
it->second = s;
|
||||
else
|
||||
cache.strings.emplace(sSetting, s);
|
||||
InitDir(value);
|
||||
}
|
||||
else if (ConfigUtils::IsBoolSetting(setting))
|
||||
|
||||
if (ConfigUtils::IsBoolSetting(setting))
|
||||
{
|
||||
if (s == "true" || s == "t" || s == "yes" || s == "y")
|
||||
s = "true";
|
||||
else if (s == "false" || s == "f" || s == "no" || s == "n")
|
||||
s = "false";
|
||||
if (value == "true" || value == "t" || value == "yes" || value == "y")
|
||||
{
|
||||
value = "true";
|
||||
}
|
||||
else if (value == "false" || value == "f" || value == "no" || value == "n")
|
||||
{
|
||||
value = "false";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Invalid boolean value: ", s);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto it = cache.bools.find(sSetting);
|
||||
// Update cache
|
||||
if (it != cache.bools.end())
|
||||
it->second = s == "true";
|
||||
else
|
||||
cache.bools.emplace(sSetting, value == "true");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Not a string setting");
|
||||
return false;
|
||||
}
|
||||
|
||||
XMLObject& configuration = GetConfiguration();
|
||||
std::vector<XMLObject>* values = configuration.GetObjectPtr(sSetting);
|
||||
if (values == nullptr)
|
||||
configuration.AddXMLObject({sSetting, {}, s});
|
||||
else if (values->size() > 1)
|
||||
LOG_ERROR("Multiple values of setting, changing first: ", sSetting, "=", s);
|
||||
else
|
||||
(*values)[0].SetText(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigFile::AddSettingVectorString(ConfigSetting setting, const std::string& value)
|
||||
{
|
||||
// Check if valid enum
|
||||
if (ConfigUtils::IsVectorSetting(setting))
|
||||
{
|
||||
std::string s = value;
|
||||
if (ConfigUtils::IsDirectory(setting) && s[s.size() - 1] != '/')
|
||||
{
|
||||
s += '/';
|
||||
}
|
||||
std::string sSetting = ConfigUtils::GetSettingName(setting);
|
||||
auto it = cache.vecStrings.find(sSetting);
|
||||
|
||||
// Update cache
|
||||
if (it != cache.vecStrings.end())
|
||||
it->second.push_back(s);
|
||||
else
|
||||
cache.vecStrings.emplace(sSetting, std::vector<std::string>{s});
|
||||
|
||||
GetConfiguration().AddXMLObject({sSetting, {}, s});
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Not a vector setting");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigFile::RemoveSettingVectorString(ConfigSetting setting, const std::string& value)
|
||||
{
|
||||
// Check if valid enum
|
||||
if (ConfigUtils::IsVectorSetting(setting))
|
||||
{
|
||||
std::string s = value;
|
||||
if (ConfigUtils::IsDirectory(setting) && s[s.size() - 1] != '/')
|
||||
{
|
||||
s += '/';
|
||||
}
|
||||
std::string sSetting = ConfigUtils::GetSettingName(setting);
|
||||
|
||||
auto it = cache.vecStrings.find(sSetting);
|
||||
if (it != cache.vecStrings.end())
|
||||
{
|
||||
// Update cache
|
||||
for (auto itVec = it->second.begin(); itVec != it->second.end(); ++itVec)
|
||||
{
|
||||
if (*itVec == s)
|
||||
{
|
||||
it->second.erase(itVec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<XMLObject>* values = GetConfiguration().GetObjectPtr(sSetting);
|
||||
bool found = false;
|
||||
for (auto it = values->begin(); it != values->end(); ++it)
|
||||
{
|
||||
if (it->GetText() == s)
|
||||
{
|
||||
values->erase(it);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
LOG_ERROR("Couldn't find value: ", s);
|
||||
LOG_ERROR("Invalid boolean value: ", value);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
switch (setting)
|
||||
{
|
||||
LOG_ERROR("Not a vector setting");
|
||||
case ConfigSetting::SourceDir:
|
||||
sourceDir = value;
|
||||
break;
|
||||
case ConfigSetting::OutputDir:
|
||||
outputDir = value;
|
||||
break;
|
||||
case ConfigSetting::OutputName:
|
||||
outputName = value;
|
||||
break;
|
||||
case ConfigSetting::OutputType:
|
||||
outputType = value;
|
||||
break;
|
||||
case ConfigSetting::ProjectName:
|
||||
projectName = value;
|
||||
break;
|
||||
case ConfigSetting::HFileName:
|
||||
hFileName = value;
|
||||
break;
|
||||
case ConfigSetting::GenerateHFile:
|
||||
generateHFile = value == "true";
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Not a string setting");
|
||||
return false;
|
||||
}
|
||||
|
||||
XMLObject& config = GetTargetConfig();
|
||||
std::vector<XMLObject>& values = config.GetObjects(sSetting);
|
||||
if (values.empty())
|
||||
{
|
||||
config.AddXMLObject({sSetting, {}, value});
|
||||
return true;
|
||||
}
|
||||
|
||||
if (values.size() > 1)
|
||||
LOG_ERROR("Multiple values of setting, changing first: ", sSetting, "=", value);
|
||||
|
||||
values.front().SetText(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigFile::AddSettingVectorString(ConfigSetting setting, std::string value)
|
||||
{
|
||||
if (ConfigUtils::IsDirectory(setting))
|
||||
{
|
||||
InitDir(value);
|
||||
}
|
||||
|
||||
switch (setting)
|
||||
{
|
||||
case ConfigSetting::LibraryDir:
|
||||
libraryDirs.emplace_back(value);
|
||||
break;
|
||||
case ConfigSetting::IncludeDir:
|
||||
includeDirs.emplace_back(value);
|
||||
break;
|
||||
case ConfigSetting::Dependency:
|
||||
dependencies.emplace_back(value, target);
|
||||
break;
|
||||
case ConfigSetting::Library:
|
||||
libraries.emplace_back(value);
|
||||
break;
|
||||
case ConfigSetting::Define:
|
||||
defines.emplace_back(value);
|
||||
break;
|
||||
case ConfigSetting::CFlag:
|
||||
cFlags.emplace_back(value);
|
||||
break;
|
||||
case ConfigSetting::LFlag:
|
||||
lFlags.emplace_back(value);
|
||||
break;
|
||||
case ConfigSetting::ExcludeHeader:
|
||||
excludeHeaders.emplace_back(value);
|
||||
break;
|
||||
case ConfigSetting::ExcludeSource:
|
||||
excludeSources.emplace_back(value);
|
||||
break;
|
||||
case ConfigSetting::ExecPreArgument:
|
||||
preArguments.emplace_back(value);
|
||||
break;
|
||||
case ConfigSetting::ExecArgument:
|
||||
arguments.emplace_back(value);
|
||||
break;
|
||||
case ConfigSetting::SourceFile:
|
||||
sourceFiles.emplace_back(value);
|
||||
break;
|
||||
case ConfigSetting::IncludeDirExclDep:
|
||||
includeDirExclDeps.emplace_back(value);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Not a vector setting");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string sSetting = ConfigUtils::GetSettingName(setting);
|
||||
XMLObject& config = GetTargetConfig();
|
||||
config.AddXMLObject({sSetting, {}, value});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigFile::RemoveSettingVectorString(ConfigSetting setting, std::string value)
|
||||
{
|
||||
switch (setting)
|
||||
{
|
||||
case ConfigSetting::LibraryDir:
|
||||
RemoveFromVector(libraryDirs, value);
|
||||
break;
|
||||
case ConfigSetting::IncludeDir:
|
||||
RemoveFromVector(includeDirs, value);
|
||||
break;
|
||||
case ConfigSetting::Dependency:
|
||||
RemoveFromVector(dependencies, value);
|
||||
break;
|
||||
case ConfigSetting::Library:
|
||||
RemoveFromVector(libraries, value);
|
||||
break;
|
||||
case ConfigSetting::Define:
|
||||
RemoveFromVector(defines, value);
|
||||
break;
|
||||
case ConfigSetting::CFlag:
|
||||
RemoveFromVector(cFlags, value);
|
||||
break;
|
||||
case ConfigSetting::LFlag:
|
||||
RemoveFromVector(lFlags, value);
|
||||
break;
|
||||
case ConfigSetting::ExcludeHeader:
|
||||
RemoveFromVector(excludeHeaders, value);
|
||||
break;
|
||||
case ConfigSetting::ExcludeSource:
|
||||
RemoveFromVector(excludeSources, value);
|
||||
break;
|
||||
case ConfigSetting::ExecPreArgument:
|
||||
RemoveFromVector(preArguments, value);
|
||||
break;
|
||||
case ConfigSetting::ExecArgument:
|
||||
RemoveFromVector(arguments, value);
|
||||
break;
|
||||
case ConfigSetting::SourceFile:
|
||||
RemoveFromVector(sourceFiles, value);
|
||||
break;
|
||||
case ConfigSetting::IncludeDirExclDep:
|
||||
RemoveFromVector(includeDirExclDeps, value);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Not a vector setting");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string sSetting = ConfigUtils::GetSettingName(setting);
|
||||
|
||||
XMLObject& config = GetTargetConfig();
|
||||
std::vector<XMLObject>& values = config.GetObjects(sSetting);
|
||||
bool found = false;
|
||||
for (auto it = values.begin(); it != values.end(); ++it)
|
||||
{
|
||||
if (it->GetText() == value)
|
||||
{
|
||||
values.erase(it);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
LOG_ERROR("Couldn't find value: ", value);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
XMLObject& ConfigFile::GetConfiguration()
|
||||
void ConfigFile::RemoveFromVector(std::vector<std::string>& vector, const std::string& string)
|
||||
{
|
||||
std::vector<XMLObject>* configurations = config.GetObjectPtr("configuration");
|
||||
if (configurations == nullptr || configurations->size() == 0)
|
||||
for (auto it = vector.begin(); it != vector.end(); it++)
|
||||
{
|
||||
LOG_ERROR("No configuration in makegen.xml");
|
||||
assert(false);
|
||||
}
|
||||
for (auto it = configurations->begin(); it != configurations->end(); ++it)
|
||||
{
|
||||
if (!it->HasAttribute("name"))
|
||||
if (*it == string)
|
||||
{
|
||||
LOG_ERROR("No name attribute in configuration tag");
|
||||
continue;
|
||||
}
|
||||
if (it->GetAttribute("name") == target)
|
||||
{
|
||||
return *it;
|
||||
vector.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR("Couldn\'t find given target=",
|
||||
target,
|
||||
" in config file. Using target=",
|
||||
(*configurations)[0].HasAttribute("name") ? (*configurations)[0].GetAttribute("name") : "");
|
||||
return (*configurations)[0];
|
||||
}
|
||||
|
||||
const std::string& ConfigFile::GetConfigPath() const
|
||||
void ConfigFile::RemoveFromVector(std::vector<Dependency>& vector, const std::string& string)
|
||||
{
|
||||
for (auto it = vector.begin(); it != vector.end(); it++)
|
||||
{
|
||||
if (it->path == string)
|
||||
{
|
||||
vector.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::filesystem::path& ConfigFile::GetConfigPath() const
|
||||
{
|
||||
return configPath;
|
||||
}
|
||||
|
||||
ConfigFile& ConfigFile::GetDependencyConfig(size_t i)
|
||||
ConfigFile& ConfigFile::GetDependencyConfig(const std::string& path)
|
||||
{
|
||||
return dependencyConfigs[i];
|
||||
std::filesystem::path fullPath = std::filesystem::canonical(path);
|
||||
for (auto& config : dependencyConfigs)
|
||||
{
|
||||
if (config.configPath == fullPath)
|
||||
return config;
|
||||
}
|
||||
ABORT("Failed to find config file: ", fullPath.string());
|
||||
}
|
||||
|
||||
std::optional<ConfigFile> ConfigFile::GetConfigFile(const std::string& filepath, const FlagData& flagData)
|
||||
@@ -364,57 +645,39 @@ std::optional<ConfigFile> ConfigFile::GetConfigFile(const std::string& filepath,
|
||||
std::map<std::string, ConfigFile>& loadedConfigs,
|
||||
const FlagData& flagData)
|
||||
{
|
||||
std::string realPath = FileUtils::GetRealPath(filepath);
|
||||
if (realPath == "")
|
||||
return {};
|
||||
auto it = loadedConfigs.find(realPath);
|
||||
std::filesystem::path configPath = std::filesystem::canonical(filepath) / CONFIG_FILENAME;
|
||||
|
||||
auto it = loadedConfigs.find(configPath);
|
||||
if (it != loadedConfigs.end())
|
||||
return std::nullopt;
|
||||
|
||||
if (!FileUtils::FileExists(configPath))
|
||||
{
|
||||
return {};
|
||||
ConfigFileConf::CreateXMLFile(configPath);
|
||||
if (!FileUtils::FileExists(configPath))
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool oldFile = false;
|
||||
std::ifstream f(filepath + CONFIG_FILENAME);
|
||||
if (!f.good())
|
||||
{
|
||||
ConfigFileConf::CreateXMLFile(realPath);
|
||||
// try to read an old config file
|
||||
f.close();
|
||||
f = std::ifstream(filepath + CONFIG_FILENAME);
|
||||
}
|
||||
ConfigFile config{filepath, flagData};
|
||||
loadedConfigs.emplace(configPath, config);
|
||||
|
||||
// Check if the file exists
|
||||
if (f.good())
|
||||
const std::vector<Dependency>& dependencies = config.GetDependencies();
|
||||
for (size_t i = 0; i < dependencies.size(); ++i)
|
||||
{
|
||||
f.close();
|
||||
ConfigFile conf = ConfigFile(filepath, flagData);
|
||||
if (conf.hasInitError)
|
||||
return {};
|
||||
loadedConfigs.emplace(realPath, conf);
|
||||
|
||||
std::vector<Dependency> dependencies = conf.GetDependencies();
|
||||
// Create dependency config files.
|
||||
for (size_t i = 0; i < dependencies.size(); ++i)
|
||||
FlagData dependencyFlagData = flagData;
|
||||
if (!dependencies[i].target.empty())
|
||||
{
|
||||
FlagData dependencyFlagData = flagData;
|
||||
dependencyFlagData.target = dependencies[i].target;
|
||||
std::optional<ConfigFile> dep =
|
||||
GetConfigFile(conf.configPath + dependencies[i].path, loadedConfigs, dependencyFlagData);
|
||||
if (dep)
|
||||
{
|
||||
conf.dependencyConfigs.push_back(*dep);
|
||||
dependencies[i].path = dep->configPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove the dependency since it is already accounted for
|
||||
dependencies.erase(dependencies.begin() + i);
|
||||
--i;
|
||||
}
|
||||
dependencyFlagData.flags |= FLAG_TARGET;
|
||||
}
|
||||
std::filesystem::path dependencyFilePath = config.configPath / dependencies[i].path;
|
||||
std::optional<ConfigFile> dependencyConfig = GetConfigFile(dependencyFilePath, loadedConfigs, dependencyFlagData);
|
||||
if (dependencyConfig.has_value())
|
||||
{
|
||||
config.dependencyConfigs.emplace_back(dependencyConfig.value());
|
||||
}
|
||||
return conf;
|
||||
}
|
||||
return {};
|
||||
return config;
|
||||
}
|
||||
|
||||
void ConfigFile::InputBoolean(const std::string& inputText, bool& b)
|
||||
@@ -461,6 +724,7 @@ void ConfigFile::InputMultiple(const std::string& inputText, std::vector<std::st
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Will probably remove this, as it is not kept up to date, and I feel like it is rather unuseful
|
||||
ConfigFile ConfigFile::Gen(const FlagData& flagData)
|
||||
{
|
||||
bool executable, shared, generateHFile;
|
||||
@@ -534,5 +798,5 @@ ConfigFile ConfigFile::Gen(const FlagData& flagData)
|
||||
void ConfigFile::Save() const
|
||||
{
|
||||
std::ofstream file("makegen.xml");
|
||||
file << config;
|
||||
file << makegen;
|
||||
}
|
||||
|
||||
+71
-29
@@ -14,20 +14,6 @@ static const std::string CONFIG_FILENAME = "makegen.xml";
|
||||
|
||||
class ConfigFile
|
||||
{
|
||||
private:
|
||||
ConfigCache cache;
|
||||
|
||||
XMLObject config;
|
||||
// Current configuration
|
||||
std::string target;
|
||||
|
||||
std::string configPath;
|
||||
std::vector<ConfigFile> dependencyConfigs;
|
||||
|
||||
std::vector<Dependency> dependencies;
|
||||
|
||||
bool hasInitError = false;
|
||||
|
||||
public:
|
||||
// Generates a new default config file
|
||||
ConfigFile(const std::string& path, const FlagData& flagData, int);
|
||||
@@ -36,33 +22,89 @@ public:
|
||||
|
||||
void Save() const;
|
||||
|
||||
std::string& GetSettingString(ConfigSetting setting);
|
||||
bool GetSettingBool(ConfigSetting setting);
|
||||
std::vector<std::string>& GetSettingVectorString(ConfigSetting setting);
|
||||
std::vector<std::string> GetSetting(ConfigSetting setting);
|
||||
const std::string& GetOutputDir() const;
|
||||
const std::string& GetOutputName() const;
|
||||
const std::string& GetProjectName() const;
|
||||
const std::string& GetOutputType() const;
|
||||
const std::optional<std::string>& GetSourceDir() const;
|
||||
const std::optional<std::string>& GetHFileName() const;
|
||||
const std::vector<std::string>& GetLibraryDirs() const;
|
||||
const std::vector<std::string>& GetIncludeDirs() const;
|
||||
const std::vector<std::string>& GetLibraries() const;
|
||||
const std::vector<std::string>& GetDefines() const;
|
||||
const std::vector<std::string>& GetCFlags() const;
|
||||
const std::vector<std::string>& GetLFlags() const;
|
||||
const std::vector<std::string>& GetExcludeHeaders() const;
|
||||
const std::vector<std::string>& GetExcludeSources() const;
|
||||
const std::vector<std::string>& GetSourceFiles() const;
|
||||
const std::vector<std::string>& GetPreArguments() const;
|
||||
const std::vector<std::string>& GetArguments() const;
|
||||
const std::vector<std::string>& GetIncludeDirExclDeps() const;
|
||||
const std::vector<Dependency>& GetDependencies() const;
|
||||
bool IsGenerateHFile() const;
|
||||
|
||||
bool SetSettingString(ConfigSetting setting, const std::string& value);
|
||||
bool AddSettingVectorString(ConfigSetting setting, const std::string& value);
|
||||
bool RemoveSettingVectorString(ConfigSetting setting, const std::string& value);
|
||||
std::vector<std::string> GetSetting(ConfigSetting setting) const;
|
||||
|
||||
XMLObject& GetConfiguration();
|
||||
const std::string& GetConfigPath() const;
|
||||
ConfigFile& GetDependencyConfig(size_t i);
|
||||
bool SetSettingString(ConfigSetting setting, std::string value);
|
||||
bool AddSettingVectorString(ConfigSetting setting, std::string value);
|
||||
bool RemoveSettingVectorString(ConfigSetting setting, std::string value);
|
||||
|
||||
private:
|
||||
void Init(const FlagData& flagData);
|
||||
void InitDependencies();
|
||||
const std::filesystem::path& GetConfigPath() const;
|
||||
ConfigFile& GetDependencyConfig(const std::string& path);
|
||||
|
||||
public:
|
||||
static ConfigFile Gen(const FlagData& flagData);
|
||||
static std::optional<ConfigFile> GetConfigFile(const std::string& filepath, const FlagData& flagData);
|
||||
|
||||
private:
|
||||
XMLObject makegen;
|
||||
XMLObject config;
|
||||
// Current configuration
|
||||
std::string target;
|
||||
|
||||
std::filesystem::path configPath;
|
||||
std::vector<ConfigFile> dependencyConfigs;
|
||||
|
||||
std::vector<Dependency> dependencies;
|
||||
std::string outputName;
|
||||
std::string outputDir;
|
||||
std::string projectName;
|
||||
std::string outputType;
|
||||
std::optional<std::string> sourceDir;
|
||||
std::optional<std::string> hFileName;
|
||||
std::vector<std::string> libraryDirs;
|
||||
std::vector<std::string> includeDirs;
|
||||
std::vector<std::string> libraries;
|
||||
std::vector<std::string> defines;
|
||||
std::vector<std::string> cFlags;
|
||||
std::vector<std::string> lFlags;
|
||||
std::vector<std::string> excludeHeaders;
|
||||
std::vector<std::string> excludeSources;
|
||||
std::vector<std::string> sourceFiles;
|
||||
std::vector<std::string> preArguments;
|
||||
std::vector<std::string> arguments;
|
||||
std::vector<std::string> includeDirExclDeps;
|
||||
bool generateHFile{false};
|
||||
|
||||
private:
|
||||
void Init(const FlagData& flagData);
|
||||
void InitTarget(const FlagData& flagData);
|
||||
void InitTargetConfig();
|
||||
XMLObject& GetTargetConfig();
|
||||
void InitDependencies();
|
||||
void InitStringSetting(const std::string& name, std::string* output);
|
||||
void InitOptionalStringSetting(const std::string& name, std::optional<std::string>* output);
|
||||
void InitStringListSetting(const std::string& name, std::vector<std::string>* output);
|
||||
void InitBoolSetting(const std::string& name, bool* output);
|
||||
|
||||
void InitDir(std::string& dir) const;
|
||||
void InitOptionalDir(std::optional<std::string>& dir) const;
|
||||
void InitDirs(std::vector<std::string>& dirs) const;
|
||||
void RemoveFromVector(std::vector<std::string>& vector, const std::string& string);
|
||||
void RemoveFromVector(std::vector<Dependency>& vector, const std::string& string);
|
||||
|
||||
static std::optional<ConfigFile> GetConfigFile(const std::string& filepath,
|
||||
std::map<std::string, ConfigFile>& loadedConfigs,
|
||||
const FlagData& flagData);
|
||||
static std::optional<ConfigFile> Load(const std::string& filename);
|
||||
static void InputBoolean(const std::string& inputText, bool& b);
|
||||
static void InputMultiple(const std::string& inputText, std::vector<std::string>& vec, bool needEnding);
|
||||
static void InputString(const std::string& inputText, std::string& vec, bool needEnding, bool allowEmpty);
|
||||
|
||||
+2
-14
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -41,8 +39,6 @@ enum class ConfigSetting
|
||||
HFileName = 37,
|
||||
// Bools
|
||||
GenerateHFile = 64,
|
||||
// Other
|
||||
Invalid = 1024
|
||||
};
|
||||
|
||||
struct ConfigUtils
|
||||
@@ -91,8 +87,6 @@ struct ConfigUtils
|
||||
return "sourcefile";
|
||||
case ConfigSetting::IncludeDirExclDep:
|
||||
return "includedirexcldep";
|
||||
case ConfigSetting::Invalid:
|
||||
return "invalid";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -122,7 +116,6 @@ struct ConfigUtils
|
||||
case ConfigSetting::ExecArgument:
|
||||
case ConfigSetting::GenerateHFile:
|
||||
case ConfigSetting::SourceFile:
|
||||
case ConfigSetting::Invalid:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
@@ -153,7 +146,6 @@ struct ConfigUtils
|
||||
case ConfigSetting::GenerateHFile:
|
||||
case ConfigSetting::SourceFile:
|
||||
case ConfigSetting::IncludeDirExclDep:
|
||||
case ConfigSetting::Invalid:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
@@ -184,7 +176,6 @@ struct ConfigUtils
|
||||
case ConfigSetting::ProjectName:
|
||||
case ConfigSetting::HFileName:
|
||||
case ConfigSetting::GenerateHFile:
|
||||
case ConfigSetting::Invalid:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
@@ -214,7 +205,6 @@ struct ConfigUtils
|
||||
case ConfigSetting::ExecPreArgument:
|
||||
case ConfigSetting::ExecArgument:
|
||||
case ConfigSetting::SourceFile:
|
||||
case ConfigSetting::Invalid:
|
||||
case ConfigSetting::IncludeDirExclDep:
|
||||
return false;
|
||||
}
|
||||
@@ -240,8 +230,7 @@ struct ConfigUtils
|
||||
case ConfigSetting::GenerateHFile:
|
||||
return GetDefaultSettingBool(setting) ? "true" : "false";
|
||||
default:
|
||||
LOG_ERROR("INVALID STRING ENUM: ", (int)setting);
|
||||
assert(false);
|
||||
ASSERT(false, "INVALID STRING ENUM: ", (int)setting);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -253,8 +242,7 @@ struct ConfigUtils
|
||||
case ConfigSetting::GenerateHFile:
|
||||
return false;
|
||||
default:
|
||||
LOG_ERROR("NOT BOOLEAN VALUE: ", (int)setting);
|
||||
assert(false);
|
||||
ASSERT(false, "NOT BOOLEAN VALUE: ", (int)setting);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-28
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -42,42 +41,19 @@ struct FileUtils
|
||||
|
||||
static std::string GetTopDirectory(const std::string& dir)
|
||||
{
|
||||
if (dir.size() == 0)
|
||||
{
|
||||
LOG_ERROR("Cannot send empty string to FileUtils::GetTopDirectory()");
|
||||
assert(false);
|
||||
}
|
||||
ASSERT(!dir.empty(), "Cannot send empty string to FileUtils::GetTopDirectory()");
|
||||
|
||||
size_t dirEnd = std::string::npos;
|
||||
if (dir[dir.size() - 1] == '/')
|
||||
dirEnd = dir.size() - 2;
|
||||
size_t pos = dir.find_last_of("/", dirEnd);
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
LOG_ERROR("Couldn't find / (slash) in directory. This shouldn't occur.");
|
||||
assert(false);
|
||||
}
|
||||
ASSERT(pos != std::string::npos, "Couldn't find / (slash) in directory. This shouldn't occur.");
|
||||
return dir.substr(pos + 1, dirEnd - pos);
|
||||
}
|
||||
|
||||
static std::string GetRealPath(const std::string& filename)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
if (access(filename.c_str(), F_OK) != -1)
|
||||
{
|
||||
char* path = realpath(filename.c_str(), NULL);
|
||||
std::string sPath = path;
|
||||
sPath += "/";
|
||||
free(path);
|
||||
return sPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Directory doesn't exist: ", filename);
|
||||
return "";
|
||||
}
|
||||
#endif
|
||||
LOG_ERROR("GetRealPath not supported");
|
||||
return "";
|
||||
return std::filesystem::canonical(filename).string();
|
||||
}
|
||||
|
||||
static std::string GetRelativePath(std::string from, std::string to)
|
||||
|
||||
+20
-6
@@ -4,11 +4,22 @@
|
||||
|
||||
#include "FileUtils.h"
|
||||
|
||||
// TODO: Consider removing this functionality, since its not really used anyways
|
||||
void HFileGen::Create(ConfigFile& conf)
|
||||
{
|
||||
const std::optional<std::string>& hFileName = conf.GetHFileName();
|
||||
if (!hFileName.has_value())
|
||||
{
|
||||
LOG_ERROR("hfilename is not specified but generatehfile is true");
|
||||
return;
|
||||
}
|
||||
|
||||
std::set<std::string> hFiles;
|
||||
std::vector<std::string> files;
|
||||
std::string path = conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::SourceDir);
|
||||
const std::optional<std::string>& sourceDir = conf.GetSourceDir();
|
||||
std::string path = conf.GetConfigPath();
|
||||
if (sourceDir.has_value())
|
||||
path += sourceDir.value();
|
||||
FileUtils::GetAllFiles(path, files);
|
||||
// include paramenter with the path of the file
|
||||
// For example src/graphics/Window.h -> graphics/Window.h if src is a src folder
|
||||
@@ -18,8 +29,7 @@ void HFileGen::Create(ConfigFile& conf)
|
||||
if (extensionPos != std::string::npos)
|
||||
{
|
||||
std::string filename = it->substr(path.length());
|
||||
if (Utils::IsHeaderFile(filename) &&
|
||||
filename != conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::HFileName))
|
||||
if (Utils::IsHeaderFile(filename) && filename != conf.GetConfigPath() / hFileName.value())
|
||||
{
|
||||
// Make files sorted in alphabetical order
|
||||
hFiles.emplace(filename);
|
||||
@@ -27,12 +37,16 @@ void HFileGen::Create(ConfigFile& conf)
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<std::string>& excludeHeaders = conf.GetSettingVectorString(ConfigSetting::ExcludeHeader);
|
||||
std::ofstream os(path + "/" + conf.GetSettingString(ConfigSetting::HFileName));
|
||||
const std::vector<std::string>& excludeHeaders = conf.GetExcludeHeaders();
|
||||
std::ofstream os(path + "/" + hFileName.value());
|
||||
os << "#pragma once" << std::endl << std::endl;
|
||||
for (auto&& hFile : hFiles)
|
||||
{
|
||||
std::string headerFile = conf.GetSettingString(ConfigSetting::SourceDir) + hFile;
|
||||
const std::optional<std::string>& srcDir = conf.GetSourceDir();
|
||||
std::string headerFile = hFile;
|
||||
if (srcDir.has_value())
|
||||
headerFile = srcDir.value() + headerFile;
|
||||
|
||||
auto it = std::find(excludeHeaders.begin(), excludeHeaders.end(), headerFile);
|
||||
if (it == excludeHeaders.end())
|
||||
os << "#include <" << hFile << ">" << std::endl;
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ public:
|
||||
{
|
||||
std::string filePathInMakeFile = filepath;
|
||||
if (!filepath.is_absolute())
|
||||
filePathInMakeFile = std::filesystem::relative(conf.GetConfigPath() + "/" + filepath.string(), "./").string();
|
||||
filePathInMakeFile = std::filesystem::relative(conf.GetConfigPath() / filepath.string(), "./").string();
|
||||
|
||||
if (printSet.find(filePathInMakeFile) != printSet.end())
|
||||
return stream;
|
||||
|
||||
+39
-34
@@ -16,13 +16,13 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
|
||||
else
|
||||
Utils::GetCppAndHFiles(conf, hFiles, cppFiles);
|
||||
|
||||
std::ofstream outputFile(conf.GetConfigPath() + "Makefile");
|
||||
std::ofstream outputFile(conf.GetConfigPath() / "Makefile");
|
||||
outputFile << "# This Makefile was generated using MakeGen " << MAKEGEN_VERSION << " made by Tim Håkansson"
|
||||
<< std::endl;
|
||||
outputFile << "# and is licensed under MIT. Full source of the project can be found at" << std::endl;
|
||||
outputFile << "# https://gitea.timha.se/Thraix/MakeGen" << std::endl;
|
||||
outputFile << "CC=@g++" << std::endl;
|
||||
std::string outputtype = conf.GetSettingString(ConfigSetting::OutputType);
|
||||
std::string outputtype = conf.GetOutputType();
|
||||
if (outputtype != "executable")
|
||||
{
|
||||
if (outputtype == "sharedlibrary")
|
||||
@@ -34,19 +34,19 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
|
||||
outputFile << "CO=@g++ -o" << std::endl;
|
||||
|
||||
outputFile << "MKDIR_P=mkdir -p" << std::endl;
|
||||
outputFile << "BIN=" << conf.GetSettingString(ConfigSetting::OutputDir) << std::endl;
|
||||
outputFile << "BIN=" << conf.GetOutputDir() << std::endl;
|
||||
outputFile << "OBJPATH=$(BIN)intermediates" << std::endl;
|
||||
outputFile << "INCLUDES=";
|
||||
std::vector<std::string>& includedirs = conf.GetSettingVectorString(ConfigSetting::IncludeDir);
|
||||
for (auto it = includedirs.begin(); it != includedirs.end(); ++it)
|
||||
const std::vector<std::string>& includeDirs = conf.GetIncludeDirs();
|
||||
for (const auto& includeDir : includeDirs)
|
||||
{
|
||||
outputFile << "-I " << *it << " ";
|
||||
outputFile << "-I " << includeDir << " ";
|
||||
}
|
||||
|
||||
std::vector<std::string>& includedirsexcldep = conf.GetSettingVectorString(ConfigSetting::IncludeDirExclDep);
|
||||
for (auto it = includedirsexcldep.begin(); it != includedirsexcldep.end(); ++it)
|
||||
const std::vector<std::string>& includeDirExclDeps = conf.GetIncludeDirExclDeps();
|
||||
for (const auto& includeDirExclDep : includeDirExclDeps)
|
||||
{
|
||||
outputFile << "-I " << *it << " ";
|
||||
outputFile << "-I " << includeDirExclDeps << " ";
|
||||
}
|
||||
outputFile << std::endl;
|
||||
outputFile << "OBJECTS=";
|
||||
@@ -67,42 +67,42 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
|
||||
{
|
||||
outputFile << "CFLAGS=$(INCLUDES) -fPIC -std=c++17 -c ";
|
||||
}
|
||||
std::vector<std::string>& defines = conf.GetSettingVectorString(ConfigSetting::Define);
|
||||
for (auto it = defines.begin(); it != defines.end(); ++it)
|
||||
const std::vector<std::string>& defines = conf.GetDefines();
|
||||
for (const auto& define : defines)
|
||||
{
|
||||
outputFile << "-D" << *it << " ";
|
||||
outputFile << "-D" << define << " ";
|
||||
}
|
||||
std::vector<std::string>& cflags = conf.GetSettingVectorString(ConfigSetting::CFlag);
|
||||
for (auto it = cflags.begin(); it != cflags.end(); ++it)
|
||||
const std::vector<std::string>& cFlags = conf.GetCFlags();
|
||||
for (const auto& cFlag : cFlags)
|
||||
{
|
||||
outputFile << *it << " ";
|
||||
outputFile << cFlag << " ";
|
||||
}
|
||||
outputFile << std::endl;
|
||||
if (outputtype == "executable")
|
||||
{
|
||||
std::vector<std::string>& libdirs = conf.GetSettingVectorString(ConfigSetting::LibraryDir);
|
||||
const std::vector<std::string>& libraryDirs = conf.GetLibraryDirs();
|
||||
outputFile << "LIBDIR=";
|
||||
for (auto it = libdirs.begin(); it != libdirs.end(); ++it)
|
||||
for (const auto& libraryDir : libraryDirs)
|
||||
{
|
||||
outputFile << "-L " << *it << " ";
|
||||
outputFile << "-L " << libraryDir << " ";
|
||||
}
|
||||
outputFile << std::endl;
|
||||
std::vector<std::string>& lflags = conf.GetSettingVectorString(ConfigSetting::LFlag);
|
||||
const std::vector<std::string>& lFlags = conf.GetLFlags();
|
||||
outputFile << "LDFLAGS=";
|
||||
for (auto it = lflags.begin(); it != lflags.end(); ++it)
|
||||
for (const auto& lFlag : lFlags)
|
||||
{
|
||||
outputFile << *it << " ";
|
||||
outputFile << lFlag << " ";
|
||||
}
|
||||
for (auto it = libdirs.begin(); it != libdirs.end(); ++it)
|
||||
for (const auto& libraryDir : libraryDirs)
|
||||
{
|
||||
outputFile << "-Wl,-rpath=" << *it << " ";
|
||||
outputFile << "-Wl,-rpath=" << libraryDir << " ";
|
||||
}
|
||||
outputFile << std::endl;
|
||||
std::vector<std::string>& libs = conf.GetSettingVectorString(ConfigSetting::Library);
|
||||
const std::vector<std::string>& libraries = conf.GetLibraries();
|
||||
outputFile << "LIBS=$(LIBDIR) ";
|
||||
for (auto it = libs.begin(); it != libs.end(); ++it)
|
||||
for (const auto& library : libraries)
|
||||
{
|
||||
outputFile << "-l" << *it << " ";
|
||||
outputFile << "-l" << library << " ";
|
||||
}
|
||||
outputFile << std::endl;
|
||||
const std::vector<Dependency>& dependencies = conf.GetDependencies();
|
||||
@@ -116,7 +116,7 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
|
||||
outputFile << std::endl;
|
||||
}
|
||||
}
|
||||
outputFile << "OUTPUT=$(BIN)" << conf.GetSettingString(ConfigSetting::OutputName) << std::endl;
|
||||
outputFile << "OUTPUT=$(BIN)" << conf.GetOutputName() << std::endl;
|
||||
outputFile << ".PHONY: all directories rebuild clean run" << std::endl;
|
||||
|
||||
// All
|
||||
@@ -142,13 +142,19 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
|
||||
outputFile << "run: all" << std::endl;
|
||||
if (outputtype == "executable")
|
||||
{
|
||||
std::vector<std::string>& prearguments = conf.GetSettingVectorString(ConfigSetting::ExecPreArgument);
|
||||
std::vector<std::string>& arguments = conf.GetSettingVectorString(ConfigSetting::ExecArgument);
|
||||
const std::vector<std::string>& prearguments = conf.GetPreArguments();
|
||||
const std::vector<std::string>& arguments = conf.GetArguments();
|
||||
|
||||
outputFile << "\t@";
|
||||
for (auto&& preargument : prearguments) outputFile << preargument << " ";
|
||||
for (const auto& preargument : prearguments)
|
||||
{
|
||||
outputFile << preargument << " ";
|
||||
}
|
||||
outputFile << "./$(OUTPUT)";
|
||||
for (auto&& argument : arguments) outputFile << " " << argument;
|
||||
for (const auto& argument : arguments)
|
||||
{
|
||||
outputFile << " " << argument;
|
||||
}
|
||||
outputFile << std::endl;
|
||||
}
|
||||
|
||||
@@ -170,9 +176,8 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
|
||||
|
||||
// Install
|
||||
outputFile << "install: all" << std::endl;
|
||||
outputFile << "\t$(info Installing " << conf.GetSettingString(ConfigSetting::ProjectName) << " to /usr/bin/)"
|
||||
<< std::endl;
|
||||
outputFile << "\t@cp $(OUTPUT) /usr/bin/" << conf.GetSettingString(ConfigSetting::OutputName) << std::endl;
|
||||
outputFile << "\t$(info Installing " << conf.GetProjectName() << " to /usr/bin/)" << std::endl;
|
||||
outputFile << "\t@cp $(OUTPUT) /usr/bin/" << conf.GetOutputName() << std::endl;
|
||||
|
||||
std::map<std::string, IncludeDeps*> dependencies;
|
||||
size_t i = 0;
|
||||
|
||||
+55
-52
@@ -70,18 +70,17 @@ std::string Utils::CommonPrefix(const std::string& s1, const std::string& s2)
|
||||
void Utils::GetCppFiles(ConfigFile& conf, std::set<std::string>& cppFiles)
|
||||
{
|
||||
std::vector<std::string> files;
|
||||
std::string sourceDir = conf.GetSettingString(ConfigSetting::SourceDir);
|
||||
std::string path = conf.GetConfigPath() + sourceDir;
|
||||
if (!sourceDir.empty())
|
||||
const std::optional<std::string>& sourceDir = conf.GetSourceDir();
|
||||
if (sourceDir.has_value())
|
||||
{
|
||||
FileUtils::GetAllFiles(path, files);
|
||||
FileUtils::GetAllFiles(conf.GetConfigPath() / sourceDir.value(), files);
|
||||
}
|
||||
const std::vector<std::string>& excludeSources = conf.GetSettingVectorString(ConfigSetting::ExcludeSource);
|
||||
const std::vector<std::string>& excludeSources = conf.GetExcludeSources();
|
||||
|
||||
for (const auto& sourceFile : conf.GetSettingVectorString(ConfigSetting::SourceFile))
|
||||
for (const auto& sourceFile : conf.GetSourceFiles())
|
||||
{
|
||||
if (FileUtils::FileExists(conf.GetConfigPath() + sourceFile))
|
||||
cppFiles.emplace(conf.GetConfigPath() + sourceFile);
|
||||
if (FileUtils::FileExists(conf.GetConfigPath() / sourceFile))
|
||||
cppFiles.emplace(sourceFile);
|
||||
else
|
||||
LOG_WARNING("Source file doesn't exist: ", sourceFile);
|
||||
}
|
||||
@@ -102,61 +101,60 @@ void Utils::GetCppFiles(ConfigFile& conf, std::set<std::string>& cppFiles)
|
||||
|
||||
void Utils::GetCppAndHFiles(ConfigFile& conf, std::set<HFile>& hFiles, std::set<std::string>& cppFiles)
|
||||
{
|
||||
std::vector<std::string> files;
|
||||
std::string sourceDir = conf.GetSettingString(ConfigSetting::SourceDir);
|
||||
std::string path = conf.GetConfigPath() + sourceDir;
|
||||
if (!sourceDir.empty())
|
||||
const std::vector<std::string>& excludeSources = conf.GetExcludeSources();
|
||||
for (const auto& sourceFile : conf.GetSourceFiles())
|
||||
{
|
||||
FileUtils::GetAllFiles(path, files);
|
||||
}
|
||||
const std::vector<std::string>& excludeSources = conf.GetSettingVectorString(ConfigSetting::ExcludeSource);
|
||||
for (const auto& sourceFile : conf.GetSettingVectorString(ConfigSetting::SourceFile))
|
||||
{
|
||||
if (FileUtils::FileExists(conf.GetConfigPath() + sourceFile))
|
||||
cppFiles.emplace(conf.GetConfigPath() + sourceFile);
|
||||
if (FileUtils::FileExists(conf.GetConfigPath() / sourceFile))
|
||||
cppFiles.emplace(sourceFile);
|
||||
else
|
||||
LOG_WARNING("Source file doesn't exist: ", sourceFile);
|
||||
}
|
||||
for (const auto& filename : files)
|
||||
{
|
||||
if (IsSourceFile(filename))
|
||||
{
|
||||
std::filesystem::path filepath = std::filesystem::relative(filename, "./");
|
||||
auto it = std::find(excludeSources.begin(), excludeSources.end(), filepath.string());
|
||||
if (it == excludeSources.end())
|
||||
{
|
||||
cppFiles.emplace(filepath.string());
|
||||
}
|
||||
}
|
||||
else if (IsHeaderFile(filename))
|
||||
{
|
||||
std::filesystem::path path = std::filesystem::relative(filename, sourceDir);
|
||||
hFiles.emplace(HFile{path.string(), sourceDir, false});
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& includePath : conf.GetSettingVectorString(ConfigSetting::IncludeDir))
|
||||
const std::optional<std::string>& sourceDir = conf.GetSourceDir();
|
||||
if (sourceDir.has_value())
|
||||
{
|
||||
std::vector<std::string> files;
|
||||
FileUtils::GetAllFiles(includePath, files);
|
||||
for (const auto& file : files)
|
||||
FileUtils::GetAllFiles(conf.GetConfigPath() / sourceDir.value(), files);
|
||||
for (const auto& filename : files)
|
||||
{
|
||||
std::filesystem::path path = std::filesystem::relative(file, includePath);
|
||||
if (IsHeaderFile(path.string()))
|
||||
if (IsSourceFile(filename))
|
||||
{
|
||||
hFiles.emplace(HFile{path.string(), includePath, false});
|
||||
std::filesystem::path filepath = std::filesystem::relative(filename, "./");
|
||||
auto it = std::find(excludeSources.begin(), excludeSources.end(), filepath.string());
|
||||
if (it == excludeSources.end())
|
||||
{
|
||||
cppFiles.emplace(filepath.string());
|
||||
}
|
||||
}
|
||||
else if (IsHeaderFile(filename))
|
||||
{
|
||||
std::filesystem::path path = std::filesystem::relative(filename, sourceDir.value());
|
||||
hFiles.emplace(HFile{path.string(), sourceDir.value(), false});
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& includePath : conf.GetIncludeDirs())
|
||||
{
|
||||
std::vector<std::string> files;
|
||||
FileUtils::GetAllFiles(includePath, files);
|
||||
for (const auto& file : files)
|
||||
{
|
||||
std::filesystem::path path = std::filesystem::relative(file, includePath);
|
||||
if (IsHeaderFile(path.string()))
|
||||
{
|
||||
hFiles.emplace(HFile{path.string(), includePath, false});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<Dependency>& dependencies = conf.GetDependencies();
|
||||
for (size_t i = 0; i < dependencies.size(); ++i)
|
||||
{
|
||||
GetHFiles(dependencies[i].path, conf.GetDependencyConfig(i), hFiles);
|
||||
GetHFiles(conf.GetDependencyConfig(dependencies[i].path), hFiles);
|
||||
}
|
||||
}
|
||||
|
||||
void Utils::GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::set<HFile>& hFiles)
|
||||
void Utils::GetHFiles(ConfigFile& conf, std::set<HFile>& hFiles)
|
||||
{
|
||||
// TODO: Fix so that cyclic dependencies doesn't crash the tool.
|
||||
// Cyclic dependencies probably shouldn't exist.
|
||||
@@ -164,11 +162,19 @@ void Utils::GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::s
|
||||
const std::vector<Dependency>& dependencies = conf.GetDependencies();
|
||||
for (size_t i = 0; i < dependencies.size(); ++i)
|
||||
{
|
||||
GetHFiles(dependencyDir + dependencies[i].path, conf.GetDependencyConfig(i), hFiles);
|
||||
std::filesystem::path dependencyConfigPath =
|
||||
std::filesystem::canonical(conf.GetConfigPath() / dependencies[i].path);
|
||||
GetHFiles(conf.GetDependencyConfig(dependencyConfigPath), hFiles);
|
||||
}
|
||||
|
||||
const std::optional<std::string>& sourceDir = conf.GetSourceDir();
|
||||
if (!sourceDir.has_value())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> files;
|
||||
std::string depSrcDir = dependencyDir + conf.GetSettingString(ConfigSetting::SourceDir);
|
||||
std::string depSrcDir = conf.GetConfigPath() / sourceDir.value();
|
||||
FileUtils::GetAllFiles(depSrcDir, files);
|
||||
for (auto it = files.begin(); it != files.end(); ++it)
|
||||
{
|
||||
@@ -178,7 +184,7 @@ void Utils::GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::s
|
||||
auto it = hFiles.find({filename, "", false});
|
||||
if (it != hFiles.end())
|
||||
{
|
||||
if (filename == conf.GetSettingString(ConfigSetting::HFileName) && !it->isProjectHFile)
|
||||
if (filename == conf.GetHFileName() && !it->isProjectHFile)
|
||||
{
|
||||
HFile hfile = *it;
|
||||
hfile.isProjectHFile = true;
|
||||
@@ -188,10 +194,7 @@ void Utils::GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::s
|
||||
}
|
||||
else
|
||||
{
|
||||
hFiles.emplace(HFile{filename,
|
||||
depSrcDir,
|
||||
conf.GetSettingBool(ConfigSetting::GenerateHFile) &&
|
||||
filename == conf.GetSettingString(ConfigSetting::HFileName)});
|
||||
hFiles.emplace(HFile{filename, depSrcDir, conf.IsGenerateHFile() && filename == conf.GetHFileName()});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ struct Utils
|
||||
static void Replace(std::string& str, const std::string& from, const std::string& to);
|
||||
static void GetCppFiles(ConfigFile& conf, std::set<std::string>& cppFiles);
|
||||
static void GetCppAndHFiles(ConfigFile& conf, std::set<HFile>& hFiles, std::set<std::string>& cppFiles);
|
||||
static void GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::set<HFile>& hFiles);
|
||||
static void GetHFiles(ConfigFile& conf, std::set<HFile>& hFiles);
|
||||
|
||||
// Used for parsing xml
|
||||
static bool IsWhiteSpace(char c);
|
||||
|
||||
+20
-5
@@ -51,7 +51,7 @@ Usage: makegen [options]
|
||||
|
||||
void GenMakefile(ConfigFile& conf, unsigned int flags)
|
||||
{
|
||||
if (conf.GetSettingBool(ConfigSetting::GenerateHFile))
|
||||
if (conf.IsGenerateHFile())
|
||||
HFileGen::Create(conf);
|
||||
Makefile::Save(conf, flags);
|
||||
}
|
||||
@@ -145,7 +145,7 @@ bool RunMake(const std::string& filepath, unsigned int flags, ConfigFile& conf)
|
||||
{
|
||||
RETURN_IF(system(std::string(make + " install").c_str()) != 0, false);
|
||||
}
|
||||
if (flags & FLAG_RUN && conf.GetSettingString(ConfigSetting::OutputType) == "executable")
|
||||
if (flags & FLAG_RUN && conf.GetOutputType() == "executable")
|
||||
{
|
||||
RETURN_IF(system(std::string(make + " run").c_str()) != 0, false);
|
||||
}
|
||||
@@ -175,14 +175,14 @@ bool MakeGen(const std::string& filepath, const FlagData& flagData, ConfigFile&
|
||||
std::filesystem::current_path(currentPath);
|
||||
}
|
||||
LOG_INFO("-----------------------------------");
|
||||
LOG_INFO("Building ", conf.GetSettingString(ConfigSetting::ProjectName));
|
||||
LOG_INFO("Building ", conf.GetProjectName());
|
||||
LOG_INFO("Generating Makefile...");
|
||||
Timer timer;
|
||||
GenMakefile(conf, flagData.flags);
|
||||
LOG_INFO("Took ", round(timer.Elapsed() * 1000.0) / 1000.0, "s");
|
||||
LOG_INFO("Running Makefile...");
|
||||
|
||||
std::string outputPath = conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::OutputDir);
|
||||
std::string outputPath = conf.GetConfigPath() / conf.GetOutputDir();
|
||||
if (!FileUtils::HasPath(outputPath))
|
||||
{
|
||||
FileUtils::CreateDirectory(outputPath);
|
||||
@@ -193,7 +193,7 @@ bool MakeGen(const std::string& filepath, const FlagData& flagData, ConfigFile&
|
||||
return RunMake(filepath, flagData.flags, conf);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
int Run(int argc, char** argv)
|
||||
{
|
||||
FlagData flagData = ReadFlags(argc, argv);
|
||||
if (flagData.flags & FLAG_HELP)
|
||||
@@ -221,4 +221,19 @@ int main(int argc, char** argv)
|
||||
{
|
||||
LOG_ERROR("Couldn\'t load config file");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Run(argc, argv);
|
||||
}
|
||||
catch (const AssertException& exception)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,16 @@ std::vector<XMLObject>* XMLObject::GetObjectPtr(const std::string& name)
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
std::vector<XMLObject>& XMLObject::GetObjects(const std::string& name)
|
||||
{
|
||||
static std::vector<XMLObject> empty{};
|
||||
auto it = objects.find(name);
|
||||
if (it == objects.end())
|
||||
return empty;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const std::vector<XMLObject>& XMLObject::GetObjects(const std::string& name) const
|
||||
{
|
||||
static std::vector<XMLObject> empty{};
|
||||
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
|
||||
unsigned int GetObjectCount() const;
|
||||
std::vector<XMLObject>* GetObjectPtr(const std::string& name);
|
||||
|
||||
std::vector<XMLObject>& GetObjects(const std::string& name);
|
||||
const std::vector<XMLObject>& GetObjects(const std::string& name) const;
|
||||
const std::map<std::string, std::vector<XMLObject>>& GetObjects() const;
|
||||
const std::string& GetName() const;
|
||||
|
||||
Reference in New Issue
Block a user