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
#include <iostream>
#include <vector>
#include <set>
#include <vector>
#define BIT(x) (1<<x)
#define BIT(x) (1 << x)
#define STRINGIFY(x) #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_TARGET = BIT(11);
#define LOG_INFO(...) LogHelper(__VA_ARGS__)
#define LOG_WARNING(...) LogHelper(__VA_ARGS__)
#define LOG_ERROR(...) LogHelper(__VA_ARGS__)
@@ -42,22 +41,22 @@ void Log(const T& var)
std::cout << var;
}
template <typename T, typename ...Ts>
void Log(const T& var, const Ts& ...vars)
template <typename T, typename... Ts>
void Log(const T& var, const Ts&... vars)
{
Log(var);
Log(vars...);
}
template <typename T, typename ...Ts>
template <typename T, typename... Ts>
void LogHelper(const T& var)
{
Log(var);
std::cout << std::endl;
}
template <typename T, typename ...Ts>
void LogHelper(const T& var, const Ts& ...vars)
template <typename T, typename... Ts>
void LogHelper(const T& var, const Ts&... vars)
{
Log(var);
Log(vars...);
+41 -42
View File
@@ -5,7 +5,7 @@
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.
Usage: makegen conf <command> [<args>] [--help]
@@ -25,7 +25,7 @@ Querying config settings
void ConfigCLI::DisplayGenHelp()
{
LOG_INFO(1+(char*)R"(
LOG_INFO(1 + (char*)R"(
Generate a config file from prompts
Usage: makegen conf gen <option>
@@ -39,7 +39,7 @@ options:
void ConfigCLI::DisplayAddHelp()
{
LOG_INFO(1+(char*)R"(
LOG_INFO(1 + (char*)R"(
Add values to config settings which support multiple arguments
Usage: makegen conf add <setting> <value> [<values>]
@@ -60,7 +60,7 @@ Valid settings are:
void ConfigCLI::DisplayRemoveHelp()
{
LOG_INFO(1+(char*)R"(
LOG_INFO(1 + (char*)R"(
Remove values to config settings which support multiple
Usage: makegen conf remove <setting> <value> [<
@@ -81,7 +81,7 @@ Valid settings are
void ConfigCLI::DisplaySetHelp()
{
LOG_INFO(1+(char*)R"(
LOG_INFO(1 + (char*)R"(
Set value to config settings which only support one argument
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()
{
LOG_INFO(1+(char*)R"(
LOG_INFO(1 + (char*)R"(
Get value of the config setting
Usage: makegen conf get <setting>
@@ -128,7 +128,6 @@ Valid settings are:
genhfile Specifies if MakeGen should generate a project h-file)");
}
ConfigSetting ConfigCLI::CLIStringToSetting(const std::string& s)
{
static std::map<std::string, ConfigSetting> map{
@@ -152,30 +151,30 @@ ConfigSetting ConfigCLI::CLIStringToSetting(const std::string& s)
{"genhfile", ConfigSetting::GenerateHFile},
};
auto it = map.find(s);
if(it == map.end())
if (it == map.end())
return ConfigSetting::Invalid;
return it->second;
}
int ConfigCLI::Gen(int argc, char** argv)
{
if(argc < 2 || std::string(argv[1]) == "--help")
if (argc < 2 || std::string(argv[1]) == "--help")
{
DisplayGenHelp();
return 0;
}
if(argc < 2)
if (argc < 2)
{
LOG_ERROR("gen needs exactly one parameter");
return 1;
}
std::string option = argv[1];
if(option == "prompt")
if (option == "prompt")
{
ConfigFile::Gen(FlagData{}).Save();
return 0;
}
if(option == "default")
if (option == "default")
{
ConfigFile{FileUtils::GetRealPath("."), FlagData{}, 0}.Save();
return 0;
@@ -189,21 +188,21 @@ int ConfigCLI::Gen(int argc, char** argv)
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();
return 0;
}
if(argc < 3)
if (argc < 3)
{
LOG_ERROR("add needs at least two parameters");
return 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]);
}
@@ -214,7 +213,7 @@ int ConfigCLI::Add(int argc, char** argv, ConfigFile& config)
}
return 1;
}
for(int i = 2; i<argc;++i)
for (int i = 2; i < argc; ++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)
{
if(argc < 2 || std::string(argv[1]) == "--help")
if (argc < 2 || std::string(argv[1]) == "--help")
{
DisplayRemoveHelp();
return 0;
}
if(argc < 3)
if (argc < 3)
{
LOG_ERROR("remove needs at least two parameters");
return 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]);
}
@@ -251,7 +250,7 @@ int ConfigCLI::Remove(int argc, char** argv, ConfigFile& config)
return 1;
}
for(int i = 2; i<argc;++i)
for (int i = 2; i < argc; ++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)
{
if(argc < 2 || std::string(argv[1]) == "--help")
if (argc < 2 || std::string(argv[1]) == "--help")
{
DisplaySetHelp();
return 0;
}
if(argc != 3)
if (argc != 3)
{
LOG_ERROR("set needs exactly two parameters");
return 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]);
}
@@ -295,19 +294,19 @@ int ConfigCLI::Set(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();
return 0;
}
if(argc != 2)
if (argc != 2)
{
LOG_ERROR("get needs exactly one parameter");
return 1;
}
ConfigSetting setting = CLIStringToSetting(argv[1]);
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);
}
@@ -317,32 +316,32 @@ int ConfigCLI::Get(int argc, char** argv, ConfigFile& config)
int ConfigCLI::Main(int argc, char** argv)
{
// Do nothing
if(argc < 2 || std::string(argv[1]) == "--help")
if (argc < 2 || std::string(argv[1]) == "--help")
{
DisplayCLIHelp();
return 0;
}
std::optional<ConfigFile> config = ConfigFile::GetConfigFile("./", FlagData{});
std::string command = argv[1];
if(command == "gen")
if (command == "gen")
{
if(config)
if (config)
{
LOG_ERROR("Config file already exist (", CONFIG_FILENAME, ")");
return 1;
}
return Gen(argc-1, &argv[1]);
return Gen(argc - 1, &argv[1]);
}
else if(config)
else if (config)
{
if(command == "add")
return Add(argc-1, &argv[1], *config);
else if(command == "remove")
return Remove(argc-1, &argv[1], *config);
else if(command == "set")
return Set(argc-1, &argv[1], *config);
else if(command == "get")
return Get(argc-1, &argv[1], *config);
if (command == "add")
return Add(argc - 1, &argv[1], *config);
else if (command == "remove")
return Remove(argc - 1, &argv[1], *config);
else if (command == "set")
return Set(argc - 1, &argv[1], *config);
else if (command == "get")
return Get(argc - 1, &argv[1], *config);
else
{
LOG_ERROR("Unknown config command: ", command);
+15 -15
View File
@@ -4,22 +4,22 @@
struct ConfigCLI
{
public:
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();
public:
static int Main(int argc, char** argv);
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 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 ConfigSetting CLIStringToSetting(const std::string& s);
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 <fstream>
#include "FileUtils.h"
#include "compatibility/ConfigFileConf.h"
#include "xml/XML.h"
#include <fstream>
ConfigFile::ConfigFile(const std::string& path, const FlagData& flagData, int)
: 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
makegen.AddXMLObject(XMLObject("version", {}, "v1.3.0"));
if(flagData.flags & FLAG_TARGET)
if (flagData.flags & FLAG_TARGET)
makegen.AddXMLObject(XMLObject("target", {}, flagData.target));
else
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)
: config{XML::FromFile(path + CONFIG_FILENAME)}, configPath{path}
: config{XML::FromFile(path + CONFIG_FILENAME)},
configPath{path}
{
Init(flagData);
}
ConfigFile::ConfigFile(XMLObject& config, const std::string& path, const FlagData& flagData)
: config{config}, configPath{path}
: config{config},
configPath{path}
{
Init(flagData);
}
@@ -57,23 +59,22 @@ void ConfigFile::Init(const FlagData& flagData)
{
const std::vector<XMLObject>* targetXml = config.GetObjectPtr("target");
target = "Release";
if(!targetXml || targetXml->size() == 0)
if (!targetXml || targetXml->size() == 0)
{
LOG_ERROR("No target found in config file. Using target=", target);
return;
}
if(targetXml->size() > 1)
if (targetXml->size() > 1)
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();
}
}
std::string& ConfigFile::GetSettingString(ConfigSetting setting)
{
// 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");
return cache.strings.emplace("invalid", "").first->second;
@@ -81,43 +82,43 @@ std::string& ConfigFile::GetSettingString(ConfigSetting setting)
std::string sSetting = ConfigUtils::GetSettingName(setting);
auto it = cache.strings.find(sSetting);
if(it != cache.strings.end())
if (it != cache.strings.end())
return it->second;
const std::vector<XMLObject>* values = GetConfiguration().GetObjectPtr(sSetting);
// No value found, using default
if(values == nullptr)
if (values == nullptr)
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());
}
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 += '/';
return cache.strings.emplace(sSetting, s).first->second;
}
bool ConfigFile::GetSettingBool(ConfigSetting setting)
{
if(setting == ConfigSetting::Invalid)
if (setting == ConfigSetting::Invalid)
{
LOG_ERROR("Invalid config setting");
return false;
}
std::string sSetting = ConfigUtils::GetSettingName(setting);
auto it = cache.bools.find(sSetting);
if(it != cache.bools.end())
if (it != cache.bools.end())
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;
if(values->size() != 1)
if (values->size() != 1)
{
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);
auto it = cache.vecStrings.find(sSetting);
if(it != cache.vecStrings.end())
if (it != cache.vecStrings.end())
return it->second;
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;
std::vector<std::string> strings;
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;
std::string s = it->GetText();
if(ConfigUtils::IsDirectory(setting) && s[s.size()-1] != '/')
if (ConfigUtils::IsDirectory(setting) && s[s.size() - 1] != '/')
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)
{
if(ConfigUtils::IsStringSetting(setting))
if (ConfigUtils::IsStringSetting(setting))
return {GetSettingString(setting)};
else if(ConfigUtils::IsVectorSetting(setting))
else if (ConfigUtils::IsVectorSetting(setting))
return GetSettingVectorString(setting);
else if(ConfigUtils::IsBoolSetting(setting))
else if (ConfigUtils::IsBoolSetting(setting))
return {GetSettingBool(setting) ? "true" : "false"};
else
{
@@ -170,24 +171,24 @@ bool ConfigFile::SetSettingString(ConfigSetting setting, const std::string& valu
// Check if valid enum
std::string s = value;
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 += '/';
}
auto it = cache.strings.find(sSetting);
// Update cache
if(it != cache.strings.end())
if (it != cache.strings.end())
it->second = s;
else
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";
else if(s == "false" || s == "f" || s == "no" || s == "n")
else if (s == "false" || s == "f" || s == "no" || s == "n")
s = "false";
else
{
@@ -197,7 +198,7 @@ bool ConfigFile::SetSettingString(ConfigSetting setting, const std::string& valu
auto it = cache.bools.find(sSetting);
// Update cache
if(it != cache.bools.end())
if (it != cache.bools.end())
it->second = s == "true";
else
cache.bools.emplace(sSetting, value == "true");
@@ -210,9 +211,9 @@ bool ConfigFile::SetSettingString(ConfigSetting setting, const std::string& valu
XMLObject& configuration = GetConfiguration();
std::vector<XMLObject>* values = configuration.GetObjectPtr(sSetting);
if(values == nullptr)
if (values == nullptr)
configuration.AddXMLObject({sSetting, {}, s});
else if(values->size() > 1)
else if (values->size() > 1)
LOG_ERROR("Multiple values of setting, changing first: ", sSetting, "=", s);
else
(*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)
{
// Check if valid enum
if(ConfigUtils::IsVectorSetting(setting))
if (ConfigUtils::IsVectorSetting(setting))
{
std::string s = value;
if(ConfigUtils::IsDirectory(setting) && s[s.size()-1] != '/')
if (ConfigUtils::IsDirectory(setting) && s[s.size() - 1] != '/')
{
s += '/';
}
@@ -233,7 +234,7 @@ bool ConfigFile::AddSettingVectorString(ConfigSetting setting, const std::string
auto it = cache.vecStrings.find(sSetting);
// Update cache
if(it != cache.vecStrings.end())
if (it != cache.vecStrings.end())
it->second.push_back(s);
else
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)
{
// Check if valid enum
if(ConfigUtils::IsVectorSetting(setting))
if (ConfigUtils::IsVectorSetting(setting))
{
std::string s = value;
if(ConfigUtils::IsDirectory(setting) && s[s.size()-1] != '/')
if (ConfigUtils::IsDirectory(setting) && s[s.size() - 1] != '/')
{
s += '/';
}
std::string sSetting = ConfigUtils::GetSettingName(setting);
auto it = cache.vecStrings.find(sSetting);
if(it != cache.vecStrings.end())
if (it != cache.vecStrings.end())
{
// 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);
}
@@ -275,16 +276,16 @@ bool ConfigFile::RemoveSettingVectorString(ConfigSetting setting, const std::str
std::vector<XMLObject>* values = GetConfiguration().GetObjectPtr(sSetting);
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);
found = true;
break;
}
}
if(!found)
if (!found)
{
LOG_ERROR("Couldn't find value: ", s);
return false;
@@ -301,25 +302,26 @@ bool ConfigFile::RemoveSettingVectorString(ConfigSetting setting, const std::str
XMLObject& ConfigFile::GetConfiguration()
{
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");
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");
continue;
}
if(it->GetAttribute("name") == target)
if (it->GetAttribute("name") == target)
{
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];
}
@@ -339,20 +341,22 @@ std::optional<ConfigFile> ConfigFile::GetConfigFile(const std::string& filepath,
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);
if(realPath == "")
if (realPath == "")
return {};
auto it = loadedConfigs.find(realPath);
if(it != loadedConfigs.end())
if (it != loadedConfigs.end())
{
return {};
}
bool oldFile = false;
std::ifstream f(filepath + CONFIG_FILENAME);
if(!f.good())
if (!f.good())
{
ConfigFileConf::CreateXMLFile(realPath);
// 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
if(f.good())
if (f.good())
{
f.close();
ConfigFile conf = ConfigFile(filepath, flagData);
if(conf.hasInitError)
if (conf.hasInitError)
return {};
loadedConfigs.emplace(realPath, conf);
std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency);
// 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);
if(dep)
if (dep)
{
conf.dependencyConfigs.push_back(*dep);
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)
{
std::string input;
while(true)
while (true)
{
LOG_INFO(inputText);
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';
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)
{
str = "";
while(true)
while (true)
{
LOG_INFO(inputText);
std::getline(std::cin, str);
if(needEnding && str[str.length()-1] != '/' && !str.empty())
if (needEnding && str[str.length() - 1] != '/' && !str.empty())
str += '/';
if(allowEmpty || !str.empty())
if (allowEmpty || !str.empty())
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)
{
std::string input;
while(true)
while (true)
{
InputString(inputText, input, needEnding, true);
if(input == "")
if (input == "")
break;
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)
{
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;
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(executable)
if (executable)
{
InputMultiple("Enter library:", libs,false);
InputMultiple("Enter library directory:", libdirs,true);
InputMultiple("Enter project dependencies:", dependencies,true);
InputMultiple("Enter library:", libs, false);
InputMultiple("Enter library directory:", libdirs, true);
InputMultiple("Enter project dependencies:", dependencies, true);
}
else
{
InputBoolean("Should it be compiled as a shared library? (y/n)", shared);
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);
}
@@ -466,18 +471,17 @@ ConfigFile ConfigFile::Gen(const FlagData& flagData)
InputMultiple("Enter excluded source files flags:", excludeSources, false);
InputMultiple("Enter excluded header files flags:", excludeHeaders, false);
InputString("Enter output directory (default: bin):", outputdir, true, true);
if(outputdir == "")
if (outputdir == "")
outputdir = "bin/";
InputString("Enter a name for the project:", projectname, false, false);
InputString("Enter a name for the output file:", outputname, false, false);
// Create xml
XMLObject makegen("makegen", {}, std::map<std::string, std::vector<XMLObject>>{});
// Version, target and configuration is probably going to be used in the future
makegen.AddXMLObject(XMLObject("version", {}, "v1.3.0"));
if(flagData.flags & FLAG_TARGET)
if (flagData.flags & FLAG_TARGET)
makegen.AddXMLObject(XMLObject("target", {}, flagData.target));
else
makegen.AddXMLObject(XMLObject("target", {}, "Release"));
@@ -488,22 +492,18 @@ ConfigFile ConfigFile::Gen(const FlagData& flagData)
configuration.AddXMLObject(XMLObject("srcdir", {}, srcdir));
configuration.AddXMLObject(XMLObject("outputdir", {}, outputdir));
configuration.AddXMLObject(XMLObject("hfilename", {}, hFile));
configuration.AddXMLObject(XMLObject("outputtype", {},
executable ? "executable" : (shared ? "sharedlibrary" : "staticlibrary")));
configuration.AddXMLObject(
XMLObject("outputtype", {}, executable ? "executable" : (shared ? "sharedlibrary" : "staticlibrary")));
configuration.AddXMLObject(XMLObject("generatehfile", {}, generateHFile ? "true" : "false"));
for(auto it = libs.begin();it != libs.end(); ++it)
configuration.AddXMLObject({"library",{},*it});
for(auto it = libdirs.begin();it != libdirs.end(); ++it)
configuration.AddXMLObject({"librarydir",{},*it});
for(auto it = includedirs.begin();it != includedirs.end(); ++it)
configuration.AddXMLObject({"includedir",{},*it});
for(auto it = defines.begin();it != defines.end(); ++it)
configuration.AddXMLObject({"define",{},*it});
for(auto it = compileFlags.begin();it != compileFlags.end(); ++it)
configuration.AddXMLObject({"cflag",{},*it});
for(auto it = dependencies.begin();it != dependencies.end(); ++it)
configuration.AddXMLObject({"dependency",{},*it});
for (auto it = libs.begin(); it != libs.end(); ++it) configuration.AddXMLObject({"library", {}, *it});
for (auto it = libdirs.begin(); it != libdirs.end(); ++it) configuration.AddXMLObject({"librarydir", {}, *it});
for (auto it = includedirs.begin(); it != includedirs.end(); ++it)
configuration.AddXMLObject({"includedir", {}, *it});
for (auto it = defines.begin(); it != defines.end(); ++it) configuration.AddXMLObject({"define", {}, *it});
for (auto it = 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);
return ConfigFile{makegen, FileUtils::GetRealPath("."), flagData};
Executable → Regular
+43 -39
View File
@@ -1,60 +1,64 @@
#pragma once
#include "ConfigUtils.h"
#include "FlagData.h"
#include "xml/XMLObject.h"
#include <map>
#include <optional>
#include <string>
#include <vector>
#include "ConfigUtils.h"
#include "FlagData.h"
#include "xml/XMLObject.h"
static const std::string CONFIG_FILENAME = "makegen.xml";
class ConfigFile
{
private:
ConfigCache cache;
private:
ConfigCache cache;
XMLObject config;
// Current configuration
std::string target;
XMLObject config;
// Current configuration
std::string target;
std::string configPath;
std::vector<ConfigFile> dependencyConfigs;
std::string configPath;
std::vector<ConfigFile> dependencyConfigs;
bool hasInitError = false;
bool hasInitError = false;
public:
// Generates a new default config file
ConfigFile(const std::string& path, const FlagData& flagData, int);
ConfigFile(const std::string& path, const FlagData& flagData);
ConfigFile(XMLObject& config, const std::string& path, const FlagData& flagData);
public:
// Generates a new default config file
ConfigFile(const std::string& path, const FlagData& flagData, int);
ConfigFile(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);
bool GetSettingBool(ConfigSetting setting);
std::vector<std::string>& GetSettingVectorString(ConfigSetting setting);
std::vector<std::string> GetSetting(ConfigSetting setting);
std::string& GetSettingString(ConfigSetting setting);
bool GetSettingBool(ConfigSetting setting);
std::vector<std::string>& GetSettingVectorString(ConfigSetting setting);
std::vector<std::string> GetSetting(ConfigSetting setting);
bool SetSettingString(ConfigSetting setting, const std::string& value);
bool AddSettingVectorString(ConfigSetting setting, const std::string& value);
bool RemoveSettingVectorString(ConfigSetting setting, const std::string& value);
bool SetSettingString(ConfigSetting setting, const std::string& value);
bool AddSettingVectorString(ConfigSetting setting, const std::string& value);
bool RemoveSettingVectorString(ConfigSetting setting, const std::string& value);
XMLObject& GetConfiguration();
const std::string& GetConfigPath() const;
ConfigFile& GetDependencyConfig(size_t i);
private:
void Init(const FlagData& flagData);
XMLObject& GetConfiguration();
const std::string& GetConfigPath() const;
ConfigFile& GetDependencyConfig(size_t i);
public:
static ConfigFile Gen(const FlagData& flagData);
static std::optional<ConfigFile> GetConfigFile(const std::string& filepath, const FlagData& flagData);
private:
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);
private:
void Init(const FlagData& flagData);
public:
static ConfigFile Gen(const FlagData& flagData);
static std::optional<ConfigFile> GetConfigFile(const std::string& filepath, const FlagData& flagData);
private:
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
#include <assert.h>
#include <map>
#include <string>
#include <vector>
#include "Common.h"
#include "FileUtils.h"
#include <assert.h>
#include <map>
#include <vector>
#include <string>
struct ConfigCache
{
std::map<std::string, std::string> strings;
@@ -18,9 +19,26 @@ struct ConfigCache
enum class ConfigSetting
{
// 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
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
GenerateHFile = 64,
// Other
@@ -31,7 +49,7 @@ struct ConfigUtils
{
static std::string GetSettingName(ConfigSetting setting)
{
switch(setting)
switch (setting)
{
case ConfigSetting::SourceDir:
return "srcdir";
@@ -81,7 +99,7 @@ struct ConfigUtils
static bool IsDirectory(ConfigSetting setting)
{
switch(setting)
switch (setting)
{
case ConfigSetting::SourceDir:
case ConfigSetting::OutputDir:
@@ -112,7 +130,7 @@ struct ConfigUtils
static bool IsStringSetting(ConfigSetting setting)
{
switch(setting)
switch (setting)
{
case ConfigSetting::SourceDir:
case ConfigSetting::OutputDir:
@@ -143,7 +161,7 @@ struct ConfigUtils
static bool IsVectorSetting(ConfigSetting setting)
{
switch(setting)
switch (setting)
{
case ConfigSetting::LibraryDir:
case ConfigSetting::IncludeDir:
@@ -171,9 +189,10 @@ struct ConfigUtils
}
return false;
}
static bool IsBoolSetting(ConfigSetting setting)
{
switch(setting)
switch (setting)
{
case ConfigSetting::GenerateHFile:
return true;
@@ -204,7 +223,7 @@ struct ConfigUtils
static std::string GetDefaultSettingString(ConfigSetting setting, const std::string& path)
{
switch(setting)
switch (setting)
{
case ConfigSetting::SourceDir:
return "src/";
@@ -229,7 +248,7 @@ struct ConfigUtils
static bool GetDefaultSettingBool(ConfigSetting setting)
{
switch(setting)
switch (setting)
{
case ConfigSetting::GenerateHFile:
return false;
@@ -248,23 +267,18 @@ struct ConfigUtils
{
std::string projectname = GetDefaultProjectName(path);
std::string outputname;
std::transform(
projectname.begin(),
projectname.end(),
std::back_inserter(outputname),
[](unsigned char c)
{
if(c == ' ')
return '_';
return (char)std::tolower(c);
});
auto it = std::remove_if(
outputname.begin(),
outputname.end(),
[](unsigned char c)
{
return (c < '0' || c > '9') && (c < 'a' || c > 'z') && c != '_';
});
std::transform(projectname.begin(),
projectname.end(),
std::back_inserter(outputname),
[](unsigned char c)
{
if (c == ' ')
return '_';
return (char)std::tolower(c);
});
auto it = std::remove_if(outputname.begin(),
outputname.end(),
[](unsigned char c) { return (c < '0' || c > '9') && (c < 'a' || c > 'z') && c != '_'; });
outputname.erase(it, outputname.end());
outputname += ".out";
return outputname;
@@ -274,12 +288,7 @@ struct ConfigUtils
{
std::string hfile = GetDefaultProjectName(path);
auto it = std::remove_if(
hfile.begin(),
hfile.end(),
[](unsigned char c)
{
return (c < 'a' || c > 'z') && (c < 'A' || c > 'Z');
});
hfile.begin(), hfile.end(), [](unsigned char c) { return (c < 'a' || c > 'z') && (c < 'A' || c > 'Z'); });
hfile.erase(it, hfile.end());
hfile += ".h";
return hfile;
+46 -44
View File
@@ -1,18 +1,20 @@
#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 "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
{
@@ -20,7 +22,7 @@ struct FileUtils
{
struct stat info;
if(stat(path.c_str(), &info) != 0)
if (stat(path.c_str(), &info) != 0)
return false;
else
return true;
@@ -33,23 +35,23 @@ struct FileUtils
static std::string GetCurrentDirectory()
{
static char path[256]; // Usual maximum filename
static char path[256]; // Usual maximum filename
getcwd(path, sizeof(path));
return GetTopDirectory(path);
}
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()");
assert(false);
}
size_t dirEnd = std::string::npos;
if(dir[dir.size()-1] == '/')
dirEnd = dir.size()-2;
if (dir[dir.size() - 1] == '/')
dirEnd = dir.size() - 2;
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.");
assert(false);
@@ -60,11 +62,11 @@ struct FileUtils
static std::string GetRealPath(const std::string& filename)
{
#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);
std::string sPath = path;
sPath+="/";
sPath += "/";
free(path);
return sPath;
}
@@ -81,30 +83,30 @@ struct FileUtils
static std::string GetRelativePath(std::string from, std::string to)
{
std::string result;
if(to[to.size()-1] == '/')
if (to[to.size() - 1] == '/')
to.pop_back();
if(from[from.size()-1] == '/')
if (from[from.size() - 1] == '/')
from.pop_back();
// 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
if(to.size() == from.size())
if (to.size() == from.size())
return "";
// 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
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());
size_t n = std::count(sub.begin(), sub.end(), '/');
for(int i = 0;i<n;i++)
for (int i = 0; i < n; i++)
{
result+="..";
if(i != n-1)
result+="/";
result += "..";
if (i != n - 1)
result += "/";
}
return result;
}
@@ -112,21 +114,20 @@ struct FileUtils
else
{
// Find the most common directory
std::string commonPath = Utils::CommonPrefix(from,to);
std::string commonPath = Utils::CommonPrefix(from, to);
if (commonPath.empty())
return "";
while(commonPath.back() != '/')
commonPath.pop_back();
while (commonPath.back() != '/') commonPath.pop_back();
commonPath.pop_back();
// Go back to the common directory
std::string sub = from.substr(commonPath.size());
size_t n = std::count(sub.begin(), sub.end(), '/');
for(int i = 0;i<n;i++)
for (int i = 0; i < n; i++)
{
result+="..";
if(i != n-1)
result+="/";
result += "..";
if (i != n - 1)
result += "/";
}
// Add the path which diverges
result += to.substr(commonPath.size());
@@ -137,24 +138,25 @@ struct FileUtils
static void GetAllFiles(const std::string& folder, std::vector<std::string>& files)
{
DIR* dp;
struct dirent *dirp;
if((dp = opendir(folder.c_str())) == NULL){
struct dirent* dirp;
if ((dp = opendir(folder.c_str())) == NULL)
{
LOG_ERROR("Failed to open directory: ", folder);
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;
if(strcmp(dirp->d_name,"..") == 0)
if (strcmp(dirp->d_name, "..") == 0)
continue;
GetAllFiles(folder+dirp->d_name+"/", files);
GetAllFiles(folder + dirp->d_name + "/", files);
}
else
{
files.push_back(folder+dirp->d_name);
files.push_back(folder + dirp->d_name);
}
}
closedir(dp);
+1 -1
View File
@@ -5,5 +5,5 @@
struct FlagData
{
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 "FileUtils.h"
#include <set>
#include "FileUtils.h"
void HFileGen::Create(ConfigFile& conf)
{
std::set<std::string> hFiles;
std::vector<std::string> files;
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
// 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(".");
if(extensionPos != std::string::npos)
if (extensionPos != std::string::npos)
{
std::string filename = it->substr(path.length());
if(Utils::IsHeaderFile(filename) && filename != conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::HFileName))
if (Utils::IsHeaderFile(filename) &&
filename != conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::HFileName))
{
// Make files sorted in alphabetical order
hFiles.emplace(filename);
@@ -28,11 +30,11 @@ void HFileGen::Create(ConfigFile& conf)
const std::vector<std::string>& excludeHeaders = conf.GetSettingVectorString(ConfigSetting::ExcludeHeader);
std::ofstream os(path + "/" + conf.GetSettingString(ConfigSetting::HFileName));
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);
if(it == excludeHeaders.end())
if (it == excludeHeaders.end())
os << "#include <" << hFile << ">" << std::endl;
}
}
+2 -2
View File
@@ -4,6 +4,6 @@
class HFileGen
{
public:
static void Create(ConfigFile& conf);
public:
static void Create(ConfigFile& conf);
};
Executable → Regular
+29 -17
View File
@@ -1,31 +1,39 @@
#include "IncludeDeps.h"
#include "Common.h"
#include <sstream>
#include "Common.h"
std::set<std::string> IncludeDeps::printSet;
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::IncludeDeps(const std::string& filename, bool projectHFile, const std::set<HFile>& files, std::map<std::string, IncludeDeps*>& allDeps)
: filepath(filename), projectHFile{projectHFile}
IncludeDeps::IncludeDeps(const std::string& filename,
bool projectHFile,
const std::set<HFile>& files,
std::map<std::string, IncludeDeps*>& allDeps)
: filepath(filename),
projectHFile{projectHFile}
{
std::filesystem::path path{filepath};
if(Utils::IsHeaderFile(filename))
if (Utils::IsHeaderFile(filename))
{
allDeps.emplace(filepath, this);
}
std::ifstream file(filepath);
std::string line;
while(std::getline(file,line))
while (std::getline(file, line))
{
std::string start;
std::stringstream ss{line};
ss >> start;
if(start == "#include")
if (start == "#include")
{
std::string include = GetIncludeFile(line);
@@ -39,25 +47,29 @@ IncludeDeps::IncludeDeps(const std::string& filename, bool projectHFile, const s
if (FileUtils::FileExists(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);
dependencies.emplace(includeFileRelativeToSource, inc);
} else {
}
else
{
dependencies.emplace(itD->first, itD->second);
}
}
else
{
auto it = files.find({include, "", false});
if(it != files.end())
if (it != files.end())
{
auto itD = allDeps.find(it->filepath);
if(itD == allDeps.end())
if (itD == allDeps.end())
{
IncludeDeps* inc = new IncludeDeps(it->filepath, it->isProjectHFile, files, allDeps);
dependencies.emplace(it->filepath, inc);
}else{
}
else
{
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)
{
size_t bracket = line.find('<');
if(bracket == std::string::npos)
if (bracket == std::string::npos)
{
bracket = line.find('\"');
if(bracket == std::string::npos)
if (bracket == std::string::npos)
{
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;
}
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
#include "ConfigFile.h"
#include "FileUtils.h"
#include <iostream>
#include <filesystem>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include "ConfigFile.h"
#include "FileUtils.h"
struct CompareIncludeDeps;
class IncludeDeps
{
public:
std::map<std::string, IncludeDeps*> dependencies;
std::filesystem::path filepath;
bool projectHFile;
static std::set<std::string> printSet;
static int printCounter;
public:
std::map<std::string, IncludeDeps*> dependencies;
std::filesystem::path filepath;
bool projectHFile;
static std::set<std::string> printSet;
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::string filePathInMakeFile = filepath;
if(!filepath.is_absolute())
filePathInMakeFile = std::filesystem::relative(conf.GetConfigPath() + "/" + filepath.string(), "./").string();
std::ostream& Output(std::ostream& stream, const ConfigFile& conf)
{
std::string filePathInMakeFile = filepath;
if (!filepath.is_absolute())
filePathInMakeFile = std::filesystem::relative(conf.GetConfigPath() + "/" + filepath.string(), "./").string();
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();
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;
}
};
struct CompareIncludeDeps
{
using is_transparent = void;
bool operator()(const IncludeDeps* d1, const IncludeDeps* d2) const
{
return d1->filepath < d2->filepath;
}
bool operator()(const IncludeDeps* d, const std::string& filepath) const
{
return d->filepath < filepath;
}
bool operator()(const std::string& filepath, const IncludeDeps* d) const
{
return filepath < d->filepath;
+36 -36
View File
@@ -1,30 +1,31 @@
#include "Makefile.h"
#include "IncludeDeps.h"
#include "Utils.h"
#include "Common.h"
#include <fstream>
#include <map>
#include "Common.h"
#include "IncludeDeps.h"
#include "Utils.h"
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;
if(flags & FLAG_SIMPLE)
if (flags & FLAG_SIMPLE)
Utils::GetCppFiles(conf, cppFiles);
else
Utils::GetCppAndHFiles(conf, hFiles, cppFiles);
std::ofstream outputFile(conf.GetConfigPath()+ "Makefile");
outputFile << "# This Makefile was generated using MakeGen "<< MAKEGEN_VERSION << " made by Tim Håkansson" << std::endl;
std::ofstream outputFile(conf.GetConfigPath() + "Makefile");
outputFile << "# This Makefile was generated using MakeGen " << MAKEGEN_VERSION << " made by Tim Håkansson"
<< std::endl;
outputFile << "# and is licensed under MIT. Full source of the project can be found at" << std::endl;
outputFile << "# https://github.com/Thraix/MakeGen" << std::endl;
outputFile << "CC=@g++" << std::endl;
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;
else
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 << "INCLUDES=";
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 << " ";
}
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 << std::endl;
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 slash = it->find_last_of("/")+1;
size_t slash = it->find_last_of("/") + 1;
outputFile << "$(OBJPATH)/" << it->substr(slash, extensionPos - slash) << ".o ";
}
outputFile << std::endl;
if(outputtype == "executable" || outputtype != "sharedlibrary")
if (outputtype == "executable" || outputtype != "sharedlibrary")
{
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 ";
}
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 << " ";
}
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 << 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=";
for(auto it = libdirs.begin();it!=libdirs.end();++it)
for (auto it = libdirs.begin(); it != libdirs.end(); ++it)
{
outputFile << "-L " << *it << " ";
}
outputFile << std::endl;
std::vector<std::string>& lflags = conf.GetSettingVectorString(ConfigSetting::LFlag);
outputFile << "LDFLAGS=";
for(auto it = lflags.begin(); it != lflags.end(); ++it)
for (auto it = lflags.begin(); it != lflags.end(); ++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 << std::endl;
std::vector<std::string>& libs = conf.GetSettingVectorString(ConfigSetting::Library);
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 << std::endl;
std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency);
if(!dependencies.empty())
if (!dependencies.empty())
{
outputFile << "DEPENDENCIES=";
for(auto it = dependencies.begin();it!=dependencies.end();++it)
for (auto it = dependencies.begin(); it != dependencies.end(); ++it)
{
outputFile << *it << " ";
}
@@ -132,17 +133,15 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
// Run
outputFile << "run: all" << std::endl;
if(outputtype == "executable")
if (outputtype == "executable")
{
std::vector<std::string>& prearguments = conf.GetSettingVectorString(ConfigSetting::ExecPreArgument);
std::vector<std::string>& arguments = conf.GetSettingVectorString(ConfigSetting::ExecArgument);
outputFile << "\t@";
for(auto&& preargument : prearguments)
outputFile << preargument << " ";
for (auto&& preargument : prearguments) outputFile << preargument << " ";
outputFile << "./$(OUTPUT)";
for(auto&& argument : arguments)
outputFile << " " << argument;
for (auto&& argument : arguments) outputFile << " " << argument;
outputFile << std::endl;
}
@@ -157,27 +156,28 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
// Output file
outputFile << "$(OUTPUT): $(OBJECTS)" << 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;
else
outputFile << "\t$(CO) $(OUTPUT) $(OBJECTS)" << std::endl;
// Install
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;
std::map<std::string, IncludeDeps*> dependencies;
size_t i = 0;
for(auto it = cppFiles.begin(); it != cppFiles.end();++it)
for (auto it = cppFiles.begin(); it != cppFiles.end(); ++it)
{
i++;
auto itD = dependencies.find(*it);
if(itD == dependencies.end())
if (itD == dependencies.end())
{
size_t extensionPos = it->find_last_of(".");
size_t slash = it->find_last_of("/")+1;
std::string oFile = it->substr(slash, extensionPos - slash)+".o ";
size_t slash = it->find_last_of("/") + 1;
std::string oFile = it->substr(slash, extensionPos - slash) + ".o ";
outputFile << "$(OBJPATH)/" << oFile << ":";
if (flags & FLAG_SIMPLE)
Executable → Regular
+2 -2
View File
@@ -4,6 +4,6 @@
class Makefile
{
public:
static void Save(ConfigFile& conf, unsigned int flags);
public:
static void Save(ConfigFile& conf, unsigned int flags);
};
Executable → Regular
+19 -14
View File
@@ -4,20 +4,25 @@
class Timer
{
private:
std::chrono::time_point<std::chrono::high_resolution_clock> m_start;
public:
Timer(){
Reset();
}
private:
std::chrono::time_point<std::chrono::high_resolution_clock> m_start;
void Reset()
{
m_start = std::chrono::high_resolution_clock::now();
}
public:
Timer()
{
Reset();
}
float Elapsed()
{
return std::chrono::duration_cast<std::chrono::duration<float,std::milli>>(std::chrono::high_resolution_clock::now() - m_start).count() / 1000.0f;
}
void Reset()
{
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 <filesystem>
#include "ConfigFile.h"
#include "FileUtils.h"
#include <filesystem>
bool Utils::IsSourceFile(const std::string& filepath)
{
std::string_view extension(filepath);
size_t pSlash = 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);
return false;
@@ -24,7 +24,7 @@ bool Utils::IsHeaderFile(const std::string& filepath)
std::string_view extension(filepath);
size_t pSlash = 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;
}
@@ -40,13 +40,12 @@ bool Utils::StartsWith(const std::string& str, const std::string& prefix)
return str.compare(0, prefix.size(), prefix) == 0;
}
std::string Utils::CommonPrefix(const std::string& s1, const std::string& s2)
{
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;
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);
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);
else
LOG_WARNING("Source file doesn't exist: ", sourceFile);
}
for(auto& filename : files)
for (auto& filename : files)
{
std::filesystem::path filepath = std::filesystem::relative(filename, "./");
if(IsSourceFile(filename))
if (IsSourceFile(filename))
{
auto it = std::find(excludeSources.begin(), excludeSources.end(), filename);
if(it == excludeSources.end())
if (it == excludeSources.end())
{
cppFiles.emplace(filepath.string());
}
@@ -98,39 +97,39 @@ void Utils::GetCppAndHFiles(ConfigFile& conf, std::set<HFile>& hFiles, std::set<
FileUtils::GetAllFiles(path, files);
}
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);
else
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, "./");
auto it = std::find(excludeSources.begin(), excludeSources.end(), filepath.string());
if(it == excludeSources.end())
if (it == excludeSources.end())
{
cppFiles.emplace(filepath.string());
}
}
else if(IsHeaderFile(filename))
else if (IsHeaderFile(filename))
{
std::filesystem::path path = std::filesystem::relative(filename, sourceDir);
hFiles.emplace(HFile{path.string(), sourceDir, false});
}
}
for(const auto& includePath : conf.GetSettingVectorString(ConfigSetting::IncludeDir))
for (const auto& includePath : conf.GetSettingVectorString(ConfigSetting::IncludeDir))
{
std::vector<std::string> files;
FileUtils::GetAllFiles(includePath, files);
for(const auto& file : files)
for (const auto& file : files)
{
std::filesystem::path path = std::filesystem::relative(file, includePath);
if(IsHeaderFile(path.string()))
if (IsHeaderFile(path.string()))
{
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);
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);
}
@@ -150,7 +149,7 @@ void Utils::GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::s
// Cyclic dependencies probably shouldn't exist.
// so just warn the user that it does and terminate.
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);
}
@@ -158,15 +157,15 @@ void Utils::GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::s
std::vector<std::string> files;
std::string depSrcDir = dependencyDir + conf.GetSettingString(ConfigSetting::SourceDir);
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());
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.isProjectHFile = true;
@@ -176,11 +175,15 @@ void Utils::GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::s
}
else
{
hFiles.emplace(HFile{filename, depSrcDir, conf.GetSettingBool(ConfigSetting::GenerateHFile) && filename == conf.GetSettingString(ConfigSetting::HFileName)});
hFiles.emplace(HFile{filename,
depSrcDir,
conf.GetSettingBool(ConfigSetting::GenerateHFile) &&
filename == conf.GetSettingString(ConfigSetting::HFileName)});
}
}
}
}
bool Utils::IsWhiteSpace(char c)
{
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)
{
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 true;
+5 -3
View File
@@ -5,7 +5,6 @@
#include <set>
#include <string>
struct HFile
{
std::string filename;
@@ -14,8 +13,11 @@ struct HFile
std::filesystem::path filepath;
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)
{
+55 -58
View File
@@ -2,41 +2,42 @@
const std::string CONFIG_FILENAME_CONF = "makegen.conf";
#include "../ConfigFile.h"
#include "../FileUtils.h"
#include <algorithm>
#include <fstream>
#include "../ConfigFile.h"
#include "../FileUtils.h"
#define FLAG_NONE 0
#define FLAG_VECTOR 1
#define FLAG_STRING 2
#define FLAG_BOOL 3
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
// and replace whitespace with underscore
std::transform(
projectname.begin(),
projectname.end(),
std::back_inserter(outputname),
[](unsigned char c)
{
if(c == ' ')
return '_';
return (char)std::tolower(c);
});
std::transform(projectname.begin(),
projectname.end(),
std::back_inserter(outputname),
[](unsigned char c)
{
if (c == ' ')
return '_';
return (char)std::tolower(c);
});
// Removes all other characters
outputdir.erase(std::remove_if(
outputdir.begin(),
outputdir.end(),
[](unsigned char c)
{
return (c < 'a' || c > 'z') && c != '_';
}));
outputdir.begin(), outputdir.end(), [](unsigned char c) { return (c < 'a' || c > 'z') && c != '_'; }));
// Add suffix
outputname += ".out";
@@ -57,11 +58,10 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
std::ifstream file(filepath + CONFIG_FILENAME_CONF);
std::string line;
if(file.is_open())
if (file.is_open())
{
// 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}},
{"#outputdir", {&conf.outputdir, true}},
{"#outputname", {&conf.outputname, false}},
@@ -70,8 +70,7 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
};
// 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}},
{"#libdirs", {&conf.libdirs, true}},
{"#includedirs", {&conf.includedirs, true}},
@@ -81,23 +80,22 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
{"#sourcefiles", {&conf.sourceFiles, false}},
};
std::map<std::string, bool*> booleans =
{
std::map<std::string, bool*> booleans = {
{"#executable", &conf.executable},
{"#shared", &conf.shared},
{"#generatehfile", &conf.generateHFile},
};
while(std::getline(file,line))
while (std::getline(file, line))
{
if(line == "")
if (line == "")
continue;
if(line[0]=='#')
if (line[0] == '#')
{
// The format is a bit wacky, but it is this way since we do not want
// to use map::find for all maps. This way we gain some optimization.
auto&& itStr{strings.find(line)};
if(itStr != strings.end())
if (itStr != strings.end())
{
s = itStr->second.first;
isDirectory = itStr->second.second;
@@ -106,7 +104,7 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
else
{
auto&& itVec{vectors.find(line)};
if(itVec != vectors.end())
if (itVec != vectors.end())
{
vec = itVec->second.first;
isDirectory = itVec->second.second;
@@ -115,7 +113,7 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
else
{
auto&& itBool{booleans.find(line)};
if(itBool != booleans.end())
if (itBool != booleans.end())
{
b = itBool->second;
loadFlag = FLAG_BOOL;
@@ -130,23 +128,24 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
}
else
{
if(loadFlag == FLAG_STRING)
if (loadFlag == FLAG_STRING)
{
if(isDirectory && line[line.size()-1] != '/')
if (isDirectory && line[line.size() - 1] != '/')
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 += '/';
}
vec->push_back(line);
}
else if(loadFlag == FLAG_BOOL)
else if (loadFlag == FLAG_BOOL)
{
if(line == "true")
if (line == "true")
*b = true;
else
*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("------ GENERATING NEW CONFIGURATION FILE");
if(conf.hFile == "")
conf.hFile = conf.projectname+".h";
if (conf.hFile == "")
conf.hFile = conf.projectname + ".h";
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("outputdir", {}, conf.outputdir));
configuration.AddXMLObject(XMLObject("hfilename", {}, conf.hFile));
configuration.AddXMLObject(XMLObject("outputtype", {},
conf.executable ? "executable" : (conf.shared ? "sharedlibrary" : "staticlibrary")));
configuration.AddXMLObject(
XMLObject("outputtype", {}, conf.executable ? "executable" : (conf.shared ? "sharedlibrary" : "staticlibrary")));
configuration.AddXMLObject(XMLObject("generatehfile", {}, conf.generateHFile ? "true" : "false"));
for(auto it = conf.libs.begin();it != conf.libs.end(); ++it)
configuration.AddXMLObject({"library",{},*it});
for(auto it = conf.libdirs.begin();it != conf.libdirs.end(); ++it)
configuration.AddXMLObject({"librarydir",{},*it});
for(auto it = conf.includedirs.begin();it != conf.includedirs.end(); ++it)
configuration.AddXMLObject({"includedir",{},*it});
for(auto it = conf.defines.begin();it != conf.defines.end(); ++it)
configuration.AddXMLObject({"define",{},*it});
for(auto it = conf.flags.begin();it != conf.flags.end(); ++it)
configuration.AddXMLObject({"cflag",{},*it});
for(auto it = conf.dependencies.begin();it != conf.dependencies.end(); ++it)
configuration.AddXMLObject({"dependency",{},*it});
for(auto it = conf.sourceFiles.begin();it != conf.sourceFiles.end(); ++it)
configuration.AddXMLObject({"sourcefile",{},*it});
for (auto it = conf.libs.begin(); it != conf.libs.end(); ++it) configuration.AddXMLObject({"library", {}, *it});
for (auto it = conf.libdirs.begin(); it != conf.libdirs.end(); ++it)
configuration.AddXMLObject({"librarydir", {}, *it});
for (auto it = conf.includedirs.begin(); it != conf.includedirs.end(); ++it)
configuration.AddXMLObject({"includedir", {}, *it});
for (auto it = conf.defines.begin(); it != conf.defines.end(); ++it)
configuration.AddXMLObject({"define", {}, *it});
for (auto it = conf.flags.begin(); it != conf.flags.end(); ++it) configuration.AddXMLObject({"cflag", {}, *it});
for (auto it = conf.dependencies.begin(); it != conf.dependencies.end(); ++it)
configuration.AddXMLObject({"dependency", {}, *it});
for (auto it = conf.sourceFiles.begin(); it != conf.sourceFiles.end(); ++it)
configuration.AddXMLObject({"sourcefile", {}, *it});
makegen.AddXMLObject(configuration);
std::ofstream xmlFile(conf.configPath + "makegen.xml");
+23 -21
View File
@@ -9,27 +9,29 @@ class ConfigFile;
class ConfigFileConf
{
public:
std::string configPath;
std::vector<std::string> libs;
std::vector<std::string> libdirs;
std::vector<std::string> includedirs;
std::vector<std::string> defines;
std::vector<std::string> flags;
std::vector<std::string> dependencies;
std::vector<std::string> sourceFiles;
public:
std::string configPath;
std::vector<std::string> libs;
std::vector<std::string> libdirs;
std::vector<std::string> includedirs;
std::vector<std::string> defines;
std::vector<std::string> flags;
std::vector<std::string> dependencies;
std::vector<std::string> sourceFiles;
std::string outputdir;
std::string srcdir;
std::string outputname;
std::string projectname;
std::string hFile;
bool executable;
bool shared;
bool generateHFile;
public:
ConfigFileConf();
std::string outputdir;
std::string srcdir;
std::string outputname;
std::string projectname;
std::string hFile;
bool executable;
bool shared;
bool generateHFile;
static void CreateXMLFile(const std::string& filename);
private:
public:
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 "ConfigCLI.h"
#include "ConfigFile.h"
@@ -7,18 +11,14 @@
#include "Makefile.h"
#include "Timer.h"
#include <cmath>
#include <thread>
#include <filesystem>
#define RETURN_IF(x, b) \
if(x)\
return b;
if (x) \
return b;
void PrintHelp()
{
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.
By default it always compiles code with parallell jobs.
@@ -52,61 +52,61 @@ Usage: makegen [options]
void GenMakefile(ConfigFile& conf, unsigned int flags)
{
if(conf.GetSettingBool(ConfigSetting::GenerateHFile))
if (conf.GetSettingBool(ConfigSetting::GenerateHFile))
HFileGen::Create(conf);
Makefile::Save(conf, flags);
}
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};
FlagData flagData{};
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]);
if(flag == "-h" || flag == "--help")
if (flag == "-h" || flag == "--help")
{
flagData.flags |= FLAG_HELP;
}
else if(flag == "-v" || flag == "--version")
else if (flag == "-v" || 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;
}
else if(flag == "clean" || flag == "-c")
else if (flag == "clean" || flag == "-c")
{
make = false;
flagData.flags |= FLAG_CLEAN;
}
else if(flag == "run" || flag == "-e" || flag == "execute")
else if (flag == "run" || flag == "-e" || flag == "execute")
{
flagData.flags |= FLAG_RUN;
}
else if(flag == "install" || flag == "-i")
else if (flag == "install" || flag == "-i")
{
flagData.flags |= FLAG_INSTALL;
}
else if(flag == "rebuild" || flag == "-r")
else if (flag == "rebuild" || flag == "-r")
{
flagData.flags |= FLAG_CLEAN;
flagData.flags |= FLAG_MAKE;
}
else if(flag == "single" || flag == "-s")
else if (flag == "single" || flag == "-s")
{
flagData.flags |= FLAG_SINGLE_THREAD;
}
else if(flag == "--simple")
else if (flag == "--simple")
{
flagData.flags |= FLAG_SIMPLE;
}
else if(Utils::StartsWith(flag, "--target="))
else if (Utils::StartsWith(flag, "--target="))
{
std::string prefix("--target=");
if (flag.size() < prefix.size() + 1)
@@ -117,14 +117,14 @@ FlagData ReadFlags(int argc, char** argv)
flagData.flags |= FLAG_TARGET;
flagData.target = flag.substr(std::string("--target=").size());
}
else if(flag != "")
else if (flag != "")
{
LOG_ERROR("Unknown argument ", flag);
return FlagData{FLAG_HELP};
}
}
}
if(make)
if (make)
flagData.flags |= FLAG_MAKE;
return flagData;
}
@@ -132,21 +132,21 @@ FlagData ReadFlags(int argc, char** argv)
bool RunMake(const std::string& filepath, unsigned int flags, ConfigFile& conf)
{
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()) + " ";
if(flags & FLAG_CLEAN)
if (flags & FLAG_CLEAN)
{
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);
}
if(flags & FLAG_INSTALL)
if (flags & FLAG_INSTALL)
{
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);
}
@@ -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)
{
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::current_path(dependencies[i]);
auto conf = ConfigFile::GetConfigFile("./", flagData);
if(conf)
if (conf)
{
bool success = MakeGen("./", flagData, conf.value());
if(!success)
if (!success)
{
std::filesystem::current_path(currentPath);
return success;
@@ -178,40 +178,40 @@ bool MakeGen(const std::string& filepath, const FlagData& flagData, ConfigFile&
LOG_INFO("Generating Makefile...");
Timer timer;
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...");
std::string outputPath = conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::OutputDir);
if(!FileUtils::HasPath(outputPath))
if (!FileUtils::HasPath(outputPath))
{
FileUtils::CreateDirectory(outputPath);
std::string intermediatePath = outputPath + "intermediates";
if(!FileUtils::HasPath(intermediatePath ))
FileUtils::CreateDirectory(intermediatePath );
if (!FileUtils::HasPath(intermediatePath))
FileUtils::CreateDirectory(intermediatePath);
}
return RunMake(filepath, flagData.flags, conf);
}
int main(int argc, char** argv)
{
FlagData flagData = ReadFlags(argc,argv);
if(flagData.flags & FLAG_HELP)
FlagData flagData = ReadFlags(argc, argv);
if (flagData.flags & FLAG_HELP)
{
PrintHelp();
return 0;
}
if(flagData.flags & FLAG_VERSION)
if (flagData.flags & FLAG_VERSION)
{
LOG_INFO("MakeGen ", MAKEGEN_VERSION);
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{};
auto conf = ConfigFile::GetConfigFile("./", flagData);
if(conf)
if (conf)
{
bool success = MakeGen("./", flagData, *conf);
return success ? 0 : 1;
+9 -9
View File
@@ -1,28 +1,28 @@
#include "XML.h"
#include <algorithm>
#include <fstream>
#include "XMLException.h"
#include <fstream>
#include <algorithm>
XMLObject XML::FromString(const std::string& string, const std::string& filename="")
XMLObject XML::FromString(const std::string& string, const std::string& filename = "")
{
int startLine = 1;
int startPos = 0;
// Remove version tag.
if(string.find("<?") != std::string::npos)
if (string.find("<?") != std::string::npos)
{
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)
{
std::ifstream file(filename, std::ios::binary | std::ios::ate);
if(!file)
throw XMLException("Could not read file \""+filename+"\"");
if (!file)
throw XMLException("Could not read file \"" + filename + "\"");
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
std::string buffer;
+19 -13
View File
@@ -1,22 +1,28 @@
#pragma once
#include "XMLObject.h"
#include <exception>
#include <string>
#include "XMLObject.h"
class XMLException : public std::exception
{
private:
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)
{}
private:
std::string m_message;
virtual const char* what() const throw()
{
return m_message.c_str();
}
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()
{
return m_message.c_str();
}
};
+63 -59
View File
@@ -1,9 +1,9 @@
#include "XMLObject.h"
#include <cstring>
#include "../Common.h"
#include "../Utils.h"
#include <cstring>
#include "XMLException.h"
XMLObject::XMLObject(const std::string& string)
@@ -11,7 +11,7 @@ XMLObject::XMLObject(const std::string& string)
int pos = 0;
int line = 1;
XMLLoadData data{pos, line, ""};
if(!ReadHead(string, data))
if (!ReadHead(string, data))
ReadBodyTail(string, data);
}
@@ -28,16 +28,22 @@ XMLObject::XMLObject(const std::string& string, XMLLoadData& data)
ReadBodyTail(string, data);
}
XMLObject::XMLObject(const std::string& name, 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::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)
: name(name), attributes(attributes), objects(objects)
XMLObject::XMLObject(const std::string& name,
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
@@ -69,7 +75,7 @@ unsigned int XMLObject::GetObjectCount() const
std::vector<XMLObject>* XMLObject::GetObjectPtr(const std::string& name)
{
auto it = objects.find(name);
if(it == objects.end())
if (it == objects.end())
return nullptr;
return &it->second;
@@ -92,7 +98,7 @@ const std::string& XMLObject::GetText() const
void XMLObject::SetName(const std::string& name)
{
if(Utils::IsWord(name))
if (Utils::IsWord(name))
this->name = name;
else
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)
{
if(Utils::IsWord(property))
if (Utils::IsWord(property))
attributes.emplace(property, value);
else
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)
{
auto it = objects.find(object.name);
if(it == objects.end())
if (it == objects.end())
objects.emplace(object.name, std::vector<XMLObject>{object});
else
it->second.push_back(object);
@@ -123,18 +129,18 @@ void XMLObject::AddXMLObject(const XMLObject& object)
bool XMLObject::RemoveXMLObject(const XMLObject& object)
{
auto it = objects.find(object.name);
if(it == objects.end())
if (it == objects.end())
return 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);
removed = true;
}
else
else
++it2;
}
return removed;
@@ -142,7 +148,7 @@ bool XMLObject::RemoveXMLObject(const XMLObject& object)
XMLObject XMLObject::GetStrippedXMLObject() const
{
if(text == "")
if (text == "")
return XMLObject(name, attributes, objects);
else
return XMLObject(name, attributes, text);
@@ -154,7 +160,6 @@ XMLObject XMLObject::GetStrippedXMLObject() const
// //
////////////////////////////////////////////////////////////
bool XMLObject::ReadHead(const std::string& string, XMLLoadData& data)
{
// 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++;
ReadWhiteSpace(string, data);
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++;
// nothing more to read.
return true;
@@ -187,7 +193,9 @@ bool XMLObject::ReadHead(const std::string& string, XMLLoadData& data)
ReadWhiteSpace(string, data);
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)++;
return false;
}
@@ -203,7 +211,8 @@ void XMLObject::ReadName(const std::string& string, XMLLoadData& data)
ReadWhiteSpace(string, data);
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 =
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)++;
ReadWhiteSpace(string, data);
@@ -256,7 +267,10 @@ void XMLObject::ReadBodyTail(const std::string& string, XMLLoadData& data)
ReadWhiteSpace(string, data);
std::string closeTag = GetClosingTag(string, data);
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;
}
// 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)
{
while (Utils::IsWhiteSpace(string[data.pos])) {
while (Utils::IsWhiteSpace(string[data.pos]))
{
if (string[data.pos] == '\n')
(data.line)++;
(data.pos)++;
}
}
std::string XMLObject::GetClosingTag(const std::string& string, XMLLoadData& data)
{
int startPos = data.pos;
@@ -307,7 +321,8 @@ std::string XMLObject::GetClosingTag(const std::string& string, XMLLoadData& dat
ReadWhiteSpace(string, data);
std::string tag = Utils::GetWord(string, data.pos);
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();
ReadWhiteSpace(string, data);
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)
{
std::vector<std::pair<std::string, std::string>> entities
{
{"&quot;","\""},
{"&apos;", "\'"},
{"&lt;", "<"},
{"&gt;",">"},
{"&amp;", "&"}
};
std::vector<std::pair<std::string, std::string>> entities{
{"&quot;", "\""}, {"&apos;", "\'"}, {"&lt;", "<"}, {"&gt;", ">"}, {"&amp;", "&"}};
size_t pos = string.find('&');
while(pos != std::string::npos)
while (pos != std::string::npos)
{
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);
found = true;
}
}
if(!found)
LOG_ERROR("(" + data.file + ":" + std::to_string(data.line) + "): ""Ampersand found in xml but isn't a predefined entity.");
pos = string.find('&', pos+1);
if (!found)
LOG_ERROR("(" + data.file + ":" + std::to_string(data.line) +
"): "
"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)
{
if(!(Utils::IsLetter(string[data.pos]) ||
string[data.pos] == '_' ||
string[data.pos] == ':'))
if (!(Utils::IsLetter(string[data.pos]) || string[data.pos] == '_' || string[data.pos] == ':'))
throw XMLException(std::string("Name doesn't start with a letter."), data);
int endPos = data.pos + 1;
while (endPos < string.length() && (
Utils::IsLetter(string[endPos]) ||
string[endPos] == '_' ||
string[endPos] == '-' ||
string[endPos] == ':' ||
string[endPos] == '.'))
while (endPos < string.length() && (Utils::IsLetter(string[endPos]) || string[endPos] == '_' ||
string[endPos] == '-' || string[endPos] == ':' || string[endPos] == '.'))
endPos++;
return string.substr(data.pos, endPos - data.pos);
}
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 << "<" << 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 << ">";
if(text != "")
if (text != "")
{
stream << text;
}
else
{
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";
it2->WriteToStream(stream, indent+1);
it2->WriteToStream(stream, indent + 1);
hasChild = true;
}
}
if(hasChild)
if (hasChild)
{
stream << "\n";
for(int i = 0;i<indent;i++)
for (int i = 0; i < indent; i++)
{
stream << " ";
}
@@ -403,4 +408,3 @@ std::ostream& XMLObject::WriteToStream(std::ostream& stream, int indent) const
return stream;
}
+104 -96
View File
@@ -1,110 +1,118 @@
#pragma once
#include <string>
#include <map>
#include <set>
#include <string>
#include <vector>
class XMLObject
{
public:
friend class XMLexception;
struct XMLLoadData
public:
friend class XMLexception;
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;
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;
auto it1 = object1.attributes.begin();
auto it2 = object2.attributes.begin();
while (it1 != object1.attributes.end())
{
auto it1 = object1.attributes.begin();
auto it2 = object2.attributes.begin();
while(it1 != object1.attributes.end())
{
if(it1->first != it2->first || it1->second != it1->second)
return false;
++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);
// 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);
{
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);
// 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);
};