Compare commits
16 Commits
302081d66b
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| d39536213b | |||
| 577ac677db | |||
| 736aae3d39 | |||
| 8ff0411952 | |||
| 5d00ada431 | |||
| c0d6afbf1a | |||
| b112ab4501 | |||
| 1edcfb570b | |||
| 7c68a839fc | |||
| 6976d330fc | |||
| 658d6df8a5 | |||
| aa0b390379 | |||
| d3c334dc79 | |||
| f6caefb078 | |||
| 61f9c3ee0d | |||
| febfda55cc |
+334
@@ -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
|
||||||
|
...
|
||||||
|
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
bin/*
|
bin/*
|
||||||
.ycm_extra_conf.py
|
.ycm_extra_conf.py
|
||||||
|
compile_flags.txt
|
||||||
|
|||||||
@@ -1,65 +1,69 @@
|
|||||||
# This Makefile was generated using MakeGen v1.3.0 made by Tim Håkansson
|
# This Makefile was generated using MakeGen v1.3.12 made by Tim Håkansson
|
||||||
# and is licensed under MIT. Full source of the project can be found at
|
# and is licensed under MIT. Full source of the project can be found at
|
||||||
# https://github.com/Thraix/MakeGen
|
# https://gitea.timha.se/Thraix/MakeGen
|
||||||
CC=@g++
|
CC=@g++
|
||||||
CO=@g++ -o
|
CO=@g++ -o
|
||||||
MKDIR_P=mkdir -p
|
MKDIR_P=mkdir -p
|
||||||
BIN=bin/
|
BIN=bin/Release/
|
||||||
OBJPATH=$(BIN)intermediates
|
OBJPATH=$(BIN)intermediates
|
||||||
INCLUDES=
|
INCLUDES=
|
||||||
OBJECTS=$(OBJPATH)/ConfigCLI.o $(OBJPATH)/ConfigFile.o $(OBJPATH)/HFileGen.o $(OBJPATH)/IncludeDeps.o $(OBJPATH)/Makefile.o $(OBJPATH)/Utils.o $(OBJPATH)/ConfigFileConf.o $(OBJPATH)/main.o $(OBJPATH)/XML.o $(OBJPATH)/XMLObject.o
|
OBJECTS=$(OBJPATH)/src/CompileFlags.o $(OBJPATH)/src/ConfigCLI.o $(OBJPATH)/src/ConfigFile.o $(OBJPATH)/src/HFileGen.o $(OBJPATH)/src/IncludeDeps.o $(OBJPATH)/src/Makefile.o $(OBJPATH)/src/Utils.o $(OBJPATH)/src/compatibility/ConfigFileConf.o $(OBJPATH)/src/main.o $(OBJPATH)/src/xml/XML.o $(OBJPATH)/src/xml/XMLObject.o
|
||||||
CFLAGS=$(INCLUDES) -std=c++17 -c -D_DEBUG -g3 -w
|
CFLAGS=$(INCLUDES) -std=c++17 -c
|
||||||
LIBDIR=
|
LIBDIR=
|
||||||
LDFLAGS=
|
LDFLAGS=
|
||||||
LIBS=$(LIBDIR)
|
LIBS=$(LIBDIR)
|
||||||
OUTPUT=$(BIN)makegen
|
OUTPUT=$(BIN)makegen
|
||||||
.PHONY: all directories rebuild clean run
|
.PHONY: all directories rebuild clean run
|
||||||
all: directories $(OUTPUT)
|
all: directories $(OUTPUT)
|
||||||
directories: $(BIN) $(OBJPATH)
|
directories: $(OBJPATH)/src $(OBJPATH)/src/compatibility $(OBJPATH)/src/xml
|
||||||
$(BIN):
|
$(OBJPATH)/src:
|
||||||
$(info Creating output directories)
|
@$(MKDIR_P) $@
|
||||||
@$(MKDIR_P) $(BIN)
|
$(OBJPATH)/src/compatibility:
|
||||||
$(OBJPATH):
|
@$(MKDIR_P) $@
|
||||||
@$(MKDIR_P) $(OBJPATH)
|
$(OBJPATH)/src/xml:
|
||||||
|
@$(MKDIR_P) $@
|
||||||
run: all
|
run: all
|
||||||
@./$(OUTPUT)
|
@./$(OUTPUT)
|
||||||
rebuild: clean all
|
rebuild: clean all
|
||||||
clean:
|
clean:
|
||||||
$(info Removing intermediates)
|
$(info Removing $(OBJPATH) and $(OUTPUT))
|
||||||
rm -rf $(OBJPATH)/*.o
|
@rm -rf $(OBJPATH)/ $(OUTPUT)
|
||||||
$(OUTPUT): $(OBJECTS)
|
$(OUTPUT): $(OBJECTS)
|
||||||
$(info Generating output file)
|
$(info Generating output file $(OUTPUT))
|
||||||
$(CO) $(OUTPUT) $(OBJECTS) $(LDFLAGS) $(LIBS)
|
$(CO) $(OUTPUT) $(OBJECTS) $(LDFLAGS) $(LIBS)
|
||||||
install: all
|
install: all
|
||||||
$(info Installing MakeGen to /usr/bin/)
|
$(info Installing MakeGen to /usr/bin/)
|
||||||
@cp $(OUTPUT) /usr/bin/makegen
|
@cp $(OUTPUT) /usr/bin/makegen
|
||||||
$(OBJPATH)/ConfigCLI.o : src/ConfigCLI.cpp src/Common.h src/ConfigCLI.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/xml/XMLObject.h
|
$(OBJPATH)/src/CompileFlags.o: src/CompileFlags.cpp src/CompileFlags.h src/ConfigFile.h src/ConfigUtils.h src/Common.h src/AssertException.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h makegen.xml
|
||||||
$(info -[10%]- $<)
|
$(info -[9%]- $<)
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
$(OBJPATH)/ConfigFile.o : src/ConfigFile.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/FileUtils.h src/Utils.h src/xml/XMLObject.h src/compatibility/ConfigFileConf.h src/xml/XML.h
|
$(OBJPATH)/src/ConfigCLI.o: src/ConfigCLI.cpp src/Common.h src/AssertException.h src/ConfigCLI.h src/ConfigFile.h src/ConfigUtils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h src/FileUtils.h src/Utils.h makegen.xml
|
||||||
$(info -[20%]- $<)
|
$(info -[18%]- $<)
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
$(OBJPATH)/HFileGen.o : src/HFileGen.cpp src/FileUtils.h src/Common.h src/Utils.h src/HFileGen.h src/ConfigFile.h src/ConfigUtils.h src/xml/XMLObject.h
|
$(OBJPATH)/src/ConfigFile.o: src/ConfigFile.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/AssertException.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h src/FileUtils.h src/Utils.h src/compatibility/ConfigFileConf.h src/xml/XML.h makegen.xml
|
||||||
$(info -[30%]- $<)
|
$(info -[27%]- $<)
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
$(OBJPATH)/IncludeDeps.o : src/IncludeDeps.cpp src/Common.h src/IncludeDeps.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/xml/XMLObject.h
|
$(OBJPATH)/src/HFileGen.o: src/HFileGen.cpp src/FileUtils.h src/Common.h src/AssertException.h src/Utils.h src/HFileGen.h src/ConfigFile.h src/ConfigUtils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h makegen.xml
|
||||||
$(info -[40%]- $<)
|
$(info -[36%]- $<)
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
$(OBJPATH)/Makefile.o : src/Makefile.cpp src/IncludeDeps.h src/ConfigFile.h src/ConfigUtils.h src/Common.h src/FileUtils.h src/Utils.h src/xml/XMLObject.h src/Makefile.h
|
$(OBJPATH)/src/IncludeDeps.o: src/IncludeDeps.cpp src/Common.h src/AssertException.h src/IncludeDeps.h src/ConfigFile.h src/ConfigUtils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h src/FileUtils.h src/Utils.h makegen.xml
|
||||||
$(info -[50%]- $<)
|
$(info -[45%]- $<)
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
$(OBJPATH)/Utils.o : src/Utils.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/FileUtils.h src/Utils.h src/xml/XMLObject.h
|
$(OBJPATH)/src/Makefile.o: src/Makefile.cpp src/Common.h src/AssertException.h src/IncludeDeps.h src/ConfigFile.h src/ConfigUtils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h src/FileUtils.h src/Utils.h src/Makefile.h makegen.xml
|
||||||
$(info -[60%]- $<)
|
$(info -[54%]- $<)
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
$(OBJPATH)/ConfigFileConf.o : src/compatibility/ConfigFileConf.cpp src/compatibility/ConfigFileConf.h
|
$(OBJPATH)/src/Utils.o: src/Utils.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/AssertException.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h src/FileUtils.h src/Utils.h makegen.xml
|
||||||
$(info -[70%]- $<)
|
$(info -[63%]- $<)
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
$(OBJPATH)/main.o : src/main.cpp src/Common.h src/ConfigCLI.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/xml/XMLObject.h src/HFileGen.h src/Makefile.h src/Timer.h
|
$(OBJPATH)/src/compatibility/ConfigFileConf.o: src/compatibility/ConfigFileConf.cpp src/Common.h src/AssertException.h src/xml/XMLObject.h src/compatibility/ConfigFileConf.h makegen.xml
|
||||||
$(info -[80%]- $<)
|
$(info -[72%]- $<)
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
$(OBJPATH)/XML.o : src/xml/XML.cpp src/xml/XML.h src/xml/XMLObject.h src/xml/XMLException.h
|
$(OBJPATH)/src/main.o: src/main.cpp src/Common.h src/AssertException.h src/CompileFlags.h src/ConfigFile.h src/ConfigUtils.h src/Dependency.h src/FlagData.h src/xml/XMLObject.h src/ConfigCLI.h src/HFileGen.h src/Makefile.h src/Timer.h src/Utils.h makegen.xml
|
||||||
|
$(info -[81%]- $<)
|
||||||
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
|
$(OBJPATH)/src/xml/XML.o: src/xml/XML.cpp src/xml/XML.h src/xml/XMLObject.h src/xml/XMLException.h makegen.xml
|
||||||
$(info -[90%]- $<)
|
$(info -[90%]- $<)
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
$(OBJPATH)/XMLObject.o : src/xml/XMLObject.cpp src/xml/XMLException.h src/xml/XMLObject.h
|
$(OBJPATH)/src/xml/XMLObject.o: src/xml/XMLObject.cpp src/Common.h src/AssertException.h src/Utils.h src/xml/XMLException.h src/xml/XMLObject.h makegen.xml
|
||||||
$(info -[100%]- $<)
|
$(info -[100%]- $<)
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
|
|||||||
@@ -16,10 +16,7 @@ After MakeGen is installed it will always be able to generate a Makefile (even w
|
|||||||
However it will not compile your code if those programs don't exist.
|
However it will not compile your code if those programs don't exist.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
To install MakeGen make sure you have the dependencies listed above.
|
To install MakeGen make sure you have the dependencies listed above and clone this repository.
|
||||||
Then clone this repository:
|
|
||||||
|
|
||||||
git clone git@github.com:Thraix/MakeGen.git
|
|
||||||
|
|
||||||
Then navigate into the MakeGen folder (`cd MakeGen`) and run:
|
Then navigate into the MakeGen folder (`cd MakeGen`) and run:
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -1,7 +1,7 @@
|
|||||||
<makegen>
|
<makegen>
|
||||||
<configuration name="Release">
|
<configuration name="Release">
|
||||||
<generatehfile>false</generatehfile>
|
<cppversion>c++17</cppversion>
|
||||||
<outputdir>bin/</outputdir>
|
<outputdir>bin/Release/</outputdir>
|
||||||
<outputname>makegen</outputname>
|
<outputname>makegen</outputname>
|
||||||
<outputtype>executable</outputtype>
|
<outputtype>executable</outputtype>
|
||||||
<projectname>MakeGen</projectname>
|
<projectname>MakeGen</projectname>
|
||||||
@@ -10,14 +10,14 @@
|
|||||||
<configuration name="Debug">
|
<configuration name="Debug">
|
||||||
<cflag>-g3</cflag>
|
<cflag>-g3</cflag>
|
||||||
<cflag>-w</cflag>
|
<cflag>-w</cflag>
|
||||||
|
<cppversion>c++17</cppversion>
|
||||||
<define>_DEBUG</define>
|
<define>_DEBUG</define>
|
||||||
<generatehfile>false</generatehfile>
|
<outputdir>bin/Debug/</outputdir>
|
||||||
<outputdir>bin/</outputdir>
|
|
||||||
<outputname>makegen</outputname>
|
<outputname>makegen</outputname>
|
||||||
<outputtype>executable</outputtype>
|
<outputtype>executable</outputtype>
|
||||||
<projectname>MakeGen</projectname>
|
<projectname>MakeGen</projectname>
|
||||||
<srcdir>src/</srcdir>
|
<srcdir>src/</srcdir>
|
||||||
</configuration>
|
</configuration>
|
||||||
<target>Debug</target>
|
<target>Release</target>
|
||||||
<version>v1.3.0</version>
|
<version>v1.3.11</version>
|
||||||
</makegen>
|
</makegen>
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
struct AssertException : public std::runtime_error
|
||||||
|
{
|
||||||
|
AssertException()
|
||||||
|
: std::runtime_error{"assertion failed"}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
Executable → Regular
+57
-9
@@ -1,8 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#define BIT(x) (1<<x)
|
#include "AssertException.h"
|
||||||
|
|
||||||
|
#define BIT(x) (1 << x)
|
||||||
|
|
||||||
#define STRINGIFY(x) #x
|
#define STRINGIFY(x) #x
|
||||||
#define STR(x) STRINGIFY(x)
|
#define STR(x) STRINGIFY(x)
|
||||||
@@ -12,7 +16,7 @@
|
|||||||
// Release, should be backwards compatible with any minor version
|
// Release, should be backwards compatible with any minor version
|
||||||
#define MAKEGEN_VERSION_RELEASE 3
|
#define MAKEGEN_VERSION_RELEASE 3
|
||||||
// Minor changes, generally bug fixes
|
// Minor changes, generally bug fixes
|
||||||
#define MAKEGEN_VERSION_MINOR 0
|
#define MAKEGEN_VERSION_MINOR 12
|
||||||
|
|
||||||
#define MAKEGEN_VERSION ("v" STR(MAKEGEN_VERSION_MAJOR) "." STR(MAKEGEN_VERSION_RELEASE) "." STR(MAKEGEN_VERSION_MINOR))
|
#define MAKEGEN_VERSION ("v" STR(MAKEGEN_VERSION_MAJOR) "." STR(MAKEGEN_VERSION_RELEASE) "." STR(MAKEGEN_VERSION_MINOR))
|
||||||
|
|
||||||
@@ -27,11 +31,25 @@ const static unsigned int FLAG_SINGLE_THREAD = BIT(7);
|
|||||||
const static unsigned int FLAG_DEPENDENCY = BIT(8);
|
const static unsigned int FLAG_DEPENDENCY = BIT(8);
|
||||||
const static unsigned int FLAG_SIMPLE = BIT(9);
|
const static unsigned int FLAG_SIMPLE = BIT(9);
|
||||||
const static unsigned int FLAG_CONFIG = BIT(10);
|
const static unsigned int FLAG_CONFIG = BIT(10);
|
||||||
|
const static unsigned int FLAG_TARGET = BIT(11);
|
||||||
|
const static unsigned int FLAG_GEN_COMP_FLAGS = BIT(12);
|
||||||
|
|
||||||
#define LOG_INFO(...) LogHelper(__VA_ARGS__)
|
#define LOG_INFO(...) LogHelper(__VA_ARGS__)
|
||||||
#define LOG_WARNING(...) LogHelper(__VA_ARGS__)
|
#define LOG_WARNING(...) LogHelper(__VA_ARGS__)
|
||||||
#define LOG_ERROR(...) LogHelper(__VA_ARGS__)
|
#define LOG_ERROR(...) LogHelper("\033[1;31m[ERROR] ", __VA_ARGS__, "\033[0m")
|
||||||
|
#define ASSERT(expr, ...) \
|
||||||
|
if (!(expr)) \
|
||||||
|
{ \
|
||||||
|
LOG_ERROR(__VA_ARGS__); \
|
||||||
|
throw AssertException{}; \
|
||||||
|
} \
|
||||||
|
false
|
||||||
|
#define ABORT(...) \
|
||||||
|
{ \
|
||||||
|
LOG_ERROR(__VA_ARGS__); \
|
||||||
|
throw AssertException{}; \
|
||||||
|
} \
|
||||||
|
false
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Log(const T& var)
|
void Log(const T& var)
|
||||||
@@ -39,24 +57,54 @@ void Log(const T& var)
|
|||||||
std::cout << var;
|
std::cout << var;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename ...Ts>
|
template <typename T, typename... Ts>
|
||||||
void Log(const T& var, const Ts& ...vars)
|
void Log(const T& var, const Ts&... vars)
|
||||||
{
|
{
|
||||||
Log(var);
|
Log(var);
|
||||||
Log(vars...);
|
Log(vars...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename ...Ts>
|
template <typename T, typename... Ts>
|
||||||
void LogHelper(const T& var)
|
void LogHelper(const T& var)
|
||||||
{
|
{
|
||||||
Log(var);
|
Log(var);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename ...Ts>
|
template <typename T, typename... Ts>
|
||||||
void LogHelper(const T& var, const Ts& ...vars)
|
void LogHelper(const T& var, const Ts&... vars)
|
||||||
{
|
{
|
||||||
Log(var);
|
Log(var);
|
||||||
Log(vars...);
|
Log(vars...);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::ostream& operator<<(std::ostream& ostream, const std::vector<T>& vec)
|
||||||
|
{
|
||||||
|
ostream << "[" << std::endl;
|
||||||
|
for (size_t i = 0; i < vec.size(); i++)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
ostream << ", " << std::endl;
|
||||||
|
ostream << vec[i];
|
||||||
|
}
|
||||||
|
ostream << std::endl << "]";
|
||||||
|
return ostream;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::ostream& operator<<(std::ostream& ostream, const std::set<T>& set)
|
||||||
|
{
|
||||||
|
ostream << "[" << std::endl;
|
||||||
|
int i = 0;
|
||||||
|
for (const auto& elem : set)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
ostream << ", " << std::endl;
|
||||||
|
ostream << " " << elem;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
ostream << std::endl << "]";
|
||||||
|
return ostream;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#include "CompileFlags.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
void CompileFlags::Save(ConfigFile& conf)
|
||||||
|
{
|
||||||
|
std::ofstream file{"compile_flags.txt"};
|
||||||
|
file << "-xc++" << std::endl;
|
||||||
|
file << "-std=" << conf.GetCppVersion() << std::endl;
|
||||||
|
|
||||||
|
const std::vector<std::string>& includeDirs = conf.GetIncludeDirs();
|
||||||
|
for (const auto& includeDir : includeDirs)
|
||||||
|
{
|
||||||
|
file << "-I" << includeDir << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& includeDirExclDeps = conf.GetIncludeDirExclDeps();
|
||||||
|
for (const auto& includeDirExclDep : includeDirExclDeps)
|
||||||
|
{
|
||||||
|
file << "-I" << includeDirExclDep << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& defines = conf.GetDefines();
|
||||||
|
for (const auto& defines : defines)
|
||||||
|
{
|
||||||
|
file << "-D" << defines << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ConfigFile.h"
|
||||||
|
|
||||||
|
class CompileFlags
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void Save(ConfigFile& conf);
|
||||||
|
};
|
||||||
+73
-79
@@ -2,12 +2,11 @@
|
|||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "ConfigFile.h"
|
#include "ConfigFile.h"
|
||||||
|
#include "FileUtils.h"
|
||||||
#include <set>
|
|
||||||
|
|
||||||
void ConfigCLI::DisplayCLIHelp()
|
void ConfigCLI::DisplayCLIHelp()
|
||||||
{
|
{
|
||||||
LOG_INFO(1+(char*)R"(
|
LOG_INFO(1 + (char*)R"(
|
||||||
MakeGen conf is used to create, modify and query the makegen.xml file.
|
MakeGen conf is used to create, modify and query the makegen.xml file.
|
||||||
|
|
||||||
Usage: makegen conf <command> [<args>] [--help]
|
Usage: makegen conf <command> [<args>] [--help]
|
||||||
@@ -27,7 +26,7 @@ Querying config settings
|
|||||||
|
|
||||||
void ConfigCLI::DisplayGenHelp()
|
void ConfigCLI::DisplayGenHelp()
|
||||||
{
|
{
|
||||||
LOG_INFO(1+(char*)R"(
|
LOG_INFO(1 + (char*)R"(
|
||||||
Generate a config file from prompts
|
Generate a config file from prompts
|
||||||
|
|
||||||
Usage: makegen conf gen <option>
|
Usage: makegen conf gen <option>
|
||||||
@@ -41,7 +40,7 @@ options:
|
|||||||
|
|
||||||
void ConfigCLI::DisplayAddHelp()
|
void ConfigCLI::DisplayAddHelp()
|
||||||
{
|
{
|
||||||
LOG_INFO(1+(char*)R"(
|
LOG_INFO(1 + (char*)R"(
|
||||||
Add values to config settings which support multiple arguments
|
Add values to config settings which support multiple arguments
|
||||||
|
|
||||||
Usage: makegen conf add <setting> <value> [<values>]
|
Usage: makegen conf add <setting> <value> [<values>]
|
||||||
@@ -56,13 +55,13 @@ Valid settings are:
|
|||||||
dependency Project which current project depends on
|
dependency Project which current project depends on
|
||||||
excludesource Exclude source file from compiling
|
excludesource Exclude source file from compiling
|
||||||
excludeheader Exclude header file from project h-file
|
excludeheader Exclude header file from project h-file
|
||||||
argument Command line argument for the executable
|
argument Command line argument for the executable
|
||||||
preargument Command line argument before the executabe, e.g. gdb)");
|
preargument Command line argument before the executabe, e.g. gdb)");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigCLI::DisplayRemoveHelp()
|
void ConfigCLI::DisplayRemoveHelp()
|
||||||
{
|
{
|
||||||
LOG_INFO(1+(char*)R"(
|
LOG_INFO(1 + (char*)R"(
|
||||||
Remove values to config settings which support multiple
|
Remove values to config settings which support multiple
|
||||||
|
|
||||||
Usage: makegen conf remove <setting> <value> [<
|
Usage: makegen conf remove <setting> <value> [<
|
||||||
@@ -77,13 +76,13 @@ Valid settings are
|
|||||||
dependency Project which current project depends on
|
dependency Project which current project depends on
|
||||||
excludesource Exclude source file from compiling
|
excludesource Exclude source file from compiling
|
||||||
excludeheader Exclude header file from project h-file
|
excludeheader Exclude header file from project h-file
|
||||||
argument Command line argument for the executable
|
argument Command line argument for the executable
|
||||||
preargument Command line argument before the executabe, e.g. gdb)");
|
preargument Command line argument before the executabe, e.g. gdb)");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigCLI::DisplaySetHelp()
|
void ConfigCLI::DisplaySetHelp()
|
||||||
{
|
{
|
||||||
LOG_INFO(1+(char*)R"(
|
LOG_INFO(1 + (char*)R"(
|
||||||
Set value to config settings which only support one argument
|
Set value to config settings which only support one argument
|
||||||
|
|
||||||
Usage: makegen conf set <setting> <value>
|
Usage: makegen conf set <setting> <value>
|
||||||
@@ -95,6 +94,7 @@ Valid string settings are:
|
|||||||
outputtype Type of the output, valid values are executable, sharedlibrary
|
outputtype Type of the output, valid values are executable, sharedlibrary
|
||||||
and staticlibrary
|
and staticlibrary
|
||||||
hfile Name of the generated project h-file
|
hfile Name of the generated project h-file
|
||||||
|
cppversion Version of the c++ to use
|
||||||
|
|
||||||
Valid boolean settings are:
|
Valid boolean settings are:
|
||||||
genhfile Specifies if MakeGen should generate a project h-file
|
genhfile Specifies if MakeGen should generate a project h-file
|
||||||
@@ -104,7 +104,7 @@ Boolean values can be set to either true/t/yes/y or false/f/no/n)");
|
|||||||
|
|
||||||
void ConfigCLI::DisplayGetHelp()
|
void ConfigCLI::DisplayGetHelp()
|
||||||
{
|
{
|
||||||
LOG_INFO(1+(char*)R"(
|
LOG_INFO(1 + (char*)R"(
|
||||||
Get value of the config setting
|
Get value of the config setting
|
||||||
|
|
||||||
Usage: makegen conf get <setting>
|
Usage: makegen conf get <setting>
|
||||||
@@ -127,10 +127,11 @@ Valid settings are:
|
|||||||
and staticlibrary
|
and staticlibrary
|
||||||
projectname Name of the project
|
projectname Name of the project
|
||||||
hfile Name of the generated project h-file
|
hfile Name of the generated project h-file
|
||||||
genhfile Specifies if MakeGen should generate a project h-file)");
|
genhfile Specifies if MakeGen should generate a project h-file
|
||||||
|
cppversion Specifies the version of c++ to use (default=c++17)
|
||||||
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ConfigSetting ConfigCLI::CLIStringToSetting(const std::string& s)
|
ConfigSetting ConfigCLI::CLIStringToSetting(const std::string& s)
|
||||||
{
|
{
|
||||||
static std::map<std::string, ConfigSetting> map{
|
static std::map<std::string, ConfigSetting> map{
|
||||||
@@ -152,34 +153,34 @@ ConfigSetting ConfigCLI::CLIStringToSetting(const std::string& s)
|
|||||||
{"argument", ConfigSetting::ExecArgument},
|
{"argument", ConfigSetting::ExecArgument},
|
||||||
{"dependency", ConfigSetting::Dependency},
|
{"dependency", ConfigSetting::Dependency},
|
||||||
{"genhfile", ConfigSetting::GenerateHFile},
|
{"genhfile", ConfigSetting::GenerateHFile},
|
||||||
|
{"cppversion", ConfigSetting::CppVersion},
|
||||||
};
|
};
|
||||||
auto it = map.find(s);
|
auto it = map.find(s);
|
||||||
if(it == map.end())
|
ASSERT(it != map.end(), "Invalid config setting: ", s);
|
||||||
return ConfigSetting::Invalid;
|
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ConfigCLI::Gen(int argc, char** argv)
|
int ConfigCLI::Gen(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if(argc < 2 || std::string(argv[1]) == "--help")
|
if (argc < 2 || std::string(argv[1]) == "--help")
|
||||||
{
|
{
|
||||||
DisplayGenHelp();
|
DisplayGenHelp();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(argc < 2)
|
if (argc < 2)
|
||||||
{
|
{
|
||||||
LOG_ERROR("gen needs exactly one parameter");
|
LOG_ERROR("gen needs exactly one parameter");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
std::string option = argv[1];
|
std::string option = argv[1];
|
||||||
if(option == "prompt")
|
if (option == "prompt")
|
||||||
{
|
{
|
||||||
ConfigFile::Gen().Save();
|
ConfigFile::Gen(FlagData{}).Save();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(option == "default")
|
if (option == "default")
|
||||||
{
|
{
|
||||||
ConfigFile{FileUtils::GetRealPath("."),0}.Save();
|
ConfigFile{std::filesystem::current_path(), FlagData{}, 0}.Save();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -191,32 +192,25 @@ int ConfigCLI::Gen(int argc, char** argv)
|
|||||||
|
|
||||||
int ConfigCLI::Add(int argc, char** argv, ConfigFile& config)
|
int ConfigCLI::Add(int argc, char** argv, ConfigFile& config)
|
||||||
{
|
{
|
||||||
if(argc < 2 || std::string(argv[1]) == "--help")
|
if (argc < 2 || std::string(argv[1]) == "--help")
|
||||||
{
|
{
|
||||||
DisplayAddHelp();
|
DisplayAddHelp();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(argc < 3)
|
if (argc < 3)
|
||||||
{
|
{
|
||||||
LOG_ERROR("add needs at least two parameters");
|
LOG_ERROR("add needs at least two parameters");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigSetting setting = CLIStringToSetting(argv[1]);
|
ConfigSetting setting = CLIStringToSetting(argv[1]);
|
||||||
if(!ConfigUtils::IsVectorSetting(setting))
|
if (!ConfigUtils::IsVectorSetting(setting))
|
||||||
{
|
{
|
||||||
if(setting == ConfigSetting::Invalid)
|
LOG_ERROR("Cannot remove setting which only supports one argument");
|
||||||
{
|
LOG_ERROR("use set instead.");
|
||||||
LOG_ERROR("No such setting: ", argv[1]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_ERROR("Cannot remove setting which only supports one argument");
|
|
||||||
LOG_ERROR("use set instead.");
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
for(int i = 2; i<argc;++i)
|
for (int i = 2; i < argc; ++i)
|
||||||
{
|
{
|
||||||
config.AddSettingVectorString(setting, argv[i]);
|
config.AddSettingVectorString(setting, argv[i]);
|
||||||
}
|
}
|
||||||
@@ -227,33 +221,26 @@ int ConfigCLI::Add(int argc, char** argv, ConfigFile& config)
|
|||||||
|
|
||||||
int ConfigCLI::Remove(int argc, char** argv, ConfigFile& config)
|
int ConfigCLI::Remove(int argc, char** argv, ConfigFile& config)
|
||||||
{
|
{
|
||||||
if(argc < 2 || std::string(argv[1]) == "--help")
|
if (argc < 2 || std::string(argv[1]) == "--help")
|
||||||
{
|
{
|
||||||
DisplayRemoveHelp();
|
DisplayRemoveHelp();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(argc < 3)
|
if (argc < 3)
|
||||||
{
|
{
|
||||||
LOG_ERROR("remove needs at least two parameters");
|
LOG_ERROR("remove needs at least two parameters");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigSetting setting = CLIStringToSetting(argv[1]);
|
ConfigSetting setting = CLIStringToSetting(argv[1]);
|
||||||
if(!ConfigUtils::IsVectorSetting(setting))
|
if (!ConfigUtils::IsVectorSetting(setting))
|
||||||
{
|
{
|
||||||
if(setting == ConfigSetting::Invalid)
|
LOG_ERROR("Cannot remove setting which only supports one argument");
|
||||||
{
|
LOG_ERROR("use set instead.");
|
||||||
LOG_ERROR("No such setting: ", argv[1]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_ERROR("Cannot remove setting which only supports one argument");
|
|
||||||
LOG_ERROR("use set instead.");
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 2; i<argc;++i)
|
for (int i = 2; i < argc; ++i)
|
||||||
{
|
{
|
||||||
config.RemoveSettingVectorString(setting, argv[i]);
|
config.RemoveSettingVectorString(setting, argv[i]);
|
||||||
}
|
}
|
||||||
@@ -264,29 +251,22 @@ int ConfigCLI::Remove(int argc, char** argv, ConfigFile& config)
|
|||||||
|
|
||||||
int ConfigCLI::Set(int argc, char** argv, ConfigFile& config)
|
int ConfigCLI::Set(int argc, char** argv, ConfigFile& config)
|
||||||
{
|
{
|
||||||
if(argc < 2 || std::string(argv[1]) == "--help")
|
if (argc < 2 || std::string(argv[1]) == "--help")
|
||||||
{
|
{
|
||||||
DisplaySetHelp();
|
DisplaySetHelp();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(argc != 3)
|
if (argc != 3)
|
||||||
{
|
{
|
||||||
LOG_ERROR("set needs exactly two parameters");
|
LOG_ERROR("set needs exactly two parameters");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigSetting setting = CLIStringToSetting(argv[1]);
|
ConfigSetting setting = CLIStringToSetting(argv[1]);
|
||||||
if(!ConfigUtils::IsStringSetting(setting) && !ConfigUtils::IsBoolSetting(setting))
|
if (!ConfigUtils::IsStringSetting(setting) && !ConfigUtils::IsBoolSetting(setting))
|
||||||
{
|
{
|
||||||
if(setting == ConfigSetting::Invalid)
|
LOG_ERROR("Cannot set setting which supports multiple arguments");
|
||||||
{
|
LOG_ERROR("use add or remove instead.");
|
||||||
LOG_ERROR("No such setting: ", argv[1]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_ERROR("Cannot set setting which supports multiple arguments");
|
|
||||||
LOG_ERROR("use add or remove instead.");
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,19 +277,19 @@ int ConfigCLI::Set(int argc, char** argv, ConfigFile& config)
|
|||||||
|
|
||||||
int ConfigCLI::Get(int argc, char** argv, ConfigFile& config)
|
int ConfigCLI::Get(int argc, char** argv, ConfigFile& config)
|
||||||
{
|
{
|
||||||
if(argc < 2 || std::string(argv[1]) == "--help")
|
if (argc < 2 || std::string(argv[1]) == "--help")
|
||||||
{
|
{
|
||||||
DisplayGetHelp();
|
DisplayGetHelp();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(argc != 2)
|
if (argc != 2)
|
||||||
{
|
{
|
||||||
LOG_ERROR("get needs exactly one parameter");
|
LOG_ERROR("get needs exactly one parameter");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
ConfigSetting setting = CLIStringToSetting(argv[1]);
|
ConfigSetting setting = CLIStringToSetting(argv[1]);
|
||||||
std::vector<std::string> vector = config.GetSetting(setting);
|
std::vector<std::string> vector = config.GetSetting(setting);
|
||||||
for(auto it = vector.begin(); it != vector.end(); ++it)
|
for (auto it = vector.begin(); it != vector.end(); ++it)
|
||||||
{
|
{
|
||||||
LOG_INFO(*it);
|
LOG_INFO(*it);
|
||||||
}
|
}
|
||||||
@@ -319,39 +299,53 @@ int ConfigCLI::Get(int argc, char** argv, ConfigFile& config)
|
|||||||
int ConfigCLI::Main(int argc, char** argv)
|
int ConfigCLI::Main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
// Do nothing
|
// Do nothing
|
||||||
if(argc < 2 || std::string(argv[1]) == "--help")
|
if (argc < 2 || std::string(argv[1]) == "--help")
|
||||||
{
|
{
|
||||||
DisplayCLIHelp();
|
DisplayCLIHelp();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
std::optional<ConfigFile> config = ConfigFile::GetConfigFile();
|
std::string target = "";
|
||||||
std::string command = argv[1];
|
int commandIndex = 1;
|
||||||
if(command == "gen")
|
if (argc >= 1 && Utils::StartsWith(argv[1], "--target="))
|
||||||
{
|
{
|
||||||
if(config)
|
std::string prefix("--target=");
|
||||||
|
std::string flag(argv[1]);
|
||||||
|
if (flag.size() < prefix.size() + 1)
|
||||||
|
{
|
||||||
|
LOG_ERROR("No target specified in --target=<target>");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
target = flag.substr(std::string("--target=").size());
|
||||||
|
commandIndex++;
|
||||||
|
}
|
||||||
|
std::optional<ConfigFile> config = ConfigFile::GetConfigFile("./", FlagData{target == "" ? 0 : FLAG_TARGET, target});
|
||||||
|
std::string command = argv[commandIndex];
|
||||||
|
if (command == "gen")
|
||||||
|
{
|
||||||
|
if (config)
|
||||||
{
|
{
|
||||||
LOG_ERROR("Config file already exist (", CONFIG_FILENAME, ")");
|
LOG_ERROR("Config file already exist (", CONFIG_FILENAME, ")");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return Gen(argc-1, &argv[1]);
|
return Gen(argc - commandIndex, &argv[commandIndex]);
|
||||||
}
|
}
|
||||||
else if(config)
|
else if (config)
|
||||||
{
|
{
|
||||||
if(command == "add")
|
if (command == "add")
|
||||||
return Add(argc-1, &argv[1], *config);
|
return Add(argc - commandIndex, &argv[commandIndex], *config);
|
||||||
else if(command == "remove")
|
else if (command == "remove")
|
||||||
return Remove(argc-1, &argv[1], *config);
|
return Remove(argc - commandIndex, &argv[commandIndex], *config);
|
||||||
else if(command == "set")
|
else if (command == "set")
|
||||||
return Set(argc-1, &argv[1], *config);
|
return Set(argc - commandIndex, &argv[commandIndex], *config);
|
||||||
else if(command == "get")
|
else if (command == "get")
|
||||||
return Get(argc-1, &argv[1], *config);
|
return Get(argc - commandIndex, &argv[commandIndex], *config);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_ERROR("Unknown config command: ", command);
|
LOG_ERROR("Unknown config command: ", command);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_ERROR("There is no config file in the current directory");
|
LOG_ERROR("There is no config file in the current directory");
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
+16
-16
@@ -2,24 +2,24 @@
|
|||||||
|
|
||||||
#include "ConfigFile.h"
|
#include "ConfigFile.h"
|
||||||
|
|
||||||
struct ConfigCLI
|
struct ConfigCLI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static int Main(int argc, char** argv);
|
static int Main(int argc, char** argv);
|
||||||
private:
|
|
||||||
static void DisplayCLIHelp();
|
|
||||||
static void DisplayGenHelp();
|
|
||||||
static void DisplayAddHelp();
|
|
||||||
static void DisplayRemoveHelp();
|
|
||||||
static void DisplaySetHelp();
|
|
||||||
static void DisplayGetHelp();
|
|
||||||
|
|
||||||
static ConfigSetting CLIStringToSetting(const std::string& s);
|
private:
|
||||||
|
static void DisplayCLIHelp();
|
||||||
|
static void DisplayGenHelp();
|
||||||
|
static void DisplayAddHelp();
|
||||||
|
static void DisplayRemoveHelp();
|
||||||
|
static void DisplaySetHelp();
|
||||||
|
static void DisplayGetHelp();
|
||||||
|
|
||||||
static int Gen(int argc, char** argv);
|
static ConfigSetting CLIStringToSetting(const std::string& s);
|
||||||
static int Add(int argc, char** argv, ConfigFile& config);
|
|
||||||
static int Remove(int argc, char** argv, ConfigFile& config);
|
|
||||||
static int Set(int argc, char** argv, ConfigFile& config);
|
|
||||||
static int Get(int argc, char** argv, ConfigFile& config);
|
|
||||||
|
|
||||||
|
static int Gen(int argc, char** argv);
|
||||||
|
static int Add(int argc, char** argv, ConfigFile& config);
|
||||||
|
static int Remove(int argc, char** argv, ConfigFile& config);
|
||||||
|
static int Set(int argc, char** argv, ConfigFile& config);
|
||||||
|
static int Get(int argc, char** argv, ConfigFile& config);
|
||||||
};
|
};
|
||||||
|
|||||||
Executable → Regular
+679
-350
File diff suppressed because it is too large
Load Diff
Executable → Regular
+93
-38
@@ -1,59 +1,114 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ConfigUtils.h"
|
|
||||||
#include "xml/XMLObject.h"
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "ConfigUtils.h"
|
||||||
|
#include "Dependency.h"
|
||||||
|
#include "FlagData.h"
|
||||||
|
#include "xml/XMLObject.h"
|
||||||
|
|
||||||
static const std::string CONFIG_FILENAME = "makegen.xml";
|
static const std::string CONFIG_FILENAME = "makegen.xml";
|
||||||
|
|
||||||
class ConfigFile
|
class ConfigFile
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
ConfigCache cache;
|
// 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);
|
||||||
|
|
||||||
XMLObject config;
|
void Save() const;
|
||||||
// Current configuration
|
|
||||||
std::string target;
|
|
||||||
|
|
||||||
std::string configPath;
|
const std::string& GetOutputDir() const;
|
||||||
std::vector<ConfigFile> dependencyConfigs;
|
const std::string& GetOutputName() const;
|
||||||
|
const std::string& GetProjectName() const;
|
||||||
|
const std::string& GetOutputType() const;
|
||||||
|
const std::string& GetCppVersion() const;
|
||||||
|
const std::optional<std::string>& GetSourceDir() const;
|
||||||
|
const std::optional<std::string>& GetHFileName() const;
|
||||||
|
const std::vector<std::string>& GetLibraryDirs() const;
|
||||||
|
const std::vector<std::string>& GetIncludeDirs() const;
|
||||||
|
const std::vector<std::string>& GetLibraries() const;
|
||||||
|
const std::vector<std::string>& GetDefines() const;
|
||||||
|
const std::vector<std::string>& GetCFlags() const;
|
||||||
|
const std::vector<std::string>& GetLFlags() const;
|
||||||
|
const std::vector<std::string>& GetExcludeHeaders() const;
|
||||||
|
const std::vector<std::string>& GetExcludeSources() const;
|
||||||
|
const std::vector<std::string>& GetSourceFiles() const;
|
||||||
|
const std::vector<std::string>& GetPreArguments() const;
|
||||||
|
const std::vector<std::string>& GetArguments() const;
|
||||||
|
const std::vector<std::string>& GetIncludeDirExclDeps() const;
|
||||||
|
const std::vector<Dependency>& GetDependencies() const;
|
||||||
|
bool IsGenerateHFile() const;
|
||||||
|
|
||||||
bool hasInitError = false;
|
std::vector<std::string> GetSetting(ConfigSetting setting) const;
|
||||||
|
|
||||||
public:
|
bool SetSettingString(ConfigSetting setting, std::string value);
|
||||||
// Generates a new default config file
|
bool AddSettingVectorString(ConfigSetting setting, std::string value);
|
||||||
ConfigFile(const std::string& path, int);
|
bool RemoveSettingVectorString(ConfigSetting setting, std::string value);
|
||||||
ConfigFile(const std::string& path);
|
|
||||||
ConfigFile(XMLObject& config, const std::string& path);
|
|
||||||
|
|
||||||
void Save() const;
|
const std::filesystem::path& GetConfigPath() const;
|
||||||
|
ConfigFile& GetDependencyConfig(const std::string& path);
|
||||||
|
|
||||||
std::string& GetSettingString(ConfigSetting setting);
|
static ConfigFile Gen(const FlagData& flagData);
|
||||||
bool GetSettingBool(ConfigSetting setting);
|
static std::optional<ConfigFile> GetConfigFile(const std::string& filepath, const FlagData& flagData);
|
||||||
std::vector<std::string>& GetSettingVectorString(ConfigSetting setting);
|
|
||||||
std::vector<std::string> GetSetting(ConfigSetting setting);
|
|
||||||
|
|
||||||
bool SetSettingString(ConfigSetting setting, const std::string& value);
|
private:
|
||||||
bool AddSettingVectorString(ConfigSetting setting, const std::string& value);
|
XMLObject makegen;
|
||||||
bool RemoveSettingVectorString(ConfigSetting setting, const std::string& value);
|
XMLObject config;
|
||||||
|
// Current configuration
|
||||||
|
std::string target;
|
||||||
|
|
||||||
XMLObject& GetConfiguration();
|
std::filesystem::path configPath;
|
||||||
const std::string& GetConfigPath() const;
|
std::vector<ConfigFile> dependencyConfigs;
|
||||||
ConfigFile& GetDependencyConfig(size_t i);
|
|
||||||
private:
|
|
||||||
void Init();
|
|
||||||
|
|
||||||
public:
|
std::vector<Dependency> dependencies;
|
||||||
static ConfigFile Gen();
|
std::string outputName;
|
||||||
static std::optional<ConfigFile> GetConfigFile(const std::string& filepath = "./");
|
std::string outputDir;
|
||||||
private:
|
std::string projectName;
|
||||||
static std::optional<ConfigFile> GetConfigFile(const std::string& filepath, std::map<std::string, ConfigFile>& loadedConfigs);
|
std::string outputType;
|
||||||
static std::optional<ConfigFile> Load(const std::string& filename);
|
std::string cppVersion;
|
||||||
static void InputBoolean(const std::string& inputText, bool& b);
|
std::optional<std::string> sourceDir;
|
||||||
static void InputMultiple(const std::string& inputText, std::vector<std::string>& vec, bool needEnding);
|
std::optional<std::string> hFileName;
|
||||||
static void InputString(const std::string& inputText, std::string& vec, bool needEnding, bool allowEmpty);
|
std::vector<std::string> libraryDirs;
|
||||||
|
std::vector<std::string> includeDirs;
|
||||||
|
std::vector<std::string> libraries;
|
||||||
|
std::vector<std::string> defines;
|
||||||
|
std::vector<std::string> cFlags;
|
||||||
|
std::vector<std::string> lFlags;
|
||||||
|
std::vector<std::string> excludeHeaders;
|
||||||
|
std::vector<std::string> excludeSources;
|
||||||
|
std::vector<std::string> sourceFiles;
|
||||||
|
std::vector<std::string> preArguments;
|
||||||
|
std::vector<std::string> arguments;
|
||||||
|
std::vector<std::string> includeDirExclDeps;
|
||||||
|
bool generateHFile{false};
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Init(const FlagData& flagData);
|
||||||
|
void InitTarget(const FlagData& flagData);
|
||||||
|
void InitTargetConfig();
|
||||||
|
XMLObject& GetTargetConfig();
|
||||||
|
void InitDependencies();
|
||||||
|
void InitStringSetting(const std::string& name, std::string* output);
|
||||||
|
void InitStringSetting(const std::string& name, const std::string& defaultVal, std::string* output);
|
||||||
|
void InitOptionalStringSetting(const std::string& name, std::optional<std::string>* output);
|
||||||
|
void InitStringListSetting(const std::string& name, std::vector<std::string>* output);
|
||||||
|
void InitBoolSetting(const std::string& name, bool* output);
|
||||||
|
|
||||||
|
void InitDir(std::string& dir) const;
|
||||||
|
void InitOptionalDir(std::optional<std::string>& dir) const;
|
||||||
|
void InitDirs(std::vector<std::string>& dirs) const;
|
||||||
|
void RemoveFromVector(std::vector<std::string>& vector, const std::string& string);
|
||||||
|
void RemoveFromVector(std::vector<Dependency>& vector, const std::string& string);
|
||||||
|
|
||||||
|
static std::optional<ConfigFile> GetConfigFile(const std::string& filepath,
|
||||||
|
std::map<std::string, ConfigFile>& loadedConfigs,
|
||||||
|
const FlagData& flagData);
|
||||||
|
static 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);
|
||||||
};
|
};
|
||||||
|
|||||||
+89
-99
@@ -1,37 +1,46 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common.h"
|
#include <algorithm>
|
||||||
#include "FileUtils.h"
|
#include <filesystem>
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
struct ConfigCache
|
#include "Common.h"
|
||||||
{
|
|
||||||
std::map<std::string, std::string> strings;
|
|
||||||
std::map<std::string, std::vector<std::string>> vecStrings;
|
|
||||||
std::map<std::string, bool> bools;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ConfigSetting
|
enum class ConfigSetting
|
||||||
{
|
{
|
||||||
// vectors
|
// vectors
|
||||||
Library = 0, LibraryDir = 1, IncludeDir = 2, Define = 3, Dependency = 4, CFlag = 5, LFlag = 6, ExcludeSource = 7, ExcludeHeader = 8, ExecPreArgument = 9, ExecArgument = 10,
|
Library,
|
||||||
|
LibraryDir,
|
||||||
|
IncludeDir,
|
||||||
|
Define,
|
||||||
|
Dependency,
|
||||||
|
CFlag,
|
||||||
|
LFlag,
|
||||||
|
ExcludeSource,
|
||||||
|
ExcludeHeader,
|
||||||
|
ExecPreArgument,
|
||||||
|
ExecArgument,
|
||||||
|
SourceFile,
|
||||||
|
IncludeDirExclDep,
|
||||||
// Strings
|
// Strings
|
||||||
SourceDir = 32, OutputDir = 33, OutputName = 34, OutputType = 35, ProjectName = 36, HFileName = 37,
|
SourceDir,
|
||||||
|
OutputDir,
|
||||||
|
OutputName,
|
||||||
|
OutputType,
|
||||||
|
ProjectName,
|
||||||
|
HFileName,
|
||||||
|
CppVersion,
|
||||||
// Bools
|
// Bools
|
||||||
GenerateHFile = 64,
|
GenerateHFile,
|
||||||
// Other
|
|
||||||
Invalid = 1024
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConfigUtils
|
struct ConfigUtils
|
||||||
{
|
{
|
||||||
static std::string GetSettingName(ConfigSetting setting)
|
static std::string GetSettingName(ConfigSetting setting)
|
||||||
{
|
{
|
||||||
switch(setting)
|
switch (setting)
|
||||||
{
|
{
|
||||||
case ConfigSetting::SourceDir:
|
case ConfigSetting::SourceDir:
|
||||||
return "srcdir";
|
return "srcdir";
|
||||||
@@ -69,20 +78,26 @@ struct ConfigUtils
|
|||||||
return "argument";
|
return "argument";
|
||||||
case ConfigSetting::GenerateHFile:
|
case ConfigSetting::GenerateHFile:
|
||||||
return "generatehfile";
|
return "generatehfile";
|
||||||
case ConfigSetting::Invalid:
|
case ConfigSetting::SourceFile:
|
||||||
return "invalid";
|
return "sourcefile";
|
||||||
|
case ConfigSetting::IncludeDirExclDep:
|
||||||
|
return "includedirexcldep";
|
||||||
|
case ConfigSetting::CppVersion:
|
||||||
|
return "cppversion";
|
||||||
}
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsDirectory(ConfigSetting setting)
|
static bool IsDirectory(ConfigSetting setting)
|
||||||
{
|
{
|
||||||
switch(setting)
|
switch (setting)
|
||||||
{
|
{
|
||||||
case ConfigSetting::SourceDir:
|
case ConfigSetting::SourceDir:
|
||||||
case ConfigSetting::OutputDir:
|
case ConfigSetting::OutputDir:
|
||||||
case ConfigSetting::LibraryDir:
|
case ConfigSetting::LibraryDir:
|
||||||
case ConfigSetting::IncludeDir:
|
case ConfigSetting::IncludeDir:
|
||||||
case ConfigSetting::Dependency:
|
case ConfigSetting::Dependency:
|
||||||
|
case ConfigSetting::IncludeDirExclDep:
|
||||||
return true;
|
return true;
|
||||||
case ConfigSetting::OutputName:
|
case ConfigSetting::OutputName:
|
||||||
case ConfigSetting::OutputType:
|
case ConfigSetting::OutputType:
|
||||||
@@ -97,16 +112,16 @@ struct ConfigUtils
|
|||||||
case ConfigSetting::ExecPreArgument:
|
case ConfigSetting::ExecPreArgument:
|
||||||
case ConfigSetting::ExecArgument:
|
case ConfigSetting::ExecArgument:
|
||||||
case ConfigSetting::GenerateHFile:
|
case ConfigSetting::GenerateHFile:
|
||||||
|
case ConfigSetting::SourceFile:
|
||||||
|
case ConfigSetting::CppVersion:
|
||||||
return false;
|
return false;
|
||||||
default:
|
|
||||||
LOG_ERROR("INVALID ENUM: ", (int)setting);
|
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsStringSetting(ConfigSetting setting)
|
static bool IsStringSetting(ConfigSetting setting)
|
||||||
{
|
{
|
||||||
switch(setting)
|
switch (setting)
|
||||||
{
|
{
|
||||||
case ConfigSetting::SourceDir:
|
case ConfigSetting::SourceDir:
|
||||||
case ConfigSetting::OutputDir:
|
case ConfigSetting::OutputDir:
|
||||||
@@ -114,6 +129,7 @@ struct ConfigUtils
|
|||||||
case ConfigSetting::OutputType:
|
case ConfigSetting::OutputType:
|
||||||
case ConfigSetting::ProjectName:
|
case ConfigSetting::ProjectName:
|
||||||
case ConfigSetting::HFileName:
|
case ConfigSetting::HFileName:
|
||||||
|
case ConfigSetting::CppVersion:
|
||||||
return true;
|
return true;
|
||||||
case ConfigSetting::LibraryDir:
|
case ConfigSetting::LibraryDir:
|
||||||
case ConfigSetting::IncludeDir:
|
case ConfigSetting::IncludeDir:
|
||||||
@@ -127,14 +143,16 @@ struct ConfigUtils
|
|||||||
case ConfigSetting::ExecPreArgument:
|
case ConfigSetting::ExecPreArgument:
|
||||||
case ConfigSetting::ExecArgument:
|
case ConfigSetting::ExecArgument:
|
||||||
case ConfigSetting::GenerateHFile:
|
case ConfigSetting::GenerateHFile:
|
||||||
case ConfigSetting::Invalid:
|
case ConfigSetting::SourceFile:
|
||||||
|
case ConfigSetting::IncludeDirExclDep:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsVectorSetting(ConfigSetting setting)
|
static bool IsVectorSetting(ConfigSetting setting)
|
||||||
{
|
{
|
||||||
switch(setting)
|
switch (setting)
|
||||||
{
|
{
|
||||||
case ConfigSetting::LibraryDir:
|
case ConfigSetting::LibraryDir:
|
||||||
case ConfigSetting::IncludeDir:
|
case ConfigSetting::IncludeDir:
|
||||||
@@ -147,6 +165,8 @@ struct ConfigUtils
|
|||||||
case ConfigSetting::ExcludeSource:
|
case ConfigSetting::ExcludeSource:
|
||||||
case ConfigSetting::ExecPreArgument:
|
case ConfigSetting::ExecPreArgument:
|
||||||
case ConfigSetting::ExecArgument:
|
case ConfigSetting::ExecArgument:
|
||||||
|
case ConfigSetting::SourceFile:
|
||||||
|
case ConfigSetting::IncludeDirExclDep:
|
||||||
return true;
|
return true;
|
||||||
case ConfigSetting::SourceDir:
|
case ConfigSetting::SourceDir:
|
||||||
case ConfigSetting::OutputDir:
|
case ConfigSetting::OutputDir:
|
||||||
@@ -155,100 +175,75 @@ struct ConfigUtils
|
|||||||
case ConfigSetting::ProjectName:
|
case ConfigSetting::ProjectName:
|
||||||
case ConfigSetting::HFileName:
|
case ConfigSetting::HFileName:
|
||||||
case ConfigSetting::GenerateHFile:
|
case ConfigSetting::GenerateHFile:
|
||||||
case ConfigSetting::Invalid:
|
case ConfigSetting::CppVersion:
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static bool IsBoolSetting(ConfigSetting setting)
|
|
||||||
{
|
|
||||||
switch(setting)
|
|
||||||
{
|
|
||||||
case ConfigSetting::GenerateHFile:
|
|
||||||
return true;
|
|
||||||
case ConfigSetting::SourceDir:
|
|
||||||
case ConfigSetting::OutputDir:
|
|
||||||
case ConfigSetting::OutputName:
|
|
||||||
case ConfigSetting::OutputType:
|
|
||||||
case ConfigSetting::ProjectName:
|
|
||||||
case ConfigSetting::HFileName:
|
|
||||||
case ConfigSetting::LibraryDir:
|
|
||||||
case ConfigSetting::IncludeDir:
|
|
||||||
case ConfigSetting::Dependency:
|
|
||||||
case ConfigSetting::Library:
|
|
||||||
case ConfigSetting::Define:
|
|
||||||
case ConfigSetting::CFlag:
|
|
||||||
case ConfigSetting::LFlag:
|
|
||||||
case ConfigSetting::ExcludeHeader:
|
|
||||||
case ConfigSetting::ExcludeSource:
|
|
||||||
case ConfigSetting::ExecPreArgument:
|
|
||||||
case ConfigSetting::ExecArgument:
|
|
||||||
case ConfigSetting::Invalid:
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetDefaultSettingString(ConfigSetting setting, const std::string& path)
|
static bool IsBoolSetting(ConfigSetting setting)
|
||||||
{
|
{
|
||||||
switch(setting)
|
switch (setting)
|
||||||
{
|
{
|
||||||
case ConfigSetting::SourceDir:
|
|
||||||
return "src/";
|
|
||||||
case ConfigSetting::OutputDir:
|
|
||||||
return "bin/";
|
|
||||||
case ConfigSetting::OutputName:
|
|
||||||
return GetDefaultOutputName(path);
|
|
||||||
case ConfigSetting::OutputType:
|
|
||||||
return "executable";
|
|
||||||
case ConfigSetting::ProjectName:
|
|
||||||
return GetDefaultProjectName(path);
|
|
||||||
case ConfigSetting::HFileName:
|
|
||||||
return GetDefaultHFileName(path);
|
|
||||||
case ConfigSetting::GenerateHFile:
|
case ConfigSetting::GenerateHFile:
|
||||||
return GetDefaultSettingBool(setting) ? "true" : "false";
|
return true;
|
||||||
default:
|
case ConfigSetting::SourceDir:
|
||||||
LOG_ERROR("INVALID STRING ENUM: ", (int)setting);
|
case ConfigSetting::OutputDir:
|
||||||
assert(false);
|
case ConfigSetting::OutputName:
|
||||||
|
case ConfigSetting::OutputType:
|
||||||
|
case ConfigSetting::ProjectName:
|
||||||
|
case ConfigSetting::HFileName:
|
||||||
|
case ConfigSetting::LibraryDir:
|
||||||
|
case ConfigSetting::IncludeDir:
|
||||||
|
case ConfigSetting::Dependency:
|
||||||
|
case ConfigSetting::Library:
|
||||||
|
case ConfigSetting::Define:
|
||||||
|
case ConfigSetting::CFlag:
|
||||||
|
case ConfigSetting::LFlag:
|
||||||
|
case ConfigSetting::ExcludeHeader:
|
||||||
|
case ConfigSetting::ExcludeSource:
|
||||||
|
case ConfigSetting::ExecPreArgument:
|
||||||
|
case ConfigSetting::ExecArgument:
|
||||||
|
case ConfigSetting::SourceFile:
|
||||||
|
case ConfigSetting::IncludeDirExclDep:
|
||||||
|
case ConfigSetting::CppVersion:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GetDefaultSettingBool(ConfigSetting setting)
|
static bool GetDefaultSettingBool(ConfigSetting setting)
|
||||||
{
|
{
|
||||||
switch(setting)
|
switch (setting)
|
||||||
{
|
{
|
||||||
case ConfigSetting::GenerateHFile:
|
case ConfigSetting::GenerateHFile:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("NOT BOOLEAN VALUE: ", (int)setting);
|
ASSERT(false, "NOT BOOLEAN VALUE: ", (int)setting);
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetDefaultProjectName(const std::string& path)
|
static std::string GetDefaultProjectName(const std::string& path)
|
||||||
{
|
{
|
||||||
return FileUtils::GetTopDirectory(path);
|
return std::filesystem::canonical(path).filename();
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetDefaultOutputName(const std::string& path)
|
static std::string GetDefaultOutputName(const std::string& path)
|
||||||
{
|
{
|
||||||
std::string projectname = GetDefaultProjectName(path);
|
std::string projectname = GetDefaultProjectName(path);
|
||||||
std::string outputname;
|
std::string outputname;
|
||||||
std::transform(
|
std::transform(projectname.begin(),
|
||||||
projectname.begin(),
|
projectname.end(),
|
||||||
projectname.end(),
|
std::back_inserter(outputname),
|
||||||
std::back_inserter(outputname),
|
[](unsigned char c)
|
||||||
[](unsigned char c)
|
{
|
||||||
{
|
if (c == ' ')
|
||||||
if(c == ' ')
|
return '_';
|
||||||
return '_';
|
return (char)std::tolower(c);
|
||||||
return (char)std::tolower(c);
|
});
|
||||||
});
|
auto it = std::remove_if(outputname.begin(),
|
||||||
auto it = std::remove_if(
|
outputname.end(),
|
||||||
outputname.begin(),
|
[](unsigned char c) { return (c < '0' || c > '9') && (c < 'a' || c > 'z') && c != '_'; });
|
||||||
outputname.end(),
|
|
||||||
[](unsigned char c)
|
|
||||||
{
|
|
||||||
return (c < '0' || c > '9') && (c < 'a' || c > 'z') && c != '_';
|
|
||||||
});
|
|
||||||
outputname.erase(it, outputname.end());
|
outputname.erase(it, outputname.end());
|
||||||
outputname += ".out";
|
outputname += ".out";
|
||||||
return outputname;
|
return outputname;
|
||||||
@@ -258,12 +253,7 @@ struct ConfigUtils
|
|||||||
{
|
{
|
||||||
std::string hfile = GetDefaultProjectName(path);
|
std::string hfile = GetDefaultProjectName(path);
|
||||||
auto it = std::remove_if(
|
auto it = std::remove_if(
|
||||||
hfile.begin(),
|
hfile.begin(), hfile.end(), [](unsigned char c) { return (c < 'a' || c > 'z') && (c < 'A' || c > 'Z'); });
|
||||||
hfile.end(),
|
|
||||||
[](unsigned char c)
|
|
||||||
{
|
|
||||||
return (c < 'a' || c > 'z') && (c < 'A' || c > 'Z');
|
|
||||||
});
|
|
||||||
hfile.erase(it, hfile.end());
|
hfile.erase(it, hfile.end());
|
||||||
hfile += ".h";
|
hfile += ".h";
|
||||||
return hfile;
|
return hfile;
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct Dependency
|
||||||
|
{
|
||||||
|
std::string path;
|
||||||
|
std::string target;
|
||||||
|
|
||||||
|
Dependency(const std::string& path, const std::string& target)
|
||||||
|
: path{path},
|
||||||
|
target{target}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
+28
-131
@@ -1,159 +1,56 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstring>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include <algorithm>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <cstring>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
struct FileUtils
|
struct FileUtils
|
||||||
{
|
{
|
||||||
static bool HasPath(const std::string& path)
|
|
||||||
{
|
|
||||||
struct stat info;
|
|
||||||
|
|
||||||
if(stat(path.c_str(), &info) != 0)
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool CreateDirectory(const std::string& path)
|
|
||||||
{
|
|
||||||
return mkdir(path.c_str(), 0777);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string GetCurrentDirectory()
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
size_t pos = dir.find_last_of("/", dirEnd);
|
|
||||||
if(pos == std::string::npos)
|
|
||||||
{
|
|
||||||
LOG_ERROR("Couldn't find / (slash) in directory. This shouldn't occur.");
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
return dir.substr(pos + 1, dirEnd - pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string GetRealPath(const std::string& filename)
|
static std::string GetRealPath(const std::string& filename)
|
||||||
{
|
{
|
||||||
#if defined(__linux__)
|
return std::filesystem::canonical(filename).string();
|
||||||
if(access(filename.c_str(), F_OK ) != -1)
|
|
||||||
{
|
|
||||||
char* path = realpath(filename.c_str(), NULL);
|
|
||||||
std::string sPath = path;
|
|
||||||
sPath+="/";
|
|
||||||
free(path);
|
|
||||||
return sPath;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_ERROR("Directory doesn't exist: ", filename);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
LOG_ERROR("GetRealPath not supported");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string GetRelativePath(std::string from, std::string to)
|
|
||||||
{
|
|
||||||
std::string result;
|
|
||||||
if(to[to.size()-1] == '/')
|
|
||||||
to.pop_back();
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
// Same directory
|
|
||||||
if(to.size() == from.size())
|
|
||||||
return "";
|
|
||||||
// Remove the 'from' path
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
std::string sub = from.substr(to.size());
|
|
||||||
size_t n = std::count(sub.begin(), sub.end(), '/');
|
|
||||||
for(int i = 0;i<n;i++)
|
|
||||||
{
|
|
||||||
result+="..";
|
|
||||||
if(i != n-1)
|
|
||||||
result+="/";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
// Otherwise it's a path in another directory
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Find the most common directory
|
|
||||||
std::string commonPath = Utils::CommonPrefix(from,to);
|
|
||||||
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++)
|
|
||||||
{
|
|
||||||
result+="..";
|
|
||||||
if(i != n-1)
|
|
||||||
result+="/";
|
|
||||||
}
|
|
||||||
// Add the path which diverges
|
|
||||||
result += to.substr(commonPath.size());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetAllFiles(const std::string& folder, std::vector<std::string>& files)
|
static void GetAllFiles(const std::string& folder, std::vector<std::string>& files)
|
||||||
{
|
{
|
||||||
DIR* dp;
|
DIR* dp;
|
||||||
struct dirent *dirp;
|
struct dirent* dirp;
|
||||||
if((dp = opendir(folder.c_str())) == NULL){
|
if ((dp = opendir(folder.c_str())) == NULL)
|
||||||
LOG_ERROR(errno);
|
{
|
||||||
|
LOG_ERROR("Failed to open directory: ", folder);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while((dirp = readdir(dp)) != NULL)
|
while ((dirp = readdir(dp)) != NULL)
|
||||||
{
|
{
|
||||||
if(dirp->d_type == DT_DIR)
|
if (dirp->d_type == DT_DIR)
|
||||||
{
|
{
|
||||||
if(strcmp(dirp->d_name,".") == 0)
|
if (strcmp(dirp->d_name, ".") == 0)
|
||||||
continue;
|
continue;
|
||||||
if(strcmp(dirp->d_name,"..") == 0)
|
if (strcmp(dirp->d_name, "..") == 0)
|
||||||
continue;
|
continue;
|
||||||
GetAllFiles(folder+dirp->d_name+"/", files);
|
GetAllFiles(folder + dirp->d_name + "/", files);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
files.push_back(folder+dirp->d_name);
|
files.push_back(folder + dirp->d_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(dp);
|
closedir(dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool FileExists(const std::string& filename)
|
||||||
|
{
|
||||||
|
return std::filesystem::exists(filename) && !std::filesystem::is_directory(filename);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct FlagData
|
||||||
|
{
|
||||||
|
unsigned int flags{0};
|
||||||
|
std::string target{""}; // Only set if flags contain FLAG_TARGET
|
||||||
|
};
|
||||||
+27
-11
@@ -1,23 +1,35 @@
|
|||||||
#include "HFileGen.h"
|
#include "HFileGen.h"
|
||||||
|
|
||||||
#include "FileUtils.h"
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#include "FileUtils.h"
|
||||||
|
|
||||||
|
// TODO: Consider removing this functionality, since its not really used anyways
|
||||||
void HFileGen::Create(ConfigFile& conf)
|
void HFileGen::Create(ConfigFile& conf)
|
||||||
{
|
{
|
||||||
|
const std::optional<std::string>& hFileName = conf.GetHFileName();
|
||||||
|
if (!hFileName.has_value())
|
||||||
|
{
|
||||||
|
LOG_ERROR("hfilename is not specified but generatehfile is true");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::set<std::string> hFiles;
|
std::set<std::string> hFiles;
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
std::string path = conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::SourceDir);
|
const std::optional<std::string>& sourceDir = conf.GetSourceDir();
|
||||||
FileUtils::GetAllFiles(path,files);
|
std::string path = conf.GetConfigPath();
|
||||||
|
if (sourceDir.has_value())
|
||||||
|
path += sourceDir.value();
|
||||||
|
FileUtils::GetAllFiles(path, files);
|
||||||
// include paramenter with the path of the file
|
// include paramenter with the path of the file
|
||||||
// For example src/graphics/Window.h -> graphics/Window.h if src is a src folder
|
// For example src/graphics/Window.h -> graphics/Window.h if src is a src folder
|
||||||
for(auto it = files.begin(); it!=files.end();++it)
|
for (auto it = files.begin(); it != files.end(); ++it)
|
||||||
{
|
{
|
||||||
size_t extensionPos = it->find_last_of(".");
|
size_t extensionPos = it->find_last_of(".");
|
||||||
if(extensionPos != std::string::npos)
|
if (extensionPos != std::string::npos)
|
||||||
{
|
{
|
||||||
std::string filename = it->substr(path.length());
|
std::string filename = it->substr(path.length());
|
||||||
if(Utils::IsHeaderFile(filename) && filename != conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::HFileName))
|
if (Utils::IsHeaderFile(filename) && filename != conf.GetConfigPath() / hFileName.value())
|
||||||
{
|
{
|
||||||
// Make files sorted in alphabetical order
|
// Make files sorted in alphabetical order
|
||||||
hFiles.emplace(filename);
|
hFiles.emplace(filename);
|
||||||
@@ -25,14 +37,18 @@ void HFileGen::Create(ConfigFile& conf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string>& excludeHeaders = conf.GetSettingVectorString(ConfigSetting::ExcludeHeader);
|
const std::vector<std::string>& excludeHeaders = conf.GetExcludeHeaders();
|
||||||
std::ofstream os(path + "/" + conf.GetSettingString(ConfigSetting::HFileName));
|
std::ofstream os(path + "/" + hFileName.value());
|
||||||
os << "#pragma once" << std::endl << std::endl;
|
os << "#pragma once" << std::endl << std::endl;
|
||||||
for(auto&& hFile : hFiles)
|
for (auto&& hFile : hFiles)
|
||||||
{
|
{
|
||||||
std::string headerFile = conf.GetSettingString(ConfigSetting::SourceDir) + hFile;
|
const std::optional<std::string>& srcDir = conf.GetSourceDir();
|
||||||
|
std::string headerFile = hFile;
|
||||||
|
if (srcDir.has_value())
|
||||||
|
headerFile = srcDir.value() + headerFile;
|
||||||
|
|
||||||
auto it = std::find(excludeHeaders.begin(), excludeHeaders.end(), headerFile);
|
auto it = std::find(excludeHeaders.begin(), excludeHeaders.end(), headerFile);
|
||||||
if(it == excludeHeaders.end())
|
if (it == excludeHeaders.end())
|
||||||
os << "#include <" << hFile << ">" << std::endl;
|
os << "#include <" << hFile << ">" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#include "ConfigFile.h"
|
#include "ConfigFile.h"
|
||||||
|
|
||||||
class HFileGen
|
class HFileGen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void Create(ConfigFile& conf);
|
static void Create(ConfigFile& conf);
|
||||||
};
|
};
|
||||||
|
|||||||
Executable → Regular
+64
-29
@@ -1,64 +1,99 @@
|
|||||||
#include "IncludeDeps.h"
|
#include "IncludeDeps.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
std::set<std::string> IncludeDeps::printSet;
|
std::set<std::string> IncludeDeps::printSet;
|
||||||
int IncludeDeps::printCounter = 0;
|
int IncludeDeps::printCounter = 0;
|
||||||
|
|
||||||
IncludeDeps::IncludeDeps(const std::string& filename, const std::string& dir, const std::set<HFile>& files, std::map<std::string, IncludeDeps*>& allDeps)
|
IncludeDeps::IncludeDeps(const std::string& filename,
|
||||||
: IncludeDeps{filename, dir, false, files, allDeps}
|
const std::set<HFile>& files,
|
||||||
{}
|
std::map<std::string, IncludeDeps*>& allDeps)
|
||||||
|
: IncludeDeps{filename, false, files, allDeps}
|
||||||
IncludeDeps::IncludeDeps(const std::string& filename, const std::string& dir, bool projectHFile, const std::set<HFile>& files, std::map<std::string, IncludeDeps*>& allDeps)
|
|
||||||
: filepath(dir+filename), projectHFile{projectHFile}
|
|
||||||
{
|
{
|
||||||
if(Utils::IsHeaderFile(filename))
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
{
|
{
|
||||||
allDeps.emplace(filepath, this);
|
allDeps.emplace(filepath, this);
|
||||||
}
|
}
|
||||||
std::ifstream file(filepath);
|
std::ifstream file(filepath);
|
||||||
std::string line;
|
std::string line;
|
||||||
while(std::getline(file,line))
|
while (std::getline(file, line))
|
||||||
{
|
{
|
||||||
size_t pos = line.find("#include");
|
std::string start;
|
||||||
if(pos != std::string::npos)
|
std::stringstream ss{line};
|
||||||
|
ss >> start;
|
||||||
|
if (start == "#include")
|
||||||
{
|
{
|
||||||
std::string include = GetIncludeFile(line, pos, filename);
|
std::string include = GetIncludeFile(line);
|
||||||
auto it = files.find({include, "", false});
|
|
||||||
if(it != files.end())
|
std::filesystem::path includeFileRelativeToSource;
|
||||||
|
if (path.is_absolute())
|
||||||
|
includeFileRelativeToSource = std::filesystem::relative("/", ".").string() + "/" + include;
|
||||||
|
else
|
||||||
|
includeFileRelativeToSource = std::filesystem::relative(path.parent_path(), ".").string() + "/" + include;
|
||||||
|
|
||||||
|
// Check if file can be found relative to current file:
|
||||||
|
if (FileUtils::FileExists(includeFileRelativeToSource.string()))
|
||||||
{
|
{
|
||||||
auto itD = allDeps.find(it->filepath);
|
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
|
||||||
{
|
{
|
||||||
IncludeDeps* inc = new IncludeDeps(it->filename,it->directory, it->isProjectHFile, files,allDeps);
|
|
||||||
dependencies.emplace(it->filepath, inc);
|
|
||||||
}else{
|
|
||||||
dependencies.emplace(itD->first, itD->second);
|
dependencies.emplace(itD->first, itD->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto it = files.find({include, "", false});
|
||||||
|
if (it != files.end())
|
||||||
|
{
|
||||||
|
auto itD = allDeps.find(it->filepath);
|
||||||
|
if (itD == allDeps.end())
|
||||||
|
{
|
||||||
|
IncludeDeps* inc = new IncludeDeps(it->filepath, it->isProjectHFile, files, allDeps);
|
||||||
|
dependencies.emplace(it->filepath, inc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dependencies.emplace(itD->first, itD->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string IncludeDeps::GetIncludeFile(const std::string& line, size_t pos, const std::string& filename)
|
std::string IncludeDeps::GetIncludeFile(const std::string& line)
|
||||||
{
|
{
|
||||||
size_t bracket = line.find('<',pos);
|
size_t bracket = line.find('<');
|
||||||
if(bracket == std::string::npos)
|
if (bracket == std::string::npos)
|
||||||
{
|
{
|
||||||
bracket = line.find('\"',pos);
|
bracket = line.find('\"');
|
||||||
if(bracket == std::string::npos)
|
if (bracket == std::string::npos)
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
size_t slash = filename.find_last_of("/");
|
|
||||||
|
|
||||||
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);
|
||||||
if(slash == std::string::npos)
|
return include;
|
||||||
slash = -1;
|
|
||||||
return filename.substr(0,slash+1)+include;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return line.substr(bracket+1, line.find('>',bracket+1)-bracket-1);
|
return line.substr(bracket + 1, line.find('>', bracket + 1) - bracket - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Executable → Regular
+41
-28
@@ -1,61 +1,74 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ConfigFile.h"
|
#include <filesystem>
|
||||||
#include "FileUtils.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "ConfigFile.h"
|
||||||
|
#include "FileUtils.h"
|
||||||
|
|
||||||
struct CompareIncludeDeps;
|
struct CompareIncludeDeps;
|
||||||
|
|
||||||
class IncludeDeps
|
class IncludeDeps
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::map<std::string, IncludeDeps*> dependencies;
|
std::map<std::string, IncludeDeps*> dependencies;
|
||||||
std::string filepath;
|
std::filesystem::path filepath;
|
||||||
bool projectHFile;
|
bool projectHFile;
|
||||||
static std::set<std::string> printSet;
|
static std::set<std::string> printSet;
|
||||||
static int printCounter;
|
static int printCounter;
|
||||||
|
|
||||||
IncludeDeps(const std::string& filename, const std::string& dir, 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, const std::string& dir, 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, size_t pos, const std::string& filename);
|
std::string GetIncludeFile(const std::string& line);
|
||||||
|
|
||||||
std::ostream& Output(std::ostream& stream, const ConfigFile& conf)
|
std::ostream& Output(std::ostream& stream, const ConfigFile& conf)
|
||||||
{
|
{
|
||||||
if(printSet.find(filepath) != printSet.end())
|
std::string filePathInMakeFile = filepath;
|
||||||
return stream;
|
if (!filepath.is_absolute())
|
||||||
printCounter++;
|
filePathInMakeFile = std::filesystem::relative(conf.GetConfigPath() / filepath.string(), "./").string();
|
||||||
printSet.emplace(filepath);
|
|
||||||
if(!projectHFile)
|
if (printSet.find(filePathInMakeFile) != printSet.end())
|
||||||
stream << FileUtils::GetRelativePath(conf.GetConfigPath(), filepath);
|
|
||||||
for(auto it = dependencies.begin();it!=dependencies.end();++it)
|
|
||||||
{
|
|
||||||
stream << " ";
|
|
||||||
(it->second)->Output(stream, conf);
|
|
||||||
}
|
|
||||||
printCounter--;
|
|
||||||
if(printCounter == 0)
|
|
||||||
printSet.clear();
|
|
||||||
return stream;
|
return stream;
|
||||||
|
printSet.emplace(filePathInMakeFile);
|
||||||
|
printCounter++;
|
||||||
|
|
||||||
|
if (!projectHFile)
|
||||||
|
{
|
||||||
|
stream << " " << filePathInMakeFile;
|
||||||
}
|
}
|
||||||
|
for (auto it = dependencies.begin(); it != dependencies.end(); ++it)
|
||||||
|
{
|
||||||
|
(it->second)->Output(stream, conf);
|
||||||
|
}
|
||||||
|
printCounter--;
|
||||||
|
if (printCounter == 0)
|
||||||
|
printSet.clear();
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CompareIncludeDeps
|
struct CompareIncludeDeps
|
||||||
{
|
{
|
||||||
using is_transparent = void;
|
using is_transparent = void;
|
||||||
|
|
||||||
bool operator()(const IncludeDeps* d1, const IncludeDeps* d2) const
|
bool operator()(const IncludeDeps* d1, const IncludeDeps* d2) const
|
||||||
{
|
{
|
||||||
return d1->filepath < d2->filepath;
|
return d1->filepath < d2->filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const IncludeDeps* d, const std::string& filepath) const
|
bool operator()(const IncludeDeps* d, const std::string& filepath) const
|
||||||
{
|
{
|
||||||
return d->filepath < filepath;
|
return d->filepath < filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const std::string& filepath, const IncludeDeps* d) const
|
bool operator()(const std::string& filepath, const IncludeDeps* d) const
|
||||||
{
|
{
|
||||||
return filepath < d->filepath;
|
return filepath < d->filepath;
|
||||||
|
|||||||
+115
-77
@@ -1,29 +1,31 @@
|
|||||||
#include "Makefile.h"
|
#include "Makefile.h"
|
||||||
|
|
||||||
#include "IncludeDeps.h"
|
|
||||||
#include "Utils.h"
|
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "IncludeDeps.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
void Makefile::Save(ConfigFile& conf, unsigned int flags)
|
void Makefile::Save(ConfigFile& conf, unsigned int flags)
|
||||||
{
|
{
|
||||||
std::set<HFile> hFiles; // hFile, directory
|
std::set<HFile> hFiles; // hFile, directory
|
||||||
std::set<std::string> cppFiles;
|
std::set<std::string> cppFiles;
|
||||||
if(flags & FLAG_SIMPLE)
|
if (flags & FLAG_SIMPLE)
|
||||||
Utils::GetCppFiles(conf, cppFiles);
|
Utils::GetCppFiles(conf, cppFiles);
|
||||||
else
|
else
|
||||||
Utils::GetCppAndHFiles(conf, hFiles, cppFiles);
|
Utils::GetCppAndHFiles(conf, hFiles, cppFiles);
|
||||||
|
|
||||||
std::ofstream outputFile(conf.GetConfigPath()+ "Makefile");
|
std::ofstream outputFile(conf.GetConfigPath() / "Makefile");
|
||||||
outputFile << "# This Makefile was generated using MakeGen "<< MAKEGEN_VERSION << " made by Tim Håkansson" << std::endl;
|
outputFile << "# This Makefile was generated using MakeGen " << MAKEGEN_VERSION << " made by Tim Håkansson"
|
||||||
|
<< std::endl;
|
||||||
outputFile << "# and is licensed under MIT. Full source of the project can be found at" << std::endl;
|
outputFile << "# and is licensed under MIT. Full source of the project can be found at" << std::endl;
|
||||||
outputFile << "# https://github.com/Thraix/MakeGen" << std::endl;
|
outputFile << "# https://gitea.timha.se/Thraix/MakeGen" << std::endl;
|
||||||
outputFile << "CC=@g++" << std::endl;
|
outputFile << "CC=@g++" << std::endl;
|
||||||
std::string outputtype = conf.GetSettingString(ConfigSetting::OutputType);
|
std::string outputtype = conf.GetOutputType();
|
||||||
if(outputtype != "executable")
|
if (outputtype != "executable")
|
||||||
{
|
{
|
||||||
if(outputtype == "sharedlibrary")
|
if (outputtype == "sharedlibrary")
|
||||||
outputFile << "CO=@g++ -shared -o" << std::endl;
|
outputFile << "CO=@g++ -shared -o" << std::endl;
|
||||||
else
|
else
|
||||||
outputFile << "CO=@g++ -o" << std::endl;
|
outputFile << "CO=@g++ -o" << std::endl;
|
||||||
@@ -32,111 +34,127 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
|
|||||||
outputFile << "CO=@g++ -o" << std::endl;
|
outputFile << "CO=@g++ -o" << std::endl;
|
||||||
|
|
||||||
outputFile << "MKDIR_P=mkdir -p" << std::endl;
|
outputFile << "MKDIR_P=mkdir -p" << std::endl;
|
||||||
outputFile << "BIN=" << conf.GetSettingString(ConfigSetting::OutputDir) << std::endl;
|
outputFile << "BIN=" << conf.GetOutputDir() << std::endl;
|
||||||
outputFile << "OBJPATH=$(BIN)intermediates" << std::endl;
|
outputFile << "OBJPATH=$(BIN)intermediates" << std::endl;
|
||||||
outputFile << "INCLUDES=";
|
outputFile << "INCLUDES=";
|
||||||
std::vector<std::string>& includedirs = conf.GetSettingVectorString(ConfigSetting::IncludeDir);
|
const std::vector<std::string>& includeDirs = conf.GetIncludeDirs();
|
||||||
for(auto it = includedirs.begin(); it != includedirs.end(); ++it)
|
for (const auto& includeDir : includeDirs)
|
||||||
{
|
{
|
||||||
outputFile << "-I " << *it << " ";
|
outputFile << "-I " << includeDir << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& includeDirExclDeps = conf.GetIncludeDirExclDeps();
|
||||||
|
for (const auto& includeDirExclDep : includeDirExclDeps)
|
||||||
|
{
|
||||||
|
outputFile << "-I " << includeDirExclDep << " ";
|
||||||
}
|
}
|
||||||
outputFile << std::endl;
|
outputFile << std::endl;
|
||||||
outputFile << "OBJECTS=";
|
outputFile << "OBJECTS=";
|
||||||
for(auto it = cppFiles.begin();it!=cppFiles.end();++it)
|
for (auto it = cppFiles.begin(); it != cppFiles.end(); ++it)
|
||||||
{
|
{
|
||||||
size_t extensionPos = it->find_last_of(".");
|
std::filesystem::path cppFile(*it);
|
||||||
size_t slash = it->find_last_of("/")+1;
|
std::filesystem::path oFile = cppFile.replace_extension("o");
|
||||||
outputFile << "$(OBJPATH)/" << it->substr(slash, extensionPos - slash) << ".o ";
|
std::string oFileStr = oFile.string();
|
||||||
|
Utils::Replace(oFileStr, "..", "dotdot");
|
||||||
|
outputFile << "$(OBJPATH)/" << oFileStr << " ";
|
||||||
}
|
}
|
||||||
outputFile << std::endl;
|
outputFile << std::endl;
|
||||||
if(outputtype == "executable" || outputtype != "sharedlibrary")
|
if (outputtype == "executable" || outputtype != "sharedlibrary")
|
||||||
{
|
{
|
||||||
outputFile << "CFLAGS=$(INCLUDES) -std=c++17 -c ";
|
outputFile << "CFLAGS=$(INCLUDES) -std=" + conf.GetCppVersion() + " -c ";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
outputFile << "CFLAGS=$(INCLUDES) -fPIC -std=c++17 -c ";
|
outputFile << "CFLAGS=$(INCLUDES) -fPIC -std=" + conf.GetCppVersion() + " -c ";
|
||||||
}
|
}
|
||||||
std::vector<std::string>& defines = conf.GetSettingVectorString(ConfigSetting::Define);
|
const std::vector<std::string>& defines = conf.GetDefines();
|
||||||
for(auto it = defines.begin(); it != defines.end(); ++it)
|
for (const auto& define : defines)
|
||||||
{
|
{
|
||||||
outputFile << "-D" << *it << " ";
|
outputFile << "-D" << define << " ";
|
||||||
}
|
}
|
||||||
std::vector<std::string>& cflags = conf.GetSettingVectorString(ConfigSetting::CFlag);
|
const std::vector<std::string>& cFlags = conf.GetCFlags();
|
||||||
for(auto it = cflags.begin(); it != cflags.end(); ++it)
|
for (const auto& cFlag : cFlags)
|
||||||
{
|
{
|
||||||
outputFile << *it << " ";
|
outputFile << cFlag << " ";
|
||||||
}
|
}
|
||||||
outputFile << std::endl;
|
outputFile << std::endl;
|
||||||
if(outputtype == "executable")
|
if (outputtype == "executable")
|
||||||
{
|
{
|
||||||
std::vector<std::string>& libdirs= conf.GetSettingVectorString(ConfigSetting::LibraryDir);
|
const std::vector<std::string>& libraryDirs = conf.GetLibraryDirs();
|
||||||
outputFile << "LIBDIR=";
|
outputFile << "LIBDIR=";
|
||||||
for(auto it = libdirs.begin();it!=libdirs.end();++it)
|
for (const auto& libraryDir : libraryDirs)
|
||||||
{
|
{
|
||||||
outputFile << "-L " << *it << " ";
|
outputFile << "-L " << libraryDir << " ";
|
||||||
}
|
}
|
||||||
outputFile << std::endl;
|
outputFile << std::endl;
|
||||||
std::vector<std::string>& lflags = conf.GetSettingVectorString(ConfigSetting::LFlag);
|
const std::vector<std::string>& lFlags = conf.GetLFlags();
|
||||||
outputFile << "LDFLAGS=";
|
outputFile << "LDFLAGS=";
|
||||||
for(auto it = lflags.begin(); it != lflags.end(); ++it)
|
for (const auto& lFlag : lFlags)
|
||||||
{
|
{
|
||||||
outputFile << *it << " ";
|
outputFile << lFlag << " ";
|
||||||
}
|
}
|
||||||
for(auto it = libdirs.begin(); it != libdirs.end(); ++it)
|
for (const auto& libraryDir : libraryDirs)
|
||||||
{
|
{
|
||||||
outputFile << "-Wl,-rpath=" << *it << " ";
|
outputFile << "-Wl,-rpath=" << libraryDir << " ";
|
||||||
}
|
}
|
||||||
outputFile << std::endl;
|
outputFile << std::endl;
|
||||||
std::vector<std::string>& libs = conf.GetSettingVectorString(ConfigSetting::Library);
|
const std::vector<std::string>& libraries = conf.GetLibraries();
|
||||||
outputFile << "LIBS=$(LIBDIR) ";
|
outputFile << "LIBS=$(LIBDIR) ";
|
||||||
for(auto it = libs.begin(); it != libs.end(); ++it)
|
for (const auto& library : libraries)
|
||||||
{
|
{
|
||||||
outputFile << "-l" << *it << " ";
|
outputFile << "-l" << library << " ";
|
||||||
}
|
}
|
||||||
outputFile << std::endl;
|
outputFile << std::endl;
|
||||||
std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency);
|
const std::vector<Dependency>& dependencies = conf.GetDependencies();
|
||||||
if(!dependencies.empty())
|
if (!dependencies.empty())
|
||||||
{
|
{
|
||||||
outputFile << "DEPENDENCIES=";
|
outputFile << "DEPENDENCIES=";
|
||||||
for(auto it = dependencies.begin();it!=dependencies.end();++it)
|
for (const auto& [path, target] : dependencies)
|
||||||
{
|
{
|
||||||
outputFile << *it << " ";
|
outputFile << path << " ";
|
||||||
}
|
}
|
||||||
outputFile << std::endl;
|
outputFile << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outputFile << "OUTPUT=$(BIN)" << conf.GetSettingString(ConfigSetting::OutputName) << std::endl;
|
outputFile << "OUTPUT=$(BIN)" << conf.GetOutputName() << std::endl;
|
||||||
outputFile << ".PHONY: all directories rebuild clean run" << std::endl;
|
outputFile << ".PHONY: all directories rebuild clean run" << std::endl;
|
||||||
|
|
||||||
// All
|
// All
|
||||||
outputFile << "all: directories $(OUTPUT)" << std::endl;
|
outputFile << "all: directories $(OUTPUT)" << std::endl;
|
||||||
|
|
||||||
// Directories
|
// Directories
|
||||||
outputFile << "directories: $(BIN) $(OBJPATH)" << std::endl;
|
std::set<std::string> intermediateDirectories = GetIntermediateDirectories(cppFiles);
|
||||||
|
outputFile << "directories: ";
|
||||||
|
for (const auto& intermediateDirectory : intermediateDirectories)
|
||||||
|
{
|
||||||
|
outputFile << intermediateDirectory << " ";
|
||||||
|
}
|
||||||
|
outputFile << std::endl;
|
||||||
|
|
||||||
// Bin path
|
// Intermediate directories
|
||||||
outputFile << "$(BIN):" << std::endl;
|
for (const auto& intermediateDirectory : intermediateDirectories)
|
||||||
outputFile << "\t$(info Creating output directories)" << std::endl;
|
{
|
||||||
outputFile << "\t@$(MKDIR_P) $(BIN)" << std::endl;
|
outputFile << intermediateDirectory << ":" << std::endl;
|
||||||
|
outputFile << "\t@$(MKDIR_P) $@" << std::endl;
|
||||||
// Object path
|
}
|
||||||
outputFile << "$(OBJPATH):" << std::endl;
|
|
||||||
outputFile << "\t@$(MKDIR_P) $(OBJPATH)" << std::endl;
|
|
||||||
|
|
||||||
// Run
|
// Run
|
||||||
outputFile << "run: all" << std::endl;
|
outputFile << "run: all" << std::endl;
|
||||||
if(outputtype == "executable")
|
if (outputtype == "executable")
|
||||||
{
|
{
|
||||||
std::vector<std::string>& prearguments = conf.GetSettingVectorString(ConfigSetting::ExecPreArgument);
|
const std::vector<std::string>& prearguments = conf.GetPreArguments();
|
||||||
std::vector<std::string>& arguments = conf.GetSettingVectorString(ConfigSetting::ExecArgument);
|
const std::vector<std::string>& arguments = conf.GetArguments();
|
||||||
|
|
||||||
outputFile << "\t@";
|
outputFile << "\t@";
|
||||||
for(auto&& preargument : prearguments)
|
for (const auto& preargument : prearguments)
|
||||||
|
{
|
||||||
outputFile << preargument << " ";
|
outputFile << preargument << " ";
|
||||||
|
}
|
||||||
outputFile << "./$(OUTPUT)";
|
outputFile << "./$(OUTPUT)";
|
||||||
for(auto&& argument : arguments)
|
for (const auto& argument : arguments)
|
||||||
|
{
|
||||||
outputFile << " " << argument;
|
outputFile << " " << argument;
|
||||||
|
}
|
||||||
outputFile << std::endl;
|
outputFile << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,41 +163,61 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
|
|||||||
|
|
||||||
// Clean
|
// Clean
|
||||||
outputFile << "clean:" << std::endl;
|
outputFile << "clean:" << std::endl;
|
||||||
outputFile << "\t$(info Removing intermediates)" << std::endl;
|
outputFile << "\t$(info Removing $(OBJPATH) and $(OUTPUT))" << std::endl;
|
||||||
outputFile << "\trm -rf $(OBJPATH)/*.o" << std::endl;
|
outputFile << "\t@rm -rf $(OBJPATH)/ $(OUTPUT)" << std::endl;
|
||||||
|
|
||||||
// Output file
|
// Output file
|
||||||
outputFile << "$(OUTPUT): $(OBJECTS)" << std::endl;
|
outputFile << "$(OUTPUT): $(OBJECTS)" << std::endl;
|
||||||
outputFile << "\t$(info Generating output file)" << std::endl;
|
outputFile << "\t$(info Generating output file $(OUTPUT))" << std::endl;
|
||||||
if(outputtype == "executable")
|
if (outputtype == "executable")
|
||||||
outputFile << "\t$(CO) $(OUTPUT) $(OBJECTS) $(LDFLAGS) $(LIBS)" << std::endl;
|
outputFile << "\t$(CO) $(OUTPUT) $(OBJECTS) $(LDFLAGS) $(LIBS)" << std::endl;
|
||||||
else
|
else
|
||||||
outputFile << "\t$(CO) $(OUTPUT) $(OBJECTS)" << std::endl;
|
outputFile << "\t$(CO) $(OUTPUT) $(OBJECTS)" << std::endl;
|
||||||
|
|
||||||
// Install
|
// Install
|
||||||
outputFile << "install: all" << std::endl;
|
outputFile << "install: all" << std::endl;
|
||||||
outputFile << "\t$(info Installing " << conf.GetSettingString(ConfigSetting::ProjectName) <<" to /usr/bin/)" << std::endl;
|
outputFile << "\t$(info Installing " << conf.GetProjectName() << " to /usr/bin/)" << std::endl;
|
||||||
outputFile << "\t@cp $(OUTPUT) /usr/bin/" << conf.GetSettingString(ConfigSetting::OutputName) << std::endl;
|
outputFile << "\t@cp $(OUTPUT) /usr/bin/" << conf.GetOutputName() << std::endl;
|
||||||
|
|
||||||
std::map<std::string, IncludeDeps*> dependencies;
|
std::map<std::string, IncludeDeps*> dependencies;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for(auto it = cppFiles.begin(); it != cppFiles.end();++it)
|
for (auto it = cppFiles.begin(); it != cppFiles.end(); ++it)
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
std::string& srcdir = conf.GetSettingString(ConfigSetting::SourceDir);
|
auto itD = dependencies.find(*it);
|
||||||
auto itD = dependencies.find(srcdir + *it);
|
if (itD == dependencies.end())
|
||||||
if(itD == dependencies.end())
|
|
||||||
{
|
{
|
||||||
IncludeDeps* deps = new IncludeDeps(*it, conf.GetConfigPath() + srcdir,hFiles,dependencies);
|
std::filesystem::path cppFile(*it);
|
||||||
size_t extensionPos = it->find_last_of(".");
|
std::filesystem::path oFile = cppFile.replace_extension("o");
|
||||||
size_t slash = it->find_last_of("/")+1;
|
std::string oFileStr = oFile.string();
|
||||||
std::string oFile = it->substr(slash, extensionPos - slash)+".o ";
|
Utils::Replace(oFileStr, "..", "dotdot");
|
||||||
|
outputFile << "$(OBJPATH)/" << oFileStr << ":";
|
||||||
outputFile << "$(OBJPATH)/" << oFile << ": ";
|
if (flags & FLAG_SIMPLE)
|
||||||
deps->Output(outputFile, conf);
|
{
|
||||||
outputFile << std::endl;
|
outputFile << " " << *it << " makegen.xml" << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IncludeDeps* deps = new IncludeDeps(*it, hFiles, dependencies);
|
||||||
|
deps->Output(outputFile, conf);
|
||||||
|
outputFile << " makegen.xml" << std::endl;
|
||||||
|
}
|
||||||
outputFile << "\t$(info -[" << (int)(i / (float)cppFiles.size() * 100) << "%]- $<)" << std::endl;
|
outputFile << "\t$(info -[" << (int)(i / (float)cppFiles.size() * 100) << "%]- $<)" << std::endl;
|
||||||
outputFile << "\t$(CC) $(CFLAGS) -o $@ $<" << std::endl;
|
outputFile << "\t$(CC) $(CFLAGS) -o $@ $<" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<std::string> Makefile::GetIntermediateDirectories(const std::set<std::string>& cppFiles)
|
||||||
|
{
|
||||||
|
std::set<std::string> intermediateDirectories;
|
||||||
|
for (const auto& cppFile : cppFiles)
|
||||||
|
{
|
||||||
|
std::filesystem::path cppPath{cppFile};
|
||||||
|
std::filesystem::path oFile = cppPath.replace_extension("o");
|
||||||
|
std::string parentPathStr = oFile.parent_path().string();
|
||||||
|
Utils::Replace(parentPathStr, "..", "dotdot");
|
||||||
|
intermediateDirectories.emplace("$(OBJPATH)/" + parentPathStr);
|
||||||
|
}
|
||||||
|
return intermediateDirectories;
|
||||||
|
}
|
||||||
|
|||||||
Executable → Regular
+5
-2
@@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
class Makefile
|
class Makefile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void Save(ConfigFile& conf, unsigned int flags);
|
static void Save(ConfigFile& conf, unsigned int flags);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::set<std::string> GetIntermediateDirectories(const std::set<std::string>& cppFiles);
|
||||||
};
|
};
|
||||||
|
|||||||
Executable → Regular
+19
-14
@@ -4,20 +4,25 @@
|
|||||||
|
|
||||||
class Timer
|
class Timer
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::chrono::time_point<std::chrono::high_resolution_clock> m_start;
|
std::chrono::time_point<std::chrono::high_resolution_clock> m_start;
|
||||||
public:
|
|
||||||
Timer(){
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset()
|
public:
|
||||||
{
|
Timer()
|
||||||
m_start = std::chrono::high_resolution_clock::now();
|
{
|
||||||
}
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
float Elapsed()
|
void Reset()
|
||||||
{
|
{
|
||||||
return std::chrono::duration_cast<std::chrono::duration<float,std::milli>>(std::chrono::high_resolution_clock::now() - m_start).count() / 1000.0f;
|
m_start = std::chrono::high_resolution_clock::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Elapsed()
|
||||||
|
{
|
||||||
|
return std::chrono::duration_cast<std::chrono::duration<float, std::milli>>(
|
||||||
|
std::chrono::high_resolution_clock::now() - m_start)
|
||||||
|
.count() /
|
||||||
|
1000.0f;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+127
-50
@@ -1,5 +1,7 @@
|
|||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include "ConfigFile.h"
|
#include "ConfigFile.h"
|
||||||
#include "FileUtils.h"
|
#include "FileUtils.h"
|
||||||
|
|
||||||
@@ -8,7 +10,7 @@ bool Utils::IsSourceFile(const std::string& filepath)
|
|||||||
std::string_view extension(filepath);
|
std::string_view extension(filepath);
|
||||||
size_t pSlash = filepath.find_last_of('/');
|
size_t pSlash = filepath.find_last_of('/');
|
||||||
size_t pDot = filepath.find_last_of('.');
|
size_t pDot = filepath.find_last_of('.');
|
||||||
if(pDot == std::string::npos || (pSlash != std::string::npos && pSlash > pDot))
|
if (pDot == std::string::npos || (pSlash != std::string::npos && pSlash > pDot))
|
||||||
{
|
{
|
||||||
LOG_ERROR("No file extension for file: ", filepath);
|
LOG_ERROR("No file extension for file: ", filepath);
|
||||||
return false;
|
return false;
|
||||||
@@ -22,21 +24,41 @@ bool Utils::IsHeaderFile(const std::string& filepath)
|
|||||||
std::string_view extension(filepath);
|
std::string_view extension(filepath);
|
||||||
size_t pSlash = filepath.find_last_of('/');
|
size_t pSlash = filepath.find_last_of('/');
|
||||||
size_t pDot = filepath.find_last_of('.');
|
size_t pDot = filepath.find_last_of('.');
|
||||||
if(pDot == std::string::npos || (pSlash != std::string::npos && pSlash > pDot))
|
if (pDot == std::string::npos || (pSlash != std::string::npos && pSlash > pDot))
|
||||||
{
|
{
|
||||||
LOG_ERROR("No file extension for file: ", filepath);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
extension.remove_prefix(pDot + 1);
|
extension.remove_prefix(pDot + 1);
|
||||||
return extension == "hpp" || extension == "h" || extension == "hxx";
|
return extension == "hpp" || extension == "h" || extension == "hxx";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Utils::StartsWith(const std::string& str, const std::string& prefix)
|
||||||
|
{
|
||||||
|
if (str.size() < prefix.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return str.compare(0, prefix.size(), prefix) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Utils::Replace(std::string& str, const std::string& from, const std::string& to)
|
||||||
|
{
|
||||||
|
if (from.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
size_t pos = str.find(from, 0);
|
||||||
|
while (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
str.replace(pos, from.length(), to);
|
||||||
|
pos = str.find(from, pos + to.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string Utils::CommonPrefix(const std::string& s1, const std::string& s2)
|
std::string Utils::CommonPrefix(const std::string& s1, const std::string& s2)
|
||||||
{
|
{
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
for(size_t i = 0; i<s1.size() && i<s2.size();++i)
|
for (size_t i = 0; i < s1.size() && i < s2.size(); ++i)
|
||||||
{
|
{
|
||||||
if(s1[i] != s2[i])
|
if (s1[i] != s2[i])
|
||||||
{
|
{
|
||||||
n = i;
|
n = i;
|
||||||
break;
|
break;
|
||||||
@@ -48,20 +70,30 @@ std::string Utils::CommonPrefix(const std::string& s1, const std::string& s2)
|
|||||||
void Utils::GetCppFiles(ConfigFile& conf, std::set<std::string>& cppFiles)
|
void Utils::GetCppFiles(ConfigFile& conf, std::set<std::string>& cppFiles)
|
||||||
{
|
{
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
std::string path = conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::SourceDir);
|
const std::optional<std::string>& sourceDir = conf.GetSourceDir();
|
||||||
FileUtils::GetAllFiles(path, files);
|
if (sourceDir.has_value())
|
||||||
const std::vector<std::string>& excludeSources = conf.GetSettingVectorString(ConfigSetting::ExcludeSource);
|
|
||||||
|
|
||||||
for(auto it = files.begin(); it!=files.end();++it)
|
|
||||||
{
|
{
|
||||||
std::string filename = it->substr(path.length());
|
FileUtils::GetAllFiles(conf.GetConfigPath() / sourceDir.value(), files);
|
||||||
if(IsSourceFile(filename))
|
}
|
||||||
|
const std::vector<std::string>& excludeSources = conf.GetExcludeSources();
|
||||||
|
|
||||||
|
for (const auto& sourceFile : conf.GetSourceFiles())
|
||||||
|
{
|
||||||
|
if (FileUtils::FileExists(conf.GetConfigPath() / sourceFile))
|
||||||
|
cppFiles.emplace(sourceFile);
|
||||||
|
else
|
||||||
|
LOG_WARNING("Source file doesn't exist: ", sourceFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& filename : files)
|
||||||
|
{
|
||||||
|
std::filesystem::path filepath = std::filesystem::relative(filename, "./");
|
||||||
|
if (IsSourceFile(filename))
|
||||||
{
|
{
|
||||||
std::string sourceFile =conf.GetSettingString(ConfigSetting::SourceDir) + filename;
|
auto it = std::find(excludeSources.begin(), excludeSources.end(), filename);
|
||||||
auto it = std::find(excludeSources.begin(), excludeSources.end(), sourceFile);
|
if (it == excludeSources.end())
|
||||||
if(it == excludeSources.end())
|
|
||||||
{
|
{
|
||||||
cppFiles.emplace(filename);
|
cppFiles.emplace(filepath.string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,60 +101,105 @@ void Utils::GetCppFiles(ConfigFile& conf, std::set<std::string>& cppFiles)
|
|||||||
|
|
||||||
void Utils::GetCppAndHFiles(ConfigFile& conf, std::set<HFile>& hFiles, std::set<std::string>& cppFiles)
|
void Utils::GetCppAndHFiles(ConfigFile& conf, std::set<HFile>& hFiles, std::set<std::string>& cppFiles)
|
||||||
{
|
{
|
||||||
std::vector<std::string> files;
|
const std::vector<std::string>& excludeSources = conf.GetExcludeSources();
|
||||||
std::string path = conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::SourceDir);
|
for (const auto& sourceFile : conf.GetSourceFiles())
|
||||||
FileUtils::GetAllFiles(path,files);
|
|
||||||
const std::vector<std::string>& excludeSources = conf.GetSettingVectorString(ConfigSetting::ExcludeSource);
|
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
std::string filename = it->substr(path.length());
|
if (FileUtils::FileExists(conf.GetConfigPath() / sourceFile))
|
||||||
if(IsSourceFile(filename))
|
cppFiles.emplace(sourceFile);
|
||||||
{
|
else
|
||||||
std::string sourceFile =conf.GetSettingString(ConfigSetting::SourceDir) + filename;
|
LOG_WARNING("Source file doesn't exist: ", sourceFile);
|
||||||
auto it = std::find(excludeSources.begin(), excludeSources.end(), sourceFile);
|
|
||||||
if(it == excludeSources.end())
|
|
||||||
{
|
|
||||||
cppFiles.emplace(filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(IsHeaderFile(filename))
|
|
||||||
{
|
|
||||||
hFiles.emplace(HFile{filename,path,false});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency);
|
const std::optional<std::string>& sourceDir = conf.GetSourceDir();
|
||||||
for(size_t i = 0; i < dependencies.size(); ++i)
|
if (sourceDir.has_value())
|
||||||
{
|
{
|
||||||
GetHFiles(dependencies[i], conf.GetDependencyConfig(i), hFiles);
|
std::vector<std::string> files;
|
||||||
|
FileUtils::GetAllFiles(conf.GetConfigPath() / sourceDir.value(), files);
|
||||||
|
for (const auto& filename : files)
|
||||||
|
{
|
||||||
|
if (IsSourceFile(filename))
|
||||||
|
{
|
||||||
|
std::filesystem::path filepath = std::filesystem::relative(filename, "./");
|
||||||
|
auto it = std::find(excludeSources.begin(), excludeSources.end(), filepath.string());
|
||||||
|
if (it == excludeSources.end())
|
||||||
|
{
|
||||||
|
cppFiles.emplace(filepath.string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (IsHeaderFile(filename))
|
||||||
|
{
|
||||||
|
std::filesystem::path path = std::filesystem::relative(filename, sourceDir.value());
|
||||||
|
hFiles.emplace(HFile{path.string(), sourceDir.value(), false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& includePath : conf.GetIncludeDirs())
|
||||||
|
{
|
||||||
|
std::vector<std::string> files;
|
||||||
|
FileUtils::GetAllFiles(includePath, files);
|
||||||
|
for (const auto& file : files)
|
||||||
|
{
|
||||||
|
std::filesystem::path path = std::filesystem::relative(file, includePath);
|
||||||
|
if (IsHeaderFile(path.string()))
|
||||||
|
{
|
||||||
|
hFiles.emplace(HFile{path.string(), includePath, false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const std::vector<Dependency>& dependencies = conf.GetDependencies();
|
||||||
|
for (size_t i = 0; i < dependencies.size(); ++i)
|
||||||
|
{
|
||||||
|
GetHFiles(conf.GetDependencyConfig(dependencies[i].path), hFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Utils::GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::set<HFile>& hFiles)
|
void Utils::GetHFiles(ConfigFile& conf, std::set<HFile>& hFiles)
|
||||||
{
|
{
|
||||||
// TODO: Fix so that cyclic dependencies doesn't crash the tool.
|
// TODO: Fix so that cyclic dependencies doesn't crash the tool.
|
||||||
// Cyclic dependencies probably shouldn't exist.
|
// Cyclic dependencies probably shouldn't exist.
|
||||||
// so just warn the user that it does and terminate.
|
// so just warn the user that it does and terminate.
|
||||||
std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency);
|
const std::vector<Dependency>& dependencies = conf.GetDependencies();
|
||||||
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);
|
std::filesystem::path dependencyConfigPath =
|
||||||
|
std::filesystem::canonical(conf.GetConfigPath() / dependencies[i].path);
|
||||||
|
GetHFiles(conf.GetDependencyConfig(dependencyConfigPath), hFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::optional<std::string>& sourceDir = conf.GetSourceDir();
|
||||||
|
if (!sourceDir.has_value())
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
std::string depSrcDir = dependencyDir + conf.GetSettingString(ConfigSetting::SourceDir);
|
std::string depSrcDir = conf.GetConfigPath() / sourceDir.value();
|
||||||
FileUtils::GetAllFiles(depSrcDir, files);
|
FileUtils::GetAllFiles(depSrcDir, files);
|
||||||
for(auto it = files.begin(); it!=files.end();++it)
|
for (auto it = files.begin(); it != files.end(); ++it)
|
||||||
{
|
{
|
||||||
if(IsHeaderFile(*it))
|
if (IsHeaderFile(*it))
|
||||||
{
|
{
|
||||||
std::string filename = it->substr(depSrcDir.length());
|
std::string filename = it->substr(depSrcDir.length());
|
||||||
hFiles.emplace(HFile{filename, depSrcDir, conf.GetSettingBool(ConfigSetting::GenerateHFile) && filename == conf.GetSettingString(ConfigSetting::HFileName)});
|
auto it = hFiles.find({filename, "", false});
|
||||||
|
if (it != hFiles.end())
|
||||||
|
{
|
||||||
|
if (filename == conf.GetHFileName() && !it->isProjectHFile)
|
||||||
|
{
|
||||||
|
HFile hfile = *it;
|
||||||
|
hfile.isProjectHFile = true;
|
||||||
|
hFiles.erase(it);
|
||||||
|
hFiles.emplace(hfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hFiles.emplace(HFile{filename, depSrcDir, conf.IsGenerateHFile() && filename == conf.GetHFileName()});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Utils::IsWhiteSpace(char c)
|
bool Utils::IsWhiteSpace(char c)
|
||||||
{
|
{
|
||||||
return c == '\n' || c == '\t' || c == '\r' || c == ' ' || c == '\t';
|
return c == '\n' || c == '\t' || c == '\r' || c == ' ' || c == '\t';
|
||||||
@@ -135,9 +212,9 @@ bool Utils::IsLetter(char c)
|
|||||||
|
|
||||||
bool Utils::IsWord(const std::string& string)
|
bool Utils::IsWord(const std::string& string)
|
||||||
{
|
{
|
||||||
for(auto it{string.begin()}; it != string.end();++it)
|
for (auto it{string.begin()}; it != string.end(); ++it)
|
||||||
{
|
{
|
||||||
if(!IsLetter(*it))
|
if (!IsLetter(*it))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+18
-6
@@ -1,25 +1,33 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <iostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
struct HFile
|
struct HFile
|
||||||
{
|
{
|
||||||
std::string filename;
|
std::string filename;
|
||||||
std::string directory;
|
|
||||||
bool isProjectHFile;
|
bool isProjectHFile;
|
||||||
|
|
||||||
std::string filepath;
|
std::filesystem::path filepath;
|
||||||
|
|
||||||
HFile(const std::string& filename, const std::string& directory, bool isProjectHFile)
|
HFile(const std::string& filename, const std::string& directory, bool isProjectHFile)
|
||||||
: filename{filename}, directory{directory}, isProjectHFile{isProjectHFile}, filepath{directory+filename}
|
: filename{filename},
|
||||||
{}
|
isProjectHFile{isProjectHFile},
|
||||||
|
filepath{directory + filename}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
friend bool operator<(const HFile& h1, const HFile& h2)
|
friend bool operator<(const HFile& h1, const HFile& h2)
|
||||||
{
|
{
|
||||||
return h1.filename < h2.filename;
|
return h1.filename < h2.filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream& ostream, const HFile& hFile)
|
||||||
|
{
|
||||||
|
return ostream << "filename: " << hFile.filename << "\tfilepath: " << hFile.filepath.string();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfigFile;
|
class ConfigFile;
|
||||||
@@ -28,10 +36,14 @@ struct Utils
|
|||||||
{
|
{
|
||||||
static bool IsSourceFile(const std::string& filepath);
|
static bool IsSourceFile(const std::string& filepath);
|
||||||
static bool IsHeaderFile(const std::string& filepath);
|
static bool IsHeaderFile(const std::string& filepath);
|
||||||
|
|
||||||
static std::string CommonPrefix(const std::string& s1, const std::string& s2);
|
static std::string CommonPrefix(const std::string& s1, const std::string& s2);
|
||||||
|
|
||||||
|
static bool StartsWith(const std::string& str, const std::string& prefix);
|
||||||
|
static void Replace(std::string& str, const std::string& from, const std::string& to);
|
||||||
static void GetCppFiles(ConfigFile& conf, std::set<std::string>& cppFiles);
|
static void GetCppFiles(ConfigFile& conf, std::set<std::string>& cppFiles);
|
||||||
static void GetCppAndHFiles(ConfigFile& conf, std::set<HFile>& hFiles, std::set<std::string>& cppFiles);
|
static void GetCppAndHFiles(ConfigFile& conf, std::set<HFile>& hFiles, std::set<std::string>& cppFiles);
|
||||||
static void GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::set<HFile>& hFiles);
|
static void GetHFiles(ConfigFile& conf, std::set<HFile>& hFiles);
|
||||||
|
|
||||||
// Used for parsing xml
|
// Used for parsing xml
|
||||||
static bool IsWhiteSpace(char c);
|
static bool IsWhiteSpace(char c);
|
||||||
|
|||||||
@@ -2,41 +2,43 @@
|
|||||||
|
|
||||||
const std::string CONFIG_FILENAME_CONF = "makegen.conf";
|
const std::string CONFIG_FILENAME_CONF = "makegen.conf";
|
||||||
|
|
||||||
#include "../ConfigFile.h"
|
|
||||||
#include "../FileUtils.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "../xml/XMLObject.h"
|
||||||
|
|
||||||
#define FLAG_NONE 0
|
#define FLAG_NONE 0
|
||||||
#define FLAG_VECTOR 1
|
#define FLAG_VECTOR 1
|
||||||
#define FLAG_STRING 2
|
#define FLAG_STRING 2
|
||||||
#define FLAG_BOOL 3
|
#define FLAG_BOOL 3
|
||||||
|
|
||||||
ConfigFileConf::ConfigFileConf()
|
ConfigFileConf::ConfigFileConf()
|
||||||
: outputdir("bin/"), srcdir("src/"), outputname(""), projectname(FileUtils::GetCurrentDirectory()), hFile(""), executable(true), shared(true), generateHFile(false)
|
: outputdir("bin/Release"),
|
||||||
|
srcdir("src/"),
|
||||||
|
outputname(""),
|
||||||
|
projectname(std::filesystem::current_path().filename()),
|
||||||
|
hFile(""),
|
||||||
|
executable(true),
|
||||||
|
shared(true),
|
||||||
|
generateHFile(false)
|
||||||
{
|
{
|
||||||
// Converts project name (current directory) to lowercase
|
// Converts project name (current directory) to lowercase
|
||||||
// and replace whitespace with underscore
|
// and replace whitespace with underscore
|
||||||
std::transform(
|
std::transform(projectname.begin(),
|
||||||
projectname.begin(),
|
projectname.end(),
|
||||||
projectname.end(),
|
std::back_inserter(outputname),
|
||||||
std::back_inserter(outputname),
|
[](unsigned char c)
|
||||||
[](unsigned char c)
|
{
|
||||||
{
|
if (c == ' ')
|
||||||
if(c == ' ')
|
return '_';
|
||||||
return '_';
|
return (char)std::tolower(c);
|
||||||
return (char)std::tolower(c);
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// Removes all other characters
|
// Removes all other characters
|
||||||
std::remove_if(
|
outputdir.erase(std::remove_if(
|
||||||
outputdir.begin(),
|
outputdir.begin(), outputdir.end(), [](unsigned char c) { return (c < 'a' || c > 'z') && c != '_'; }));
|
||||||
outputdir.end(),
|
|
||||||
[](unsigned char c)
|
|
||||||
{
|
|
||||||
return (c < 'a' || c > 'z') && c != '_';
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add suffix
|
// Add suffix
|
||||||
outputname += ".out";
|
outputname += ".out";
|
||||||
@@ -57,11 +59,10 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
|
|||||||
std::ifstream file(filepath + CONFIG_FILENAME_CONF);
|
std::ifstream file(filepath + CONFIG_FILENAME_CONF);
|
||||||
std::string line;
|
std::string line;
|
||||||
|
|
||||||
if(file.is_open())
|
if (file.is_open())
|
||||||
{
|
{
|
||||||
// config name, { pointer to memory, isDirectory}
|
// config name, { pointer to memory, isDirectory}
|
||||||
std::map<std::string, std::pair<std::string*, bool>> strings =
|
std::map<std::string, std::pair<std::string*, bool>> strings = {
|
||||||
{
|
|
||||||
{"#srcdir", {&conf.srcdir, true}},
|
{"#srcdir", {&conf.srcdir, true}},
|
||||||
{"#outputdir", {&conf.outputdir, true}},
|
{"#outputdir", {&conf.outputdir, true}},
|
||||||
{"#outputname", {&conf.outputname, false}},
|
{"#outputname", {&conf.outputname, false}},
|
||||||
@@ -70,33 +71,32 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
|
|||||||
};
|
};
|
||||||
|
|
||||||
// config name, { pointer to memory, isDirectory}
|
// config name, { pointer to memory, isDirectory}
|
||||||
std::map<std::string, std::pair<std::vector<std::string>*, bool>> vectors =
|
std::map<std::string, std::pair<std::vector<std::string>*, bool>> vectors = {
|
||||||
{
|
|
||||||
{"#libs", {&conf.libs, false}},
|
{"#libs", {&conf.libs, false}},
|
||||||
{"#libdirs", {&conf.libdirs, true}},
|
{"#libdirs", {&conf.libdirs, true}},
|
||||||
{"#includedirs", {&conf.includedirs, true}},
|
{"#includedirs", {&conf.includedirs, true}},
|
||||||
{"#compileflags", {&conf.flags, false}},
|
{"#compileflags", {&conf.flags, false}},
|
||||||
{"#defines", {&conf.defines, false}},
|
{"#defines", {&conf.defines, false}},
|
||||||
{"#dependencies", {&conf.dependencies, true}},
|
{"#dependencies", {&conf.dependencies, true}},
|
||||||
|
{"#sourcefiles", {&conf.sourceFiles, false}},
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<std::string, bool*> booleans =
|
std::map<std::string, bool*> booleans = {
|
||||||
{
|
|
||||||
{"#executable", &conf.executable},
|
{"#executable", &conf.executable},
|
||||||
{"#shared", &conf.shared},
|
{"#shared", &conf.shared},
|
||||||
{"#generatehfile", &conf.generateHFile},
|
{"#generatehfile", &conf.generateHFile},
|
||||||
};
|
};
|
||||||
|
|
||||||
while(std::getline(file,line))
|
while (std::getline(file, line))
|
||||||
{
|
{
|
||||||
if(line == "")
|
if (line == "")
|
||||||
continue;
|
continue;
|
||||||
if(line[0]=='#')
|
if (line[0] == '#')
|
||||||
{
|
{
|
||||||
// The format is a bit wacky, but it is this way since we do not want
|
// The format is a bit wacky, but it is this way since we do not want
|
||||||
// to use map::find for all maps. This way we gain some optimization.
|
// to use map::find for all maps. This way we gain some optimization.
|
||||||
auto&& itStr{strings.find(line)};
|
auto&& itStr{strings.find(line)};
|
||||||
if(itStr != strings.end())
|
if (itStr != strings.end())
|
||||||
{
|
{
|
||||||
s = itStr->second.first;
|
s = itStr->second.first;
|
||||||
isDirectory = itStr->second.second;
|
isDirectory = itStr->second.second;
|
||||||
@@ -105,7 +105,7 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto&& itVec{vectors.find(line)};
|
auto&& itVec{vectors.find(line)};
|
||||||
if(itVec != vectors.end())
|
if (itVec != vectors.end())
|
||||||
{
|
{
|
||||||
vec = itVec->second.first;
|
vec = itVec->second.first;
|
||||||
isDirectory = itVec->second.second;
|
isDirectory = itVec->second.second;
|
||||||
@@ -114,7 +114,7 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto&& itBool{booleans.find(line)};
|
auto&& itBool{booleans.find(line)};
|
||||||
if(itBool != booleans.end())
|
if (itBool != booleans.end())
|
||||||
{
|
{
|
||||||
b = itBool->second;
|
b = itBool->second;
|
||||||
loadFlag = FLAG_BOOL;
|
loadFlag = FLAG_BOOL;
|
||||||
@@ -129,23 +129,24 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(loadFlag == FLAG_STRING)
|
if (loadFlag == FLAG_STRING)
|
||||||
{
|
{
|
||||||
if(isDirectory && line[line.size()-1] != '/')
|
if (isDirectory && line[line.size() - 1] != '/')
|
||||||
line += '/';
|
line += '/';
|
||||||
*s = line;
|
*s = line;
|
||||||
}
|
}
|
||||||
else if(loadFlag == FLAG_VECTOR)
|
else if (loadFlag == FLAG_VECTOR)
|
||||||
{
|
{
|
||||||
if(isDirectory && line[line.size()-1] != '/')
|
if (isDirectory && line[line.size() - 1] != '/')
|
||||||
{;
|
{
|
||||||
|
;
|
||||||
line += '/';
|
line += '/';
|
||||||
}
|
}
|
||||||
vec->push_back(line);
|
vec->push_back(line);
|
||||||
}
|
}
|
||||||
else if(loadFlag == FLAG_BOOL)
|
else if (loadFlag == FLAG_BOOL)
|
||||||
{
|
{
|
||||||
if(line == "true")
|
if (line == "true")
|
||||||
*b = true;
|
*b = true;
|
||||||
else
|
else
|
||||||
*b = false;
|
*b = false;
|
||||||
@@ -155,13 +156,13 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
|
|||||||
|
|
||||||
LOG_INFO("------ COULDN\'T FIND makegen.xml. BUT FOUND OLD makegen.conf.");
|
LOG_INFO("------ COULDN\'T FIND makegen.xml. BUT FOUND OLD makegen.conf.");
|
||||||
LOG_INFO("------ GENERATING NEW CONFIGURATION FILE");
|
LOG_INFO("------ GENERATING NEW CONFIGURATION FILE");
|
||||||
if(conf.hFile == "")
|
if (conf.hFile == "")
|
||||||
conf.hFile = conf.projectname+".h";
|
conf.hFile = conf.projectname + ".h";
|
||||||
|
|
||||||
XMLObject makegen("makegen", {}, std::map<std::string, std::vector<XMLObject>>{});
|
XMLObject makegen("makegen", {}, std::map<std::string, std::vector<XMLObject>>{});
|
||||||
|
|
||||||
// Version, target and configuration is probably going to be used in the future
|
// Version, target and configuration is probably going to be used in the future
|
||||||
makegen.AddXMLObject(XMLObject("version", {}, "v1.3.0"));
|
makegen.AddXMLObject(XMLObject("version", {}, MAKEGEN_VERSION));
|
||||||
makegen.AddXMLObject(XMLObject("target", {}, "Release"));
|
makegen.AddXMLObject(XMLObject("target", {}, "Release"));
|
||||||
|
|
||||||
XMLObject configuration("configuration", {{"name", "Release"}}, std::map<std::string, std::vector<XMLObject>>{});
|
XMLObject configuration("configuration", {{"name", "Release"}}, std::map<std::string, std::vector<XMLObject>>{});
|
||||||
@@ -170,22 +171,22 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
|
|||||||
configuration.AddXMLObject(XMLObject("srcdir", {}, conf.srcdir));
|
configuration.AddXMLObject(XMLObject("srcdir", {}, conf.srcdir));
|
||||||
configuration.AddXMLObject(XMLObject("outputdir", {}, conf.outputdir));
|
configuration.AddXMLObject(XMLObject("outputdir", {}, conf.outputdir));
|
||||||
configuration.AddXMLObject(XMLObject("hfilename", {}, conf.hFile));
|
configuration.AddXMLObject(XMLObject("hfilename", {}, conf.hFile));
|
||||||
configuration.AddXMLObject(XMLObject("outputtype", {},
|
configuration.AddXMLObject(
|
||||||
conf.executable ? "executable" : (conf.shared ? "sharedlibrary" : "staticlibrary")));
|
XMLObject("outputtype", {}, conf.executable ? "executable" : (conf.shared ? "sharedlibrary" : "staticlibrary")));
|
||||||
configuration.AddXMLObject(XMLObject("generatehfile", {}, conf.generateHFile ? "true" : "false"));
|
configuration.AddXMLObject(XMLObject("generatehfile", {}, conf.generateHFile ? "true" : "false"));
|
||||||
|
|
||||||
for(auto it = conf.libs.begin();it != conf.libs.end(); ++it)
|
for (auto it = conf.libs.begin(); it != conf.libs.end(); ++it) configuration.AddXMLObject({"library", {}, *it});
|
||||||
configuration.AddXMLObject({"library",{},*it});
|
for (auto it = conf.libdirs.begin(); it != conf.libdirs.end(); ++it)
|
||||||
for(auto it = conf.libdirs.begin();it != conf.libdirs.end(); ++it)
|
configuration.AddXMLObject({"librarydir", {}, *it});
|
||||||
configuration.AddXMLObject({"librarydir",{},*it});
|
for (auto it = conf.includedirs.begin(); it != conf.includedirs.end(); ++it)
|
||||||
for(auto it = conf.includedirs.begin();it != conf.includedirs.end(); ++it)
|
configuration.AddXMLObject({"includedir", {}, *it});
|
||||||
configuration.AddXMLObject({"includedir",{},*it});
|
for (auto it = conf.defines.begin(); it != conf.defines.end(); ++it)
|
||||||
for(auto it = conf.defines.begin();it != conf.defines.end(); ++it)
|
configuration.AddXMLObject({"define", {}, *it});
|
||||||
configuration.AddXMLObject({"define",{},*it});
|
for (auto it = conf.flags.begin(); it != conf.flags.end(); ++it) configuration.AddXMLObject({"cflag", {}, *it});
|
||||||
for(auto it = conf.flags.begin();it != conf.flags.end(); ++it)
|
for (auto it = conf.dependencies.begin(); it != conf.dependencies.end(); ++it)
|
||||||
configuration.AddXMLObject({"cflag",{},*it});
|
configuration.AddXMLObject({"dependency", {}, *it});
|
||||||
for(auto it = conf.dependencies.begin();it != conf.dependencies.end(); ++it)
|
for (auto it = conf.sourceFiles.begin(); it != conf.sourceFiles.end(); ++it)
|
||||||
configuration.AddXMLObject({"dependency",{},*it});
|
configuration.AddXMLObject({"sourcefile", {}, *it});
|
||||||
|
|
||||||
makegen.AddXMLObject(configuration);
|
makegen.AddXMLObject(configuration);
|
||||||
std::ofstream xmlFile(conf.configPath + "makegen.xml");
|
std::ofstream xmlFile(conf.configPath + "makegen.xml");
|
||||||
|
|||||||
@@ -9,26 +9,29 @@ class ConfigFile;
|
|||||||
|
|
||||||
class ConfigFileConf
|
class ConfigFileConf
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string configPath;
|
std::string configPath;
|
||||||
std::vector<std::string> libs;
|
std::vector<std::string> libs;
|
||||||
std::vector<std::string> libdirs;
|
std::vector<std::string> libdirs;
|
||||||
std::vector<std::string> includedirs;
|
std::vector<std::string> includedirs;
|
||||||
std::vector<std::string> defines;
|
std::vector<std::string> defines;
|
||||||
std::vector<std::string> flags;
|
std::vector<std::string> flags;
|
||||||
std::vector<std::string> dependencies;
|
std::vector<std::string> dependencies;
|
||||||
|
std::vector<std::string> sourceFiles;
|
||||||
|
|
||||||
std::string outputdir;
|
std::string outputdir;
|
||||||
std::string srcdir;
|
std::string srcdir;
|
||||||
std::string outputname;
|
std::string outputname;
|
||||||
std::string projectname;
|
std::string projectname;
|
||||||
std::string hFile;
|
std::string hFile;
|
||||||
bool executable;
|
bool executable;
|
||||||
bool shared;
|
bool shared;
|
||||||
bool generateHFile;
|
bool generateHFile;
|
||||||
public:
|
|
||||||
ConfigFileConf();
|
|
||||||
|
|
||||||
static void CreateXMLFile(const std::string& filename);
|
public:
|
||||||
private:
|
ConfigFileConf();
|
||||||
|
|
||||||
|
static void CreateXMLFile(const std::string& filename);
|
||||||
|
|
||||||
|
private:
|
||||||
};
|
};
|
||||||
|
|||||||
Executable → Regular
+138
-94
@@ -1,22 +1,27 @@
|
|||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "CompileFlags.h"
|
||||||
#include "ConfigCLI.h"
|
#include "ConfigCLI.h"
|
||||||
#include "ConfigFile.h"
|
#include "ConfigFile.h"
|
||||||
#include "FileUtils.h"
|
#include "FlagData.h"
|
||||||
#include "HFileGen.h"
|
#include "HFileGen.h"
|
||||||
#include "Makefile.h"
|
#include "Makefile.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
#include "Utils.h"
|
||||||
#include <cmath>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#define RETURN_IF(x, b) \
|
#define RETURN_IF(x, b) \
|
||||||
if(x)\
|
if (x) \
|
||||||
return b;
|
return b;
|
||||||
|
|
||||||
void PrintHelp()
|
void PrintHelp()
|
||||||
{
|
{
|
||||||
LOG_INFO("MakeGen ", MAKEGEN_VERSION);
|
LOG_INFO("MakeGen ", MAKEGEN_VERSION);
|
||||||
LOG_INFO(1+(char*)R"(
|
LOG_INFO(1 + (char*)R"(
|
||||||
|
|
||||||
MakeGen is a utility tool to generate and run Makefiles in a simple manner.
|
MakeGen is a utility tool to generate and run Makefiles in a simple manner.
|
||||||
By default it always compiles code with parallell jobs.
|
By default it always compiles code with parallell jobs.
|
||||||
@@ -24,175 +29,214 @@ By default it always compiles code with parallell jobs.
|
|||||||
Usage: makegen [options]
|
Usage: makegen [options]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-h, --help Displays this information
|
-h, --help Displays this information
|
||||||
-v, --version Displays the version of this program
|
-v, --version Displays the version of this program
|
||||||
-m,-a, make, all Generates a Makefile and runs
|
-m,-a, make, all Generates a Makefile and runs
|
||||||
make all
|
make all
|
||||||
-i, install Generates a Makefile and runs
|
-i, install Generates a Makefile and runs
|
||||||
make all && make install
|
make all && make install
|
||||||
-c, clean Generates a Makefile and runs
|
-c, clean Generates a Makefile and runs
|
||||||
make clean
|
make clean
|
||||||
-r, rebuild Generates a Makefile and runs
|
-r, rebuild Generates a Makefile and runs
|
||||||
make clean && make all
|
make clean && make all
|
||||||
-e, run, execute Generates a Makefile and runs
|
-e, run, execute Generates a Makefile and runs
|
||||||
make all && make run
|
make all && make run
|
||||||
-s, single Runs additional makegen options as single thread
|
-s, single Runs additional makegen options as single thread
|
||||||
(no --jobs=X flag)
|
(no --jobs=X flag)
|
||||||
--simple Creates a simple Makefile without include dependencies
|
--simple Creates a simple Makefile without include dependencies
|
||||||
(no --jobs=X flag)
|
--target=<target> Run the makegen.xml file with the specified target
|
||||||
|
gcf, generate-compile-flags
|
||||||
|
Generates a Makefile and runs
|
||||||
|
|
||||||
If no option is given it will run \"make all\"
|
If no option is given it will run "make all"
|
||||||
|
|
||||||
If multiple make options are given it will run in the following order:
|
If multiple make options are given it will run in the following order:
|
||||||
clean all install run, rebuild will be translated to \"clean make\")");
|
clean all install run, rebuild will be translated to "clean make")");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenMakefile(ConfigFile& conf, unsigned int flags)
|
void GenMakefile(ConfigFile& conf, unsigned int flags)
|
||||||
{
|
{
|
||||||
if(conf.GetSettingBool(ConfigSetting::GenerateHFile))
|
if (conf.IsGenerateHFile())
|
||||||
HFileGen::Create(conf);
|
HFileGen::Create(conf);
|
||||||
Makefile::Save(conf, flags);
|
Makefile::Save(conf, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ReadFlags(int argc, char** argv)
|
FlagData ReadFlags(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if(argc >= 2 && std::string(argv[1]) == "conf")
|
if (argc >= 2 && std::string(argv[1]) == "conf")
|
||||||
return FLAG_CONFIG;
|
return FlagData{FLAG_CONFIG};
|
||||||
unsigned int flags = 0;
|
FlagData flagData{};
|
||||||
bool make = true;
|
bool make = true;
|
||||||
for(int i = 1;i<argc;i++)
|
for (int i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
if(strlen(argv[i]) > 1)
|
if (strlen(argv[i]) > 1)
|
||||||
{
|
{
|
||||||
std::string flag(argv[i]);
|
std::string flag(argv[i]);
|
||||||
if(flag == "-h" || flag == "--help")
|
if (flag == "-h" || flag == "--help")
|
||||||
{
|
{
|
||||||
flags |= FLAG_HELP;
|
flagData.flags |= FLAG_HELP;
|
||||||
}
|
}
|
||||||
else if(flag == "-v" || flag == "--version")
|
else if (flag == "-v" || flag == "--version")
|
||||||
{
|
{
|
||||||
flags |= FLAG_VERSION;
|
flagData.flags |= FLAG_VERSION;
|
||||||
}
|
}
|
||||||
else if(flag == "make" || flag == "-m" || flag == "all" || flag == "-a")
|
else if (flag == "make" || flag == "-m" || flag == "all" || flag == "-a")
|
||||||
{
|
{
|
||||||
flags |= FLAG_MAKE;
|
flagData.flags |= FLAG_MAKE;
|
||||||
}
|
}
|
||||||
else if(flag == "clean" || flag == "-c")
|
else if (flag == "clean" || flag == "-c")
|
||||||
{
|
{
|
||||||
make = false;
|
make = false;
|
||||||
flags |= FLAG_CLEAN;
|
flagData.flags |= FLAG_CLEAN;
|
||||||
}
|
}
|
||||||
else if(flag == "run" || flag == "-e" || flag == "execute")
|
else if (flag == "run" || flag == "-e" || flag == "execute")
|
||||||
{
|
{
|
||||||
flags |= FLAG_RUN;
|
flagData.flags |= FLAG_RUN;
|
||||||
}
|
}
|
||||||
else if(flag == "install" || flag == "-i")
|
else if (flag == "install" || flag == "-i")
|
||||||
{
|
{
|
||||||
flags |= FLAG_INSTALL;
|
flagData.flags |= FLAG_INSTALL;
|
||||||
}
|
}
|
||||||
else if(flag == "rebuild" || flag == "-r")
|
else if (flag == "rebuild" || flag == "-r")
|
||||||
{
|
{
|
||||||
flags |= FLAG_CLEAN;
|
flagData.flags |= FLAG_CLEAN;
|
||||||
flags |= FLAG_MAKE;
|
flagData.flags |= FLAG_MAKE;
|
||||||
}
|
}
|
||||||
else if(flag == "single" || flag == "-s")
|
else if (flag == "single" || flag == "-s")
|
||||||
{
|
{
|
||||||
flags |= FLAG_SINGLE_THREAD;
|
flagData.flags |= FLAG_SINGLE_THREAD;
|
||||||
}
|
}
|
||||||
else if(flag == "--simple")
|
else if (flag == "gcf" || flag == "generate-compile-flags")
|
||||||
{
|
{
|
||||||
flags |= FLAG_SIMPLE;
|
flagData.flags |= FLAG_GEN_COMP_FLAGS;
|
||||||
}
|
}
|
||||||
else if(flag != "")
|
else if (flag == "--simple")
|
||||||
|
{
|
||||||
|
flagData.flags |= FLAG_SIMPLE;
|
||||||
|
}
|
||||||
|
else if (Utils::StartsWith(flag, "--target="))
|
||||||
|
{
|
||||||
|
std::string prefix("--target=");
|
||||||
|
if (flag.size() < prefix.size() + 1)
|
||||||
|
{
|
||||||
|
LOG_ERROR("No target specified in --target=<target>");
|
||||||
|
return FlagData{FLAG_HELP};
|
||||||
|
}
|
||||||
|
flagData.flags |= FLAG_TARGET;
|
||||||
|
flagData.target = flag.substr(std::string("--target=").size());
|
||||||
|
}
|
||||||
|
else if (flag != "")
|
||||||
{
|
{
|
||||||
LOG_ERROR("Unknown argument ", flag);
|
LOG_ERROR("Unknown argument ", flag);
|
||||||
return FLAG_HELP;
|
return FlagData{FLAG_HELP};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(make)
|
if (make)
|
||||||
flags |= FLAG_MAKE;
|
flagData.flags |= FLAG_MAKE;
|
||||||
return flags;
|
return flagData;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RunMake(const std::string& filepath, unsigned int flags, ConfigFile& conf)
|
bool RunMake(const std::string& filepath, unsigned int flags, ConfigFile& conf)
|
||||||
{
|
{
|
||||||
std::string make = "make --no-print-directory -C " + filepath;
|
std::string make = "make --no-print-directory -C " + filepath;
|
||||||
if(!(flags & FLAG_SINGLE_THREAD))
|
if (!(flags & FLAG_SINGLE_THREAD))
|
||||||
make += " -j" + std::to_string(std::thread::hardware_concurrency()) + " ";
|
make += " -j" + std::to_string(std::thread::hardware_concurrency()) + " ";
|
||||||
if(flags & FLAG_CLEAN)
|
if (flags & FLAG_CLEAN)
|
||||||
{
|
{
|
||||||
RETURN_IF(system(std::string(make + " clean").c_str()) != 0, false);
|
RETURN_IF(system(std::string(make + " clean").c_str()) != 0, false);
|
||||||
}
|
}
|
||||||
if(flags & FLAG_MAKE)
|
if (flags & FLAG_MAKE)
|
||||||
{
|
{
|
||||||
RETURN_IF(system(std::string(make + " all").c_str()) != 0, false);
|
RETURN_IF(system(std::string(make + " all").c_str()) != 0, false);
|
||||||
}
|
}
|
||||||
if(flags & FLAG_INSTALL)
|
if (flags & FLAG_INSTALL)
|
||||||
{
|
{
|
||||||
RETURN_IF(system(std::string(make + " install").c_str()) != 0, false);
|
RETURN_IF(system(std::string(make + " install").c_str()) != 0, false);
|
||||||
}
|
}
|
||||||
if(flags & FLAG_RUN && conf.GetSettingString(ConfigSetting::OutputType) == "executable")
|
if (flags & FLAG_RUN && conf.GetOutputType() == "executable")
|
||||||
{
|
{
|
||||||
RETURN_IF(system(std::string(make + " run").c_str()) != 0, false);
|
RETURN_IF(system(std::string(make + " run").c_str()) != 0, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MakeGen(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);
|
const std::vector<Dependency>& dependencies = conf.GetDependencies();
|
||||||
for(size_t i = 0;i<dependencies.size();++i)
|
for (size_t i = 0; i < dependencies.size(); ++i)
|
||||||
{
|
{
|
||||||
bool success = MakeGen(dependencies[i], flags, conf.GetDependencyConfig(i));
|
std::filesystem::path currentPath = std::filesystem::current_path();
|
||||||
if(!success)
|
std::filesystem::current_path(dependencies[i].path);
|
||||||
return success;
|
FlagData dependencyFlagData = flagData;
|
||||||
|
dependencyFlagData.target = dependencies[i].target;
|
||||||
|
|
||||||
|
std::optional<ConfigFile> conf = ConfigFile::GetConfigFile("./", dependencyFlagData);
|
||||||
|
if (conf)
|
||||||
|
{
|
||||||
|
bool success = MakeGen("./", dependencyFlagData, conf.value());
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
std::filesystem::current_path(currentPath);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::filesystem::current_path(currentPath);
|
||||||
}
|
}
|
||||||
LOG_INFO("-----------------------------------");
|
LOG_INFO("-----------------------------------");
|
||||||
LOG_INFO("Building ", conf.GetSettingString(ConfigSetting::ProjectName));
|
LOG_INFO("Building ", conf.GetProjectName());
|
||||||
LOG_INFO("Generating Makefile...");
|
LOG_INFO("Generating Makefile...");
|
||||||
Timer timer;
|
Timer timer;
|
||||||
GenMakefile(conf, flags);
|
GenMakefile(conf, flagData.flags);
|
||||||
LOG_INFO("Took ", round(timer.Elapsed()*1000.0)/1000.0,"s");
|
LOG_INFO("Took ", round(timer.Elapsed() * 1000.0) / 1000.0, "s");
|
||||||
LOG_INFO("Running Makefile...");
|
LOG_INFO("Running Makefile...");
|
||||||
|
|
||||||
std::string outputPath = conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::OutputDir);
|
return RunMake(filepath, flagData.flags, conf);
|
||||||
if(!FileUtils::HasPath(outputPath))
|
|
||||||
{
|
|
||||||
FileUtils::CreateDirectory(outputPath);
|
|
||||||
std::string intermediatePath = outputPath + "intermediates";
|
|
||||||
if(!FileUtils::HasPath(intermediatePath ))
|
|
||||||
FileUtils::CreateDirectory(intermediatePath );
|
|
||||||
}
|
|
||||||
return RunMake(filepath, flags, conf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int Run(int argc, char** argv)
|
||||||
{
|
{
|
||||||
unsigned int flags = ReadFlags(argc,argv);
|
FlagData flagData = ReadFlags(argc, argv);
|
||||||
if(flags & FLAG_HELP)
|
if (flagData.flags & FLAG_HELP)
|
||||||
{
|
{
|
||||||
PrintHelp();
|
PrintHelp();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(flags & FLAG_VERSION)
|
if (flagData.flags & FLAG_VERSION)
|
||||||
{
|
{
|
||||||
LOG_INFO("MakeGen ",MAKEGEN_VERSION);
|
LOG_INFO("MakeGen ", MAKEGEN_VERSION);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(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();
|
auto conf = ConfigFile::GetConfigFile("./", flagData);
|
||||||
if(conf)
|
if (!conf.has_value())
|
||||||
{
|
|
||||||
bool success = MakeGen("./", flags, *conf);
|
|
||||||
return success ? 0 : 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
LOG_ERROR("Couldn\'t load config file");
|
LOG_ERROR("Couldn\'t load config file");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flagData.flags & FLAG_GEN_COMP_FLAGS)
|
||||||
|
{
|
||||||
|
CompileFlags::Save(conf.value());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = MakeGen("./", flagData, conf.value());
|
||||||
|
return success ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Run(argc, argv);
|
||||||
|
}
|
||||||
|
catch (const AssertException& exception)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -1,28 +1,28 @@
|
|||||||
#include "XML.h"
|
#include "XML.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#include "XMLException.h"
|
#include "XMLException.h"
|
||||||
|
|
||||||
#include <fstream>
|
XMLObject XML::FromString(const std::string& string, const std::string& filename = "")
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
XMLObject XML::FromString(const std::string& string, const std::string& filename="")
|
|
||||||
{
|
{
|
||||||
int startLine = 1;
|
int startLine = 1;
|
||||||
int startPos = 0;
|
int startPos = 0;
|
||||||
// Remove version tag.
|
// Remove version tag.
|
||||||
if(string.find("<?") != std::string::npos)
|
if (string.find("<?") != std::string::npos)
|
||||||
{
|
{
|
||||||
startPos = string.find("?>") + 3;
|
startPos = string.find("?>") + 3;
|
||||||
startLine = std::count(string.begin(), string.begin()+startPos, '\n') + 1;
|
startLine = std::count(string.begin(), string.begin() + startPos, '\n') + 1;
|
||||||
}
|
}
|
||||||
return XMLObject(string, startPos, startLine,filename);
|
return XMLObject(string, startPos, startLine, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLObject XML::FromFile(const std::string& filename)
|
XMLObject XML::FromFile(const std::string& filename)
|
||||||
{
|
{
|
||||||
std::ifstream file(filename, std::ios::binary | std::ios::ate);
|
std::ifstream file(filename, std::ios::binary | std::ios::ate);
|
||||||
if(!file)
|
if (!file)
|
||||||
throw XMLException("Could not read file \""+filename+"\"");
|
throw XMLException("Could not read file \"" + filename + "\"");
|
||||||
std::streamsize size = file.tellg();
|
std::streamsize size = file.tellg();
|
||||||
file.seekg(0, std::ios::beg);
|
file.seekg(0, std::ios::beg);
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
|
|||||||
+19
-13
@@ -1,22 +1,28 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "XMLObject.h"
|
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "XMLObject.h"
|
||||||
|
|
||||||
class XMLException : public std::exception
|
class XMLException : public std::exception
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string m_message;
|
std::string m_message;
|
||||||
public:
|
|
||||||
explicit XMLException(const std::string& message) : m_message("XMLException: " + message) {}
|
|
||||||
explicit XMLException(const std::string& message, const XMLObject::XMLLoadData& data)
|
|
||||||
: m_message("XMLException(" + data.file + ":" + std::to_string(data.line) + "): " + message)
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual const char* what() const throw()
|
public:
|
||||||
{
|
explicit XMLException(const std::string& message)
|
||||||
return m_message.c_str();
|
: m_message("XMLException: " + message)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit XMLException(const std::string& message, const XMLObject::XMLLoadData& data)
|
||||||
|
: m_message("XMLException(" + data.file + ":" + std::to_string(data.line) + "): " + message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char* what() const throw()
|
||||||
|
{
|
||||||
|
return m_message.c_str();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+84
-60
@@ -1,9 +1,9 @@
|
|||||||
#include "XMLObject.h"
|
#include "XMLObject.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "../Utils.h"
|
#include "../Utils.h"
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include "XMLException.h"
|
#include "XMLException.h"
|
||||||
|
|
||||||
XMLObject::XMLObject(const std::string& string)
|
XMLObject::XMLObject(const std::string& string)
|
||||||
@@ -11,7 +11,7 @@ XMLObject::XMLObject(const std::string& string)
|
|||||||
int pos = 0;
|
int pos = 0;
|
||||||
int line = 1;
|
int line = 1;
|
||||||
XMLLoadData data{pos, line, ""};
|
XMLLoadData data{pos, line, ""};
|
||||||
if(!ReadHead(string, data))
|
if (!ReadHead(string, data))
|
||||||
ReadBodyTail(string, data);
|
ReadBodyTail(string, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,16 +28,22 @@ XMLObject::XMLObject(const std::string& string, XMLLoadData& data)
|
|||||||
ReadBodyTail(string, data);
|
ReadBodyTail(string, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLObject::XMLObject(const std::string& name, const std::map<std::string, std::string>& attributes, const std::string& text)
|
XMLObject::XMLObject(const std::string& name,
|
||||||
:name(name), attributes(attributes), text(text)
|
const std::map<std::string, std::string>& attributes,
|
||||||
|
const std::string& text)
|
||||||
|
: name(name),
|
||||||
|
attributes(attributes),
|
||||||
|
text(text)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLObject::XMLObject(const std::string& name, const std::map<std::string, std::string>& attributes, const std::map<std::string,std::vector<XMLObject>>& objects)
|
XMLObject::XMLObject(const std::string& name,
|
||||||
: name(name), attributes(attributes), objects(objects)
|
const std::map<std::string, std::string>& attributes,
|
||||||
|
const std::map<std::string, std::vector<XMLObject>>& objects)
|
||||||
|
: name(name),
|
||||||
|
attributes(attributes),
|
||||||
|
objects(objects)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XMLObject::HasAttribute(const std::string& property) const
|
bool XMLObject::HasAttribute(const std::string& property) const
|
||||||
@@ -53,7 +59,7 @@ const std::string& XMLObject::GetAttribute(const std::string& property) const
|
|||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& XMLObject::GetAttribute(const std::string& property, const std::string& defaultValue) const
|
std::string XMLObject::GetAttribute(const std::string& property, const std::string& defaultValue) const
|
||||||
{
|
{
|
||||||
auto it = attributes.find(property);
|
auto it = attributes.find(property);
|
||||||
if (it == attributes.end())
|
if (it == attributes.end())
|
||||||
@@ -69,12 +75,32 @@ unsigned int XMLObject::GetObjectCount() const
|
|||||||
std::vector<XMLObject>* XMLObject::GetObjectPtr(const std::string& name)
|
std::vector<XMLObject>* XMLObject::GetObjectPtr(const std::string& name)
|
||||||
{
|
{
|
||||||
auto it = objects.find(name);
|
auto it = objects.find(name);
|
||||||
if(it == objects.end())
|
if (it == objects.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<XMLObject>& XMLObject::GetObjects(const std::string& name)
|
||||||
|
{
|
||||||
|
static std::vector<XMLObject> empty{};
|
||||||
|
auto it = objects.find(name);
|
||||||
|
if (it == objects.end())
|
||||||
|
return empty;
|
||||||
|
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<XMLObject>& XMLObject::GetObjects(const std::string& name) const
|
||||||
|
{
|
||||||
|
static std::vector<XMLObject> empty{};
|
||||||
|
auto it = objects.find(name);
|
||||||
|
if (it == objects.end())
|
||||||
|
return empty;
|
||||||
|
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
const std::map<std::string, std::vector<XMLObject>>& XMLObject::GetObjects() const
|
const std::map<std::string, std::vector<XMLObject>>& XMLObject::GetObjects() const
|
||||||
{
|
{
|
||||||
return objects;
|
return objects;
|
||||||
@@ -92,7 +118,7 @@ const std::string& XMLObject::GetText() const
|
|||||||
|
|
||||||
void XMLObject::SetName(const std::string& name)
|
void XMLObject::SetName(const std::string& name)
|
||||||
{
|
{
|
||||||
if(Utils::IsWord(name))
|
if (Utils::IsWord(name))
|
||||||
this->name = name;
|
this->name = name;
|
||||||
else
|
else
|
||||||
LOG_ERROR("XML Head can only be made up of letters");
|
LOG_ERROR("XML Head can only be made up of letters");
|
||||||
@@ -105,7 +131,7 @@ void XMLObject::SetText(const std::string& text)
|
|||||||
|
|
||||||
void XMLObject::AddAttribute(const std::string& property, const std::string& value)
|
void XMLObject::AddAttribute(const std::string& property, const std::string& value)
|
||||||
{
|
{
|
||||||
if(Utils::IsWord(property))
|
if (Utils::IsWord(property))
|
||||||
attributes.emplace(property, value);
|
attributes.emplace(property, value);
|
||||||
else
|
else
|
||||||
LOG_ERROR("XML property name can only be made up of letters");
|
LOG_ERROR("XML property name can only be made up of letters");
|
||||||
@@ -114,7 +140,7 @@ void XMLObject::AddAttribute(const std::string& property, const std::string& val
|
|||||||
void XMLObject::AddXMLObject(const XMLObject& object)
|
void XMLObject::AddXMLObject(const XMLObject& object)
|
||||||
{
|
{
|
||||||
auto it = objects.find(object.name);
|
auto it = objects.find(object.name);
|
||||||
if(it == objects.end())
|
if (it == objects.end())
|
||||||
objects.emplace(object.name, std::vector<XMLObject>{object});
|
objects.emplace(object.name, std::vector<XMLObject>{object});
|
||||||
else
|
else
|
||||||
it->second.push_back(object);
|
it->second.push_back(object);
|
||||||
@@ -123,18 +149,18 @@ void XMLObject::AddXMLObject(const XMLObject& object)
|
|||||||
bool XMLObject::RemoveXMLObject(const XMLObject& object)
|
bool XMLObject::RemoveXMLObject(const XMLObject& object)
|
||||||
{
|
{
|
||||||
auto it = objects.find(object.name);
|
auto it = objects.find(object.name);
|
||||||
if(it == objects.end())
|
if (it == objects.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool removed = false;
|
bool removed = false;
|
||||||
for(auto it2 = it->second.begin(); it2 != it->second.end();)
|
for (auto it2 = it->second.begin(); it2 != it->second.end();)
|
||||||
{
|
{
|
||||||
if(*it2 == object)
|
if (*it2 == object)
|
||||||
{
|
{
|
||||||
it2 = it->second.erase(it2);
|
it2 = it->second.erase(it2);
|
||||||
removed = true;
|
removed = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
++it2;
|
++it2;
|
||||||
}
|
}
|
||||||
return removed;
|
return removed;
|
||||||
@@ -142,7 +168,7 @@ bool XMLObject::RemoveXMLObject(const XMLObject& object)
|
|||||||
|
|
||||||
XMLObject XMLObject::GetStrippedXMLObject() const
|
XMLObject XMLObject::GetStrippedXMLObject() const
|
||||||
{
|
{
|
||||||
if(text == "")
|
if (text == "")
|
||||||
return XMLObject(name, attributes, objects);
|
return XMLObject(name, attributes, objects);
|
||||||
else
|
else
|
||||||
return XMLObject(name, attributes, text);
|
return XMLObject(name, attributes, text);
|
||||||
@@ -154,7 +180,6 @@ XMLObject XMLObject::GetStrippedXMLObject() const
|
|||||||
// //
|
// //
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
bool XMLObject::ReadHead(const std::string& string, XMLLoadData& data)
|
bool XMLObject::ReadHead(const std::string& string, XMLLoadData& data)
|
||||||
{
|
{
|
||||||
// Check if the first character is the start of and xml tag.
|
// Check if the first character is the start of and xml tag.
|
||||||
@@ -179,7 +204,8 @@ bool XMLObject::ReadHead(const std::string& string, XMLLoadData& data)
|
|||||||
data.pos++;
|
data.pos++;
|
||||||
ReadWhiteSpace(string, data);
|
ReadWhiteSpace(string, data);
|
||||||
if (string[data.pos] != '>')
|
if (string[data.pos] != '>')
|
||||||
throw XMLException((std::string("Invalid character proceeding / in opening XML Tag \"") + string[data.pos] + "\".").c_str(), data);
|
throw XMLException(
|
||||||
|
(std::string("Invalid character proceeding / in opening XML Tag \"") + string[data.pos] + "\".").c_str(), data);
|
||||||
data.pos++;
|
data.pos++;
|
||||||
// nothing more to read.
|
// nothing more to read.
|
||||||
return true;
|
return true;
|
||||||
@@ -187,7 +213,9 @@ bool XMLObject::ReadHead(const std::string& string, XMLLoadData& data)
|
|||||||
|
|
||||||
ReadWhiteSpace(string, data);
|
ReadWhiteSpace(string, data);
|
||||||
if (string[data.pos] != '>')
|
if (string[data.pos] != '>')
|
||||||
throw XMLException((std::string("Invalid character proceeding attributes in opening XML Tag \"") + string[data.pos] + "\".").c_str(), data);
|
throw XMLException(
|
||||||
|
(std::string("Invalid character proceeding attributes in opening XML Tag \"") + string[data.pos] + "\".").c_str(),
|
||||||
|
data);
|
||||||
(data.pos)++;
|
(data.pos)++;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -203,7 +231,8 @@ void XMLObject::ReadName(const std::string& string, XMLLoadData& data)
|
|||||||
ReadWhiteSpace(string, data);
|
ReadWhiteSpace(string, data);
|
||||||
if (string[data.pos] != '/' && string[data.pos] != '>' && Utils::IsWhiteSpace(string[data.pos]))
|
if (string[data.pos] != '/' && string[data.pos] != '>' && Utils::IsWhiteSpace(string[data.pos]))
|
||||||
{
|
{
|
||||||
throw XMLException((std::string("Invalid character proceeding name in XML Tag \"") + string[data.pos] + "\".").c_str(), data);
|
throw XMLException(
|
||||||
|
(std::string("Invalid character proceeding name in XML Tag \"") + string[data.pos] + "\".").c_str(), data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +259,9 @@ void XMLObject::ReadAttribute(const std::string& string, XMLLoadData& data)
|
|||||||
|
|
||||||
// Read =
|
// Read =
|
||||||
if (string[data.pos] != '=')
|
if (string[data.pos] != '=')
|
||||||
throw XMLException((std::string("Invalid character proceeding property name in XML Tag \"") + string[data.pos] + "\".").c_str(), data);
|
throw XMLException(
|
||||||
|
(std::string("Invalid character proceeding property name in XML Tag \"") + string[data.pos] + "\".").c_str(),
|
||||||
|
data);
|
||||||
(data.pos)++;
|
(data.pos)++;
|
||||||
ReadWhiteSpace(string, data);
|
ReadWhiteSpace(string, data);
|
||||||
|
|
||||||
@@ -256,7 +287,10 @@ void XMLObject::ReadBodyTail(const std::string& string, XMLLoadData& data)
|
|||||||
ReadWhiteSpace(string, data);
|
ReadWhiteSpace(string, data);
|
||||||
std::string closeTag = GetClosingTag(string, data);
|
std::string closeTag = GetClosingTag(string, data);
|
||||||
if (closeTag.length() == 0)
|
if (closeTag.length() == 0)
|
||||||
throw XMLException("Tag after XML Test was not a closing tag. XMLObject doesn't support text and other XMLObjects at the same time.", data);
|
throw XMLException(
|
||||||
|
"Tag after XML Test was not a closing tag. XMLObject doesn't support text and other XMLObjects at the same "
|
||||||
|
"time.",
|
||||||
|
data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Check if we can read the closing tag.
|
// Check if we can read the closing tag.
|
||||||
@@ -279,14 +313,14 @@ void XMLObject::ReadText(const std::string& string, XMLLoadData& data)
|
|||||||
|
|
||||||
void XMLObject::ReadWhiteSpace(const std::string& string, XMLLoadData& data)
|
void XMLObject::ReadWhiteSpace(const std::string& string, XMLLoadData& data)
|
||||||
{
|
{
|
||||||
while (Utils::IsWhiteSpace(string[data.pos])) {
|
while (Utils::IsWhiteSpace(string[data.pos]))
|
||||||
|
{
|
||||||
if (string[data.pos] == '\n')
|
if (string[data.pos] == '\n')
|
||||||
(data.line)++;
|
(data.line)++;
|
||||||
(data.pos)++;
|
(data.pos)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string XMLObject::GetClosingTag(const std::string& string, XMLLoadData& data)
|
std::string XMLObject::GetClosingTag(const std::string& string, XMLLoadData& data)
|
||||||
{
|
{
|
||||||
int startPos = data.pos;
|
int startPos = data.pos;
|
||||||
@@ -307,7 +341,8 @@ std::string XMLObject::GetClosingTag(const std::string& string, XMLLoadData& dat
|
|||||||
ReadWhiteSpace(string, data);
|
ReadWhiteSpace(string, data);
|
||||||
std::string tag = Utils::GetWord(string, data.pos);
|
std::string tag = Utils::GetWord(string, data.pos);
|
||||||
if (tag != name)
|
if (tag != name)
|
||||||
throw XMLException((std::string("Closing tag doesn't match opening tag. (\"") + name + "\" != \"" + tag+ "\")").c_str(), data);
|
throw XMLException(
|
||||||
|
(std::string("Closing tag doesn't match opening tag. (\"") + name + "\" != \"" + tag + "\")").c_str(), data);
|
||||||
data.pos += tag.length();
|
data.pos += tag.length();
|
||||||
ReadWhiteSpace(string, data);
|
ReadWhiteSpace(string, data);
|
||||||
if (string[data.pos] != '>')
|
if (string[data.pos] != '>')
|
||||||
@@ -318,82 +353,72 @@ std::string XMLObject::GetClosingTag(const std::string& string, XMLLoadData& dat
|
|||||||
|
|
||||||
void XMLObject::ReplacePredefinedEntities(std::string& string, XMLLoadData& data)
|
void XMLObject::ReplacePredefinedEntities(std::string& string, XMLLoadData& data)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, std::string>> entities
|
std::vector<std::pair<std::string, std::string>> entities{
|
||||||
{
|
{""", "\""}, {"'", "\'"}, {"<", "<"}, {">", ">"}, {"&", "&"}};
|
||||||
{""","\""},
|
|
||||||
{"'", "\'"},
|
|
||||||
{"<", "<"},
|
|
||||||
{">",">"},
|
|
||||||
{"&", "&"}
|
|
||||||
};
|
|
||||||
size_t pos = string.find('&');
|
size_t pos = string.find('&');
|
||||||
while(pos != std::string::npos)
|
while (pos != std::string::npos)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for(auto entity : entities)
|
for (auto entity : entities)
|
||||||
{
|
{
|
||||||
if(strncmp(&string[pos], entity.first.c_str(), entity.first.length()) == 0)
|
if (strncmp(&string[pos], entity.first.c_str(), entity.first.length()) == 0)
|
||||||
{
|
{
|
||||||
string.replace(pos, entity.first.length(), entity.second);
|
string.replace(pos, entity.first.length(), entity.second);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!found)
|
if (!found)
|
||||||
LOG_ERROR("(" + data.file + ":" + std::to_string(data.line) + "): ""Ampersand found in xml but isn't a predefined entity.");
|
LOG_ERROR("(" + data.file + ":" + std::to_string(data.line) +
|
||||||
pos = string.find('&', pos+1);
|
"): "
|
||||||
|
"Ampersand found in xml but isn't a predefined entity.");
|
||||||
|
pos = string.find('&', pos + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string XMLObject::ReadXMLName(const std::string& string, XMLLoadData& data)
|
std::string XMLObject::ReadXMLName(const std::string& string, XMLLoadData& data)
|
||||||
{
|
{
|
||||||
if(!(Utils::IsLetter(string[data.pos]) ||
|
if (!(Utils::IsLetter(string[data.pos]) || string[data.pos] == '_' || string[data.pos] == ':'))
|
||||||
string[data.pos] == '_' ||
|
|
||||||
string[data.pos] == ':'))
|
|
||||||
throw XMLException(std::string("Name doesn't start with a letter."), data);
|
throw XMLException(std::string("Name doesn't start with a letter."), data);
|
||||||
|
|
||||||
int endPos = data.pos + 1;
|
int endPos = data.pos + 1;
|
||||||
while (endPos < string.length() && (
|
while (endPos < string.length() && (Utils::IsLetter(string[endPos]) || string[endPos] == '_' ||
|
||||||
Utils::IsLetter(string[endPos]) ||
|
string[endPos] == '-' || string[endPos] == ':' || string[endPos] == '.'))
|
||||||
string[endPos] == '_' ||
|
|
||||||
string[endPos] == '-' ||
|
|
||||||
string[endPos] == ':' ||
|
|
||||||
string[endPos] == '.'))
|
|
||||||
endPos++;
|
endPos++;
|
||||||
return string.substr(data.pos, endPos - data.pos);
|
return string.substr(data.pos, endPos - data.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& XMLObject::WriteToStream(std::ostream& stream, int indent) const
|
std::ostream& XMLObject::WriteToStream(std::ostream& stream, int indent) const
|
||||||
{
|
{
|
||||||
for(int i = 0;i<indent;i++)
|
for (int i = 0; i < indent; i++)
|
||||||
{
|
{
|
||||||
stream << " ";
|
stream << " ";
|
||||||
}
|
}
|
||||||
stream << "<" << name;
|
stream << "<" << name;
|
||||||
for(auto it = attributes.begin();it!=attributes.end();++it)
|
for (auto it = attributes.begin(); it != attributes.end(); ++it)
|
||||||
{
|
{
|
||||||
stream << " " << it->first << "=\"" << it->second << "\"";
|
stream << " " << it->first << "=\"" << it->second << "\"";
|
||||||
}
|
}
|
||||||
stream << ">";
|
stream << ">";
|
||||||
if(text != "")
|
if (text != "")
|
||||||
{
|
{
|
||||||
stream << text;
|
stream << text;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool hasChild = false;
|
bool hasChild = false;
|
||||||
for(auto it = objects.begin(); it != objects.end();++it)
|
for (auto it = objects.begin(); it != objects.end(); ++it)
|
||||||
{
|
{
|
||||||
for(auto it2 = it->second.begin(); it2 != it->second.end(); ++it2)
|
for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2)
|
||||||
{
|
{
|
||||||
stream << "\n";
|
stream << "\n";
|
||||||
it2->WriteToStream(stream, indent+1);
|
it2->WriteToStream(stream, indent + 1);
|
||||||
hasChild = true;
|
hasChild = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(hasChild)
|
if (hasChild)
|
||||||
{
|
{
|
||||||
stream << "\n";
|
stream << "\n";
|
||||||
for(int i = 0;i<indent;i++)
|
for (int i = 0; i < indent; i++)
|
||||||
{
|
{
|
||||||
stream << " ";
|
stream << " ";
|
||||||
}
|
}
|
||||||
@@ -403,4 +428,3 @@ std::ostream& XMLObject::WriteToStream(std::ostream& stream, int indent) const
|
|||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+107
-96
@@ -1,110 +1,121 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class XMLObject
|
class XMLObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
friend class XMLexception;
|
friend class XMLexception;
|
||||||
struct XMLLoadData
|
|
||||||
|
struct XMLLoadData
|
||||||
|
{
|
||||||
|
int pos;
|
||||||
|
int line;
|
||||||
|
const std::string& file;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string name;
|
||||||
|
std::string text;
|
||||||
|
|
||||||
|
std::map<std::string, std::string> attributes;
|
||||||
|
std::map<std::string, std::vector<XMLObject>> objects;
|
||||||
|
|
||||||
|
public:
|
||||||
|
XMLObject()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLObject(const std::string& string);
|
||||||
|
XMLObject(const std::string& string, int pos, int line, const std::string& file);
|
||||||
|
XMLObject(const std::string& string, XMLLoadData& data);
|
||||||
|
XMLObject(const std::string& name, const std::map<std::string, std::string>& properties, const std::string& text);
|
||||||
|
XMLObject(const std::string& name,
|
||||||
|
const std::map<std::string, std::string>& properties,
|
||||||
|
const std::map<std::string, std::vector<XMLObject>>& objects);
|
||||||
|
|
||||||
|
bool HasAttribute(const std::string& property) const;
|
||||||
|
const std::string& GetAttribute(const std::string& property) const;
|
||||||
|
std::string GetAttribute(const std::string& property, const std::string& defaultValue) const;
|
||||||
|
|
||||||
|
unsigned int GetObjectCount() const;
|
||||||
|
std::vector<XMLObject>* GetObjectPtr(const std::string& name);
|
||||||
|
|
||||||
|
std::vector<XMLObject>& GetObjects(const std::string& name);
|
||||||
|
const std::vector<XMLObject>& GetObjects(const std::string& name) const;
|
||||||
|
const std::map<std::string, std::vector<XMLObject>>& GetObjects() const;
|
||||||
|
const std::string& GetName() const;
|
||||||
|
const std::string& GetText() const;
|
||||||
|
XMLObject GetStrippedXMLObject() const;
|
||||||
|
|
||||||
|
void SetName(const std::string& name);
|
||||||
|
void SetText(const std::string& text);
|
||||||
|
void AddAttribute(const std::string& property, const std::string& value);
|
||||||
|
void AddXMLObject(const XMLObject& object);
|
||||||
|
bool RemoveXMLObject(const XMLObject& object);
|
||||||
|
|
||||||
|
friend bool operator<(const XMLObject& obj1, const XMLObject& obj2)
|
||||||
|
{
|
||||||
|
return obj1.name < obj2.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& WriteToStream(std::ostream& stream, int indent = 0) const;
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream& stream, const XMLObject& object)
|
||||||
|
{
|
||||||
|
return object.WriteToStream(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const XMLObject& object1, const XMLObject& object2)
|
||||||
|
{
|
||||||
|
if (object1.attributes.size() != object2.attributes.size())
|
||||||
|
return false;
|
||||||
|
if (object1.objects.size() != object2.objects.size())
|
||||||
|
return false;
|
||||||
|
if (object1.name != object2.name)
|
||||||
|
return false;
|
||||||
|
if (object1.GetText() != object2.GetText())
|
||||||
|
return false;
|
||||||
|
|
||||||
{
|
{
|
||||||
int pos;
|
auto it1 = object1.attributes.begin();
|
||||||
int line;
|
auto it2 = object2.attributes.begin();
|
||||||
const std::string& file;
|
while (it1 != object1.attributes.end())
|
||||||
};
|
|
||||||
private:
|
|
||||||
std::string name;
|
|
||||||
std::string text;
|
|
||||||
|
|
||||||
std::map<std::string, std::string> attributes;
|
|
||||||
std::map<std::string, std::vector<XMLObject>> objects;
|
|
||||||
|
|
||||||
public:
|
|
||||||
XMLObject() {}
|
|
||||||
XMLObject(const std::string& string);
|
|
||||||
XMLObject(const std::string& string, int pos, int line, const std::string& file);
|
|
||||||
XMLObject(const std::string& string, XMLLoadData& data);
|
|
||||||
XMLObject(const std::string& name, const std::map<std::string, std::string>& properties, const std::string& text);
|
|
||||||
XMLObject(const std::string& name, const std::map<std::string, std::string>& properties, const std::map<std::string, std::vector<XMLObject>>& objects);
|
|
||||||
|
|
||||||
bool HasAttribute(const std::string& property) const;
|
|
||||||
const std::string& GetAttribute(const std::string& property) const;
|
|
||||||
const std::string& GetAttribute(const std::string& property, const std::string& defaultValue) const;
|
|
||||||
|
|
||||||
unsigned int GetObjectCount() const;
|
|
||||||
std::vector<XMLObject>* GetObjectPtr(const std::string& name);
|
|
||||||
const std::map<std::string, std::vector<XMLObject>>& GetObjects() const;
|
|
||||||
const std::string& GetName() const;
|
|
||||||
const std::string& GetText() const;
|
|
||||||
XMLObject GetStrippedXMLObject() const;
|
|
||||||
|
|
||||||
void SetName(const std::string& name);
|
|
||||||
void SetText(const std::string& text);
|
|
||||||
void AddAttribute(const std::string& property, const std::string& value);
|
|
||||||
void AddXMLObject(const XMLObject& object);
|
|
||||||
bool RemoveXMLObject(const XMLObject& object);
|
|
||||||
|
|
||||||
friend bool operator<(const XMLObject& obj1, const XMLObject& obj2)
|
|
||||||
{
|
|
||||||
return obj1.name < obj2.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream& WriteToStream(std::ostream& stream, int indent = 0) const;
|
|
||||||
friend std::ostream& operator<<(std::ostream& stream, const XMLObject& object)
|
|
||||||
{
|
|
||||||
return object.WriteToStream(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
friend bool operator==(const XMLObject& object1, const XMLObject& object2)
|
|
||||||
{
|
|
||||||
if(object1.attributes.size() != object2.attributes.size())
|
|
||||||
return false;
|
|
||||||
if(object1.objects.size() != object2.objects.size())
|
|
||||||
return false;
|
|
||||||
if(object1.name != object2.name)
|
|
||||||
return false;
|
|
||||||
if(object1.GetText() != object2.GetText())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
auto it1 = object1.attributes.begin();
|
if (it1->first != it2->first || it1->second != it1->second)
|
||||||
auto it2 = object2.attributes.begin();
|
return false;
|
||||||
while(it1 != object1.attributes.end())
|
++it1;
|
||||||
{
|
++it2;
|
||||||
if(it1->first != it2->first || it1->second != it1->second)
|
|
||||||
return false;
|
|
||||||
++it1;
|
|
||||||
++it2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
auto it1 = object1.objects.begin();
|
|
||||||
auto it2 = object2.objects.begin();
|
|
||||||
while(it1 != object1.objects.end())
|
|
||||||
{
|
|
||||||
if(it1->second != it2->second)
|
|
||||||
return false;
|
|
||||||
++it1;
|
|
||||||
++it2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
{
|
||||||
std::string GetClosingTag(const std::string& string, XMLLoadData& data);
|
auto it1 = object1.objects.begin();
|
||||||
// Returns true if the head contained closing tag.
|
auto it2 = object2.objects.begin();
|
||||||
bool ReadHead(const std::string& string, XMLLoadData& data);
|
while (it1 != object1.objects.end())
|
||||||
void ReadName(const std::string& string, XMLLoadData& data);
|
{
|
||||||
void ReadAttribute(const std::string& string, XMLLoadData& data);
|
if (it1->second != it2->second)
|
||||||
void ReadAttributes(const std::string& string, XMLLoadData& data);
|
return false;
|
||||||
void ReadBodyTail(const std::string& string, XMLLoadData& data);
|
++it1;
|
||||||
void ReadText(const std::string& string, XMLLoadData& data);
|
++it2;
|
||||||
void ReadWhiteSpace(const std::string& string, XMLLoadData& data);
|
}
|
||||||
void ReplacePredefinedEntities(std::string& string, XMLLoadData& data);
|
}
|
||||||
std::string ReadXMLName(const std::string& string, XMLLoadData& data);
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string GetClosingTag(const std::string& string, XMLLoadData& data);
|
||||||
|
// Returns true if the head contained closing tag.
|
||||||
|
bool ReadHead(const std::string& string, XMLLoadData& data);
|
||||||
|
void ReadName(const std::string& string, XMLLoadData& data);
|
||||||
|
void ReadAttribute(const std::string& string, XMLLoadData& data);
|
||||||
|
void ReadAttributes(const std::string& string, XMLLoadData& data);
|
||||||
|
void ReadBodyTail(const std::string& string, XMLLoadData& data);
|
||||||
|
void ReadText(const std::string& string, XMLLoadData& data);
|
||||||
|
void ReadWhiteSpace(const std::string& string, XMLLoadData& data);
|
||||||
|
void ReplacePredefinedEntities(std::string& string, XMLLoadData& data);
|
||||||
|
std::string ReadXMLName(const std::string& string, XMLLoadData& data);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user