diff --git a/Makefile b/Makefile
index a63c9fc..af90f28 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ MKDIR_P=mkdir -p
BIN=bin/
OBJPATH=$(BIN)intermediates
INCLUDES=
-OBJECTS=$(OBJPATH)/ConfigCLI.o $(OBJPATH)/ConfigFile.o $(OBJPATH)/HFileGen.o $(OBJPATH)/IncludeDeps.o $(OBJPATH)/Makefile.o $(OBJPATH)/Utils.o $(OBJPATH)/main.o $(OBJPATH)/XML.o $(OBJPATH)/XMLObject.o
+OBJECTS=$(OBJPATH)/ConfigCLI.o $(OBJPATH)/ConfigFile.o $(OBJPATH)/HFileGen.o $(OBJPATH)/IncludeDeps.o $(OBJPATH)/Makefile.o $(OBJPATH)/Utils.o $(OBJPATH)/ConfigFileConf.o $(OBJPATH)/main.o $(OBJPATH)/XML.o $(OBJPATH)/XMLObject.o
CFLAGS=$(INCLUDES) -std=c++17 -c -w -g3 -D_DEBUG
LIBDIR=
LDFLAGS=
@@ -33,29 +33,32 @@ $(OUTPUT): $(OBJECTS)
install: all
$(info Installing MakeGen to /usr/bin/)
@cp $(OUTPUT) /usr/bin/makegen
-$(OBJPATH)/ConfigCLI.o : src/ConfigCLI.cpp src/Common.h src/ConfigCLI.h src/ConfigFile.h
- $(info -[11%]- $<)
+$(OBJPATH)/ConfigCLI.o : src/ConfigCLI.cpp src/Common.h src/ConfigCLI.h src/ConfigFile.h src/xml/XMLObject.h
+ $(info -[10%]- $<)
$(CC) $(CFLAGS) -o $@ $<
-$(OBJPATH)/ConfigFile.o : src/ConfigFile.cpp src/ConfigFile.h src/FileUtils.h src/Common.h src/Utils.h
- $(info -[22%]- $<)
+$(OBJPATH)/ConfigFile.o : src/ConfigFile.cpp src/ConfigFile.h src/xml/XMLObject.h src/FileUtils.h src/Common.h src/Utils.h src/compatibility/ConfigFileConf.h src/xml/XML.h
+ $(info -[20%]- $<)
$(CC) $(CFLAGS) -o $@ $<
-$(OBJPATH)/HFileGen.o : src/HFileGen.cpp src/FileUtils.h src/Common.h src/Utils.h src/ConfigFile.h src/HFileGen.h
- $(info -[33%]- $<)
+$(OBJPATH)/HFileGen.o : src/HFileGen.cpp src/FileUtils.h src/Common.h src/Utils.h src/ConfigFile.h src/xml/XMLObject.h src/HFileGen.h
+ $(info -[30%]- $<)
$(CC) $(CFLAGS) -o $@ $<
-$(OBJPATH)/IncludeDeps.o : src/IncludeDeps.cpp src/Common.h src/IncludeDeps.h src/ConfigFile.h src/FileUtils.h src/Utils.h
- $(info -[44%]- $<)
+$(OBJPATH)/IncludeDeps.o : src/IncludeDeps.cpp src/Common.h src/IncludeDeps.h src/ConfigFile.h src/xml/XMLObject.h src/FileUtils.h src/Utils.h
+ $(info -[40%]- $<)
$(CC) $(CFLAGS) -o $@ $<
-$(OBJPATH)/Makefile.o : src/Makefile.cpp src/IncludeDeps.h src/ConfigFile.h src/FileUtils.h src/Common.h src/Utils.h src/Makefile.h
- $(info -[55%]- $<)
+$(OBJPATH)/Makefile.o : src/Makefile.cpp src/IncludeDeps.h src/ConfigFile.h src/xml/XMLObject.h src/FileUtils.h src/Common.h src/Utils.h src/Makefile.h
+ $(info -[50%]- $<)
$(CC) $(CFLAGS) -o $@ $<
-$(OBJPATH)/Utils.o : src/Utils.cpp src/FileUtils.h src/Common.h src/Utils.h src/ConfigFile.h
- $(info -[66%]- $<)
+$(OBJPATH)/Utils.o : src/Utils.cpp src/FileUtils.h src/Common.h src/Utils.h src/ConfigFile.h src/xml/XMLObject.h
+ $(info -[60%]- $<)
$(CC) $(CFLAGS) -o $@ $<
-$(OBJPATH)/main.o : src/main.cpp src/Common.h src/ConfigCLI.h src/ConfigFile.h src/FileUtils.h src/Utils.h src/HFileGen.h src/Makefile.h src/Timer.h
- $(info -[77%]- $<)
+$(OBJPATH)/ConfigFileConf.o : src/compatibility/ConfigFileConf.cpp src/compatibility/ConfigFileConf.h
+ $(info -[70%]- $<)
+ $(CC) $(CFLAGS) -o $@ $<
+$(OBJPATH)/main.o : src/main.cpp src/Common.h src/ConfigCLI.h src/ConfigFile.h src/xml/XMLObject.h src/FileUtils.h src/Utils.h src/HFileGen.h src/Makefile.h src/Timer.h
+ $(info -[80%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/XML.o : src/xml/XML.cpp src/xml/XML.h src/xml/XMLObject.h src/xml/XMLException.h
- $(info -[88%]- $<)
+ $(info -[90%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/XMLObject.o : src/xml/XMLObject.cpp src/xml/XMLException.h src/xml/XMLObject.h
$(info -[100%]- $<)
diff --git a/makegen.conf b/makegen.conf
deleted file mode 100644
index e445d05..0000000
--- a/makegen.conf
+++ /dev/null
@@ -1,19 +0,0 @@
-#libs
-#libdirs
-#includedirs
-#defines
-_DEBUG
-#compileflags
-#dependencies
-#srcdir
-src/
-#outputdir
-bin/
-#projectname
-MakeGen
-#outputname
-makegen
-#executable
-true
-#generatehfile
-false
diff --git a/makegen.xml b/makegen.xml
new file mode 100644
index 0000000..9cb4cbf
--- /dev/null
+++ b/makegen.xml
@@ -0,0 +1,14 @@
+
+
+ _DEBUG
+ false
+ MakeGen.h
+ bin/
+ makegen
+ executable
+ MakeGen
+ src/
+
+ Release
+ v1.3.0
+
\ No newline at end of file
diff --git a/src/Common.h b/src/Common.h
index 6dea76f..2790775 100755
--- a/src/Common.h
+++ b/src/Common.h
@@ -10,7 +10,7 @@
// Major changes, probably not be backwards compatible
#define MAKEGEN_VERSION_MAJOR 1
// Release, should be backwards compatible with any minor version
-#define MAKEGEN_VERSION_RELEASE 2
+#define MAKEGEN_VERSION_RELEASE 3
// Minor changes, should be compatible with any other minor version with same major and release.
#define MAKEGEN_VERSION_MINOR 0
#define MAKEGEN_VERSION ("v" STR(MAKEGEN_VERSION_MAJOR) "." STR(MAKEGEN_VERSION_RELEASE) "." STR(MAKEGEN_VERSION_MINOR))
diff --git a/src/ConfigFile.cpp b/src/ConfigFile.cpp
index 5347bee..be7b7a1 100755
--- a/src/ConfigFile.cpp
+++ b/src/ConfigFile.cpp
@@ -1,17 +1,14 @@
#include "ConfigFile.h"
#include "FileUtils.h"
+#include "compatibility/ConfigFileConf.h"
+#include "xml/XML.h"
#include
#include
-#define FLAG_NONE 0
-#define FLAG_VECTOR 1
-#define FLAG_STRING 2
-#define FLAG_BOOL 3
-
ConfigFile::ConfigFile()
- : outputdir("bin/"), srcdir("src/"), outputname(""), projectname(FileUtils::GetCurrentDirectory()), hFile(""), executable(true), shared(true), generateHFile(false)
+ : outputdir("bin/"), srcdir("src/"), outputname(""), projectname(FileUtils::GetCurrentDirectory()), hFile(projectname+".h"), executable(true), shared(true), generateHFile(false)
{
// Converts project name (current directory) to lowercase
// and replace whitespace with underscore
@@ -54,27 +51,42 @@ std::optional ConfigFile::GetConfigFile(const std::string& filepath,
return {};
}
+ bool oldFile = false;
std::ifstream f(filepath + CONFIG_FILENAME);
+ if(!f.good())
+ {
+ // try to read an old config file
+ f.close();
+ f = std::ifstream(filepath + "makegen.conf");
+ oldFile = true;
+ }
+
// Check if the file exists
if(f.good())
{
f.close();
- ConfigFile conf = ConfigFile::Load(realPath);
- loadedConfigs.emplace(realPath, conf);
+ std::optional conf;
+ if(oldFile)
+ conf = ConfigFileConf::Load(realPath);
+ else
+ conf = ConfigFile::Load(realPath);
+ if(!conf)
+ return {};
+ loadedConfigs.emplace(realPath, *conf);
// Create dependency config files.
- for(size_t i = 0; i < conf.dependencies.size();++i)
+ for(size_t i = 0; i < conf->dependencies.size();++i)
{
- std::optional dep = GetConfigFile(conf.configPath + conf.dependencies[i], loadedConfigs);
+ std::optional dep = GetConfigFile(conf->configPath + conf->dependencies[i], loadedConfigs);
if(dep)
{
- conf.dependencyConfigs.push_back(*dep);
- conf.dependencies[i] = dep->configPath;
+ conf->dependencyConfigs.push_back(*dep);
+ conf->dependencies[i] = dep->configPath;
}
else
{
// Remove the dependency since it is already accounted for
- conf.dependencies.erase(conf.dependencies.begin() + i);
+ conf->dependencies.erase(conf->dependencies.begin() + i);
--i;
}
}
@@ -84,120 +96,99 @@ std::optional ConfigFile::GetConfigFile(const std::string& filepath,
}
-ConfigFile ConfigFile::Load(const std::string& filepath)
+std::optional ConfigFile::Load(const std::string& filedir)
{
- ConfigFile conf;
- conf.configPath = filepath;
- unsigned int loadFlag = 0;
+ XMLObject object{XML::FromFile(filedir + CONFIG_FILENAME)};
- std::vector* vec;
- std::string* s;
- bool* b;
-
- bool isDirectory = false;
-
- std::ifstream file(filepath+CONFIG_FILENAME);
- std::string line;
-
- if(file.is_open())
+ const std::string& target = object.GetObject("target", {XMLObject{"target", {}, "Release"}})[0].GetText();
+ const std::vector& configurations = object.GetObject("configuration");
+ const XMLObject* configuration = nullptr;
+ for(auto it = configurations.begin(); it != configurations.end(); ++it)
{
- // config name, { pointer to memory, isDirectory}
- std::map> strings =
+ if(!it->HasAttribute("name"))
{
- {"#srcdir", {&conf.srcdir, true}},
- {"#outputdir", {&conf.outputdir, true}},
- {"#outputname", {&conf.outputname, false}},
- {"#projectname", {&conf.projectname, false}},
- {"#hfile", {&conf.hFile, false}},
- };
+ LOG_ERROR("No name attribute in configuration tag");
+ continue;
+ }
+ if(it->GetAttribute("name") == target)
+ {
+ configuration = &(*it);
+ break;
+ }
+ }
- // config name, { pointer to memory, isDirectory}
- std::map*, bool>> vectors =
- {
- {"#libs", {&conf.libs, false}},
- {"#libdirs", {&conf.libdirs, true}},
- {"#includedirs", {&conf.includedirs, true}},
- {"#compileflags", {&conf.flags, false}},
- {"#defines", {&conf.defines, false}},
- {"#dependencies", {&conf.dependencies, true}},
- };
+ if(configuration == nullptr)
+ {
+ LOG_ERROR("No configuration matching target: ", target);
+ return {};
+ }
- std::map booleans =
- {
- {"#executable", &conf.executable},
- {"#shared", &conf.shared},
- {"#generatehfile", &conf.generateHFile},
- };
+ ConfigFile conf;
+ conf.configPath = filedir;
+ conf.projectname = configuration->GetObject("projectname",
+ {XMLObject{"projectname", {}, conf.projectname}})[0].GetText();
+ conf.outputname = configuration->GetObject("outputname",
+ {XMLObject{"outputname", {}, conf.outputname}})[0].GetText();
+ conf.srcdir = configuration->GetObject("srcdir",
+ {XMLObject{"srcdir", {}, conf.srcdir}})[0].GetText();
+ conf.outputdir = configuration->GetObject("outputdir",
+ {XMLObject{"outputdir", {}, conf.outputdir}})[0].GetText();
+ conf.hFile = configuration->GetObject("hfile",
+ {XMLObject{"hfile", {}, conf.hFile}})[0].GetText();
+ std::string outputtype = configuration->GetObject("outputtype",
+ {XMLObject{"outputtype", {}, "executable"}})[0].GetText();
- while(std::getline(file,line))
+ if(conf.srcdir[conf.srcdir.size()-1] != '/')
+ conf.srcdir += '/';
+ if(conf.outputdir[conf.srcdir.size()-1] != '/')
+ conf.outputdir += '/';
+
+ if(outputtype == "executable")
+ conf.executable = true;
+ else if(outputtype == "staticlibrary")
+ {
+ conf.executable = false;
+ conf.shared = false;
+ }
+ else if(outputtype == "sharedlibrary")
+ {
+ conf.executable = false;
+ conf.shared = true;
+ }
+ else
+ {
+ LOG_ERROR("Invalid outputtype: ", outputtype);
+ LOG_ERROR("Valid arguments are executable, staticlibrary and sharedlibrary");
+ }
+ conf.generateHFile = configuration->GetObject("generatehfile",
+ {XMLObject{"generatehfile", {}, conf.generateHFile ? "true" : "false"}})[0].GetText() == "true";
+
+ const int vectorCount = 6;
+ std::tuple, std::vector*, bool> vectors[vectorCount] = {
+ {configuration->GetObject("library"), &conf.libs, false},
+ {configuration->GetObject("libdir"), &conf.libdirs, true},
+ {configuration->GetObject("includedir"), &conf.includedirs, true},
+ {configuration->GetObject("define"), &conf.defines, false},
+ {configuration->GetObject("compileflag"), &conf.flags, false},
+ {configuration->GetObject("dependency"), &conf.dependencies, true}
+ };
+
+ for(int i = 0;i& xmls = std::get<0>(vectors[i]);
+ std::vector* vec = std::get<1>(vectors[i]);
+ bool isDir = std::get<2>(vectors[i]);
+ for(auto it = xmls.begin(); it != xmls.end();++it)
{
- if(line == "")
- continue;
- if(line[0]=='#')
+ if(it->GetText() != "")
{
- // The format is a bit wacky, but it is this way since we do not want
- // to use map::find for all maps. This way we gain some optimization.
- auto&& itStr{strings.find(line)};
- if(itStr != strings.end())
- {
- s = itStr->second.first;
- isDirectory = itStr->second.second;
- loadFlag = FLAG_STRING;
- }
- else
- {
- auto&& itVec{vectors.find(line)};
- if(itVec != vectors.end())
- {
- vec = itVec->second.first;
- isDirectory = itVec->second.second;
- loadFlag = FLAG_VECTOR;
- }
- else
- {
- auto&& itBool{booleans.find(line)};
- if(itBool != booleans.end())
- {
- b = itBool->second;
- loadFlag = FLAG_BOOL;
- }
- else
- {
- LOG_ERROR("Invalid flag: ", line);
- loadFlag = FLAG_NONE;
- }
- }
- }
- }
- else
- {
- if(loadFlag == FLAG_STRING)
- {
- if(isDirectory && line[line.size()-1] != '/')
- line += '/';
- *s = line;
- }
- else if(loadFlag == FLAG_VECTOR)
- {
- if(isDirectory && line[line.size()-1] != '/')
- {;
- line += '/';
- }
- vec->push_back(line);
- }
- else if(loadFlag == FLAG_BOOL)
- {
- if(line == "true")
- *b = true;
- else
- *b = false;
- }
+ std::string s = it->GetText();
+ if(isDir && s[s.size()-1] != '/')
+ s += '/';
+ vec->push_back(s);
}
}
}
- if(conf.hFile == "")
- conf.hFile = conf.projectname+".h";
-
return conf;
}
@@ -279,58 +270,36 @@ ConfigFile ConfigFile::Gen()
void ConfigFile::Save() const
{
- std::ofstream file("makegen.conf");
- file << "#libs" << std::endl;
- for(auto it = libs.begin();it!=libs.end();++it)
- {
- file << *it << std::endl;
- }
- file << "#libdirs" << std::endl;
- for(auto it = libdirs.begin();it!=libdirs.end();++it)
- {
- file << *it << std::endl;
- }
- file << "#includedirs" << std::endl;
- for(auto it = includedirs.begin();it!=includedirs.end();++it)
- {
- file << *it << std::endl;
- }
- file << "#defines" << std::endl;
- for(auto it = defines.begin();it!=defines.end();++it)
- {
- file << *it << std::endl;
- }
- file << "#compileflags" << std::endl;
- for(auto it = flags.begin();it!=flags.end();++it)
- {
- file << *it << std::endl;
- }
- file << "#dependencies" << std::endl;
- for(auto it = dependencies.begin();it!=dependencies.end();++it)
- {
- file << *it << std::endl;
- }
- file << "#srcdir" << std::endl;
- file << srcdir << std::endl;
- file << "#outputdir" << std::endl;
- file << outputdir << std::endl;
- file << "#projectname" << std::endl;
- file << projectname << std::endl;
- file << "#outputname" << std::endl;
- file << outputname << std::endl;
- file << "#executable" << std::endl;
- file << (executable ? "true" : "false") << std::endl;
- file << "#generatehfile" << std::endl;
- file << (generateHFile ? "true" : "false") << std::endl;
- if(generateHFile)
- {
- file << "#hfile" << std::endl;
- file << hFile << std::endl;
- }
- if(!executable)
- {
- file << "#shared" << std::endl;
- file << (shared ? "true" : "false") << std::endl;
- }
- file.close();
+ XMLObject makegen("makegen", {}, std::map>{});
+
+ // Version, target and configuration is probably going to be used in the future
+ makegen.AddXMLObject(XMLObject("version", {}, "v1.3.0"));
+ makegen.AddXMLObject(XMLObject("target", {}, "Release"));
+
+ XMLObject configuration("configuration", {{"name", "Release"}}, std::map>{});
+ configuration.AddXMLObject(XMLObject("projectname", {}, projectname));
+ configuration.AddXMLObject(XMLObject("outputname", {}, outputname));
+ configuration.AddXMLObject(XMLObject("srcdir", {}, srcdir));
+ configuration.AddXMLObject(XMLObject("outputdir", {}, outputdir));
+ configuration.AddXMLObject(XMLObject("hfile", {}, hFile));
+ configuration.AddXMLObject(XMLObject("outputtype", {},
+ executable ? "executable" : (shared ? "sharedlibrary" : "staticlibrary")));
+ configuration.AddXMLObject(XMLObject("generatehfile", {}, generateHFile ? "true" : "false"));
+
+ for(auto it = libs.begin();it != libs.end(); ++it)
+ configuration.AddXMLObject({"library",{},*it});
+ for(auto it = libdirs.begin();it != libdirs.end(); ++it)
+ configuration.AddXMLObject({"libdir",{},*it});
+ for(auto it = includedirs.begin();it != includedirs.end(); ++it)
+ configuration.AddXMLObject({"includedir",{},*it});
+ for(auto it = defines.begin();it != defines.end(); ++it)
+ configuration.AddXMLObject({"define",{},*it});
+ for(auto it = flags.begin();it != flags.end(); ++it)
+ configuration.AddXMLObject({"compileflag",{},*it});
+ for(auto it = dependencies.begin();it != dependencies.end(); ++it)
+ configuration.AddXMLObject({"dependency",{},*it});
+
+ makegen.AddXMLObject(configuration);
+ std::ofstream file("makegen.xml");
+ file << makegen;
}
diff --git a/src/ConfigFile.h b/src/ConfigFile.h
index 3d9b36b..6e8cc71 100755
--- a/src/ConfigFile.h
+++ b/src/ConfigFile.h
@@ -1,16 +1,19 @@
#pragma once
+#include "xml/XMLObject.h"
+
#include