Initial commit for ArgParser
This commit is contained in:
+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
|
||||
...
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
bin/
|
||||
compile_flags.txt
|
||||
Makefile
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Tim Håkansson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
<makegen>
|
||||
<configuration name="Test">
|
||||
<generatehfile>false</generatehfile>
|
||||
<outputdir>bin/Test/</outputdir>
|
||||
<outputname>arg_parser</outputname>
|
||||
<outputtype>executable</outputtype>
|
||||
<projectname>ArgParser</projectname>
|
||||
<srcdir>src/</srcdir>
|
||||
</configuration>
|
||||
<configuration name="Release">
|
||||
<generatehfile>false</generatehfile>
|
||||
<outputdir>bin/Release</outputdir>
|
||||
<outputname>libarg_parser.so</outputname>
|
||||
<outputtype>sharedlibrary</outputtype>
|
||||
<sourceexclude>main.cpp</sourceexclude>
|
||||
<projectname>ArgParser</projectname>
|
||||
<srcdir>src/</srcdir>
|
||||
</configuration>
|
||||
<configuration name="Debug">
|
||||
<cflag>-g3</cflag>
|
||||
<cflag>-w</cflag>
|
||||
<define>_DEBUG</define>
|
||||
<generatehfile>false</generatehfile>
|
||||
<outputdir>bin/Debug/</outputdir>
|
||||
<outputname>arg_parser</outputname>
|
||||
<outputtype>executable</outputtype>
|
||||
<projectname>ArgParser</projectname>
|
||||
<srcdir>src/</srcdir>
|
||||
</configuration>
|
||||
<target>Release</target>
|
||||
<version>v1.3.8</version>
|
||||
</makegen>
|
||||
@@ -0,0 +1,54 @@
|
||||
#include "ActionArg.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace ap
|
||||
{
|
||||
ActionArg::ActionArg(const std::string& argument, const std::string& helpText, std::function<void()> action)
|
||||
: Arg{argument, helpText, false, true},
|
||||
action{action}
|
||||
{
|
||||
}
|
||||
|
||||
bool ActionArg::PartialMatch(const std::string& arg) const
|
||||
{
|
||||
for (const auto& argument : arguments)
|
||||
{
|
||||
if (argument == arg)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ActionArg::Parse(const std::vector<std::string>& arguments, size_t& index)
|
||||
{
|
||||
action();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string ActionArg::GetHelpArgument(bool onlyFirst) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
if (onlyFirst)
|
||||
{
|
||||
if (required)
|
||||
{
|
||||
ss << arguments.front();
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << "[" << arguments.front() << "]";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << arguments.front();
|
||||
for (int i = 1; i < arguments.size(); i++)
|
||||
{
|
||||
ss << ", " << arguments[i];
|
||||
}
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "Arg.h"
|
||||
|
||||
namespace ap
|
||||
{
|
||||
struct ActionArg : public Arg
|
||||
{
|
||||
std::function<void()> action;
|
||||
|
||||
ActionArg(const std::string& argument, const std::string& helpText, std::function<void()> action);
|
||||
|
||||
bool PartialMatch(const std::string& arg) const override;
|
||||
bool Parse(const std::vector<std::string>& arguments, size_t& index) override;
|
||||
std::string GetHelpArgument(bool onlyFirst) const override;
|
||||
};
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
#include "Arg.h"
|
||||
|
||||
namespace ap
|
||||
{
|
||||
Arg::Arg(const std::string& argument, const std::string& helpText, bool required, bool overridesMandatory)
|
||||
: helpText{helpText},
|
||||
required{required},
|
||||
overridesMandatory{overridesMandatory}
|
||||
{
|
||||
size_t lastPos = 0;
|
||||
size_t pos = argument.find(',');
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
arguments.emplace_back(argument.substr(lastPos, (pos - lastPos)));
|
||||
lastPos = pos + 1;
|
||||
pos = argument.find(',', lastPos);
|
||||
}
|
||||
arguments.emplace_back(argument.substr(lastPos));
|
||||
}
|
||||
|
||||
bool Arg::Match(const std::string& arg) const
|
||||
{
|
||||
for (const auto& argument : arguments)
|
||||
{
|
||||
if (argument == arg)
|
||||
return true;
|
||||
}
|
||||
|
||||
return MatchAdditional(arg);
|
||||
}
|
||||
|
||||
bool Arg::PartialMatch(const std::string& arg) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Arg::MatchAdditional(const std::string& arg) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ap
|
||||
{
|
||||
struct Arg
|
||||
{
|
||||
std::vector<std::string> arguments;
|
||||
std::string helpText;
|
||||
bool required;
|
||||
bool overridesMandatory;
|
||||
bool wasSpecified{false};
|
||||
|
||||
Arg(const std::string& argument, const std::string& helpText, bool required, bool overridesMandatory);
|
||||
|
||||
bool Match(const std::string& arg) const;
|
||||
virtual bool PartialMatch(const std::string& arg) const;
|
||||
|
||||
virtual bool MatchAdditional(const std::string& arg) const;
|
||||
|
||||
virtual bool Parse(const std::vector<std::string>& arguments, size_t& index) = 0;
|
||||
virtual std::string GetHelpArgument(bool onlyFirst) const = 0;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
#include "ArgParser.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
|
||||
#include "ActionArg.h"
|
||||
#include "FlagArg.h"
|
||||
|
||||
const int HELP_WIDTH = 25;
|
||||
const int MAX_WIDTH = 80;
|
||||
|
||||
namespace ap
|
||||
{
|
||||
ArgParser::ArgParser(const std::string& commandName,
|
||||
const std::string& description,
|
||||
const std::string& additionalHelp,
|
||||
const std::vector<std::string>& arguments)
|
||||
: commandName{commandName},
|
||||
description{description},
|
||||
additionalHelp{additionalHelp},
|
||||
argumentStrings{arguments}
|
||||
{
|
||||
AddAction("--help,-h", "Displays this information", [&]() { PrintHelp(); });
|
||||
}
|
||||
|
||||
ArgParser::ArgParser(const std::string& commandName,
|
||||
const std::string& description,
|
||||
const std::string& additionalHelp,
|
||||
int argc,
|
||||
char** argv)
|
||||
: commandName{commandName},
|
||||
description{description},
|
||||
additionalHelp{additionalHelp}
|
||||
{
|
||||
AddAction("--help,-h", "Displays this information", [&]() { PrintHelp(); });
|
||||
for (int i = 0; i < argc; i++)
|
||||
{
|
||||
argumentStrings.emplace_back(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void ArgParser::AddAction(const std::string& arg, const std::string& helpText, std::function<void()> action)
|
||||
{
|
||||
args.emplace_back(std::make_shared<ActionArg>(arg, helpText, action));
|
||||
}
|
||||
|
||||
void ArgParser::AddFlag(const std::string& arg, bool& flag, const std::string& helpText)
|
||||
{
|
||||
args.emplace_back(std::make_shared<FlagArg>(flag, arg, helpText));
|
||||
}
|
||||
|
||||
void ArgParser::PrintHelp() const
|
||||
{
|
||||
size_t pos = 0;
|
||||
size_t offset = 0;
|
||||
Utils::PrintMaxWidthSplit(description, pos, offset, MAX_WIDTH, " ");
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "Usage: " << std::endl;
|
||||
PrintCommandHelp(false);
|
||||
PrintCommandHelp(true);
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "Options: " << std::endl;
|
||||
|
||||
size_t width = 0;
|
||||
for (auto& arg : args)
|
||||
{
|
||||
std::string helpArg = arg->GetHelpArgument(false);
|
||||
if (helpArg.size() + 4 < HELP_WIDTH)
|
||||
width = std::max(width, helpArg.size());
|
||||
}
|
||||
width = std::min(size_t(HELP_WIDTH), width + 4);
|
||||
|
||||
for (const auto& arg : args)
|
||||
{
|
||||
PrintArgHelp(*arg, width);
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
pos = 0;
|
||||
offset = 0;
|
||||
Utils::PrintMaxWidthSplit(additionalHelp, pos, offset, MAX_WIDTH, " ");
|
||||
}
|
||||
|
||||
void ArgParser::PrintError() const
|
||||
{
|
||||
std::cout << "Use --help for more info" << std::endl;
|
||||
}
|
||||
|
||||
bool ArgParser::Parse()
|
||||
{
|
||||
bool anyOverridesMandatory = false;
|
||||
for (size_t i = 0; i < argumentStrings.size(); i++)
|
||||
{
|
||||
auto it = std::find_if(args.begin(),
|
||||
args.end(),
|
||||
[&](const std::shared_ptr<Arg>& arg)
|
||||
{ return arg->overridesMandatory && arg->Match(argumentStrings[i]); });
|
||||
if (it != args.end())
|
||||
{
|
||||
(*it)->Parse(argumentStrings, i);
|
||||
anyOverridesMandatory = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyOverridesMandatory)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < argumentStrings.size(); i++)
|
||||
{
|
||||
auto it = std::find_if(
|
||||
args.begin(), args.end(), [&](const std::shared_ptr<Arg>& arg) { return arg->Match(argumentStrings[i]); });
|
||||
if (it != args.end())
|
||||
{
|
||||
if (!(*it)->Parse(argumentStrings, i))
|
||||
{
|
||||
PrintError();
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Utils::IsMultiFlag(argumentStrings[i]))
|
||||
{
|
||||
std::vector<std::vector<std::shared_ptr<Arg>>::iterator> iterators;
|
||||
for (size_t j = 1; j < argumentStrings[i].size(); j++)
|
||||
{
|
||||
std::string flag = std::string("-") + argumentStrings[i][j];
|
||||
auto it =
|
||||
std::find_if(args.begin(), args.end(), [&](const std::shared_ptr<Arg>& arg) { return arg->Match(flag); });
|
||||
if (it == args.end())
|
||||
{
|
||||
std::cout << "Unknown flag: \"" << flag << "\" in \"" << argumentStrings[i] << "\"" << std::endl
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
PrintError();
|
||||
return false;
|
||||
}
|
||||
iterators.emplace_back(it);
|
||||
}
|
||||
|
||||
for (auto it : iterators)
|
||||
{
|
||||
if (!(*it)->Parse(argumentStrings, i))
|
||||
{
|
||||
PrintError();
|
||||
return false;
|
||||
}
|
||||
if ((*it)->overridesMandatory)
|
||||
{
|
||||
anyOverridesMandatory = true;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
std::cout << "Unknown argment: \"" << argumentStrings[i] << "\"" << std::endl << std::endl;
|
||||
PrintError();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (anyOverridesMandatory)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& arg : args)
|
||||
{
|
||||
if (arg->required && !arg->wasSpecified)
|
||||
{
|
||||
std::cout << "Mandatory argument not specified: " << arg->arguments.front() << std::endl << std::endl;
|
||||
PrintError();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ArgParser::PrintCommandHelp(bool actions) const
|
||||
{
|
||||
std::cout << " " << commandName;
|
||||
size_t offset = 4;
|
||||
if (commandName.size() - 3 > HELP_WIDTH)
|
||||
std::cout << std::endl << " ";
|
||||
else
|
||||
{
|
||||
std::cout << " ";
|
||||
offset = commandName.size() + 3;
|
||||
}
|
||||
|
||||
size_t pos = offset;
|
||||
PrintCommandArgsHelp(pos, offset, actions, true);
|
||||
PrintCommandArgsHelp(pos, offset, actions, false);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void ArgParser::PrintCommandArgsHelp(size_t& pos, size_t offset, bool actions, bool required) const
|
||||
{
|
||||
for (auto& arg : args)
|
||||
{
|
||||
if (arg->overridesMandatory == actions && arg->required == required)
|
||||
{
|
||||
Utils::PrintMaxWidth(arg->GetHelpArgument(true), pos, offset, MAX_WIDTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArgParser::PrintArgHelp(const Arg& arg, size_t offset) const
|
||||
{
|
||||
std::string helpArg = arg.GetHelpArgument(false);
|
||||
if (helpArg.size() + 4 >= HELP_WIDTH)
|
||||
{
|
||||
std::cout << " " << helpArg << std::endl;
|
||||
std::cout << std::setw(offset) << "";
|
||||
size_t pos = offset;
|
||||
Utils::PrintMaxWidthSplit(arg.helpText, pos, offset, MAX_WIDTH, " ");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << " " << std::setw(offset - 2) << std::left << helpArg;
|
||||
size_t pos = offset;
|
||||
Utils::PrintMaxWidthSplit(arg.helpText, pos, offset, MAX_WIDTH, " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#include <math.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Arg.h"
|
||||
#include "ValueArg.h"
|
||||
|
||||
namespace ap
|
||||
{
|
||||
struct ArgParser
|
||||
{
|
||||
std::string commandName;
|
||||
std::string description;
|
||||
std::string additionalHelp;
|
||||
std::vector<std::string> argumentStrings;
|
||||
std::vector<std::shared_ptr<Arg>> args;
|
||||
|
||||
ArgParser(const std::string& commandName,
|
||||
const std::string& description,
|
||||
const std::string& additionalHelp,
|
||||
const std::vector<std::string>& arguments);
|
||||
|
||||
ArgParser(const std::string& commandName,
|
||||
const std::string& description,
|
||||
const std::string& additionalHelp,
|
||||
int argc,
|
||||
char** argv);
|
||||
|
||||
void AddAction(const std::string& arg, const std::string& helpText, std::function<void()> action);
|
||||
|
||||
template <typename T>
|
||||
void Add(const std::string& arg, T& value, const std::string& helpText)
|
||||
{
|
||||
args.emplace_back(std::make_shared<ValueArg<T>>(value, arg, helpText, true));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Add(const std::string& arg, T& value, const std::string& helpText, const T& defaultValue)
|
||||
{
|
||||
value = defaultValue;
|
||||
std::stringstream ss;
|
||||
ss << helpText << " (default=" << defaultValue << ")";
|
||||
args.emplace_back(std::make_shared<ValueArg<T>>(value, arg, ss.str(), false));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AddOptional(const std::string& arg, std::optional<T>& value, const std::string& helpText)
|
||||
{
|
||||
value = std::nullopt;
|
||||
std::stringstream ss;
|
||||
ss << helpText << " (default=null)";
|
||||
args.emplace_back(std::make_shared<ValueArg<std::optional<T>>>(value, arg, ss.str(), false));
|
||||
}
|
||||
|
||||
void AddFlag(const std::string& arg, bool& flag, const std::string& helpText);
|
||||
|
||||
bool Parse();
|
||||
|
||||
private:
|
||||
void PrintCommandHelp(bool actions) const;
|
||||
void PrintCommandArgsHelp(size_t& pos, size_t offset, bool actions, bool required) const;
|
||||
void PrintArgHelp(const Arg& arg, size_t offset) const;
|
||||
void PrintHelp() const;
|
||||
void PrintError() const;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "FlagArg.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace ap
|
||||
{
|
||||
FlagArg::FlagArg(bool& flag, const std::string& argument, const std::string& helpText)
|
||||
: Arg{argument, helpText, false, false},
|
||||
flag{flag}
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
|
||||
bool FlagArg::PartialMatch(const std::string& arg) const
|
||||
{
|
||||
for (const auto& argument : arguments)
|
||||
{
|
||||
if (argument == arg)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FlagArg::Parse(const std::vector<std::string>& arguments, size_t& index)
|
||||
{
|
||||
flag = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string FlagArg::GetHelpArgument(bool onlyFirst) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
if (onlyFirst)
|
||||
{
|
||||
if (required)
|
||||
{
|
||||
ss << arguments.front();
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << "[" << arguments.front() << "]";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << arguments.front();
|
||||
for (int i = 1; i < arguments.size(); i++)
|
||||
{
|
||||
ss << ", " << arguments[i];
|
||||
}
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "Arg.h"
|
||||
|
||||
namespace ap
|
||||
{
|
||||
struct FlagArg : public Arg
|
||||
{
|
||||
bool& flag;
|
||||
|
||||
FlagArg(bool& flag, const std::string& argument, const std::string& helpText);
|
||||
|
||||
bool PartialMatch(const std::string& arg) const override;
|
||||
bool Parse(const std::vector<std::string>& arguments, size_t& index) override;
|
||||
std::string GetHelpArgument(bool onlyFirst) const override;
|
||||
};
|
||||
}
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
#include "Utils.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
namespace ap
|
||||
{
|
||||
template <>
|
||||
std::pair<bool, int> ParseValue<int>(const std::string_view& str)
|
||||
{
|
||||
try
|
||||
{
|
||||
size_t index = 0;
|
||||
int i = std::stoi(std::string(str), &index);
|
||||
|
||||
if (index != str.size())
|
||||
return {false, 0};
|
||||
|
||||
return {true, i};
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return {false, 0};
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
std::pair<bool, float> ParseValue<float>(const std::string_view& str)
|
||||
{
|
||||
try
|
||||
{
|
||||
size_t index = 0;
|
||||
float f = std::stof(std::string(str), &index);
|
||||
|
||||
if (index != str.size())
|
||||
return {false, 0};
|
||||
|
||||
return {true, f};
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return {false, 0};
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
std::pair<bool, std::string> ParseValue<std::string>(const std::string_view& str)
|
||||
{
|
||||
return {true, std::string(str)};
|
||||
}
|
||||
|
||||
template <>
|
||||
std::pair<bool, bool> ParseValue<bool>(const std::string_view& str)
|
||||
{
|
||||
if (Utils::CaseInsensitiveEqual(str, "true") || Utils::CaseInsensitiveEqual(str, "yes") || str == "y" || str == "Y")
|
||||
{
|
||||
return {true, true};
|
||||
}
|
||||
|
||||
if (Utils::CaseInsensitiveEqual(str, "false") || Utils::CaseInsensitiveEqual(str, "no") || str == "n" || str == "N")
|
||||
{
|
||||
return {true, false};
|
||||
}
|
||||
|
||||
return {false, false};
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string GetTypeHelpName<bool>()
|
||||
{
|
||||
return "<boolean>";
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string GetTypeHelpName<int>()
|
||||
{
|
||||
return "<int>";
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string GetTypeHelpName<float>()
|
||||
{
|
||||
return "<float>";
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string GetTypeHelpName<std::string>()
|
||||
{
|
||||
return "<string>";
|
||||
}
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
bool CaseInsensitiveEqual(const std::string_view& sv, const std::string& str)
|
||||
{
|
||||
if (sv.size() != str.size())
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < sv.size(); i++)
|
||||
{
|
||||
if (std::tolower(sv[i]) != str[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrintMaxWidth(
|
||||
const std::vector<std::string>& strings, size_t pos, size_t offset, size_t maxWidth, const std::string& delim)
|
||||
{
|
||||
if (strings.empty())
|
||||
return;
|
||||
|
||||
for (auto& string : strings)
|
||||
{
|
||||
PrintMaxWidth(strings.front(), pos, offset, maxWidth);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void PrintMaxWidthSplit(
|
||||
const std::string& str, size_t pos, size_t offset, size_t maxWidth, const std::string& delim)
|
||||
{
|
||||
size_t lastPos = 0;
|
||||
size_t strPos = str.find(delim);
|
||||
while (strPos != std::string::npos)
|
||||
{
|
||||
PrintMaxWidth(std::string_view(str.c_str() + lastPos, strPos - lastPos), pos, offset, maxWidth);
|
||||
lastPos = strPos + 1;
|
||||
strPos = str.find(' ', lastPos);
|
||||
}
|
||||
PrintMaxWidth(std::string_view(str.c_str() + lastPos, str.size() - lastPos), pos, offset, maxWidth);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void PrintMaxWidth(const std::string_view& view, size_t& pos, size_t offset, size_t maxWidth)
|
||||
{
|
||||
if (pos + view.size() > maxWidth && pos != offset)
|
||||
{
|
||||
std::cout << std::endl << std::setw(offset) << "";
|
||||
pos = offset;
|
||||
}
|
||||
size_t lastPos = 0;
|
||||
size_t newline = view.find('\n');
|
||||
while (newline != std::string::npos)
|
||||
{
|
||||
std::cout << view.substr(lastPos, newline - lastPos) << std::endl << std::setw(offset) << "";
|
||||
pos = offset;
|
||||
lastPos = newline + 1;
|
||||
newline = view.find('\n', lastPos);
|
||||
}
|
||||
std::cout << view.substr(lastPos);
|
||||
if (pos + view.size() != maxWidth)
|
||||
std::cout << " ";
|
||||
pos += view.size() + 1;
|
||||
}
|
||||
|
||||
bool IsMultiFlag(const std::string& arg)
|
||||
{
|
||||
if (arg[0] != '-')
|
||||
return false;
|
||||
|
||||
for (auto i = 1; i < arg.size(); i++)
|
||||
{
|
||||
if (!(arg[i] >= 'a' && arg[i] <= 'z') && !(arg[i] >= 'A' && arg[i] <= 'Z') && !(arg[i] >= '0' && arg[i] <= '9'))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ap
|
||||
{
|
||||
template <typename T>
|
||||
struct dependent_false
|
||||
{
|
||||
enum
|
||||
{
|
||||
value = false
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_optional : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_optional<std::optional<T>> : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::string GetTypeHelpName()
|
||||
{
|
||||
static_assert(dependent_false<T>::value, "No GetTypeHelpName function created for type T");
|
||||
return {false, T{}};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::pair<bool, T> ParseValue(const std::string_view& str)
|
||||
{
|
||||
static_assert(dependent_false<T>::value, "No ParseValue function created for type T");
|
||||
return {false, T{}};
|
||||
}
|
||||
|
||||
template <>
|
||||
std::pair<bool, int> ParseValue<int>(const std::string_view& str);
|
||||
|
||||
template <>
|
||||
std::pair<bool, float> ParseValue<float>(const std::string_view& str);
|
||||
|
||||
template <>
|
||||
std::pair<bool, std::string> ParseValue<std::string>(const std::string_view& str);
|
||||
|
||||
template <>
|
||||
std::pair<bool, bool> ParseValue<bool>(const std::string_view& str);
|
||||
|
||||
template <>
|
||||
std::string GetTypeHelpName<bool>();
|
||||
|
||||
template <>
|
||||
std::string GetTypeHelpName<int>();
|
||||
|
||||
template <>
|
||||
std::string GetTypeHelpName<float>();
|
||||
|
||||
template <>
|
||||
std::string GetTypeHelpName<std::string>();
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
bool CaseInsensitiveEqual(const std::string_view& sv, const std::string& str);
|
||||
void PrintMaxWidth(
|
||||
const std::vector<std::string>& strings, size_t pos, size_t offset, size_t maxWidth, const std::string& delim);
|
||||
void PrintMaxWidthSplit(
|
||||
const std::string& view, size_t pos, size_t offset, size_t maxWidth, const std::string& delim);
|
||||
void PrintMaxWidth(const std::string_view& view, size_t& pos, size_t offset, size_t maxWidth);
|
||||
|
||||
bool IsMultiFlag(const std::string& arg);
|
||||
}
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "Arg.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace ap
|
||||
{
|
||||
template <typename T>
|
||||
struct ValueArg : public Arg
|
||||
{
|
||||
T& value;
|
||||
|
||||
ValueArg(T& value, const std::string& argument, const std::string& helpText, bool required)
|
||||
: Arg{argument, helpText, required, false},
|
||||
value{value}
|
||||
{
|
||||
}
|
||||
|
||||
bool MatchAdditional(const std::string& arg) const override
|
||||
{
|
||||
size_t pos = arg.find('=');
|
||||
if (pos == std::string::npos)
|
||||
return false;
|
||||
|
||||
for (const auto& argument : arguments)
|
||||
{
|
||||
if (std::string_view(arg.c_str(), pos) == argument)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Parse(const std::vector<std::string>& arguments, size_t& index) override
|
||||
{
|
||||
wasSpecified = true;
|
||||
|
||||
size_t pos = arguments[index].find('=');
|
||||
std::string valStr;
|
||||
std::string argStr;
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
argStr = arguments[index];
|
||||
if (arguments.size() <= index + 1)
|
||||
{
|
||||
std::cout << "No argument specified for " << arguments[index] << std::endl;
|
||||
return false;
|
||||
}
|
||||
index++;
|
||||
|
||||
valStr = arguments[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
argStr = arguments[index].substr(0, pos);
|
||||
valStr = arguments[index].substr(pos + 1, arguments[index].size() - pos - 1);
|
||||
}
|
||||
|
||||
std::pair<bool, T> res;
|
||||
if constexpr (is_optional<T>::value)
|
||||
{
|
||||
res = ParseValue<typename T::value_type>(valStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = ParseValue<T>(valStr);
|
||||
}
|
||||
const auto& [result, val] = res;
|
||||
if (!result)
|
||||
{
|
||||
std::cout << "Could not parse value for argument=\"" << argStr << "\"" << " value=\"" << valStr << "\""
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
value = val;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GetHelpArgument(bool onlyFirst) const override
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
if (!onlyFirst)
|
||||
{
|
||||
ss << arguments.front();
|
||||
for (int i = 1; i < arguments.size(); i++)
|
||||
{
|
||||
ss << ", " << arguments[i];
|
||||
}
|
||||
OutputTypeHelpName(ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
if (!required)
|
||||
ss << "[";
|
||||
|
||||
ss << arguments.front();
|
||||
OutputTypeHelpName(ss);
|
||||
|
||||
if (!required)
|
||||
ss << "]";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
void OutputTypeHelpName(std::ostream& os) const
|
||||
{
|
||||
if constexpr (is_optional<T>::value)
|
||||
{
|
||||
os << " " << GetTypeHelpName<typename T::value_type>();
|
||||
}
|
||||
else
|
||||
{
|
||||
os << " " << GetTypeHelpName<T>();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
#include <optional>
|
||||
|
||||
#include "ArgParser.h"
|
||||
|
||||
void PrintVersion()
|
||||
{
|
||||
std::cout << "command v1.2.3" << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
ap::ArgParser parser(
|
||||
"makegen",
|
||||
"MakeGen is a utility tool to generate and run Makefiles in a simple manner. By default it "
|
||||
"always compiles code with parallel jobs",
|
||||
"If no option is given it will run \"make all\"\n\nIf multiple make options are given it will "
|
||||
"run in the following order:\nclean all install run, rebuild will be translated to \"clean all\"",
|
||||
argc - 1,
|
||||
argv + 1);
|
||||
|
||||
struct Args
|
||||
{
|
||||
bool make;
|
||||
bool install;
|
||||
bool clean;
|
||||
bool rebuild;
|
||||
bool run;
|
||||
bool single;
|
||||
bool simple;
|
||||
bool conf;
|
||||
std::optional<std::string> target;
|
||||
int test;
|
||||
};
|
||||
|
||||
Args args;
|
||||
parser.AddAction("--version,-v", "Displays the version of this program", PrintVersion);
|
||||
parser.AddFlag("make,all,-m,-a", args.make, "Generates a Makefile and runs \"make all\"");
|
||||
parser.AddFlag("install,-i", args.install, "Generates a Makefile and runs \"make all && make install\"");
|
||||
parser.AddFlag("clean,-c", args.clean, "Generates a Makefile and runs \"make clean\"");
|
||||
parser.AddFlag("rebuld,-r", args.rebuild, "Generates a Makefile and runs \"make clean && make all\"");
|
||||
parser.AddFlag("run,execute,-e", args.run, "Generates a Makefile and runs \"make all && make run\"");
|
||||
parser.AddFlag("single,-s", args.single, "Runs additional makegen options as single thread\n(no --jobs=X flag)");
|
||||
parser.AddFlag("--simple", args.simple, "Creates a simple Makefile without include dependencies");
|
||||
parser.AddOptional("--target,-t", args.target, "Run the makegen.xml file with the specified target");
|
||||
if (parser.Parse())
|
||||
{
|
||||
if (args.target)
|
||||
std::cout << args.target.value() << std::endl;
|
||||
else
|
||||
std::cout << "null" << std::endl;
|
||||
}
|
||||
return 0;
|
||||
#if 0
|
||||
ap::ArgParser parser("command",
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut "
|
||||
"labore et dolore magna aliqua",
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut "
|
||||
"labore et dolore magna aliqua",
|
||||
argc - 1,
|
||||
argv + 1);
|
||||
|
||||
// ArgParser parser("command",
|
||||
// "This text explains what the command does",
|
||||
// "Additional help information",
|
||||
// {{"--test", "10", "--test2=20", "--test4=tesssda", "--test5", "--test6=Y"}});
|
||||
int test;
|
||||
int test2;
|
||||
float test3;
|
||||
std::string test4;
|
||||
bool flag;
|
||||
bool b;
|
||||
bool version;
|
||||
parser.AddInfo("--version", version, "Displays the version of the program");
|
||||
parser.Add<int>(
|
||||
"--test",
|
||||
test,
|
||||
"some1 help2 text3 some4 help5 text6 some7 help8 text9 some10 "
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
|
||||
parser.Add<int>("--test2,-t", test2, "some help text 2");
|
||||
parser.Add<float>("--test3", test3, "some help text", 0.1f);
|
||||
parser.Add<std::string>("--test4", test4, "some help text");
|
||||
parser.Add<bool>("--test6", b, "some help text");
|
||||
parser.Add<bool>("--test7", b, "some help text");
|
||||
parser.AddFlag("--test5", flag, "some help text");
|
||||
parser.AddFlag("--very_very_very_very_long", flag, "some help text");
|
||||
parser.AddFlag("--very_very_very_very_longxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
flag,
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore "
|
||||
"et dolore magna aliqua");
|
||||
parser.AddFlag("--very_very_very_very", flag, "some help text");
|
||||
parser.AddFlag("--very_very_very_ver", flag, "some help text");
|
||||
if (parser.Parse())
|
||||
{
|
||||
std::cout << test << std::endl;
|
||||
std::cout << test2 << std::endl;
|
||||
std::cout << test3 << std::endl;
|
||||
std::cout << test4 << std::endl;
|
||||
std::cout << b << std::endl;
|
||||
std::cout << flag << std::endl;
|
||||
}
|
||||
|
||||
if (version)
|
||||
{
|
||||
std::cout << "Command 1.2.3" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user