Browse Source

Add convenience method to get first value

experiment/meta_header
Martchus 6 years ago
parent
commit
23346e1a8e
  1. 28
      application/argumentparser.cpp
  2. 55
      application/argumentparser.h
  3. 17
      tests/argumentparsertests.cpp

28
application/argumentparser.cpp

@ -10,6 +10,7 @@
#include <string>
#include <sstream>
#include <cstring>
#include <cstdlib>
#ifdef LOGGING_ENABLED
# include <fstream>
#endif
@ -67,6 +68,7 @@ enum ArgumentDenotationType : unsigned char {
Argument::Argument(const char *name, char abbreviation, const char *description, const char *example) :
m_name(name),
m_abbreviation(abbreviation),
m_environmentVar(nullptr),
m_description(description),
m_example(example),
m_minOccurrences(0),
@ -87,11 +89,29 @@ Argument::~Argument()
{}
/*!
* \brief Appends the name, the abbreviation and the description of the Argument to the give ostream.
* \brief Returns the first parameter value of the first occurance of the argument.
* \remarks
* - If the argument is not present and the an environment variable has been set
* using setEnvironmentVariable() the value of the specified variable will be returned.
* - Returns nullptr if no value is available though.
*/
const char *Argument::firstValue() const
{
if(!m_occurances.empty() && !m_occurances.front().values.empty()) {
return m_occurances.front().values.front();
} else if(m_environmentVar) {
return getenv(m_environmentVar);
} else {
return nullptr;
}
}
/*!
* \brief Writes the name, the abbreviation and other information about the Argument to the give ostream.
*/
void Argument::printInfo(ostream &os, unsigned char indentionLevel) const
{
for(unsigned char i = 0; i < indentionLevel; ++i) os << " ";
for(unsigned char i = 0; i < indentionLevel; ++i) os << ' ' << ' ';
if(notEmpty(name())) {
os << '-' << '-' << name();
}
@ -101,7 +121,7 @@ void Argument::printInfo(ostream &os, unsigned char indentionLevel) const
if(abbreviation()) {
os << '-' << abbreviation();
}
if(requiredValueCount() != 0) {
if(requiredValueCount()) {
unsigned int valueNamesPrint = 0;
for(auto i = valueNames().cbegin(), end = valueNames().cend(); i != end && valueNamesPrint < requiredValueCount(); ++i) {
os << ' ' << '[' << *i << ']';
@ -307,7 +327,7 @@ void ArgumentParser::addMainArgument(Argument *argument)
}
/*!
* \brief Prints help information for all main arguments which have been set using setMainArguments().
* \brief Prints help text for all assigned arguments.
*/
void ArgumentParser::printHelp(ostream &os) const
{

55
application/argumentparser.h

@ -68,20 +68,46 @@ constexpr bool operator&(ValueCompletionBehavior lhs, ValueCompletionBehavior rh
Argument LIB_EXPORT *firstPresentUncombinableArg(const ArgumentVector &args, const Argument *except);
/*!
* \brief The ArgumentOccurance struct holds argument values for an occurance of an argument.
*/
struct LIB_EXPORT ArgumentOccurance
{
ArgumentOccurance(std::size_t index);
ArgumentOccurance(std::size_t index, const std::vector<Argument *> parentPath, Argument *parent);
/*!
* \brief The index of the occurance. This is not necessarily the index in the argv array.
*/
std::size_t index;
/*!
* \brief The parameter values which have been specified after the occurance of the argument.
*/
std::vector<const char *> values;
/*!
* \brief The "path" of the occurance (the parent elements which have been specified before).
* \remarks Empty for top-level occurances.
*/
std::vector<Argument *> path;
};
/*!
* \brief Constructs an argument occurance for the specified \a index.
*/
inline ArgumentOccurance::ArgumentOccurance(std::size_t index) :
index(index)
{}
/*!
* \brief Constructs an argument occurance.
* \param index Specifies the index.
* \param parentPath Specifies the path of \a parent.
* \param parent Specifies the parent which might be nullptr for top-level occurances.
*
* The path of the new occurance is built from the specified \a parentPath and \a parent.
*/
inline ArgumentOccurance::ArgumentOccurance(std::size_t index, const std::vector<Argument *> parentPath, Argument *parent) :
index(index),
path(parentPath)
@ -105,11 +131,14 @@ public:
void setName(const char *name);
char abbreviation() const;
void setAbbreviation(char abbreviation);
const char *environmentVariable() const;
void setEnvironmentVariable(const char *environmentVariable);
const char *description() const;
void setDescription(const char *description);
const char *example() const;
void setExample(const char *example);
const std::vector<const char *> &values(std::size_t occurrance = 0) const;
const char *firstValue() const;
std::size_t requiredValueCount() const;
void setRequiredValueCount(std::size_t requiredValueCount);
const std::vector<const char *> &valueNames() const;
@ -150,6 +179,7 @@ public:
private:
const char *m_name;
char m_abbreviation;
const char *m_environmentVar;
const char *m_description;
const char *m_example;
std::size_t m_minOccurrences;
@ -259,6 +289,24 @@ inline void Argument::setAbbreviation(char abbreviation)
m_abbreviation = abbreviation;
}
/*!
* \brief Returns the environment variable queried when firstValue() is called.
* \sa firstValue(), setEnvironmentVariable()
*/
inline const char *Argument::environmentVariable() const
{
return m_environmentVar;
}
/*!
* \brief Sets the environment variable queried when firstValue() is called.
* \sa firstValue(), environmentVariable()
*/
inline void Argument::setEnvironmentVariable(const char *environmentVariable)
{
m_environmentVar = environmentVariable;
}
/*!
* \brief Returns the description of the argument.
*
@ -300,9 +348,10 @@ inline void Argument::setExample(const char *example)
}
/*!
* \brief Returns the additional values for the argument.
*
* These values set by the parser when parsing the command line arguments.
* \brief Returns the parameter values for the specified \a occurrance of argument.
* \remarks
* - The values are set by the parser when parsing the command line arguments.
* - The specified \a occurance must be less than occurrences().
*/
inline const std::vector<const char *> &Argument::values(std::size_t occurrance) const
{

17
tests/argumentparsertests.cpp

@ -12,6 +12,7 @@
#include <cppunit/TestFixture.h>
#include <cstring>
#include <cstdlib>
using namespace std;
using namespace ApplicationUtilities;
@ -64,7 +65,14 @@ void ArgumentParserTests::testArgument()
argument.addSubArgument(&subArg);
CPPUNIT_ASSERT_EQUAL(subArg.parents().at(0), &argument);
CPPUNIT_ASSERT(!subArg.conflictsWithArgument());
CPPUNIT_ASSERT(!argument.firstValue());
argument.setEnvironmentVariable("PATH");
if(getenv("PATH")) {
CPPUNIT_ASSERT(argument.firstValue());
CPPUNIT_ASSERT(!strcmp(argument.firstValue(), getenv("PATH")));
} else {
CPPUNIT_ASSERT(!argument.firstValue());
}
}
/*!
@ -82,6 +90,7 @@ void ArgumentParserTests::testParsing()
Argument fileArg("file", 'f', "specifies the path of the file to be opened");
fileArg.setValueNames({"path"});
fileArg.setRequiredValueCount(1);
fileArg.setEnvironmentVariable("PATH");
Argument filesArg("files", 'f', "specifies the path of the file(s) to be opened");
filesArg.setValueNames({"path 1", "path 2"});
filesArg.setRequiredValueCount(-1);
@ -259,6 +268,12 @@ void ArgumentParserTests::testParsing()
CPPUNIT_ASSERT(!displayTagInfoArg.isPresent());
CPPUNIT_ASSERT(!filesArg.isPresent());
CPPUNIT_ASSERT(!fileArg.isPresent());
if(getenv("PATH")) {
CPPUNIT_ASSERT(fileArg.firstValue());
CPPUNIT_ASSERT(!strcmp(fileArg.firstValue(), getenv("PATH")));
} else {
CPPUNIT_ASSERT(!fileArg.firstValue());
}
// test required value count constraint with sufficient number of provided parameters
qtConfigArgs.qtWidgetsGuiArg().reset();

Loading…
Cancel
Save