Format code based on clang format

This commit is contained in:
Thraix
2025-11-26 22:06:55 +01:00
parent 6976d330fc
commit 7c68a839fc
25 changed files with 1114 additions and 720 deletions
+334
View File
@@ -0,0 +1,334 @@
---
Language: Cpp
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: true
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveShortCaseStatements:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCaseArrows: false
AlignCaseColons: false
AlignConsecutiveTableGenBreakingDAGArgColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenCondOperatorColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenDefinitionColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowBreakBeforeNoexceptSpecifier: Never
AllowShortBlocksOnASingleLine: Never
AllowShortCaseExpressionOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortCompoundRequirementOnASingleLine: true
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AllowShortNamespacesOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AttributeMacros:
- __capability
- absl_nonnull
- absl_nullable
- absl_nullability_unknown
BinPackArguments: false
BinPackLongBracedList: true
BinPackParameters: false
BitFieldColonSpacing: Both
BracedInitializerIndentWidth: -1
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterExternBlock: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakAdjacentStringLiterals: true
BreakAfterAttributes: Leave
BreakAfterJavaFieldAnnotations: false
BreakAfterReturnType: None
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Allman
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTemplateCloser: false
BreakBeforeTernaryOperators: true
BreakBinaryOperations: Never
BreakConstructorInitializers: BeforeColon
BreakFunctionDefinitionParameters: false
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
BreakTemplateDeclarations: Yes
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
EnumTrailingComma: Leave
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 3
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '([-_](test|unittest))?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: true
IndentExportBlock: true
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequiresClause: true
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 0
DecimalMinDigits: 0
Hex: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLines:
AtEndOfFile: false
AtStartOfBlock: false
AtStartOfFile: true
KeepFormFeed: false
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MainIncludeChar: Quote
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
OneLineFormatOffRegex: ''
PackConstructorInitializers: Never
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakBeforeMemberAccess: 150
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakScopeResolution: 500
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
PPIndentWidth: -1
QualifierAlignment: Leave
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
- ParseTestProto
- ParsePartialTestProto
CanonicalDelimiter: pb
BasedOnStyle: google
ReferenceAlignment: Pointer
ReflowComments: Always
RemoveBracesLLVM: false
RemoveEmptyLinesInUnwrappedLines: false
RemoveParentheses: Leave
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Always
ShortNamespaceLines: 1
SkipMacroDefinitionBody: false
SortIncludes:
Enabled: true
IgnoreCase: false
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterOperatorKeyword: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeJsonColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterNot: false
AfterOverloadedOperator: false
AfterPlacementOperator: true
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: Never
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParens: Never
SpacesInParensOptions:
ExceptDoubleParentheses: false
InCStyleCasts: false
InConditionalStatements: false
InEmptyParentheses: false
Other: false
SpacesInSquareBrackets: false
Standard: Auto
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TableGenBreakInsideDAGArg: DontBreak
TabWidth: 2
UseTab: Never
VerilogBreakBetweenInstancePorts: true
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
WrapNamespaceBodyWithEmptyLines: Leave
...
Executable → Regular
+7 -8
View File
@@ -1,10 +1,10 @@
#pragma once #pragma once
#include <iostream> #include <iostream>
#include <vector>
#include <set> #include <set>
#include <vector>
#define BIT(x) (1<<x) #define BIT(x) (1 << x)
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define STR(x) STRINGIFY(x) #define STR(x) STRINGIFY(x)
@@ -31,7 +31,6 @@ const static unsigned int FLAG_SIMPLE = BIT(9);
const static unsigned int FLAG_CONFIG = BIT(10); const static unsigned int FLAG_CONFIG = BIT(10);
const static unsigned int FLAG_TARGET = BIT(11); const static unsigned int FLAG_TARGET = BIT(11);
#define LOG_INFO(...) LogHelper(__VA_ARGS__) #define LOG_INFO(...) LogHelper(__VA_ARGS__)
#define LOG_WARNING(...) LogHelper(__VA_ARGS__) #define LOG_WARNING(...) LogHelper(__VA_ARGS__)
#define LOG_ERROR(...) LogHelper(__VA_ARGS__) #define LOG_ERROR(...) LogHelper(__VA_ARGS__)
@@ -42,22 +41,22 @@ void Log(const T& var)
std::cout << var; std::cout << var;
} }
template <typename T, typename ...Ts> template <typename T, typename... Ts>
void Log(const T& var, const Ts& ...vars) void Log(const T& var, const Ts&... vars)
{ {
Log(var); Log(var);
Log(vars...); Log(vars...);
} }
template <typename T, typename ...Ts> template <typename T, typename... Ts>
void LogHelper(const T& var) void LogHelper(const T& var)
{ {
Log(var); Log(var);
std::cout << std::endl; std::cout << std::endl;
} }
template <typename T, typename ...Ts> template <typename T, typename... Ts>
void LogHelper(const T& var, const Ts& ...vars) void LogHelper(const T& var, const Ts&... vars)
{ {
Log(var); Log(var);
Log(vars...); Log(vars...);
+41 -42
View File
@@ -5,7 +5,7 @@
void ConfigCLI::DisplayCLIHelp() void ConfigCLI::DisplayCLIHelp()
{ {
LOG_INFO(1+(char*)R"( LOG_INFO(1 + (char*)R"(
MakeGen conf is used to create, modify and query the makegen.xml file. MakeGen conf is used to create, modify and query the makegen.xml file.
Usage: makegen conf <command> [<args>] [--help] Usage: makegen conf <command> [<args>] [--help]
@@ -25,7 +25,7 @@ Querying config settings
void ConfigCLI::DisplayGenHelp() void ConfigCLI::DisplayGenHelp()
{ {
LOG_INFO(1+(char*)R"( LOG_INFO(1 + (char*)R"(
Generate a config file from prompts Generate a config file from prompts
Usage: makegen conf gen <option> Usage: makegen conf gen <option>
@@ -39,7 +39,7 @@ options:
void ConfigCLI::DisplayAddHelp() void ConfigCLI::DisplayAddHelp()
{ {
LOG_INFO(1+(char*)R"( LOG_INFO(1 + (char*)R"(
Add values to config settings which support multiple arguments Add values to config settings which support multiple arguments
Usage: makegen conf add <setting> <value> [<values>] Usage: makegen conf add <setting> <value> [<values>]
@@ -60,7 +60,7 @@ Valid settings are:
void ConfigCLI::DisplayRemoveHelp() void ConfigCLI::DisplayRemoveHelp()
{ {
LOG_INFO(1+(char*)R"( LOG_INFO(1 + (char*)R"(
Remove values to config settings which support multiple Remove values to config settings which support multiple
Usage: makegen conf remove <setting> <value> [< Usage: makegen conf remove <setting> <value> [<
@@ -81,7 +81,7 @@ Valid settings are
void ConfigCLI::DisplaySetHelp() void ConfigCLI::DisplaySetHelp()
{ {
LOG_INFO(1+(char*)R"( LOG_INFO(1 + (char*)R"(
Set value to config settings which only support one argument Set value to config settings which only support one argument
Usage: makegen conf set <setting> <value> Usage: makegen conf set <setting> <value>
@@ -102,7 +102,7 @@ Boolean values can be set to either true/t/yes/y or false/f/no/n)");
void ConfigCLI::DisplayGetHelp() void ConfigCLI::DisplayGetHelp()
{ {
LOG_INFO(1+(char*)R"( LOG_INFO(1 + (char*)R"(
Get value of the config setting Get value of the config setting
Usage: makegen conf get <setting> Usage: makegen conf get <setting>
@@ -128,7 +128,6 @@ Valid settings are:
genhfile Specifies if MakeGen should generate a project h-file)"); genhfile Specifies if MakeGen should generate a project h-file)");
} }
ConfigSetting ConfigCLI::CLIStringToSetting(const std::string& s) ConfigSetting ConfigCLI::CLIStringToSetting(const std::string& s)
{ {
static std::map<std::string, ConfigSetting> map{ static std::map<std::string, ConfigSetting> map{
@@ -152,30 +151,30 @@ ConfigSetting ConfigCLI::CLIStringToSetting(const std::string& s)
{"genhfile", ConfigSetting::GenerateHFile}, {"genhfile", ConfigSetting::GenerateHFile},
}; };
auto it = map.find(s); auto it = map.find(s);
if(it == map.end()) if (it == map.end())
return ConfigSetting::Invalid; return ConfigSetting::Invalid;
return it->second; return it->second;
} }
int ConfigCLI::Gen(int argc, char** argv) int ConfigCLI::Gen(int argc, char** argv)
{ {
if(argc < 2 || std::string(argv[1]) == "--help") if (argc < 2 || std::string(argv[1]) == "--help")
{ {
DisplayGenHelp(); DisplayGenHelp();
return 0; return 0;
} }
if(argc < 2) if (argc < 2)
{ {
LOG_ERROR("gen needs exactly one parameter"); LOG_ERROR("gen needs exactly one parameter");
return 1; return 1;
} }
std::string option = argv[1]; std::string option = argv[1];
if(option == "prompt") if (option == "prompt")
{ {
ConfigFile::Gen(FlagData{}).Save(); ConfigFile::Gen(FlagData{}).Save();
return 0; return 0;
} }
if(option == "default") if (option == "default")
{ {
ConfigFile{FileUtils::GetRealPath("."), FlagData{}, 0}.Save(); ConfigFile{FileUtils::GetRealPath("."), FlagData{}, 0}.Save();
return 0; return 0;
@@ -189,21 +188,21 @@ int ConfigCLI::Gen(int argc, char** argv)
int ConfigCLI::Add(int argc, char** argv, ConfigFile& config) int ConfigCLI::Add(int argc, char** argv, ConfigFile& config)
{ {
if(argc < 2 || std::string(argv[1]) == "--help") if (argc < 2 || std::string(argv[1]) == "--help")
{ {
DisplayAddHelp(); DisplayAddHelp();
return 0; return 0;
} }
if(argc < 3) if (argc < 3)
{ {
LOG_ERROR("add needs at least two parameters"); LOG_ERROR("add needs at least two parameters");
return 1; return 1;
} }
ConfigSetting setting = CLIStringToSetting(argv[1]); ConfigSetting setting = CLIStringToSetting(argv[1]);
if(!ConfigUtils::IsVectorSetting(setting)) if (!ConfigUtils::IsVectorSetting(setting))
{ {
if(setting == ConfigSetting::Invalid) if (setting == ConfigSetting::Invalid)
{ {
LOG_ERROR("No such setting: ", argv[1]); LOG_ERROR("No such setting: ", argv[1]);
} }
@@ -214,7 +213,7 @@ int ConfigCLI::Add(int argc, char** argv, ConfigFile& config)
} }
return 1; return 1;
} }
for(int i = 2; i<argc;++i) for (int i = 2; i < argc; ++i)
{ {
config.AddSettingVectorString(setting, argv[i]); config.AddSettingVectorString(setting, argv[i]);
} }
@@ -225,21 +224,21 @@ int ConfigCLI::Add(int argc, char** argv, ConfigFile& config)
int ConfigCLI::Remove(int argc, char** argv, ConfigFile& config) int ConfigCLI::Remove(int argc, char** argv, ConfigFile& config)
{ {
if(argc < 2 || std::string(argv[1]) == "--help") if (argc < 2 || std::string(argv[1]) == "--help")
{ {
DisplayRemoveHelp(); DisplayRemoveHelp();
return 0; return 0;
} }
if(argc < 3) if (argc < 3)
{ {
LOG_ERROR("remove needs at least two parameters"); LOG_ERROR("remove needs at least two parameters");
return 1; return 1;
} }
ConfigSetting setting = CLIStringToSetting(argv[1]); ConfigSetting setting = CLIStringToSetting(argv[1]);
if(!ConfigUtils::IsVectorSetting(setting)) if (!ConfigUtils::IsVectorSetting(setting))
{ {
if(setting == ConfigSetting::Invalid) if (setting == ConfigSetting::Invalid)
{ {
LOG_ERROR("No such setting: ", argv[1]); LOG_ERROR("No such setting: ", argv[1]);
} }
@@ -251,7 +250,7 @@ int ConfigCLI::Remove(int argc, char** argv, ConfigFile& config)
return 1; return 1;
} }
for(int i = 2; i<argc;++i) for (int i = 2; i < argc; ++i)
{ {
config.RemoveSettingVectorString(setting, argv[i]); config.RemoveSettingVectorString(setting, argv[i]);
} }
@@ -262,21 +261,21 @@ int ConfigCLI::Remove(int argc, char** argv, ConfigFile& config)
int ConfigCLI::Set(int argc, char** argv, ConfigFile& config) int ConfigCLI::Set(int argc, char** argv, ConfigFile& config)
{ {
if(argc < 2 || std::string(argv[1]) == "--help") if (argc < 2 || std::string(argv[1]) == "--help")
{ {
DisplaySetHelp(); DisplaySetHelp();
return 0; return 0;
} }
if(argc != 3) if (argc != 3)
{ {
LOG_ERROR("set needs exactly two parameters"); LOG_ERROR("set needs exactly two parameters");
return 1; return 1;
} }
ConfigSetting setting = CLIStringToSetting(argv[1]); ConfigSetting setting = CLIStringToSetting(argv[1]);
if(!ConfigUtils::IsStringSetting(setting) && !ConfigUtils::IsBoolSetting(setting)) if (!ConfigUtils::IsStringSetting(setting) && !ConfigUtils::IsBoolSetting(setting))
{ {
if(setting == ConfigSetting::Invalid) if (setting == ConfigSetting::Invalid)
{ {
LOG_ERROR("No such setting: ", argv[1]); LOG_ERROR("No such setting: ", argv[1]);
} }
@@ -295,19 +294,19 @@ int ConfigCLI::Set(int argc, char** argv, ConfigFile& config)
int ConfigCLI::Get(int argc, char** argv, ConfigFile& config) int ConfigCLI::Get(int argc, char** argv, ConfigFile& config)
{ {
if(argc < 2 || std::string(argv[1]) == "--help") if (argc < 2 || std::string(argv[1]) == "--help")
{ {
DisplayGetHelp(); DisplayGetHelp();
return 0; return 0;
} }
if(argc != 2) if (argc != 2)
{ {
LOG_ERROR("get needs exactly one parameter"); LOG_ERROR("get needs exactly one parameter");
return 1; return 1;
} }
ConfigSetting setting = CLIStringToSetting(argv[1]); ConfigSetting setting = CLIStringToSetting(argv[1]);
std::vector<std::string> vector = config.GetSetting(setting); std::vector<std::string> vector = config.GetSetting(setting);
for(auto it = vector.begin(); it != vector.end(); ++it) for (auto it = vector.begin(); it != vector.end(); ++it)
{ {
LOG_INFO(*it); LOG_INFO(*it);
} }
@@ -317,32 +316,32 @@ int ConfigCLI::Get(int argc, char** argv, ConfigFile& config)
int ConfigCLI::Main(int argc, char** argv) int ConfigCLI::Main(int argc, char** argv)
{ {
// Do nothing // Do nothing
if(argc < 2 || std::string(argv[1]) == "--help") if (argc < 2 || std::string(argv[1]) == "--help")
{ {
DisplayCLIHelp(); DisplayCLIHelp();
return 0; return 0;
} }
std::optional<ConfigFile> config = ConfigFile::GetConfigFile("./", FlagData{}); std::optional<ConfigFile> config = ConfigFile::GetConfigFile("./", FlagData{});
std::string command = argv[1]; std::string command = argv[1];
if(command == "gen") if (command == "gen")
{ {
if(config) if (config)
{ {
LOG_ERROR("Config file already exist (", CONFIG_FILENAME, ")"); LOG_ERROR("Config file already exist (", CONFIG_FILENAME, ")");
return 1; return 1;
} }
return Gen(argc-1, &argv[1]); return Gen(argc - 1, &argv[1]);
} }
else if(config) else if (config)
{ {
if(command == "add") if (command == "add")
return Add(argc-1, &argv[1], *config); return Add(argc - 1, &argv[1], *config);
else if(command == "remove") else if (command == "remove")
return Remove(argc-1, &argv[1], *config); return Remove(argc - 1, &argv[1], *config);
else if(command == "set") else if (command == "set")
return Set(argc-1, &argv[1], *config); return Set(argc - 1, &argv[1], *config);
else if(command == "get") else if (command == "get")
return Get(argc-1, &argv[1], *config); return Get(argc - 1, &argv[1], *config);
else else
{ {
LOG_ERROR("Unknown config command: ", command); LOG_ERROR("Unknown config command: ", command);
+15 -15
View File
@@ -4,22 +4,22 @@
struct ConfigCLI struct ConfigCLI
{ {
public: public:
static int Main(int argc, char** argv); static int Main(int argc, char** argv);
private:
static void DisplayCLIHelp();
static void DisplayGenHelp();
static void DisplayAddHelp();
static void DisplayRemoveHelp();
static void DisplaySetHelp();
static void DisplayGetHelp();
static ConfigSetting CLIStringToSetting(const std::string& s); private:
static void DisplayCLIHelp();
static void DisplayGenHelp();
static void DisplayAddHelp();
static void DisplayRemoveHelp();
static void DisplaySetHelp();
static void DisplayGetHelp();
static int Gen(int argc, char** argv); static ConfigSetting CLIStringToSetting(const std::string& s);
static int Add(int argc, char** argv, ConfigFile& config);
static int Remove(int argc, char** argv, ConfigFile& config);
static int Set(int argc, char** argv, ConfigFile& config);
static int Get(int argc, char** argv, ConfigFile& config);
static int Gen(int argc, char** argv);
static int Add(int argc, char** argv, ConfigFile& config);
static int Remove(int argc, char** argv, ConfigFile& config);
static int Set(int argc, char** argv, ConfigFile& config);
static int Get(int argc, char** argv, ConfigFile& config);
}; };
Executable → Regular
+91 -91
View File
@@ -1,11 +1,11 @@
#include "ConfigFile.h" #include "ConfigFile.h"
#include <fstream>
#include "FileUtils.h" #include "FileUtils.h"
#include "compatibility/ConfigFileConf.h" #include "compatibility/ConfigFileConf.h"
#include "xml/XML.h" #include "xml/XML.h"
#include <fstream>
ConfigFile::ConfigFile(const std::string& path, const FlagData& flagData, int) ConfigFile::ConfigFile(const std::string& path, const FlagData& flagData, int)
: configPath{path} : configPath{path}
{ {
@@ -16,7 +16,7 @@ ConfigFile::ConfigFile(const std::string& path, const FlagData& flagData, int)
// Version, target and configuration is probably going to be used in the future // Version, target and configuration is probably going to be used in the future
makegen.AddXMLObject(XMLObject("version", {}, "v1.3.0")); makegen.AddXMLObject(XMLObject("version", {}, "v1.3.0"));
if(flagData.flags & FLAG_TARGET) if (flagData.flags & FLAG_TARGET)
makegen.AddXMLObject(XMLObject("target", {}, flagData.target)); makegen.AddXMLObject(XMLObject("target", {}, flagData.target));
else else
makegen.AddXMLObject(XMLObject("target", {}, "Release")); makegen.AddXMLObject(XMLObject("target", {}, "Release"));
@@ -36,13 +36,15 @@ ConfigFile::ConfigFile(const std::string& path, const FlagData& flagData, int)
} }
ConfigFile::ConfigFile(const std::string& path, const FlagData& flagData) ConfigFile::ConfigFile(const std::string& path, const FlagData& flagData)
: config{XML::FromFile(path + CONFIG_FILENAME)}, configPath{path} : config{XML::FromFile(path + CONFIG_FILENAME)},
configPath{path}
{ {
Init(flagData); Init(flagData);
} }
ConfigFile::ConfigFile(XMLObject& config, const std::string& path, const FlagData& flagData) ConfigFile::ConfigFile(XMLObject& config, const std::string& path, const FlagData& flagData)
: config{config}, configPath{path} : config{config},
configPath{path}
{ {
Init(flagData); Init(flagData);
} }
@@ -57,23 +59,22 @@ void ConfigFile::Init(const FlagData& flagData)
{ {
const std::vector<XMLObject>* targetXml = config.GetObjectPtr("target"); const std::vector<XMLObject>* targetXml = config.GetObjectPtr("target");
target = "Release"; target = "Release";
if(!targetXml || targetXml->size() == 0) if (!targetXml || targetXml->size() == 0)
{ {
LOG_ERROR("No target found in config file. Using target=", target); LOG_ERROR("No target found in config file. Using target=", target);
return; return;
} }
if(targetXml->size() > 1) if (targetXml->size() > 1)
LOG_ERROR("To many targets in config file. Using target=", (*targetXml)[0].GetText()); LOG_ERROR("To many targets in config file. Using target=", (*targetXml)[0].GetText());
if(targetXml->size() > 0) if (targetXml->size() > 0)
target = (*targetXml)[0].GetText(); target = (*targetXml)[0].GetText();
} }
} }
std::string& ConfigFile::GetSettingString(ConfigSetting setting) std::string& ConfigFile::GetSettingString(ConfigSetting setting)
{ {
// Adding it to the cache since we need to return a reference // Adding it to the cache since we need to return a reference
if(!ConfigUtils::IsStringSetting(setting)) if (!ConfigUtils::IsStringSetting(setting))
{ {
LOG_ERROR("Invalid string setting"); LOG_ERROR("Invalid string setting");
return cache.strings.emplace("invalid", "").first->second; return cache.strings.emplace("invalid", "").first->second;
@@ -81,43 +82,43 @@ std::string& ConfigFile::GetSettingString(ConfigSetting setting)
std::string sSetting = ConfigUtils::GetSettingName(setting); std::string sSetting = ConfigUtils::GetSettingName(setting);
auto it = cache.strings.find(sSetting); auto it = cache.strings.find(sSetting);
if(it != cache.strings.end()) if (it != cache.strings.end())
return it->second; return it->second;
const std::vector<XMLObject>* values = GetConfiguration().GetObjectPtr(sSetting); const std::vector<XMLObject>* values = GetConfiguration().GetObjectPtr(sSetting);
// No value found, using default // No value found, using default
if(values == nullptr) if (values == nullptr)
return cache.strings.emplace(sSetting, ConfigUtils::GetDefaultSettingString(setting, configPath)).first->second; return cache.strings.emplace(sSetting, ConfigUtils::GetDefaultSettingString(setting, configPath)).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("To many arguments for setting using first: ", (int)setting, "=", (*values)[0].GetText());
} }
std::string s = (*values)[0].GetText(); std::string s = (*values)[0].GetText();
if(ConfigUtils::IsDirectory(setting) && !s.empty() && s[s.size()-1] != '/') if (ConfigUtils::IsDirectory(setting) && !s.empty() && s[s.size() - 1] != '/')
s += '/'; s += '/';
return cache.strings.emplace(sSetting, s).first->second; return cache.strings.emplace(sSetting, s).first->second;
} }
bool ConfigFile::GetSettingBool(ConfigSetting setting) bool ConfigFile::GetSettingBool(ConfigSetting setting)
{ {
if(setting == ConfigSetting::Invalid) if (setting == ConfigSetting::Invalid)
{ {
LOG_ERROR("Invalid config setting"); LOG_ERROR("Invalid config setting");
return false; return false;
} }
std::string sSetting = ConfigUtils::GetSettingName(setting); std::string sSetting = ConfigUtils::GetSettingName(setting);
auto it = cache.bools.find(sSetting); auto it = cache.bools.find(sSetting);
if(it != cache.bools.end()) if (it != cache.bools.end())
return it->second; return it->second;
const std::vector<XMLObject>* values = GetConfiguration().GetObjectPtr(sSetting);//, const std::vector<XMLObject>* values = GetConfiguration().GetObjectPtr(sSetting); //,
if(values == nullptr) if (values == nullptr)
return cache.bools.emplace(sSetting, ConfigUtils::GetDefaultSettingBool(setting)).first->second; 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("To many arguments for setting using first: ", (int)setting, "=", (*values)[0].GetText());
} }
@@ -128,21 +129,21 @@ std::vector<std::string>& ConfigFile::GetSettingVectorString(ConfigSetting setti
{ {
std::string sSetting = ConfigUtils::GetSettingName(setting); std::string sSetting = ConfigUtils::GetSettingName(setting);
auto it = cache.vecStrings.find(sSetting); auto it = cache.vecStrings.find(sSetting);
if(it != cache.vecStrings.end()) if (it != cache.vecStrings.end())
return it->second; return it->second;
const std::vector<XMLObject>* values = GetConfiguration().GetObjectPtr(sSetting); const std::vector<XMLObject>* values = GetConfiguration().GetObjectPtr(sSetting);
if(values == nullptr) if (values == nullptr)
return cache.vecStrings.emplace(sSetting, std::vector<std::string>{}).first->second; return cache.vecStrings.emplace(sSetting, std::vector<std::string>{}).first->second;
std::vector<std::string> strings; std::vector<std::string> strings;
strings.reserve(values->size()); strings.reserve(values->size());
for(auto it = values->begin(); it != values->end(); ++it) for (auto it = values->begin(); it != values->end(); ++it)
{ {
if(it->GetText() == "") if (it->GetText() == "")
continue; continue;
std::string s = it->GetText(); std::string s = it->GetText();
if(ConfigUtils::IsDirectory(setting) && s[s.size()-1] != '/') if (ConfigUtils::IsDirectory(setting) && s[s.size() - 1] != '/')
s += '/'; s += '/';
strings.push_back(s); strings.push_back(s);
} }
@@ -152,11 +153,11 @@ std::vector<std::string>& ConfigFile::GetSettingVectorString(ConfigSetting setti
std::vector<std::string> ConfigFile::GetSetting(ConfigSetting setting) std::vector<std::string> ConfigFile::GetSetting(ConfigSetting setting)
{ {
if(ConfigUtils::IsStringSetting(setting)) if (ConfigUtils::IsStringSetting(setting))
return {GetSettingString(setting)}; return {GetSettingString(setting)};
else if(ConfigUtils::IsVectorSetting(setting)) else if (ConfigUtils::IsVectorSetting(setting))
return GetSettingVectorString(setting); return GetSettingVectorString(setting);
else if(ConfigUtils::IsBoolSetting(setting)) else if (ConfigUtils::IsBoolSetting(setting))
return {GetSettingBool(setting) ? "true" : "false"}; return {GetSettingBool(setting) ? "true" : "false"};
else else
{ {
@@ -170,24 +171,24 @@ bool ConfigFile::SetSettingString(ConfigSetting setting, const std::string& valu
// Check if valid enum // Check if valid enum
std::string s = value; std::string s = value;
std::string sSetting = ConfigUtils::GetSettingName(setting); std::string sSetting = ConfigUtils::GetSettingName(setting);
if(ConfigUtils::IsStringSetting(setting)) if (ConfigUtils::IsStringSetting(setting))
{ {
if(ConfigUtils::IsDirectory(setting) && s[s.size()-1] != '/') if (ConfigUtils::IsDirectory(setting) && s[s.size() - 1] != '/')
{ {
s += '/'; s += '/';
} }
auto it = cache.strings.find(sSetting); auto it = cache.strings.find(sSetting);
// Update cache // Update cache
if(it != cache.strings.end()) if (it != cache.strings.end())
it->second = s; it->second = s;
else else
cache.strings.emplace(sSetting, s); cache.strings.emplace(sSetting, s);
} }
else if(ConfigUtils::IsBoolSetting(setting)) else if (ConfigUtils::IsBoolSetting(setting))
{ {
if(s == "true" || s == "t" || s == "yes" || s == "y") if (s == "true" || s == "t" || s == "yes" || s == "y")
s = "true"; s = "true";
else if(s == "false" || s == "f" || s == "no" || s == "n") else if (s == "false" || s == "f" || s == "no" || s == "n")
s = "false"; s = "false";
else else
{ {
@@ -197,7 +198,7 @@ bool ConfigFile::SetSettingString(ConfigSetting setting, const std::string& valu
auto it = cache.bools.find(sSetting); auto it = cache.bools.find(sSetting);
// Update cache // Update cache
if(it != cache.bools.end()) if (it != cache.bools.end())
it->second = s == "true"; it->second = s == "true";
else else
cache.bools.emplace(sSetting, value == "true"); cache.bools.emplace(sSetting, value == "true");
@@ -210,9 +211,9 @@ bool ConfigFile::SetSettingString(ConfigSetting setting, const std::string& valu
XMLObject& configuration = GetConfiguration(); XMLObject& configuration = GetConfiguration();
std::vector<XMLObject>* values = configuration.GetObjectPtr(sSetting); std::vector<XMLObject>* values = configuration.GetObjectPtr(sSetting);
if(values == nullptr) if (values == nullptr)
configuration.AddXMLObject({sSetting, {}, s}); configuration.AddXMLObject({sSetting, {}, s});
else if(values->size() > 1) else if (values->size() > 1)
LOG_ERROR("Multiple values of setting, changing first: ", sSetting, "=", s); LOG_ERROR("Multiple values of setting, changing first: ", sSetting, "=", s);
else else
(*values)[0].SetText(s); (*values)[0].SetText(s);
@@ -222,10 +223,10 @@ bool ConfigFile::SetSettingString(ConfigSetting setting, const std::string& valu
bool ConfigFile::AddSettingVectorString(ConfigSetting setting, const std::string& value) bool ConfigFile::AddSettingVectorString(ConfigSetting setting, const std::string& value)
{ {
// Check if valid enum // Check if valid enum
if(ConfigUtils::IsVectorSetting(setting)) if (ConfigUtils::IsVectorSetting(setting))
{ {
std::string s = value; std::string s = value;
if(ConfigUtils::IsDirectory(setting) && s[s.size()-1] != '/') if (ConfigUtils::IsDirectory(setting) && s[s.size() - 1] != '/')
{ {
s += '/'; s += '/';
} }
@@ -233,7 +234,7 @@ bool ConfigFile::AddSettingVectorString(ConfigSetting setting, const std::string
auto it = cache.vecStrings.find(sSetting); auto it = cache.vecStrings.find(sSetting);
// Update cache // Update cache
if(it != cache.vecStrings.end()) if (it != cache.vecStrings.end())
it->second.push_back(s); it->second.push_back(s);
else else
cache.vecStrings.emplace(sSetting, std::vector<std::string>{s}); cache.vecStrings.emplace(sSetting, std::vector<std::string>{s});
@@ -251,22 +252,22 @@ bool ConfigFile::AddSettingVectorString(ConfigSetting setting, const std::string
bool ConfigFile::RemoveSettingVectorString(ConfigSetting setting, const std::string& value) bool ConfigFile::RemoveSettingVectorString(ConfigSetting setting, const std::string& value)
{ {
// Check if valid enum // Check if valid enum
if(ConfigUtils::IsVectorSetting(setting)) if (ConfigUtils::IsVectorSetting(setting))
{ {
std::string s = value; std::string s = value;
if(ConfigUtils::IsDirectory(setting) && s[s.size()-1] != '/') if (ConfigUtils::IsDirectory(setting) && s[s.size() - 1] != '/')
{ {
s += '/'; s += '/';
} }
std::string sSetting = ConfigUtils::GetSettingName(setting); std::string sSetting = ConfigUtils::GetSettingName(setting);
auto it = cache.vecStrings.find(sSetting); auto it = cache.vecStrings.find(sSetting);
if(it != cache.vecStrings.end()) if (it != cache.vecStrings.end())
{ {
// Update cache // Update cache
for(auto itVec = it->second.begin(); itVec != it->second.end(); ++itVec) for (auto itVec = it->second.begin(); itVec != it->second.end(); ++itVec)
{ {
if(*itVec == s) if (*itVec == s)
{ {
it->second.erase(itVec); it->second.erase(itVec);
} }
@@ -275,16 +276,16 @@ bool ConfigFile::RemoveSettingVectorString(ConfigSetting setting, const std::str
std::vector<XMLObject>* values = GetConfiguration().GetObjectPtr(sSetting); std::vector<XMLObject>* values = GetConfiguration().GetObjectPtr(sSetting);
bool found = false; bool found = false;
for(auto it = values->begin(); it != values->end();++it) for (auto it = values->begin(); it != values->end(); ++it)
{ {
if(it->GetText() == s) if (it->GetText() == s)
{ {
values->erase(it); values->erase(it);
found = true; found = true;
break; break;
} }
} }
if(!found) if (!found)
{ {
LOG_ERROR("Couldn't find value: ", s); LOG_ERROR("Couldn't find value: ", s);
return false; return false;
@@ -301,25 +302,26 @@ bool ConfigFile::RemoveSettingVectorString(ConfigSetting setting, const std::str
XMLObject& ConfigFile::GetConfiguration() XMLObject& ConfigFile::GetConfiguration()
{ {
std::vector<XMLObject>* configurations = config.GetObjectPtr("configuration"); std::vector<XMLObject>* configurations = config.GetObjectPtr("configuration");
if(configurations == nullptr || configurations->size() == 0) if (configurations == nullptr || configurations->size() == 0)
{ {
LOG_ERROR("No configuration in makegen.xml"); LOG_ERROR("No configuration in makegen.xml");
assert(false); assert(false);
} }
for(auto it = configurations->begin(); it != configurations->end(); ++it) for (auto it = configurations->begin(); it != configurations->end(); ++it)
{ {
if(!it->HasAttribute("name")) if (!it->HasAttribute("name"))
{ {
LOG_ERROR("No name attribute in configuration tag"); LOG_ERROR("No name attribute in configuration tag");
continue; continue;
} }
if(it->GetAttribute("name") == target) if (it->GetAttribute("name") == target)
{ {
return *it; return *it;
} }
} }
LOG_ERROR("Couldn\'t find given target in config file. Using target=", (*configurations)[0].HasAttribute("name") ? (*configurations)[0].GetAttribute("name") : ""); LOG_ERROR("Couldn\'t find given target in config file. Using target=",
(*configurations)[0].HasAttribute("name") ? (*configurations)[0].GetAttribute("name") : "");
return (*configurations)[0]; return (*configurations)[0];
} }
@@ -339,20 +341,22 @@ std::optional<ConfigFile> ConfigFile::GetConfigFile(const std::string& filepath,
return GetConfigFile(filepath, loadedConfigs, flagData); return GetConfigFile(filepath, loadedConfigs, flagData);
} }
std::optional<ConfigFile> ConfigFile::GetConfigFile(const std::string& filepath, std::map<std::string, ConfigFile>& loadedConfigs, const FlagData& flagData) std::optional<ConfigFile> ConfigFile::GetConfigFile(const std::string& filepath,
std::map<std::string, ConfigFile>& loadedConfigs,
const FlagData& flagData)
{ {
std::string realPath = FileUtils::GetRealPath(filepath); std::string realPath = FileUtils::GetRealPath(filepath);
if(realPath == "") if (realPath == "")
return {}; return {};
auto it = loadedConfigs.find(realPath); auto it = loadedConfigs.find(realPath);
if(it != loadedConfigs.end()) if (it != loadedConfigs.end())
{ {
return {}; return {};
} }
bool oldFile = false; bool oldFile = false;
std::ifstream f(filepath + CONFIG_FILENAME); std::ifstream f(filepath + CONFIG_FILENAME);
if(!f.good()) if (!f.good())
{ {
ConfigFileConf::CreateXMLFile(realPath); ConfigFileConf::CreateXMLFile(realPath);
// try to read an old config file // try to read an old config file
@@ -361,20 +365,20 @@ std::optional<ConfigFile> ConfigFile::GetConfigFile(const std::string& filepath,
} }
// Check if the file exists // Check if the file exists
if(f.good()) if (f.good())
{ {
f.close(); f.close();
ConfigFile conf = ConfigFile(filepath, flagData); ConfigFile conf = ConfigFile(filepath, flagData);
if(conf.hasInitError) if (conf.hasInitError)
return {}; return {};
loadedConfigs.emplace(realPath, conf); loadedConfigs.emplace(realPath, conf);
std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency); std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency);
// Create dependency config files. // Create dependency config files.
for(size_t i = 0; i < dependencies.size();++i) for (size_t i = 0; i < dependencies.size(); ++i)
{ {
std::optional<ConfigFile> dep = GetConfigFile(conf.configPath + dependencies[i], loadedConfigs, flagData); std::optional<ConfigFile> dep = GetConfigFile(conf.configPath + dependencies[i], loadedConfigs, flagData);
if(dep) if (dep)
{ {
conf.dependencyConfigs.push_back(*dep); conf.dependencyConfigs.push_back(*dep);
dependencies[i] = dep->configPath; dependencies[i] = dep->configPath;
@@ -394,13 +398,13 @@ std::optional<ConfigFile> ConfigFile::GetConfigFile(const std::string& filepath,
void ConfigFile::InputBoolean(const std::string& inputText, bool& b) void ConfigFile::InputBoolean(const std::string& inputText, bool& b)
{ {
std::string input; std::string input;
while(true) while (true)
{ {
LOG_INFO(inputText); LOG_INFO(inputText);
std::getline(std::cin, input); std::getline(std::cin, input);
if(input.length() > 0) if (input.length() > 0)
{ {
if(input[0] == 'y' || input[0] == 'n') if (input[0] == 'y' || input[0] == 'n')
{ {
b = input[0] == 'y'; b = input[0] == 'y';
return; return;
@@ -412,13 +416,13 @@ void ConfigFile::InputBoolean(const std::string& inputText, bool& b)
void ConfigFile::InputString(const std::string& inputText, std::string& str, bool needEnding, bool allowEmpty) void ConfigFile::InputString(const std::string& inputText, std::string& str, bool needEnding, bool allowEmpty)
{ {
str = ""; str = "";
while(true) while (true)
{ {
LOG_INFO(inputText); LOG_INFO(inputText);
std::getline(std::cin, str); std::getline(std::cin, str);
if(needEnding && str[str.length()-1] != '/' && !str.empty()) if (needEnding && str[str.length() - 1] != '/' && !str.empty())
str += '/'; str += '/';
if(allowEmpty || !str.empty()) if (allowEmpty || !str.empty())
return; return;
} }
} }
@@ -426,10 +430,10 @@ void ConfigFile::InputString(const std::string& inputText, std::string& str, boo
void ConfigFile::InputMultiple(const std::string& inputText, std::vector<std::string>& vec, bool needEnding) void ConfigFile::InputMultiple(const std::string& inputText, std::vector<std::string>& vec, bool needEnding)
{ {
std::string input; std::string input;
while(true) while (true)
{ {
InputString(inputText, input, needEnding, true); InputString(inputText, input, needEnding, true);
if(input == "") if (input == "")
break; break;
vec.push_back(input); vec.push_back(input);
} }
@@ -438,22 +442,23 @@ void ConfigFile::InputMultiple(const std::string& inputText, std::vector<std::st
ConfigFile ConfigFile::Gen(const FlagData& flagData) ConfigFile ConfigFile::Gen(const FlagData& flagData)
{ {
bool executable, shared, generateHFile; bool executable, shared, generateHFile;
std::vector<std::string> libs, libdirs, includedirs, defines, compileFlags, linkingFlags, dependencies, excludeSources, excludeHeaders; std::vector<std::string> libs, libdirs, includedirs, defines, compileFlags, linkingFlags, dependencies,
excludeSources, excludeHeaders;
std::string srcdir, outputdir, projectname, outputname, hFile; std::string srcdir, outputdir, projectname, outputname, hFile;
InputBoolean("Should it be compiled as an executable? (y/n)", executable); InputBoolean("Should it be compiled as an executable? (y/n)", executable);
// If it isn't an executable there is not need to have libraries // If it isn't an executable there is not need to have libraries
if(executable) if (executable)
{ {
InputMultiple("Enter library:", libs,false); InputMultiple("Enter library:", libs, false);
InputMultiple("Enter library directory:", libdirs,true); InputMultiple("Enter library directory:", libdirs, true);
InputMultiple("Enter project dependencies:", dependencies,true); InputMultiple("Enter project dependencies:", dependencies, true);
} }
else else
{ {
InputBoolean("Should it be compiled as a shared library? (y/n)", shared); InputBoolean("Should it be compiled as a shared library? (y/n)", shared);
InputBoolean("Should it compile a project h-file? (y/n):", generateHFile); InputBoolean("Should it compile a project h-file? (y/n):", generateHFile);
if(generateHFile) if (generateHFile)
{ {
InputString("Enter the project h-file name (relative to source directory): ", hFile, false, false); InputString("Enter the project h-file name (relative to source directory): ", hFile, false, false);
} }
@@ -466,18 +471,17 @@ ConfigFile ConfigFile::Gen(const FlagData& flagData)
InputMultiple("Enter excluded source files flags:", excludeSources, false); InputMultiple("Enter excluded source files flags:", excludeSources, false);
InputMultiple("Enter excluded header files flags:", excludeHeaders, false); InputMultiple("Enter excluded header files flags:", excludeHeaders, false);
InputString("Enter output directory (default: bin):", outputdir, true, true); InputString("Enter output directory (default: bin):", outputdir, true, true);
if(outputdir == "") if (outputdir == "")
outputdir = "bin/"; outputdir = "bin/";
InputString("Enter a name for the project:", projectname, false, false); InputString("Enter a name for the project:", projectname, false, false);
InputString("Enter a name for the output file:", outputname, false, false); InputString("Enter a name for the output file:", outputname, false, false);
// Create xml // Create xml
XMLObject makegen("makegen", {}, std::map<std::string, std::vector<XMLObject>>{}); XMLObject makegen("makegen", {}, std::map<std::string, std::vector<XMLObject>>{});
// Version, target and configuration is probably going to be used in the future // Version, target and configuration is probably going to be used in the future
makegen.AddXMLObject(XMLObject("version", {}, "v1.3.0")); makegen.AddXMLObject(XMLObject("version", {}, "v1.3.0"));
if(flagData.flags & FLAG_TARGET) if (flagData.flags & FLAG_TARGET)
makegen.AddXMLObject(XMLObject("target", {}, flagData.target)); makegen.AddXMLObject(XMLObject("target", {}, flagData.target));
else else
makegen.AddXMLObject(XMLObject("target", {}, "Release")); makegen.AddXMLObject(XMLObject("target", {}, "Release"));
@@ -488,22 +492,18 @@ ConfigFile ConfigFile::Gen(const FlagData& flagData)
configuration.AddXMLObject(XMLObject("srcdir", {}, srcdir)); configuration.AddXMLObject(XMLObject("srcdir", {}, srcdir));
configuration.AddXMLObject(XMLObject("outputdir", {}, outputdir)); configuration.AddXMLObject(XMLObject("outputdir", {}, outputdir));
configuration.AddXMLObject(XMLObject("hfilename", {}, hFile)); configuration.AddXMLObject(XMLObject("hfilename", {}, hFile));
configuration.AddXMLObject(XMLObject("outputtype", {}, configuration.AddXMLObject(
executable ? "executable" : (shared ? "sharedlibrary" : "staticlibrary"))); XMLObject("outputtype", {}, executable ? "executable" : (shared ? "sharedlibrary" : "staticlibrary")));
configuration.AddXMLObject(XMLObject("generatehfile", {}, generateHFile ? "true" : "false")); configuration.AddXMLObject(XMLObject("generatehfile", {}, generateHFile ? "true" : "false"));
for(auto it = libs.begin();it != libs.end(); ++it) for (auto it = libs.begin(); it != libs.end(); ++it) configuration.AddXMLObject({"library", {}, *it});
configuration.AddXMLObject({"library",{},*it}); for (auto it = libdirs.begin(); it != libdirs.end(); ++it) configuration.AddXMLObject({"librarydir", {}, *it});
for(auto it = libdirs.begin();it != libdirs.end(); ++it) for (auto it = includedirs.begin(); it != includedirs.end(); ++it)
configuration.AddXMLObject({"librarydir",{},*it}); configuration.AddXMLObject({"includedir", {}, *it});
for(auto it = includedirs.begin();it != includedirs.end(); ++it) for (auto it = defines.begin(); it != defines.end(); ++it) configuration.AddXMLObject({"define", {}, *it});
configuration.AddXMLObject({"includedir",{},*it}); for (auto it = compileFlags.begin(); it != compileFlags.end(); ++it) configuration.AddXMLObject({"cflag", {}, *it});
for(auto it = defines.begin();it != defines.end(); ++it) for (auto it = dependencies.begin(); it != dependencies.end(); ++it)
configuration.AddXMLObject({"define",{},*it}); configuration.AddXMLObject({"dependency", {}, *it});
for(auto it = compileFlags.begin();it != compileFlags.end(); ++it)
configuration.AddXMLObject({"cflag",{},*it});
for(auto it = dependencies.begin();it != dependencies.end(); ++it)
configuration.AddXMLObject({"dependency",{},*it});
makegen.AddXMLObject(configuration); makegen.AddXMLObject(configuration);
return ConfigFile{makegen, FileUtils::GetRealPath("."), flagData}; return ConfigFile{makegen, FileUtils::GetRealPath("."), flagData};
Executable → Regular
+43 -39
View File
@@ -1,60 +1,64 @@
#pragma once #pragma once
#include "ConfigUtils.h"
#include "FlagData.h"
#include "xml/XMLObject.h"
#include <map> #include <map>
#include <optional> #include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
#include "ConfigUtils.h"
#include "FlagData.h"
#include "xml/XMLObject.h"
static const std::string CONFIG_FILENAME = "makegen.xml"; static const std::string CONFIG_FILENAME = "makegen.xml";
class ConfigFile class ConfigFile
{ {
private: private:
ConfigCache cache; ConfigCache cache;
XMLObject config; XMLObject config;
// Current configuration // Current configuration
std::string target; std::string target;
std::string configPath; std::string configPath;
std::vector<ConfigFile> dependencyConfigs; std::vector<ConfigFile> dependencyConfigs;
bool hasInitError = false; bool hasInitError = false;
public: public:
// Generates a new default config file // Generates a new default config file
ConfigFile(const std::string& path, const FlagData& flagData, int); ConfigFile(const std::string& path, const FlagData& flagData, int);
ConfigFile(const std::string& path, const FlagData& flagData); ConfigFile(const std::string& path, const FlagData& flagData);
ConfigFile(XMLObject& config, const std::string& path, const FlagData& flagData); ConfigFile(XMLObject& config, const std::string& path, const FlagData& flagData);
void Save() const; void Save() const;
std::string& GetSettingString(ConfigSetting setting); std::string& GetSettingString(ConfigSetting setting);
bool GetSettingBool(ConfigSetting setting); bool GetSettingBool(ConfigSetting setting);
std::vector<std::string>& GetSettingVectorString(ConfigSetting setting); std::vector<std::string>& GetSettingVectorString(ConfigSetting setting);
std::vector<std::string> GetSetting(ConfigSetting setting); std::vector<std::string> GetSetting(ConfigSetting setting);
bool SetSettingString(ConfigSetting setting, const std::string& value); bool SetSettingString(ConfigSetting setting, const std::string& value);
bool AddSettingVectorString(ConfigSetting setting, const std::string& value); bool AddSettingVectorString(ConfigSetting setting, const std::string& value);
bool RemoveSettingVectorString(ConfigSetting setting, const std::string& value); bool RemoveSettingVectorString(ConfigSetting setting, const std::string& value);
XMLObject& GetConfiguration(); XMLObject& GetConfiguration();
const std::string& GetConfigPath() const; const std::string& GetConfigPath() const;
ConfigFile& GetDependencyConfig(size_t i); ConfigFile& GetDependencyConfig(size_t i);
private:
void Init(const FlagData& flagData);
public: private:
static ConfigFile Gen(const FlagData& flagData); void Init(const FlagData& flagData);
static std::optional<ConfigFile> GetConfigFile(const std::string& filepath, const FlagData& flagData);
private: public:
static std::optional<ConfigFile> GetConfigFile(const std::string& filepath, std::map<std::string, ConfigFile>& loadedConfigs, const FlagData& flagData); static ConfigFile Gen(const FlagData& flagData);
static std::optional<ConfigFile> Load(const std::string& filename); static std::optional<ConfigFile> GetConfigFile(const std::string& filepath, const FlagData& flagData);
static void InputBoolean(const std::string& inputText, bool& b);
static void InputMultiple(const std::string& inputText, std::vector<std::string>& vec, bool needEnding); private:
static void InputString(const std::string& inputText, std::string& vec, bool needEnding, bool allowEmpty); 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);
}; };
+46 -37
View File
@@ -1,13 +1,14 @@
#pragma once #pragma once
#include <assert.h>
#include <map>
#include <string>
#include <vector>
#include "Common.h" #include "Common.h"
#include "FileUtils.h" #include "FileUtils.h"
#include <assert.h>
#include <map>
#include <vector>
#include <string>
struct ConfigCache struct ConfigCache
{ {
std::map<std::string, std::string> strings; std::map<std::string, std::string> strings;
@@ -18,9 +19,26 @@ struct ConfigCache
enum class ConfigSetting enum class ConfigSetting
{ {
// vectors // vectors
Library = 0, LibraryDir = 1, IncludeDir = 2, Define = 3, Dependency = 4, CFlag = 5, LFlag = 6, ExcludeSource = 7, ExcludeHeader = 8, ExecPreArgument = 9, ExecArgument = 10, SourceFile = 11, IncludeDirExclDep = 12, Library = 0,
LibraryDir = 1,
IncludeDir = 2,
Define = 3,
Dependency = 4,
CFlag = 5,
LFlag = 6,
ExcludeSource = 7,
ExcludeHeader = 8,
ExecPreArgument = 9,
ExecArgument = 10,
SourceFile = 11,
IncludeDirExclDep = 12,
// Strings // Strings
SourceDir = 32, OutputDir = 33, OutputName = 34, OutputType = 35, ProjectName = 36, HFileName = 37, SourceDir = 32,
OutputDir = 33,
OutputName = 34,
OutputType = 35,
ProjectName = 36,
HFileName = 37,
// Bools // Bools
GenerateHFile = 64, GenerateHFile = 64,
// Other // Other
@@ -31,7 +49,7 @@ struct ConfigUtils
{ {
static std::string GetSettingName(ConfigSetting setting) static std::string GetSettingName(ConfigSetting setting)
{ {
switch(setting) switch (setting)
{ {
case ConfigSetting::SourceDir: case ConfigSetting::SourceDir:
return "srcdir"; return "srcdir";
@@ -81,7 +99,7 @@ struct ConfigUtils
static bool IsDirectory(ConfigSetting setting) static bool IsDirectory(ConfigSetting setting)
{ {
switch(setting) switch (setting)
{ {
case ConfigSetting::SourceDir: case ConfigSetting::SourceDir:
case ConfigSetting::OutputDir: case ConfigSetting::OutputDir:
@@ -112,7 +130,7 @@ struct ConfigUtils
static bool IsStringSetting(ConfigSetting setting) static bool IsStringSetting(ConfigSetting setting)
{ {
switch(setting) switch (setting)
{ {
case ConfigSetting::SourceDir: case ConfigSetting::SourceDir:
case ConfigSetting::OutputDir: case ConfigSetting::OutputDir:
@@ -143,7 +161,7 @@ struct ConfigUtils
static bool IsVectorSetting(ConfigSetting setting) static bool IsVectorSetting(ConfigSetting setting)
{ {
switch(setting) switch (setting)
{ {
case ConfigSetting::LibraryDir: case ConfigSetting::LibraryDir:
case ConfigSetting::IncludeDir: case ConfigSetting::IncludeDir:
@@ -171,9 +189,10 @@ struct ConfigUtils
} }
return false; return false;
} }
static bool IsBoolSetting(ConfigSetting setting) static bool IsBoolSetting(ConfigSetting setting)
{ {
switch(setting) switch (setting)
{ {
case ConfigSetting::GenerateHFile: case ConfigSetting::GenerateHFile:
return true; return true;
@@ -204,7 +223,7 @@ struct ConfigUtils
static std::string GetDefaultSettingString(ConfigSetting setting, const std::string& path) static std::string GetDefaultSettingString(ConfigSetting setting, const std::string& path)
{ {
switch(setting) switch (setting)
{ {
case ConfigSetting::SourceDir: case ConfigSetting::SourceDir:
return "src/"; return "src/";
@@ -229,7 +248,7 @@ struct ConfigUtils
static bool GetDefaultSettingBool(ConfigSetting setting) static bool GetDefaultSettingBool(ConfigSetting setting)
{ {
switch(setting) switch (setting)
{ {
case ConfigSetting::GenerateHFile: case ConfigSetting::GenerateHFile:
return false; return false;
@@ -248,23 +267,18 @@ struct ConfigUtils
{ {
std::string projectname = GetDefaultProjectName(path); std::string projectname = GetDefaultProjectName(path);
std::string outputname; std::string outputname;
std::transform( std::transform(projectname.begin(),
projectname.begin(), projectname.end(),
projectname.end(), std::back_inserter(outputname),
std::back_inserter(outputname), [](unsigned char c)
[](unsigned char c) {
{ if (c == ' ')
if(c == ' ') return '_';
return '_'; return (char)std::tolower(c);
return (char)std::tolower(c); });
}); auto it = std::remove_if(outputname.begin(),
auto it = std::remove_if( outputname.end(),
outputname.begin(), [](unsigned char c) { return (c < '0' || c > '9') && (c < 'a' || c > 'z') && c != '_'; });
outputname.end(),
[](unsigned char c)
{
return (c < '0' || c > '9') && (c < 'a' || c > 'z') && c != '_';
});
outputname.erase(it, outputname.end()); outputname.erase(it, outputname.end());
outputname += ".out"; outputname += ".out";
return outputname; return outputname;
@@ -274,12 +288,7 @@ struct ConfigUtils
{ {
std::string hfile = GetDefaultProjectName(path); std::string hfile = GetDefaultProjectName(path);
auto it = std::remove_if( auto it = std::remove_if(
hfile.begin(), hfile.begin(), hfile.end(), [](unsigned char c) { return (c < 'a' || c > 'z') && (c < 'A' || c > 'Z'); });
hfile.end(),
[](unsigned char c)
{
return (c < 'a' || c > 'z') && (c < 'A' || c > 'Z');
});
hfile.erase(it, hfile.end()); hfile.erase(it, hfile.end());
hfile += ".h"; hfile += ".h";
return hfile; return hfile;
+46 -44
View File
@@ -1,18 +1,20 @@
#pragma once #pragma once
#include <assert.h>
#include <dirent.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <algorithm>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <string>
#include <vector>
#include "Common.h" #include "Common.h"
#include "Utils.h" #include "Utils.h"
#include <algorithm>
#include <assert.h>
#include <cstring>
#include <dirent.h>
#include <fstream>
#include <sys/stat.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <unistd.h>
#include <filesystem>
struct FileUtils struct FileUtils
{ {
@@ -20,7 +22,7 @@ struct FileUtils
{ {
struct stat info; struct stat info;
if(stat(path.c_str(), &info) != 0) if (stat(path.c_str(), &info) != 0)
return false; return false;
else else
return true; return true;
@@ -33,23 +35,23 @@ struct FileUtils
static std::string GetCurrentDirectory() static std::string GetCurrentDirectory()
{ {
static char path[256]; // Usual maximum filename static char path[256]; // Usual maximum filename
getcwd(path, sizeof(path)); getcwd(path, sizeof(path));
return GetTopDirectory(path); return GetTopDirectory(path);
} }
static std::string GetTopDirectory(const std::string& dir) static std::string GetTopDirectory(const std::string& dir)
{ {
if(dir.size() == 0) if (dir.size() == 0)
{ {
LOG_ERROR("Cannot send empty string to FileUtils::GetTopDirectory()"); LOG_ERROR("Cannot send empty string to FileUtils::GetTopDirectory()");
assert(false); assert(false);
} }
size_t dirEnd = std::string::npos; size_t dirEnd = std::string::npos;
if(dir[dir.size()-1] == '/') if (dir[dir.size() - 1] == '/')
dirEnd = dir.size()-2; dirEnd = dir.size() - 2;
size_t pos = dir.find_last_of("/", dirEnd); size_t pos = dir.find_last_of("/", dirEnd);
if(pos == std::string::npos) if (pos == std::string::npos)
{ {
LOG_ERROR("Couldn't find / (slash) in directory. This shouldn't occur."); LOG_ERROR("Couldn't find / (slash) in directory. This shouldn't occur.");
assert(false); assert(false);
@@ -60,11 +62,11 @@ struct FileUtils
static std::string GetRealPath(const std::string& filename) static std::string GetRealPath(const std::string& filename)
{ {
#if defined(__linux__) #if defined(__linux__)
if(access(filename.c_str(), F_OK ) != -1) if (access(filename.c_str(), F_OK) != -1)
{ {
char* path = realpath(filename.c_str(), NULL); char* path = realpath(filename.c_str(), NULL);
std::string sPath = path; std::string sPath = path;
sPath+="/"; sPath += "/";
free(path); free(path);
return sPath; return sPath;
} }
@@ -81,30 +83,30 @@ struct FileUtils
static std::string GetRelativePath(std::string from, std::string to) static std::string GetRelativePath(std::string from, std::string to)
{ {
std::string result; std::string result;
if(to[to.size()-1] == '/') if (to[to.size() - 1] == '/')
to.pop_back(); to.pop_back();
if(from[from.size()-1] == '/') if (from[from.size() - 1] == '/')
from.pop_back(); from.pop_back();
// Check if the directory is inside 'from' // Check if the directory is inside 'from'
if(strncmp(to.c_str(), from.c_str(), from.size()) == 0) if (strncmp(to.c_str(), from.c_str(), from.size()) == 0)
{ {
// Same directory // Same directory
if(to.size() == from.size()) if (to.size() == from.size())
return ""; return "";
// Remove the 'from' path // Remove the 'from' path
return to.substr(from.size()+1); return to.substr(from.size() + 1);
} }
// Check if the directory is a child of from // Check if the directory is a child of from
else if(strncmp(from.c_str(), to.c_str(), to.size()) == 0) else if (strncmp(from.c_str(), to.c_str(), to.size()) == 0)
{ {
std::string sub = from.substr(to.size()); std::string sub = from.substr(to.size());
size_t n = std::count(sub.begin(), sub.end(), '/'); size_t n = std::count(sub.begin(), sub.end(), '/');
for(int i = 0;i<n;i++) for (int i = 0; i < n; i++)
{ {
result+=".."; result += "..";
if(i != n-1) if (i != n - 1)
result+="/"; result += "/";
} }
return result; return result;
} }
@@ -112,21 +114,20 @@ struct FileUtils
else else
{ {
// Find the most common directory // Find the most common directory
std::string commonPath = Utils::CommonPrefix(from,to); std::string commonPath = Utils::CommonPrefix(from, to);
if (commonPath.empty()) if (commonPath.empty())
return ""; return "";
while(commonPath.back() != '/') while (commonPath.back() != '/') commonPath.pop_back();
commonPath.pop_back();
commonPath.pop_back(); commonPath.pop_back();
// Go back to the common directory // Go back to the common directory
std::string sub = from.substr(commonPath.size()); std::string sub = from.substr(commonPath.size());
size_t n = std::count(sub.begin(), sub.end(), '/'); size_t n = std::count(sub.begin(), sub.end(), '/');
for(int i = 0;i<n;i++) for (int i = 0; i < n; i++)
{ {
result+=".."; result += "..";
if(i != n-1) if (i != n - 1)
result+="/"; result += "/";
} }
// Add the path which diverges // Add the path which diverges
result += to.substr(commonPath.size()); result += to.substr(commonPath.size());
@@ -137,24 +138,25 @@ struct FileUtils
static void GetAllFiles(const std::string& folder, std::vector<std::string>& files) static void GetAllFiles(const std::string& folder, std::vector<std::string>& files)
{ {
DIR* dp; DIR* dp;
struct dirent *dirp; struct dirent* dirp;
if((dp = opendir(folder.c_str())) == NULL){ if ((dp = opendir(folder.c_str())) == NULL)
{
LOG_ERROR("Failed to open directory: ", folder); LOG_ERROR("Failed to open directory: ", folder);
return; return;
} }
while((dirp = readdir(dp)) != NULL) while ((dirp = readdir(dp)) != NULL)
{ {
if(dirp->d_type == DT_DIR) if (dirp->d_type == DT_DIR)
{ {
if(strcmp(dirp->d_name,".") == 0) if (strcmp(dirp->d_name, ".") == 0)
continue; continue;
if(strcmp(dirp->d_name,"..") == 0) if (strcmp(dirp->d_name, "..") == 0)
continue; continue;
GetAllFiles(folder+dirp->d_name+"/", files); GetAllFiles(folder + dirp->d_name + "/", files);
} }
else else
{ {
files.push_back(folder+dirp->d_name); files.push_back(folder + dirp->d_name);
} }
} }
closedir(dp); closedir(dp);
+1 -1
View File
@@ -5,5 +5,5 @@
struct FlagData struct FlagData
{ {
unsigned int flags{0}; unsigned int flags{0};
std::string target{""}; // Only set if flags contain FLAG_TARGET std::string target{""}; // Only set if flags contain FLAG_TARGET
}; };
+10 -8
View File
@@ -1,23 +1,25 @@
#include "HFileGen.h" #include "HFileGen.h"
#include "FileUtils.h"
#include <set> #include <set>
#include "FileUtils.h"
void HFileGen::Create(ConfigFile& conf) void HFileGen::Create(ConfigFile& conf)
{ {
std::set<std::string> hFiles; std::set<std::string> hFiles;
std::vector<std::string> files; std::vector<std::string> files;
std::string path = conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::SourceDir); std::string path = conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::SourceDir);
FileUtils::GetAllFiles(path,files); FileUtils::GetAllFiles(path, files);
// include paramenter with the path of the file // include paramenter with the path of the file
// For example src/graphics/Window.h -> graphics/Window.h if src is a src folder // For example src/graphics/Window.h -> graphics/Window.h if src is a src folder
for(auto it = files.begin(); it!=files.end();++it) for (auto it = files.begin(); it != files.end(); ++it)
{ {
size_t extensionPos = it->find_last_of("."); size_t extensionPos = it->find_last_of(".");
if(extensionPos != std::string::npos) if (extensionPos != std::string::npos)
{ {
std::string filename = it->substr(path.length()); 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() + conf.GetSettingString(ConfigSetting::HFileName))
{ {
// Make files sorted in alphabetical order // Make files sorted in alphabetical order
hFiles.emplace(filename); hFiles.emplace(filename);
@@ -28,11 +30,11 @@ void HFileGen::Create(ConfigFile& conf)
const std::vector<std::string>& excludeHeaders = conf.GetSettingVectorString(ConfigSetting::ExcludeHeader); const std::vector<std::string>& excludeHeaders = conf.GetSettingVectorString(ConfigSetting::ExcludeHeader);
std::ofstream os(path + "/" + conf.GetSettingString(ConfigSetting::HFileName)); std::ofstream os(path + "/" + conf.GetSettingString(ConfigSetting::HFileName));
os << "#pragma once" << std::endl << std::endl; os << "#pragma once" << std::endl << std::endl;
for(auto&& hFile : hFiles) for (auto&& hFile : hFiles)
{ {
std::string headerFile = conf.GetSettingString(ConfigSetting::SourceDir) + hFile; std::string headerFile = conf.GetSettingString(ConfigSetting::SourceDir) + hFile;
auto it = std::find(excludeHeaders.begin(), excludeHeaders.end(), headerFile); auto it = std::find(excludeHeaders.begin(), excludeHeaders.end(), headerFile);
if(it == excludeHeaders.end()) if (it == excludeHeaders.end())
os << "#include <" << hFile << ">" << std::endl; os << "#include <" << hFile << ">" << std::endl;
} }
} }
+2 -2
View File
@@ -4,6 +4,6 @@
class HFileGen class HFileGen
{ {
public: public:
static void Create(ConfigFile& conf); static void Create(ConfigFile& conf);
}; };
Executable → Regular
+29 -17
View File
@@ -1,31 +1,39 @@
#include "IncludeDeps.h" #include "IncludeDeps.h"
#include "Common.h"
#include <sstream> #include <sstream>
#include "Common.h"
std::set<std::string> IncludeDeps::printSet; std::set<std::string> IncludeDeps::printSet;
int IncludeDeps::printCounter = 0; int IncludeDeps::printCounter = 0;
IncludeDeps::IncludeDeps(const std::string& filename, const std::set<HFile>& files, std::map<std::string, IncludeDeps*>& allDeps) IncludeDeps::IncludeDeps(const std::string& filename,
const std::set<HFile>& files,
std::map<std::string, IncludeDeps*>& allDeps)
: IncludeDeps{filename, false, files, allDeps} : IncludeDeps{filename, false, files, allDeps}
{} {
}
IncludeDeps::IncludeDeps(const std::string& filename, bool projectHFile, const std::set<HFile>& files, std::map<std::string, IncludeDeps*>& allDeps) IncludeDeps::IncludeDeps(const std::string& filename,
: filepath(filename), projectHFile{projectHFile} bool projectHFile,
const std::set<HFile>& files,
std::map<std::string, IncludeDeps*>& allDeps)
: filepath(filename),
projectHFile{projectHFile}
{ {
std::filesystem::path path{filepath}; std::filesystem::path path{filepath};
if(Utils::IsHeaderFile(filename)) if (Utils::IsHeaderFile(filename))
{ {
allDeps.emplace(filepath, this); allDeps.emplace(filepath, this);
} }
std::ifstream file(filepath); std::ifstream file(filepath);
std::string line; std::string line;
while(std::getline(file,line)) while (std::getline(file, line))
{ {
std::string start; std::string start;
std::stringstream ss{line}; std::stringstream ss{line};
ss >> start; ss >> start;
if(start == "#include") if (start == "#include")
{ {
std::string include = GetIncludeFile(line); std::string include = GetIncludeFile(line);
@@ -39,25 +47,29 @@ IncludeDeps::IncludeDeps(const std::string& filename, bool projectHFile, const s
if (FileUtils::FileExists(includeFileRelativeToSource.string())) if (FileUtils::FileExists(includeFileRelativeToSource.string()))
{ {
auto itD = allDeps.find(includeFileRelativeToSource.string()); auto itD = allDeps.find(includeFileRelativeToSource.string());
if(itD == allDeps.end()) if (itD == allDeps.end())
{ {
IncludeDeps* inc = new IncludeDeps(includeFileRelativeToSource.string(), false, files, allDeps); IncludeDeps* inc = new IncludeDeps(includeFileRelativeToSource.string(), false, files, allDeps);
dependencies.emplace(includeFileRelativeToSource, inc); dependencies.emplace(includeFileRelativeToSource, inc);
} else { }
else
{
dependencies.emplace(itD->first, itD->second); dependencies.emplace(itD->first, itD->second);
} }
} }
else else
{ {
auto it = files.find({include, "", false}); auto it = files.find({include, "", false});
if(it != files.end()) if (it != files.end())
{ {
auto itD = allDeps.find(it->filepath); auto itD = allDeps.find(it->filepath);
if(itD == allDeps.end()) if (itD == allDeps.end())
{ {
IncludeDeps* inc = new IncludeDeps(it->filepath, it->isProjectHFile, files, allDeps); IncludeDeps* inc = new IncludeDeps(it->filepath, it->isProjectHFile, files, allDeps);
dependencies.emplace(it->filepath, inc); dependencies.emplace(it->filepath, inc);
}else{ }
else
{
dependencies.emplace(itD->first, itD->second); dependencies.emplace(itD->first, itD->second);
} }
} }
@@ -69,19 +81,19 @@ IncludeDeps::IncludeDeps(const std::string& filename, bool projectHFile, const s
std::string IncludeDeps::GetIncludeFile(const std::string& line) std::string IncludeDeps::GetIncludeFile(const std::string& line)
{ {
size_t bracket = line.find('<'); size_t bracket = line.find('<');
if(bracket == std::string::npos) if (bracket == std::string::npos)
{ {
bracket = line.find('\"'); bracket = line.find('\"');
if(bracket == std::string::npos) if (bracket == std::string::npos)
{ {
return ""; return "";
} }
std::string include = line.substr(bracket + 1, line.find('\"',bracket+1)-bracket-1); std::string include = line.substr(bracket + 1, line.find('\"', bracket + 1) - bracket - 1);
return include; return include;
} }
else else
{ {
return line.substr(bracket+1, line.find('>',bracket+1)-bracket-1); return line.substr(bracket + 1, line.find('>', bracket + 1) - bracket - 1);
} }
} }
Executable → Regular
+40 -34
View File
@@ -1,68 +1,74 @@
#pragma once #pragma once
#include "ConfigFile.h"
#include "FileUtils.h"
#include <iostream>
#include <filesystem> #include <filesystem>
#include <iostream>
#include <map> #include <map>
#include <set> #include <set>
#include <string> #include <string>
#include "ConfigFile.h"
#include "FileUtils.h"
struct CompareIncludeDeps; struct CompareIncludeDeps;
class IncludeDeps class IncludeDeps
{ {
public: public:
std::map<std::string, IncludeDeps*> dependencies; std::map<std::string, IncludeDeps*> dependencies;
std::filesystem::path filepath; std::filesystem::path filepath;
bool projectHFile; bool projectHFile;
static std::set<std::string> printSet; static std::set<std::string> printSet;
static int printCounter; static int printCounter;
IncludeDeps(const std::string& filename, const std::set<HFile>& files, std::map<std::string, IncludeDeps*>& allDeps); IncludeDeps(const std::string& filename, const std::set<HFile>& files, std::map<std::string, IncludeDeps*>& allDeps);
IncludeDeps(const std::string& filename, bool projectHFile, const std::set<HFile>& files, std::map<std::string, IncludeDeps*>& allDeps); IncludeDeps(const std::string& filename,
bool projectHFile,
const std::set<HFile>& files,
std::map<std::string, IncludeDeps*>& allDeps);
std::string GetIncludeFile(const std::string& line); std::string GetIncludeFile(const std::string& line);
std::ostream& Output(std::ostream& stream, const ConfigFile& conf) std::ostream& Output(std::ostream& stream, const ConfigFile& conf)
{ {
std::string filePathInMakeFile = filepath; std::string filePathInMakeFile = filepath;
if(!filepath.is_absolute()) 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()) if (printSet.find(filePathInMakeFile) != printSet.end())
return stream;
printSet.emplace(filePathInMakeFile);
printCounter++;
if(!projectHFile)
{
stream << " " << filePathInMakeFile;
}
for(auto it = dependencies.begin(); it != dependencies.end(); ++it)
{
(it->second)->Output(stream, conf);
}
printCounter--;
if(printCounter == 0)
printSet.clear();
return stream; return stream;
printSet.emplace(filePathInMakeFile);
printCounter++;
if (!projectHFile)
{
stream << " " << filePathInMakeFile;
} }
for (auto it = dependencies.begin(); it != dependencies.end(); ++it)
{
(it->second)->Output(stream, conf);
}
printCounter--;
if (printCounter == 0)
printSet.clear();
return stream;
}
}; };
struct CompareIncludeDeps struct CompareIncludeDeps
{ {
using is_transparent = void; using is_transparent = void;
bool operator()(const IncludeDeps* d1, const IncludeDeps* d2) const bool operator()(const IncludeDeps* d1, const IncludeDeps* d2) const
{ {
return d1->filepath < d2->filepath; return d1->filepath < d2->filepath;
} }
bool operator()(const IncludeDeps* d, const std::string& filepath) const bool operator()(const IncludeDeps* d, const std::string& filepath) const
{ {
return d->filepath < filepath; return d->filepath < filepath;
} }
bool operator()(const std::string& filepath, const IncludeDeps* d) const bool operator()(const std::string& filepath, const IncludeDeps* d) const
{ {
return filepath < d->filepath; return filepath < d->filepath;
+36 -36
View File
@@ -1,30 +1,31 @@
#include "Makefile.h" #include "Makefile.h"
#include "IncludeDeps.h"
#include "Utils.h"
#include "Common.h"
#include <fstream> #include <fstream>
#include <map> #include <map>
#include "Common.h"
#include "IncludeDeps.h"
#include "Utils.h"
void Makefile::Save(ConfigFile& conf, unsigned int flags) void Makefile::Save(ConfigFile& conf, unsigned int flags)
{ {
std::set<HFile> hFiles; // hFile, directory std::set<HFile> hFiles; // hFile, directory
std::set<std::string> cppFiles; std::set<std::string> cppFiles;
if(flags & FLAG_SIMPLE) if (flags & FLAG_SIMPLE)
Utils::GetCppFiles(conf, cppFiles); Utils::GetCppFiles(conf, cppFiles);
else else
Utils::GetCppAndHFiles(conf, hFiles, cppFiles); 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 << "# 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 << "# and is licensed under MIT. Full source of the project can be found at" << std::endl;
outputFile << "# https://github.com/Thraix/MakeGen" << std::endl; outputFile << "# https://github.com/Thraix/MakeGen" << std::endl;
outputFile << "CC=@g++" << std::endl; outputFile << "CC=@g++" << std::endl;
std::string outputtype = conf.GetSettingString(ConfigSetting::OutputType); std::string outputtype = conf.GetSettingString(ConfigSetting::OutputType);
if(outputtype != "executable") if (outputtype != "executable")
{ {
if(outputtype == "sharedlibrary") if (outputtype == "sharedlibrary")
outputFile << "CO=@g++ -shared -o" << std::endl; outputFile << "CO=@g++ -shared -o" << std::endl;
else else
outputFile << "CO=@g++ -o" << std::endl; outputFile << "CO=@g++ -o" << std::endl;
@@ -37,25 +38,25 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
outputFile << "OBJPATH=$(BIN)intermediates" << std::endl; outputFile << "OBJPATH=$(BIN)intermediates" << std::endl;
outputFile << "INCLUDES="; outputFile << "INCLUDES=";
std::vector<std::string>& includedirs = conf.GetSettingVectorString(ConfigSetting::IncludeDir); std::vector<std::string>& includedirs = conf.GetSettingVectorString(ConfigSetting::IncludeDir);
for(auto it = includedirs.begin(); it != includedirs.end(); ++it) for (auto it = includedirs.begin(); it != includedirs.end(); ++it)
{ {
outputFile << "-I " << *it << " "; outputFile << "-I " << *it << " ";
} }
std::vector<std::string>& includedirsexcldep = conf.GetSettingVectorString(ConfigSetting::IncludeDirExclDep); std::vector<std::string>& includedirsexcldep = conf.GetSettingVectorString(ConfigSetting::IncludeDirExclDep);
for(auto it = includedirsexcldep.begin(); it != includedirsexcldep.end(); ++it) for (auto it = includedirsexcldep.begin(); it != includedirsexcldep.end(); ++it)
{ {
outputFile << "-I " << *it << " "; outputFile << "-I " << *it << " ";
} }
outputFile << std::endl; outputFile << std::endl;
outputFile << "OBJECTS="; outputFile << "OBJECTS=";
for(auto it = cppFiles.begin();it!=cppFiles.end();++it) for (auto it = cppFiles.begin(); it != cppFiles.end(); ++it)
{ {
size_t extensionPos = it->find_last_of("."); size_t extensionPos = it->find_last_of(".");
size_t slash = it->find_last_of("/")+1; size_t slash = it->find_last_of("/") + 1;
outputFile << "$(OBJPATH)/" << it->substr(slash, extensionPos - slash) << ".o "; outputFile << "$(OBJPATH)/" << it->substr(slash, extensionPos - slash) << ".o ";
} }
outputFile << std::endl; outputFile << std::endl;
if(outputtype == "executable" || outputtype != "sharedlibrary") if (outputtype == "executable" || outputtype != "sharedlibrary")
{ {
outputFile << "CFLAGS=$(INCLUDES) -std=c++17 -c "; outputFile << "CFLAGS=$(INCLUDES) -std=c++17 -c ";
} }
@@ -64,48 +65,48 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
outputFile << "CFLAGS=$(INCLUDES) -fPIC -std=c++17 -c "; outputFile << "CFLAGS=$(INCLUDES) -fPIC -std=c++17 -c ";
} }
std::vector<std::string>& defines = conf.GetSettingVectorString(ConfigSetting::Define); std::vector<std::string>& defines = conf.GetSettingVectorString(ConfigSetting::Define);
for(auto it = defines.begin(); it != defines.end(); ++it) for (auto it = defines.begin(); it != defines.end(); ++it)
{ {
outputFile << "-D" << *it << " "; outputFile << "-D" << *it << " ";
} }
std::vector<std::string>& cflags = conf.GetSettingVectorString(ConfigSetting::CFlag); std::vector<std::string>& cflags = conf.GetSettingVectorString(ConfigSetting::CFlag);
for(auto it = cflags.begin(); it != cflags.end(); ++it) for (auto it = cflags.begin(); it != cflags.end(); ++it)
{ {
outputFile << *it << " "; outputFile << *it << " ";
} }
outputFile << std::endl; outputFile << std::endl;
if(outputtype == "executable") if (outputtype == "executable")
{ {
std::vector<std::string>& libdirs= conf.GetSettingVectorString(ConfigSetting::LibraryDir); std::vector<std::string>& libdirs = conf.GetSettingVectorString(ConfigSetting::LibraryDir);
outputFile << "LIBDIR="; outputFile << "LIBDIR=";
for(auto it = libdirs.begin();it!=libdirs.end();++it) for (auto it = libdirs.begin(); it != libdirs.end(); ++it)
{ {
outputFile << "-L " << *it << " "; outputFile << "-L " << *it << " ";
} }
outputFile << std::endl; outputFile << std::endl;
std::vector<std::string>& lflags = conf.GetSettingVectorString(ConfigSetting::LFlag); std::vector<std::string>& lflags = conf.GetSettingVectorString(ConfigSetting::LFlag);
outputFile << "LDFLAGS="; outputFile << "LDFLAGS=";
for(auto it = lflags.begin(); it != lflags.end(); ++it) for (auto it = lflags.begin(); it != lflags.end(); ++it)
{ {
outputFile << *it << " "; outputFile << *it << " ";
} }
for(auto it = libdirs.begin(); it != libdirs.end(); ++it) for (auto it = libdirs.begin(); it != libdirs.end(); ++it)
{ {
outputFile << "-Wl,-rpath=" << *it << " "; outputFile << "-Wl,-rpath=" << *it << " ";
} }
outputFile << std::endl; outputFile << std::endl;
std::vector<std::string>& libs = conf.GetSettingVectorString(ConfigSetting::Library); std::vector<std::string>& libs = conf.GetSettingVectorString(ConfigSetting::Library);
outputFile << "LIBS=$(LIBDIR) "; outputFile << "LIBS=$(LIBDIR) ";
for(auto it = libs.begin(); it != libs.end(); ++it) for (auto it = libs.begin(); it != libs.end(); ++it)
{ {
outputFile << "-l" << *it << " "; outputFile << "-l" << *it << " ";
} }
outputFile << std::endl; outputFile << std::endl;
std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency); std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency);
if(!dependencies.empty()) if (!dependencies.empty())
{ {
outputFile << "DEPENDENCIES="; outputFile << "DEPENDENCIES=";
for(auto it = dependencies.begin();it!=dependencies.end();++it) for (auto it = dependencies.begin(); it != dependencies.end(); ++it)
{ {
outputFile << *it << " "; outputFile << *it << " ";
} }
@@ -132,17 +133,15 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
// Run // Run
outputFile << "run: all" << std::endl; outputFile << "run: all" << std::endl;
if(outputtype == "executable") if (outputtype == "executable")
{ {
std::vector<std::string>& prearguments = conf.GetSettingVectorString(ConfigSetting::ExecPreArgument); std::vector<std::string>& prearguments = conf.GetSettingVectorString(ConfigSetting::ExecPreArgument);
std::vector<std::string>& arguments = conf.GetSettingVectorString(ConfigSetting::ExecArgument); std::vector<std::string>& arguments = conf.GetSettingVectorString(ConfigSetting::ExecArgument);
outputFile << "\t@"; outputFile << "\t@";
for(auto&& preargument : prearguments) for (auto&& preargument : prearguments) outputFile << preargument << " ";
outputFile << preargument << " ";
outputFile << "./$(OUTPUT)"; outputFile << "./$(OUTPUT)";
for(auto&& argument : arguments) for (auto&& argument : arguments) outputFile << " " << argument;
outputFile << " " << argument;
outputFile << std::endl; outputFile << std::endl;
} }
@@ -157,27 +156,28 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
// Output file // Output file
outputFile << "$(OUTPUT): $(OBJECTS)" << std::endl; outputFile << "$(OUTPUT): $(OBJECTS)" << std::endl;
outputFile << "\t$(info Generating output file)" << std::endl; outputFile << "\t$(info Generating output file)" << std::endl;
if(outputtype == "executable") if (outputtype == "executable")
outputFile << "\t$(CO) $(OUTPUT) $(OBJECTS) $(LDFLAGS) $(LIBS)" << std::endl; outputFile << "\t$(CO) $(OUTPUT) $(OBJECTS) $(LDFLAGS) $(LIBS)" << std::endl;
else else
outputFile << "\t$(CO) $(OUTPUT) $(OBJECTS)" << std::endl; outputFile << "\t$(CO) $(OUTPUT) $(OBJECTS)" << std::endl;
// Install // Install
outputFile << "install: all" << std::endl; outputFile << "install: all" << std::endl;
outputFile << "\t$(info Installing " << conf.GetSettingString(ConfigSetting::ProjectName) <<" to /usr/bin/)" << 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@cp $(OUTPUT) /usr/bin/" << conf.GetSettingString(ConfigSetting::OutputName) << std::endl;
std::map<std::string, IncludeDeps*> dependencies; std::map<std::string, IncludeDeps*> dependencies;
size_t i = 0; size_t i = 0;
for(auto it = cppFiles.begin(); it != cppFiles.end();++it) for (auto it = cppFiles.begin(); it != cppFiles.end(); ++it)
{ {
i++; i++;
auto itD = dependencies.find(*it); auto itD = dependencies.find(*it);
if(itD == dependencies.end()) if (itD == dependencies.end())
{ {
size_t extensionPos = it->find_last_of("."); size_t extensionPos = it->find_last_of(".");
size_t slash = it->find_last_of("/")+1; size_t slash = it->find_last_of("/") + 1;
std::string oFile = it->substr(slash, extensionPos - slash)+".o "; std::string oFile = it->substr(slash, extensionPos - slash) + ".o ";
outputFile << "$(OBJPATH)/" << oFile << ":"; outputFile << "$(OBJPATH)/" << oFile << ":";
if (flags & FLAG_SIMPLE) if (flags & FLAG_SIMPLE)
Executable → Regular
+2 -2
View File
@@ -4,6 +4,6 @@
class Makefile class Makefile
{ {
public: public:
static void Save(ConfigFile& conf, unsigned int flags); static void Save(ConfigFile& conf, unsigned int flags);
}; };
Executable → Regular
+19 -14
View File
@@ -4,20 +4,25 @@
class Timer class Timer
{ {
private: private:
std::chrono::time_point<std::chrono::high_resolution_clock> m_start; std::chrono::time_point<std::chrono::high_resolution_clock> m_start;
public:
Timer(){
Reset();
}
void Reset() public:
{ Timer()
m_start = std::chrono::high_resolution_clock::now(); {
} Reset();
}
float Elapsed() void Reset()
{ {
return std::chrono::duration_cast<std::chrono::duration<float,std::milli>>(std::chrono::high_resolution_clock::now() - m_start).count() / 1000.0f; m_start = std::chrono::high_resolution_clock::now();
} }
float Elapsed()
{
return std::chrono::duration_cast<std::chrono::duration<float, std::milli>>(
std::chrono::high_resolution_clock::now() - m_start)
.count() /
1000.0f;
}
}; };
+33 -30
View File
@@ -1,16 +1,16 @@
#include "Utils.h" #include "Utils.h"
#include <filesystem>
#include "ConfigFile.h" #include "ConfigFile.h"
#include "FileUtils.h" #include "FileUtils.h"
#include <filesystem>
bool Utils::IsSourceFile(const std::string& filepath) bool Utils::IsSourceFile(const std::string& filepath)
{ {
std::string_view extension(filepath); std::string_view extension(filepath);
size_t pSlash = filepath.find_last_of('/'); size_t pSlash = filepath.find_last_of('/');
size_t pDot = filepath.find_last_of('.'); size_t pDot = filepath.find_last_of('.');
if(pDot == std::string::npos || (pSlash != std::string::npos && pSlash > pDot)) if (pDot == std::string::npos || (pSlash != std::string::npos && pSlash > pDot))
{ {
LOG_ERROR("No file extension for file: ", filepath); LOG_ERROR("No file extension for file: ", filepath);
return false; return false;
@@ -24,7 +24,7 @@ bool Utils::IsHeaderFile(const std::string& filepath)
std::string_view extension(filepath); std::string_view extension(filepath);
size_t pSlash = filepath.find_last_of('/'); size_t pSlash = filepath.find_last_of('/');
size_t pDot = filepath.find_last_of('.'); size_t pDot = filepath.find_last_of('.');
if(pDot == std::string::npos || (pSlash != std::string::npos && pSlash > pDot)) if (pDot == std::string::npos || (pSlash != std::string::npos && pSlash > pDot))
{ {
return false; return false;
} }
@@ -40,13 +40,12 @@ bool Utils::StartsWith(const std::string& str, const std::string& prefix)
return str.compare(0, prefix.size(), prefix) == 0; return str.compare(0, prefix.size(), prefix) == 0;
} }
std::string Utils::CommonPrefix(const std::string& s1, const std::string& s2) std::string Utils::CommonPrefix(const std::string& s1, const std::string& s2)
{ {
size_t n = 0; size_t n = 0;
for(size_t i = 0; i<s1.size() && i<s2.size();++i) for (size_t i = 0; i < s1.size() && i < s2.size(); ++i)
{ {
if(s1[i] != s2[i]) if (s1[i] != s2[i])
{ {
n = i; n = i;
break; break;
@@ -66,21 +65,21 @@ void Utils::GetCppFiles(ConfigFile& conf, std::set<std::string>& cppFiles)
} }
const std::vector<std::string>& excludeSources = conf.GetSettingVectorString(ConfigSetting::ExcludeSource); const std::vector<std::string>& excludeSources = conf.GetSettingVectorString(ConfigSetting::ExcludeSource);
for(const auto& sourceFile : conf.GetSettingVectorString(ConfigSetting::SourceFile)) for (const auto& sourceFile : conf.GetSettingVectorString(ConfigSetting::SourceFile))
{ {
if(FileUtils::FileExists(conf.GetConfigPath() + sourceFile)) if (FileUtils::FileExists(conf.GetConfigPath() + sourceFile))
cppFiles.emplace(conf.GetConfigPath() + sourceFile); cppFiles.emplace(conf.GetConfigPath() + sourceFile);
else else
LOG_WARNING("Source file doesn't exist: ", sourceFile); LOG_WARNING("Source file doesn't exist: ", sourceFile);
} }
for(auto& filename : files) for (auto& filename : files)
{ {
std::filesystem::path filepath = std::filesystem::relative(filename, "./"); std::filesystem::path filepath = std::filesystem::relative(filename, "./");
if(IsSourceFile(filename)) if (IsSourceFile(filename))
{ {
auto it = std::find(excludeSources.begin(), excludeSources.end(), filename); auto it = std::find(excludeSources.begin(), excludeSources.end(), filename);
if(it == excludeSources.end()) if (it == excludeSources.end())
{ {
cppFiles.emplace(filepath.string()); cppFiles.emplace(filepath.string());
} }
@@ -98,39 +97,39 @@ void Utils::GetCppAndHFiles(ConfigFile& conf, std::set<HFile>& hFiles, std::set<
FileUtils::GetAllFiles(path, files); FileUtils::GetAllFiles(path, files);
} }
const std::vector<std::string>& excludeSources = conf.GetSettingVectorString(ConfigSetting::ExcludeSource); const std::vector<std::string>& excludeSources = conf.GetSettingVectorString(ConfigSetting::ExcludeSource);
for(const auto& sourceFile : conf.GetSettingVectorString(ConfigSetting::SourceFile)) for (const auto& sourceFile : conf.GetSettingVectorString(ConfigSetting::SourceFile))
{ {
if(FileUtils::FileExists(conf.GetConfigPath() + sourceFile)) if (FileUtils::FileExists(conf.GetConfigPath() + sourceFile))
cppFiles.emplace(conf.GetConfigPath() + sourceFile); cppFiles.emplace(conf.GetConfigPath() + sourceFile);
else else
LOG_WARNING("Source file doesn't exist: ", sourceFile); LOG_WARNING("Source file doesn't exist: ", sourceFile);
} }
for(const auto& filename : files) for (const auto& filename : files)
{ {
if(IsSourceFile(filename)) if (IsSourceFile(filename))
{ {
std::filesystem::path filepath = std::filesystem::relative(filename, "./"); std::filesystem::path filepath = std::filesystem::relative(filename, "./");
auto it = std::find(excludeSources.begin(), excludeSources.end(), filepath.string()); auto it = std::find(excludeSources.begin(), excludeSources.end(), filepath.string());
if(it == excludeSources.end()) if (it == excludeSources.end())
{ {
cppFiles.emplace(filepath.string()); cppFiles.emplace(filepath.string());
} }
} }
else if(IsHeaderFile(filename)) else if (IsHeaderFile(filename))
{ {
std::filesystem::path path = std::filesystem::relative(filename, sourceDir); std::filesystem::path path = std::filesystem::relative(filename, sourceDir);
hFiles.emplace(HFile{path.string(), sourceDir, false}); hFiles.emplace(HFile{path.string(), sourceDir, false});
} }
} }
for(const auto& includePath : conf.GetSettingVectorString(ConfigSetting::IncludeDir)) for (const auto& includePath : conf.GetSettingVectorString(ConfigSetting::IncludeDir))
{ {
std::vector<std::string> files; std::vector<std::string> files;
FileUtils::GetAllFiles(includePath, files); FileUtils::GetAllFiles(includePath, files);
for(const auto& file : files) for (const auto& file : files)
{ {
std::filesystem::path path = std::filesystem::relative(file, includePath); std::filesystem::path path = std::filesystem::relative(file, includePath);
if(IsHeaderFile(path.string())) if (IsHeaderFile(path.string()))
{ {
hFiles.emplace(HFile{path.string(), includePath, false}); hFiles.emplace(HFile{path.string(), includePath, false});
} }
@@ -138,7 +137,7 @@ void Utils::GetCppAndHFiles(ConfigFile& conf, std::set<HFile>& hFiles, std::set<
} }
std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency); std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency);
for(size_t i = 0; i < dependencies.size(); ++i) for (size_t i = 0; i < dependencies.size(); ++i)
{ {
GetHFiles(dependencies[i], conf.GetDependencyConfig(i), hFiles); GetHFiles(dependencies[i], conf.GetDependencyConfig(i), hFiles);
} }
@@ -150,7 +149,7 @@ void Utils::GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::s
// Cyclic dependencies probably shouldn't exist. // Cyclic dependencies probably shouldn't exist.
// so just warn the user that it does and terminate. // so just warn the user that it does and terminate.
std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency); std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency);
for(size_t i = 0; i < dependencies.size(); ++i) for (size_t i = 0; i < dependencies.size(); ++i)
{ {
GetHFiles(dependencies[i], conf.GetDependencyConfig(i), hFiles); GetHFiles(dependencies[i], conf.GetDependencyConfig(i), hFiles);
} }
@@ -158,15 +157,15 @@ void Utils::GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::s
std::vector<std::string> files; std::vector<std::string> files;
std::string depSrcDir = dependencyDir + conf.GetSettingString(ConfigSetting::SourceDir); std::string depSrcDir = dependencyDir + conf.GetSettingString(ConfigSetting::SourceDir);
FileUtils::GetAllFiles(depSrcDir, files); FileUtils::GetAllFiles(depSrcDir, files);
for(auto it = files.begin(); it!=files.end();++it) for (auto it = files.begin(); it != files.end(); ++it)
{ {
if(IsHeaderFile(*it)) if (IsHeaderFile(*it))
{ {
std::string filename = it->substr(depSrcDir.length()); std::string filename = it->substr(depSrcDir.length());
auto it = hFiles.find({filename, "", false}); auto it = hFiles.find({filename, "", false});
if(it != hFiles.end()) if (it != hFiles.end())
{ {
if(filename == conf.GetSettingString(ConfigSetting::HFileName) && !it->isProjectHFile) if (filename == conf.GetSettingString(ConfigSetting::HFileName) && !it->isProjectHFile)
{ {
HFile hfile = *it; HFile hfile = *it;
hfile.isProjectHFile = true; hfile.isProjectHFile = true;
@@ -176,11 +175,15 @@ void Utils::GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::s
} }
else else
{ {
hFiles.emplace(HFile{filename, depSrcDir, conf.GetSettingBool(ConfigSetting::GenerateHFile) && filename == conf.GetSettingString(ConfigSetting::HFileName)}); hFiles.emplace(HFile{filename,
depSrcDir,
conf.GetSettingBool(ConfigSetting::GenerateHFile) &&
filename == conf.GetSettingString(ConfigSetting::HFileName)});
} }
} }
} }
} }
bool Utils::IsWhiteSpace(char c) bool Utils::IsWhiteSpace(char c)
{ {
return c == '\n' || c == '\t' || c == '\r' || c == ' ' || c == '\t'; return c == '\n' || c == '\t' || c == '\r' || c == ' ' || c == '\t';
@@ -193,9 +196,9 @@ bool Utils::IsLetter(char c)
bool Utils::IsWord(const std::string& string) bool Utils::IsWord(const std::string& string)
{ {
for(auto it{string.begin()}; it != string.end();++it) for (auto it{string.begin()}; it != string.end(); ++it)
{ {
if(!IsLetter(*it)) if (!IsLetter(*it))
return false; return false;
} }
return true; return true;
+5 -3
View File
@@ -5,7 +5,6 @@
#include <set> #include <set>
#include <string> #include <string>
struct HFile struct HFile
{ {
std::string filename; std::string filename;
@@ -14,8 +13,11 @@ struct HFile
std::filesystem::path filepath; std::filesystem::path filepath;
HFile(const std::string& filename, const std::string& directory, bool isProjectHFile) HFile(const std::string& filename, const std::string& directory, bool isProjectHFile)
: filename{filename}, isProjectHFile{isProjectHFile}, filepath{directory+filename} : filename{filename},
{} isProjectHFile{isProjectHFile},
filepath{directory + filename}
{
}
friend bool operator<(const HFile& h1, const HFile& h2) friend bool operator<(const HFile& h1, const HFile& h2)
{ {
+55 -58
View File
@@ -2,41 +2,42 @@
const std::string CONFIG_FILENAME_CONF = "makegen.conf"; const std::string CONFIG_FILENAME_CONF = "makegen.conf";
#include "../ConfigFile.h"
#include "../FileUtils.h"
#include <algorithm> #include <algorithm>
#include <fstream> #include <fstream>
#include "../ConfigFile.h"
#include "../FileUtils.h"
#define FLAG_NONE 0 #define FLAG_NONE 0
#define FLAG_VECTOR 1 #define FLAG_VECTOR 1
#define FLAG_STRING 2 #define FLAG_STRING 2
#define FLAG_BOOL 3 #define FLAG_BOOL 3
ConfigFileConf::ConfigFileConf() ConfigFileConf::ConfigFileConf()
: outputdir("bin/"), srcdir("src/"), outputname(""), projectname(FileUtils::GetCurrentDirectory()), hFile(""), executable(true), shared(true), generateHFile(false) : outputdir("bin/"),
srcdir("src/"),
outputname(""),
projectname(FileUtils::GetCurrentDirectory()),
hFile(""),
executable(true),
shared(true),
generateHFile(false)
{ {
// Converts project name (current directory) to lowercase // Converts project name (current directory) to lowercase
// and replace whitespace with underscore // and replace whitespace with underscore
std::transform( std::transform(projectname.begin(),
projectname.begin(), projectname.end(),
projectname.end(), std::back_inserter(outputname),
std::back_inserter(outputname), [](unsigned char c)
[](unsigned char c) {
{ if (c == ' ')
if(c == ' ') return '_';
return '_'; return (char)std::tolower(c);
return (char)std::tolower(c); });
});
// Removes all other characters // Removes all other characters
outputdir.erase(std::remove_if( outputdir.erase(std::remove_if(
outputdir.begin(), outputdir.begin(), outputdir.end(), [](unsigned char c) { return (c < 'a' || c > 'z') && c != '_'; }));
outputdir.end(),
[](unsigned char c)
{
return (c < 'a' || c > 'z') && c != '_';
}));
// Add suffix // Add suffix
outputname += ".out"; outputname += ".out";
@@ -57,11 +58,10 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
std::ifstream file(filepath + CONFIG_FILENAME_CONF); std::ifstream file(filepath + CONFIG_FILENAME_CONF);
std::string line; std::string line;
if(file.is_open()) if (file.is_open())
{ {
// config name, { pointer to memory, isDirectory} // config name, { pointer to memory, isDirectory}
std::map<std::string, std::pair<std::string*, bool>> strings = std::map<std::string, std::pair<std::string*, bool>> strings = {
{
{"#srcdir", {&conf.srcdir, true}}, {"#srcdir", {&conf.srcdir, true}},
{"#outputdir", {&conf.outputdir, true}}, {"#outputdir", {&conf.outputdir, true}},
{"#outputname", {&conf.outputname, false}}, {"#outputname", {&conf.outputname, false}},
@@ -70,8 +70,7 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
}; };
// config name, { pointer to memory, isDirectory} // config name, { pointer to memory, isDirectory}
std::map<std::string, std::pair<std::vector<std::string>*, bool>> vectors = std::map<std::string, std::pair<std::vector<std::string>*, bool>> vectors = {
{
{"#libs", {&conf.libs, false}}, {"#libs", {&conf.libs, false}},
{"#libdirs", {&conf.libdirs, true}}, {"#libdirs", {&conf.libdirs, true}},
{"#includedirs", {&conf.includedirs, true}}, {"#includedirs", {&conf.includedirs, true}},
@@ -81,23 +80,22 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
{"#sourcefiles", {&conf.sourceFiles, false}}, {"#sourcefiles", {&conf.sourceFiles, false}},
}; };
std::map<std::string, bool*> booleans = std::map<std::string, bool*> booleans = {
{
{"#executable", &conf.executable}, {"#executable", &conf.executable},
{"#shared", &conf.shared}, {"#shared", &conf.shared},
{"#generatehfile", &conf.generateHFile}, {"#generatehfile", &conf.generateHFile},
}; };
while(std::getline(file,line)) while (std::getline(file, line))
{ {
if(line == "") if (line == "")
continue; continue;
if(line[0]=='#') if (line[0] == '#')
{ {
// The format is a bit wacky, but it is this way since we do not want // 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. // to use map::find for all maps. This way we gain some optimization.
auto&& itStr{strings.find(line)}; auto&& itStr{strings.find(line)};
if(itStr != strings.end()) if (itStr != strings.end())
{ {
s = itStr->second.first; s = itStr->second.first;
isDirectory = itStr->second.second; isDirectory = itStr->second.second;
@@ -106,7 +104,7 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
else else
{ {
auto&& itVec{vectors.find(line)}; auto&& itVec{vectors.find(line)};
if(itVec != vectors.end()) if (itVec != vectors.end())
{ {
vec = itVec->second.first; vec = itVec->second.first;
isDirectory = itVec->second.second; isDirectory = itVec->second.second;
@@ -115,7 +113,7 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
else else
{ {
auto&& itBool{booleans.find(line)}; auto&& itBool{booleans.find(line)};
if(itBool != booleans.end()) if (itBool != booleans.end())
{ {
b = itBool->second; b = itBool->second;
loadFlag = FLAG_BOOL; loadFlag = FLAG_BOOL;
@@ -130,23 +128,24 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
} }
else else
{ {
if(loadFlag == FLAG_STRING) if (loadFlag == FLAG_STRING)
{ {
if(isDirectory && line[line.size()-1] != '/') if (isDirectory && line[line.size() - 1] != '/')
line += '/'; line += '/';
*s = line; *s = line;
} }
else if(loadFlag == FLAG_VECTOR) else if (loadFlag == FLAG_VECTOR)
{ {
if(isDirectory && line[line.size()-1] != '/') if (isDirectory && line[line.size() - 1] != '/')
{; {
;
line += '/'; line += '/';
} }
vec->push_back(line); vec->push_back(line);
} }
else if(loadFlag == FLAG_BOOL) else if (loadFlag == FLAG_BOOL)
{ {
if(line == "true") if (line == "true")
*b = true; *b = true;
else else
*b = false; *b = false;
@@ -156,8 +155,8 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
LOG_INFO("------ COULDN\'T FIND makegen.xml. BUT FOUND OLD makegen.conf."); LOG_INFO("------ COULDN\'T FIND makegen.xml. BUT FOUND OLD makegen.conf.");
LOG_INFO("------ GENERATING NEW CONFIGURATION FILE"); LOG_INFO("------ GENERATING NEW CONFIGURATION FILE");
if(conf.hFile == "") if (conf.hFile == "")
conf.hFile = conf.projectname+".h"; conf.hFile = conf.projectname + ".h";
XMLObject makegen("makegen", {}, std::map<std::string, std::vector<XMLObject>>{}); XMLObject makegen("makegen", {}, std::map<std::string, std::vector<XMLObject>>{});
@@ -171,24 +170,22 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
configuration.AddXMLObject(XMLObject("srcdir", {}, conf.srcdir)); configuration.AddXMLObject(XMLObject("srcdir", {}, conf.srcdir));
configuration.AddXMLObject(XMLObject("outputdir", {}, conf.outputdir)); configuration.AddXMLObject(XMLObject("outputdir", {}, conf.outputdir));
configuration.AddXMLObject(XMLObject("hfilename", {}, conf.hFile)); configuration.AddXMLObject(XMLObject("hfilename", {}, conf.hFile));
configuration.AddXMLObject(XMLObject("outputtype", {}, configuration.AddXMLObject(
conf.executable ? "executable" : (conf.shared ? "sharedlibrary" : "staticlibrary"))); XMLObject("outputtype", {}, conf.executable ? "executable" : (conf.shared ? "sharedlibrary" : "staticlibrary")));
configuration.AddXMLObject(XMLObject("generatehfile", {}, conf.generateHFile ? "true" : "false")); configuration.AddXMLObject(XMLObject("generatehfile", {}, conf.generateHFile ? "true" : "false"));
for(auto it = conf.libs.begin();it != conf.libs.end(); ++it) for (auto it = conf.libs.begin(); it != conf.libs.end(); ++it) configuration.AddXMLObject({"library", {}, *it});
configuration.AddXMLObject({"library",{},*it}); for (auto it = conf.libdirs.begin(); it != conf.libdirs.end(); ++it)
for(auto it = conf.libdirs.begin();it != conf.libdirs.end(); ++it) configuration.AddXMLObject({"librarydir", {}, *it});
configuration.AddXMLObject({"librarydir",{},*it}); for (auto it = conf.includedirs.begin(); it != conf.includedirs.end(); ++it)
for(auto it = conf.includedirs.begin();it != conf.includedirs.end(); ++it) configuration.AddXMLObject({"includedir", {}, *it});
configuration.AddXMLObject({"includedir",{},*it}); for (auto it = conf.defines.begin(); it != conf.defines.end(); ++it)
for(auto it = conf.defines.begin();it != conf.defines.end(); ++it) configuration.AddXMLObject({"define", {}, *it});
configuration.AddXMLObject({"define",{},*it}); for (auto it = conf.flags.begin(); it != conf.flags.end(); ++it) configuration.AddXMLObject({"cflag", {}, *it});
for(auto it = conf.flags.begin();it != conf.flags.end(); ++it) for (auto it = conf.dependencies.begin(); it != conf.dependencies.end(); ++it)
configuration.AddXMLObject({"cflag",{},*it}); configuration.AddXMLObject({"dependency", {}, *it});
for(auto it = conf.dependencies.begin();it != conf.dependencies.end(); ++it) for (auto it = conf.sourceFiles.begin(); it != conf.sourceFiles.end(); ++it)
configuration.AddXMLObject({"dependency",{},*it}); configuration.AddXMLObject({"sourcefile", {}, *it});
for(auto it = conf.sourceFiles.begin();it != conf.sourceFiles.end(); ++it)
configuration.AddXMLObject({"sourcefile",{},*it});
makegen.AddXMLObject(configuration); makegen.AddXMLObject(configuration);
std::ofstream xmlFile(conf.configPath + "makegen.xml"); std::ofstream xmlFile(conf.configPath + "makegen.xml");
+23 -21
View File
@@ -9,27 +9,29 @@ class ConfigFile;
class ConfigFileConf class ConfigFileConf
{ {
public: public:
std::string configPath; std::string configPath;
std::vector<std::string> libs; std::vector<std::string> libs;
std::vector<std::string> libdirs; std::vector<std::string> libdirs;
std::vector<std::string> includedirs; std::vector<std::string> includedirs;
std::vector<std::string> defines; std::vector<std::string> defines;
std::vector<std::string> flags; std::vector<std::string> flags;
std::vector<std::string> dependencies; std::vector<std::string> dependencies;
std::vector<std::string> sourceFiles; std::vector<std::string> sourceFiles;
std::string outputdir; std::string outputdir;
std::string srcdir; std::string srcdir;
std::string outputname; std::string outputname;
std::string projectname; std::string projectname;
std::string hFile; std::string hFile;
bool executable; bool executable;
bool shared; bool shared;
bool generateHFile; bool generateHFile;
public:
ConfigFileConf();
static void CreateXMLFile(const std::string& filename); public:
private: ConfigFileConf();
static void CreateXMLFile(const std::string& filename);
private:
}; };
Executable → Regular
+41 -41
View File
@@ -1,3 +1,7 @@
#include <cmath>
#include <filesystem>
#include <thread>
#include "Common.h" #include "Common.h"
#include "ConfigCLI.h" #include "ConfigCLI.h"
#include "ConfigFile.h" #include "ConfigFile.h"
@@ -7,18 +11,14 @@
#include "Makefile.h" #include "Makefile.h"
#include "Timer.h" #include "Timer.h"
#include <cmath>
#include <thread>
#include <filesystem>
#define RETURN_IF(x, b) \ #define RETURN_IF(x, b) \
if(x)\ if (x) \
return b; return b;
void PrintHelp() void PrintHelp()
{ {
LOG_INFO("MakeGen ", MAKEGEN_VERSION); LOG_INFO("MakeGen ", MAKEGEN_VERSION);
LOG_INFO(1+(char*)R"( LOG_INFO(1 + (char*)R"(
MakeGen is a utility tool to generate and run Makefiles in a simple manner. MakeGen is a utility tool to generate and run Makefiles in a simple manner.
By default it always compiles code with parallell jobs. By default it always compiles code with parallell jobs.
@@ -52,61 +52,61 @@ Usage: makegen [options]
void GenMakefile(ConfigFile& conf, unsigned int flags) void GenMakefile(ConfigFile& conf, unsigned int flags)
{ {
if(conf.GetSettingBool(ConfigSetting::GenerateHFile)) if (conf.GetSettingBool(ConfigSetting::GenerateHFile))
HFileGen::Create(conf); HFileGen::Create(conf);
Makefile::Save(conf, flags); Makefile::Save(conf, flags);
} }
FlagData ReadFlags(int argc, char** argv) FlagData ReadFlags(int argc, char** argv)
{ {
if(argc >= 2 && std::string(argv[1]) == "conf") if (argc >= 2 && std::string(argv[1]) == "conf")
return FlagData{FLAG_CONFIG}; return FlagData{FLAG_CONFIG};
FlagData flagData{}; FlagData flagData{};
bool make = true; bool make = true;
for(int i = 1;i<argc;i++) for (int i = 1; i < argc; i++)
{ {
if(strlen(argv[i]) > 1) if (strlen(argv[i]) > 1)
{ {
std::string flag(argv[i]); std::string flag(argv[i]);
if(flag == "-h" || flag == "--help") if (flag == "-h" || flag == "--help")
{ {
flagData.flags |= FLAG_HELP; flagData.flags |= FLAG_HELP;
} }
else if(flag == "-v" || flag == "--version") else if (flag == "-v" || flag == "--version")
{ {
flagData.flags |= FLAG_VERSION; flagData.flags |= FLAG_VERSION;
} }
else if(flag == "make" || flag == "-m" || flag == "all" || flag == "-a") else if (flag == "make" || flag == "-m" || flag == "all" || flag == "-a")
{ {
flagData.flags |= FLAG_MAKE; flagData.flags |= FLAG_MAKE;
} }
else if(flag == "clean" || flag == "-c") else if (flag == "clean" || flag == "-c")
{ {
make = false; make = false;
flagData.flags |= FLAG_CLEAN; flagData.flags |= FLAG_CLEAN;
} }
else if(flag == "run" || flag == "-e" || flag == "execute") else if (flag == "run" || flag == "-e" || flag == "execute")
{ {
flagData.flags |= FLAG_RUN; flagData.flags |= FLAG_RUN;
} }
else if(flag == "install" || flag == "-i") else if (flag == "install" || flag == "-i")
{ {
flagData.flags |= FLAG_INSTALL; flagData.flags |= FLAG_INSTALL;
} }
else if(flag == "rebuild" || flag == "-r") else if (flag == "rebuild" || flag == "-r")
{ {
flagData.flags |= FLAG_CLEAN; flagData.flags |= FLAG_CLEAN;
flagData.flags |= FLAG_MAKE; flagData.flags |= FLAG_MAKE;
} }
else if(flag == "single" || flag == "-s") else if (flag == "single" || flag == "-s")
{ {
flagData.flags |= FLAG_SINGLE_THREAD; flagData.flags |= FLAG_SINGLE_THREAD;
} }
else if(flag == "--simple") else if (flag == "--simple")
{ {
flagData.flags |= FLAG_SIMPLE; flagData.flags |= FLAG_SIMPLE;
} }
else if(Utils::StartsWith(flag, "--target=")) else if (Utils::StartsWith(flag, "--target="))
{ {
std::string prefix("--target="); std::string prefix("--target=");
if (flag.size() < prefix.size() + 1) if (flag.size() < prefix.size() + 1)
@@ -117,14 +117,14 @@ FlagData ReadFlags(int argc, char** argv)
flagData.flags |= FLAG_TARGET; flagData.flags |= FLAG_TARGET;
flagData.target = flag.substr(std::string("--target=").size()); flagData.target = flag.substr(std::string("--target=").size());
} }
else if(flag != "") else if (flag != "")
{ {
LOG_ERROR("Unknown argument ", flag); LOG_ERROR("Unknown argument ", flag);
return FlagData{FLAG_HELP}; return FlagData{FLAG_HELP};
} }
} }
} }
if(make) if (make)
flagData.flags |= FLAG_MAKE; flagData.flags |= FLAG_MAKE;
return flagData; return flagData;
} }
@@ -132,21 +132,21 @@ FlagData ReadFlags(int argc, char** argv)
bool RunMake(const std::string& filepath, unsigned int flags, ConfigFile& conf) bool RunMake(const std::string& filepath, unsigned int flags, ConfigFile& conf)
{ {
std::string make = "make --no-print-directory -C " + filepath; std::string make = "make --no-print-directory -C " + filepath;
if(!(flags & FLAG_SINGLE_THREAD)) if (!(flags & FLAG_SINGLE_THREAD))
make += " -j" + std::to_string(std::thread::hardware_concurrency()) + " "; make += " -j" + std::to_string(std::thread::hardware_concurrency()) + " ";
if(flags & FLAG_CLEAN) if (flags & FLAG_CLEAN)
{ {
RETURN_IF(system(std::string(make + " clean").c_str()) != 0, false); RETURN_IF(system(std::string(make + " clean").c_str()) != 0, false);
} }
if(flags & FLAG_MAKE) if (flags & FLAG_MAKE)
{ {
RETURN_IF(system(std::string(make + " all").c_str()) != 0, false); RETURN_IF(system(std::string(make + " all").c_str()) != 0, false);
} }
if(flags & FLAG_INSTALL) if (flags & FLAG_INSTALL)
{ {
RETURN_IF(system(std::string(make + " install").c_str()) != 0, false); 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.GetSettingString(ConfigSetting::OutputType) == "executable")
{ {
RETURN_IF(system(std::string(make + " run").c_str()) != 0, false); RETURN_IF(system(std::string(make + " run").c_str()) != 0, false);
} }
@@ -156,16 +156,16 @@ bool RunMake(const std::string& filepath, unsigned int flags, ConfigFile& conf)
bool MakeGen(const std::string& filepath, const FlagData& flagData, ConfigFile& conf) bool MakeGen(const std::string& filepath, const FlagData& flagData, ConfigFile& conf)
{ {
std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency); std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency);
for(size_t i = 0;i<dependencies.size();++i) for (size_t i = 0; i < dependencies.size(); ++i)
{ {
std::filesystem::path currentPath = std::filesystem::current_path(); std::filesystem::path currentPath = std::filesystem::current_path();
std::filesystem::current_path(dependencies[i]); std::filesystem::current_path(dependencies[i]);
auto conf = ConfigFile::GetConfigFile("./", flagData); auto conf = ConfigFile::GetConfigFile("./", flagData);
if(conf) if (conf)
{ {
bool success = MakeGen("./", flagData, conf.value()); bool success = MakeGen("./", flagData, conf.value());
if(!success) if (!success)
{ {
std::filesystem::current_path(currentPath); std::filesystem::current_path(currentPath);
return success; return success;
@@ -178,40 +178,40 @@ bool MakeGen(const std::string& filepath, const FlagData& flagData, ConfigFile&
LOG_INFO("Generating Makefile..."); LOG_INFO("Generating Makefile...");
Timer timer; Timer timer;
GenMakefile(conf, flagData.flags); GenMakefile(conf, flagData.flags);
LOG_INFO("Took ", round(timer.Elapsed()*1000.0)/1000.0,"s"); LOG_INFO("Took ", round(timer.Elapsed() * 1000.0) / 1000.0, "s");
LOG_INFO("Running Makefile..."); LOG_INFO("Running Makefile...");
std::string outputPath = conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::OutputDir); std::string outputPath = conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::OutputDir);
if(!FileUtils::HasPath(outputPath)) if (!FileUtils::HasPath(outputPath))
{ {
FileUtils::CreateDirectory(outputPath); FileUtils::CreateDirectory(outputPath);
std::string intermediatePath = outputPath + "intermediates"; std::string intermediatePath = outputPath + "intermediates";
if(!FileUtils::HasPath(intermediatePath )) if (!FileUtils::HasPath(intermediatePath))
FileUtils::CreateDirectory(intermediatePath ); FileUtils::CreateDirectory(intermediatePath);
} }
return RunMake(filepath, flagData.flags, conf); return RunMake(filepath, flagData.flags, conf);
} }
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
FlagData flagData = ReadFlags(argc,argv); FlagData flagData = ReadFlags(argc, argv);
if(flagData.flags & FLAG_HELP) if (flagData.flags & FLAG_HELP)
{ {
PrintHelp(); PrintHelp();
return 0; return 0;
} }
if(flagData.flags & FLAG_VERSION) if (flagData.flags & FLAG_VERSION)
{ {
LOG_INFO("MakeGen ", MAKEGEN_VERSION); LOG_INFO("MakeGen ", MAKEGEN_VERSION);
return 0; return 0;
} }
if(flagData.flags & FLAG_CONFIG) if (flagData.flags & FLAG_CONFIG)
{ {
return ConfigCLI::Main(argc-1, &argv[1]); return ConfigCLI::Main(argc - 1, &argv[1]);
} }
std::map<std::string, ConfigFile> files{}; std::map<std::string, ConfigFile> files{};
auto conf = ConfigFile::GetConfigFile("./", flagData); auto conf = ConfigFile::GetConfigFile("./", flagData);
if(conf) if (conf)
{ {
bool success = MakeGen("./", flagData, *conf); bool success = MakeGen("./", flagData, *conf);
return success ? 0 : 1; return success ? 0 : 1;
+9 -9
View File
@@ -1,28 +1,28 @@
#include "XML.h" #include "XML.h"
#include <algorithm>
#include <fstream>
#include "XMLException.h" #include "XMLException.h"
#include <fstream> XMLObject XML::FromString(const std::string& string, const std::string& filename = "")
#include <algorithm>
XMLObject XML::FromString(const std::string& string, const std::string& filename="")
{ {
int startLine = 1; int startLine = 1;
int startPos = 0; int startPos = 0;
// Remove version tag. // Remove version tag.
if(string.find("<?") != std::string::npos) if (string.find("<?") != std::string::npos)
{ {
startPos = string.find("?>") + 3; startPos = string.find("?>") + 3;
startLine = std::count(string.begin(), string.begin()+startPos, '\n') + 1; startLine = std::count(string.begin(), string.begin() + startPos, '\n') + 1;
} }
return XMLObject(string, startPos, startLine,filename); return XMLObject(string, startPos, startLine, filename);
} }
XMLObject XML::FromFile(const std::string& filename) XMLObject XML::FromFile(const std::string& filename)
{ {
std::ifstream file(filename, std::ios::binary | std::ios::ate); std::ifstream file(filename, std::ios::binary | std::ios::ate);
if(!file) if (!file)
throw XMLException("Could not read file \""+filename+"\""); throw XMLException("Could not read file \"" + filename + "\"");
std::streamsize size = file.tellg(); std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg); file.seekg(0, std::ios::beg);
std::string buffer; std::string buffer;
+19 -13
View File
@@ -1,22 +1,28 @@
#pragma once #pragma once
#include "XMLObject.h"
#include <exception> #include <exception>
#include <string> #include <string>
#include "XMLObject.h"
class XMLException : public std::exception class XMLException : public std::exception
{ {
private: private:
std::string m_message; std::string m_message;
public:
explicit XMLException(const std::string& message) : m_message("XMLException: " + message) {}
explicit XMLException(const std::string& message, const XMLObject::XMLLoadData& data)
: m_message("XMLException(" + data.file + ":" + std::to_string(data.line) + "): " + message)
{}
virtual const char* what() const throw() public:
{ explicit XMLException(const std::string& message)
return m_message.c_str(); : m_message("XMLException: " + message)
} {
}
explicit XMLException(const std::string& message, const XMLObject::XMLLoadData& data)
: m_message("XMLException(" + data.file + ":" + std::to_string(data.line) + "): " + message)
{
}
virtual const char* what() const throw()
{
return m_message.c_str();
}
}; };
+63 -59
View File
@@ -1,9 +1,9 @@
#include "XMLObject.h" #include "XMLObject.h"
#include <cstring>
#include "../Common.h" #include "../Common.h"
#include "../Utils.h" #include "../Utils.h"
#include <cstring>
#include "XMLException.h" #include "XMLException.h"
XMLObject::XMLObject(const std::string& string) XMLObject::XMLObject(const std::string& string)
@@ -11,7 +11,7 @@ XMLObject::XMLObject(const std::string& string)
int pos = 0; int pos = 0;
int line = 1; int line = 1;
XMLLoadData data{pos, line, ""}; XMLLoadData data{pos, line, ""};
if(!ReadHead(string, data)) if (!ReadHead(string, data))
ReadBodyTail(string, data); ReadBodyTail(string, data);
} }
@@ -28,16 +28,22 @@ XMLObject::XMLObject(const std::string& string, XMLLoadData& data)
ReadBodyTail(string, data); ReadBodyTail(string, data);
} }
XMLObject::XMLObject(const std::string& name, const std::map<std::string, std::string>& attributes, const std::string& text) XMLObject::XMLObject(const std::string& name,
:name(name), attributes(attributes), text(text) const std::map<std::string, std::string>& attributes,
const std::string& text)
: name(name),
attributes(attributes),
text(text)
{ {
} }
XMLObject::XMLObject(const std::string& name, const std::map<std::string, std::string>& attributes, const std::map<std::string,std::vector<XMLObject>>& objects) XMLObject::XMLObject(const std::string& name,
: name(name), attributes(attributes), objects(objects) const std::map<std::string, std::string>& attributes,
const std::map<std::string, std::vector<XMLObject>>& objects)
: name(name),
attributes(attributes),
objects(objects)
{ {
} }
bool XMLObject::HasAttribute(const std::string& property) const bool XMLObject::HasAttribute(const std::string& property) const
@@ -69,7 +75,7 @@ unsigned int XMLObject::GetObjectCount() const
std::vector<XMLObject>* XMLObject::GetObjectPtr(const std::string& name) std::vector<XMLObject>* XMLObject::GetObjectPtr(const std::string& name)
{ {
auto it = objects.find(name); auto it = objects.find(name);
if(it == objects.end()) if (it == objects.end())
return nullptr; return nullptr;
return &it->second; return &it->second;
@@ -92,7 +98,7 @@ const std::string& XMLObject::GetText() const
void XMLObject::SetName(const std::string& name) void XMLObject::SetName(const std::string& name)
{ {
if(Utils::IsWord(name)) if (Utils::IsWord(name))
this->name = name; this->name = name;
else else
LOG_ERROR("XML Head can only be made up of letters"); LOG_ERROR("XML Head can only be made up of letters");
@@ -105,7 +111,7 @@ void XMLObject::SetText(const std::string& text)
void XMLObject::AddAttribute(const std::string& property, const std::string& value) void XMLObject::AddAttribute(const std::string& property, const std::string& value)
{ {
if(Utils::IsWord(property)) if (Utils::IsWord(property))
attributes.emplace(property, value); attributes.emplace(property, value);
else else
LOG_ERROR("XML property name can only be made up of letters"); LOG_ERROR("XML property name can only be made up of letters");
@@ -114,7 +120,7 @@ void XMLObject::AddAttribute(const std::string& property, const std::string& val
void XMLObject::AddXMLObject(const XMLObject& object) void XMLObject::AddXMLObject(const XMLObject& object)
{ {
auto it = objects.find(object.name); auto it = objects.find(object.name);
if(it == objects.end()) if (it == objects.end())
objects.emplace(object.name, std::vector<XMLObject>{object}); objects.emplace(object.name, std::vector<XMLObject>{object});
else else
it->second.push_back(object); it->second.push_back(object);
@@ -123,18 +129,18 @@ void XMLObject::AddXMLObject(const XMLObject& object)
bool XMLObject::RemoveXMLObject(const XMLObject& object) bool XMLObject::RemoveXMLObject(const XMLObject& object)
{ {
auto it = objects.find(object.name); auto it = objects.find(object.name);
if(it == objects.end()) if (it == objects.end())
return false; return false;
bool removed = false; bool removed = false;
for(auto it2 = it->second.begin(); it2 != it->second.end();) for (auto it2 = it->second.begin(); it2 != it->second.end();)
{ {
if(*it2 == object) if (*it2 == object)
{ {
it2 = it->second.erase(it2); it2 = it->second.erase(it2);
removed = true; removed = true;
} }
else else
++it2; ++it2;
} }
return removed; return removed;
@@ -142,7 +148,7 @@ bool XMLObject::RemoveXMLObject(const XMLObject& object)
XMLObject XMLObject::GetStrippedXMLObject() const XMLObject XMLObject::GetStrippedXMLObject() const
{ {
if(text == "") if (text == "")
return XMLObject(name, attributes, objects); return XMLObject(name, attributes, objects);
else else
return XMLObject(name, attributes, text); return XMLObject(name, attributes, text);
@@ -154,7 +160,6 @@ XMLObject XMLObject::GetStrippedXMLObject() const
// // // //
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool XMLObject::ReadHead(const std::string& string, XMLLoadData& data) bool XMLObject::ReadHead(const std::string& string, XMLLoadData& data)
{ {
// Check if the first character is the start of and xml tag. // Check if the first character is the start of and xml tag.
@@ -179,7 +184,8 @@ bool XMLObject::ReadHead(const std::string& string, XMLLoadData& data)
data.pos++; data.pos++;
ReadWhiteSpace(string, data); ReadWhiteSpace(string, data);
if (string[data.pos] != '>') if (string[data.pos] != '>')
throw XMLException((std::string("Invalid character proceeding / in opening XML Tag \"") + string[data.pos] + "\".").c_str(), data); throw XMLException(
(std::string("Invalid character proceeding / in opening XML Tag \"") + string[data.pos] + "\".").c_str(), data);
data.pos++; data.pos++;
// nothing more to read. // nothing more to read.
return true; return true;
@@ -187,7 +193,9 @@ bool XMLObject::ReadHead(const std::string& string, XMLLoadData& data)
ReadWhiteSpace(string, data); ReadWhiteSpace(string, data);
if (string[data.pos] != '>') if (string[data.pos] != '>')
throw XMLException((std::string("Invalid character proceeding attributes in opening XML Tag \"") + string[data.pos] + "\".").c_str(), data); throw XMLException(
(std::string("Invalid character proceeding attributes in opening XML Tag \"") + string[data.pos] + "\".").c_str(),
data);
(data.pos)++; (data.pos)++;
return false; return false;
} }
@@ -203,7 +211,8 @@ void XMLObject::ReadName(const std::string& string, XMLLoadData& data)
ReadWhiteSpace(string, data); ReadWhiteSpace(string, data);
if (string[data.pos] != '/' && string[data.pos] != '>' && Utils::IsWhiteSpace(string[data.pos])) if (string[data.pos] != '/' && string[data.pos] != '>' && Utils::IsWhiteSpace(string[data.pos]))
{ {
throw XMLException((std::string("Invalid character proceeding name in XML Tag \"") + string[data.pos] + "\".").c_str(), data); throw XMLException(
(std::string("Invalid character proceeding name in XML Tag \"") + string[data.pos] + "\".").c_str(), data);
} }
} }
@@ -230,7 +239,9 @@ void XMLObject::ReadAttribute(const std::string& string, XMLLoadData& data)
// Read = // Read =
if (string[data.pos] != '=') if (string[data.pos] != '=')
throw XMLException((std::string("Invalid character proceeding property name in XML Tag \"") + string[data.pos] + "\".").c_str(), data); throw XMLException(
(std::string("Invalid character proceeding property name in XML Tag \"") + string[data.pos] + "\".").c_str(),
data);
(data.pos)++; (data.pos)++;
ReadWhiteSpace(string, data); ReadWhiteSpace(string, data);
@@ -256,7 +267,10 @@ void XMLObject::ReadBodyTail(const std::string& string, XMLLoadData& data)
ReadWhiteSpace(string, data); ReadWhiteSpace(string, data);
std::string closeTag = GetClosingTag(string, data); std::string closeTag = GetClosingTag(string, data);
if (closeTag.length() == 0) if (closeTag.length() == 0)
throw XMLException("Tag after XML Test was not a closing tag. XMLObject doesn't support text and other XMLObjects at the same time.", data); throw XMLException(
"Tag after XML Test was not a closing tag. XMLObject doesn't support text and other XMLObjects at the same "
"time.",
data);
return; return;
} }
// Check if we can read the closing tag. // Check if we can read the closing tag.
@@ -279,14 +293,14 @@ void XMLObject::ReadText(const std::string& string, XMLLoadData& data)
void XMLObject::ReadWhiteSpace(const std::string& string, XMLLoadData& data) void XMLObject::ReadWhiteSpace(const std::string& string, XMLLoadData& data)
{ {
while (Utils::IsWhiteSpace(string[data.pos])) { while (Utils::IsWhiteSpace(string[data.pos]))
{
if (string[data.pos] == '\n') if (string[data.pos] == '\n')
(data.line)++; (data.line)++;
(data.pos)++; (data.pos)++;
} }
} }
std::string XMLObject::GetClosingTag(const std::string& string, XMLLoadData& data) std::string XMLObject::GetClosingTag(const std::string& string, XMLLoadData& data)
{ {
int startPos = data.pos; int startPos = data.pos;
@@ -307,7 +321,8 @@ std::string XMLObject::GetClosingTag(const std::string& string, XMLLoadData& dat
ReadWhiteSpace(string, data); ReadWhiteSpace(string, data);
std::string tag = Utils::GetWord(string, data.pos); std::string tag = Utils::GetWord(string, data.pos);
if (tag != name) if (tag != name)
throw XMLException((std::string("Closing tag doesn't match opening tag. (\"") + name + "\" != \"" + tag+ "\")").c_str(), data); throw XMLException(
(std::string("Closing tag doesn't match opening tag. (\"") + name + "\" != \"" + tag + "\")").c_str(), data);
data.pos += tag.length(); data.pos += tag.length();
ReadWhiteSpace(string, data); ReadWhiteSpace(string, data);
if (string[data.pos] != '>') if (string[data.pos] != '>')
@@ -318,82 +333,72 @@ std::string XMLObject::GetClosingTag(const std::string& string, XMLLoadData& dat
void XMLObject::ReplacePredefinedEntities(std::string& string, XMLLoadData& data) void XMLObject::ReplacePredefinedEntities(std::string& string, XMLLoadData& data)
{ {
std::vector<std::pair<std::string, std::string>> entities std::vector<std::pair<std::string, std::string>> entities{
{ {"&quot;", "\""}, {"&apos;", "\'"}, {"&lt;", "<"}, {"&gt;", ">"}, {"&amp;", "&"}};
{"&quot;","\""},
{"&apos;", "\'"},
{"&lt;", "<"},
{"&gt;",">"},
{"&amp;", "&"}
};
size_t pos = string.find('&'); size_t pos = string.find('&');
while(pos != std::string::npos) while (pos != std::string::npos)
{ {
bool found = false; bool found = false;
for(auto entity : entities) for (auto entity : entities)
{ {
if(strncmp(&string[pos], entity.first.c_str(), entity.first.length()) == 0) if (strncmp(&string[pos], entity.first.c_str(), entity.first.length()) == 0)
{ {
string.replace(pos, entity.first.length(), entity.second); string.replace(pos, entity.first.length(), entity.second);
found = true; found = true;
} }
} }
if(!found) if (!found)
LOG_ERROR("(" + data.file + ":" + std::to_string(data.line) + "): ""Ampersand found in xml but isn't a predefined entity."); LOG_ERROR("(" + data.file + ":" + std::to_string(data.line) +
pos = string.find('&', pos+1); "): "
"Ampersand found in xml but isn't a predefined entity.");
pos = string.find('&', pos + 1);
} }
} }
std::string XMLObject::ReadXMLName(const std::string& string, XMLLoadData& data) std::string XMLObject::ReadXMLName(const std::string& string, XMLLoadData& data)
{ {
if(!(Utils::IsLetter(string[data.pos]) || if (!(Utils::IsLetter(string[data.pos]) || string[data.pos] == '_' || string[data.pos] == ':'))
string[data.pos] == '_' ||
string[data.pos] == ':'))
throw XMLException(std::string("Name doesn't start with a letter."), data); throw XMLException(std::string("Name doesn't start with a letter."), data);
int endPos = data.pos + 1; int endPos = data.pos + 1;
while (endPos < string.length() && ( while (endPos < string.length() && (Utils::IsLetter(string[endPos]) || string[endPos] == '_' ||
Utils::IsLetter(string[endPos]) || string[endPos] == '-' || string[endPos] == ':' || string[endPos] == '.'))
string[endPos] == '_' ||
string[endPos] == '-' ||
string[endPos] == ':' ||
string[endPos] == '.'))
endPos++; endPos++;
return string.substr(data.pos, endPos - data.pos); return string.substr(data.pos, endPos - data.pos);
} }
std::ostream& XMLObject::WriteToStream(std::ostream& stream, int indent) const std::ostream& XMLObject::WriteToStream(std::ostream& stream, int indent) const
{ {
for(int i = 0;i<indent;i++) for (int i = 0; i < indent; i++)
{ {
stream << " "; stream << " ";
} }
stream << "<" << name; stream << "<" << name;
for(auto it = attributes.begin();it!=attributes.end();++it) for (auto it = attributes.begin(); it != attributes.end(); ++it)
{ {
stream << " " << it->first << "=\"" << it->second << "\""; stream << " " << it->first << "=\"" << it->second << "\"";
} }
stream << ">"; stream << ">";
if(text != "") if (text != "")
{ {
stream << text; stream << text;
} }
else else
{ {
bool hasChild = false; bool hasChild = false;
for(auto it = objects.begin(); it != objects.end();++it) for (auto it = objects.begin(); it != objects.end(); ++it)
{ {
for(auto it2 = it->second.begin(); it2 != it->second.end(); ++it2) for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2)
{ {
stream << "\n"; stream << "\n";
it2->WriteToStream(stream, indent+1); it2->WriteToStream(stream, indent + 1);
hasChild = true; hasChild = true;
} }
} }
if(hasChild) if (hasChild)
{ {
stream << "\n"; stream << "\n";
for(int i = 0;i<indent;i++) for (int i = 0; i < indent; i++)
{ {
stream << " "; stream << " ";
} }
@@ -403,4 +408,3 @@ std::ostream& XMLObject::WriteToStream(std::ostream& stream, int indent) const
return stream; return stream;
} }
+104 -96
View File
@@ -1,110 +1,118 @@
#pragma once #pragma once
#include <string>
#include <map> #include <map>
#include <set> #include <set>
#include <string>
#include <vector> #include <vector>
class XMLObject class XMLObject
{ {
public: public:
friend class XMLexception; friend class XMLexception;
struct XMLLoadData
struct XMLLoadData
{
int pos;
int line;
const std::string& file;
};
private:
std::string name;
std::string text;
std::map<std::string, std::string> attributes;
std::map<std::string, std::vector<XMLObject>> objects;
public:
XMLObject()
{
}
XMLObject(const std::string& string);
XMLObject(const std::string& string, int pos, int line, const std::string& file);
XMLObject(const std::string& string, XMLLoadData& data);
XMLObject(const std::string& name, const std::map<std::string, std::string>& properties, const std::string& text);
XMLObject(const std::string& name,
const std::map<std::string, std::string>& properties,
const std::map<std::string, std::vector<XMLObject>>& objects);
bool HasAttribute(const std::string& property) const;
const std::string& GetAttribute(const std::string& property) const;
const std::string& GetAttribute(const std::string& property, const std::string& defaultValue) const;
unsigned int GetObjectCount() const;
std::vector<XMLObject>* GetObjectPtr(const std::string& name);
const std::map<std::string, std::vector<XMLObject>>& GetObjects() const;
const std::string& GetName() const;
const std::string& GetText() const;
XMLObject GetStrippedXMLObject() const;
void SetName(const std::string& name);
void SetText(const std::string& text);
void AddAttribute(const std::string& property, const std::string& value);
void AddXMLObject(const XMLObject& object);
bool RemoveXMLObject(const XMLObject& object);
friend bool operator<(const XMLObject& obj1, const XMLObject& obj2)
{
return obj1.name < obj2.name;
}
std::ostream& WriteToStream(std::ostream& stream, int indent = 0) const;
friend std::ostream& operator<<(std::ostream& stream, const XMLObject& object)
{
return object.WriteToStream(stream);
}
friend bool operator==(const XMLObject& object1, const XMLObject& object2)
{
if (object1.attributes.size() != object2.attributes.size())
return false;
if (object1.objects.size() != object2.objects.size())
return false;
if (object1.name != object2.name)
return false;
if (object1.GetText() != object2.GetText())
return false;
{ {
int pos; auto it1 = object1.attributes.begin();
int line; auto it2 = object2.attributes.begin();
const std::string& file; while (it1 != object1.attributes.end())
};
private:
std::string name;
std::string text;
std::map<std::string, std::string> attributes;
std::map<std::string, std::vector<XMLObject>> objects;
public:
XMLObject() {}
XMLObject(const std::string& string);
XMLObject(const std::string& string, int pos, int line, const std::string& file);
XMLObject(const std::string& string, XMLLoadData& data);
XMLObject(const std::string& name, const std::map<std::string, std::string>& properties, const std::string& text);
XMLObject(const std::string& name, const std::map<std::string, std::string>& properties, const std::map<std::string, std::vector<XMLObject>>& objects);
bool HasAttribute(const std::string& property) const;
const std::string& GetAttribute(const std::string& property) const;
const std::string& GetAttribute(const std::string& property, const std::string& defaultValue) const;
unsigned int GetObjectCount() const;
std::vector<XMLObject>* GetObjectPtr(const std::string& name);
const std::map<std::string, std::vector<XMLObject>>& GetObjects() const;
const std::string& GetName() const;
const std::string& GetText() const;
XMLObject GetStrippedXMLObject() const;
void SetName(const std::string& name);
void SetText(const std::string& text);
void AddAttribute(const std::string& property, const std::string& value);
void AddXMLObject(const XMLObject& object);
bool RemoveXMLObject(const XMLObject& object);
friend bool operator<(const XMLObject& obj1, const XMLObject& obj2)
{
return obj1.name < obj2.name;
}
std::ostream& WriteToStream(std::ostream& stream, int indent = 0) const;
friend std::ostream& operator<<(std::ostream& stream, const XMLObject& object)
{
return object.WriteToStream(stream);
}
friend bool operator==(const XMLObject& object1, const XMLObject& object2)
{
if(object1.attributes.size() != object2.attributes.size())
return false;
if(object1.objects.size() != object2.objects.size())
return false;
if(object1.name != object2.name)
return false;
if(object1.GetText() != object2.GetText())
return false;
{ {
auto it1 = object1.attributes.begin(); if (it1->first != it2->first || it1->second != it1->second)
auto it2 = object2.attributes.begin(); return false;
while(it1 != object1.attributes.end()) ++it1;
{ ++it2;
if(it1->first != it2->first || it1->second != it1->second)
return false;
++it1;
++it2;
}
} }
{
auto it1 = object1.objects.begin();
auto it2 = object2.objects.begin();
while(it1 != object1.objects.end())
{
if(it1->second != it2->second)
return false;
++it1;
++it2;
}
}
return true;
} }
private: {
std::string GetClosingTag(const std::string& string, XMLLoadData& data); auto it1 = object1.objects.begin();
// Returns true if the head contained closing tag. auto it2 = object2.objects.begin();
bool ReadHead(const std::string& string, XMLLoadData& data); while (it1 != object1.objects.end())
void ReadName(const std::string& string, XMLLoadData& data); {
void ReadAttribute(const std::string& string, XMLLoadData& data); if (it1->second != it2->second)
void ReadAttributes(const std::string& string, XMLLoadData& data); return false;
void ReadBodyTail(const std::string& string, XMLLoadData& data); ++it1;
void ReadText(const std::string& string, XMLLoadData& data); ++it2;
void ReadWhiteSpace(const std::string& string, XMLLoadData& data); }
void ReplacePredefinedEntities(std::string& string, XMLLoadData& data); }
std::string ReadXMLName(const std::string& string, XMLLoadData& data); return true;
}
private:
std::string GetClosingTag(const std::string& string, XMLLoadData& data);
// Returns true if the head contained closing tag.
bool ReadHead(const std::string& string, XMLLoadData& data);
void ReadName(const std::string& string, XMLLoadData& data);
void ReadAttribute(const std::string& string, XMLLoadData& data);
void ReadAttributes(const std::string& string, XMLLoadData& data);
void ReadBodyTail(const std::string& string, XMLLoadData& data);
void ReadText(const std::string& string, XMLLoadData& data);
void ReadWhiteSpace(const std::string& string, XMLLoadData& data);
void ReplacePredefinedEntities(std::string& string, XMLLoadData& data);
std::string ReadXMLName(const std::string& string, XMLLoadData& data);
}; };