 |
ewmscp
..
|
Go to the documentation of this file.
76 std::ostream&
operator<< (std::ostream &aStream,
const internal::sourceItem& aItem);
78 std::istream&
operator>> (std::istream &aStream,
const char*& aCstring);
95 operator const T& ()
const {
114 operator T ()
const {
132 static std::string gMultipliers(
"kMGTPEZY");
133 aStream << gMultipliers.at(m - 1);
140 if (!aStream.eof()) {
141 auto c = aStream.peek();
142 static std::string gMultipliers(
"kMGTPEZY");
143 auto m = gMultipliers.find(c);
144 if (m != std::string::npos) {
146 n = n << ((m + 1) * 10);
156 const T& oerks = aWrapper;
162 using escapedIO::operator>>;
167 namespace escapedIO {
168 std::ostream&
operator<<(std::ostream& aStream,
const std::string& aString);
169 std::istream&
operator>>(std::istream& aStream, std::string& aString);
197 static std::map<std::string, base*> gOptions;
201 static std::map<char, base*> gShortOptions;
202 return gShortOptions;
221 virtual void fHandleOption(
int argc,
const char *argv[],
int *i);
224 virtual void fWriteCfgLines(std::ostream& aStream,
const char *aPrefix)
const;
232 base(
char aShortName,
const std::string& aLongName,
const std::string& aExplanation,
short aNargs);
239 virtual void fWriteValue(std::ostream& aStream)
const = 0;
244 virtual void fRequire(std::vector<const base*> aOtherOptions);
247 template <
typename InputIt>
void fRequire(InputIt aBegin, InputIt aEnd) {
248 for (
auto it = aBegin; it != aEnd; ++it) {
255 virtual void fForbid(std::vector<const base*> aOtherOptions);
257 template <
typename InputIt>
void fForbid(InputIt aBegin, InputIt aEnd) {
258 for (
auto it = aBegin; it != aEnd; ++it) {
293 optionError(aOffendingOption,
"value out of range") {}
303 using escapedIO::operator<<;
304 std::ostringstream valueString;
305 valueString << aBadValue;
315 conversionError(
const base* aOffendingOption,
const std::string& aBadArgument,
const std::type_info& aType) :
316 optionError(aOffendingOption,
"conversion failed"),
327 template <
typename T>
void conCatStr(std::ostringstream& msg,
const T& begin) {
330 template <
typename T,
typename ... Args>
inline void conCatStr(std::ostringstream& msg,
332 const Args& ... args) {
334 if (
sizeof...(args)) {
338 template <
typename ... Args>
inline std::string
conCat(
const Args& ... args) {
339 std::ostringstream msg;
350 static std::map<int, base*> gPositinalArgs;
351 return gPositinalArgs;
386 void fPrintOptionHelp(std::ostream& aMessageStream,
const base& aOption, std::size_t aMaxName, std::size_t aMaxExplain,
size_t lineLenght)
const;
389 parser(
const std::string& aDescription =
"",
const std::string& aTrailer =
"",
const std::vector<std::string>& aSearchPaths = {
"/etc/",
"~/.",
"~/.config/",
"./."});
407 virtual void fRequire(std::vector<const base*> aOtherOptions);
415 const std::vector<std::string>&
fParse(
int argc,
const char *argv[]);
418 const std::vector<std::string>&
fParse(
int argc,
char *argv[]);
445 template <
typename T,
bool forceRangeValueTypeString = false>
class typed_base:
public base {
448 typedef typename std::conditional < std::is_same<T, const char *>::value || forceRangeValueTypeString, std::string, T >::type
rangeValueType;
449 typedef typename std::conditional<forceRangeValueTypeString, std::string, T>::type
compareValueType;
461 template <
typename TT = std::
string>
typename std::enable_if < (!std::is_same<rangeValueType, std::string>::value) && std::is_same<TT, std::string>::value,
void >::type
fAddToRange(
const TT& aString) {
462 std::stringstream buf(aString);
464 buf >> std::setbase(0);
465 using escapedIO::operator>>;
470 template <
typename InputIt>
void fAddToRange(InputIt aBegin, InputIt aEnd) {
471 for (
auto it = aBegin; it != aEnd; ++it) {
476 template <
typename TT>
void fAddToRange(
const std::vector<TT>& aRange) {
482 std::getline(aStream, buf);
483 std::stringstream sbuf(buf);
484 while (!sbuf.eof()) {
486 using escapedIO::operator>>;
487 sbuf >> std::setbase(0) >> value;
492 using escapedIO::operator<<;
494 aStream <<
"# allowed range is";
496 aStream <<
" [" << *(
lRange.cbegin()) <<
"," << *(
lRange.crbegin()) <<
"]\n";
499 for (
const auto& it :
lRange) {
500 aStream <<
" " << it;
507 using escapedIO::operator<<;
510 }
else if (
lRange.size() == 2) {
511 if (*(
lRange.cbegin()) <= aValue && aValue <= *(
lRange.crbegin())) {
517 for (
const auto& it :
lRange) {
534 public std::conditional < std::is_fundamental<T>::value || std::is_same<T, const char*>::value,
535 fundamental_wrapper<T>,
539 typedef typename std::conditional < std::is_fundamental<T>::value || std::is_same<T, const char*>::value,
546 single(
char aShortName,
const std::string& aLongName,
const std::string& aExplanation, T aDefault,
const std::vector<T>& aRange = {}) :
549 if (!aRange.empty()) {
553 single(
char aShortName,
const std::string& aLongName,
const std::string& aExplanation) :
554 internal::
typed_base<T>(aShortName, aLongName, aExplanation, 1) {
559 T& thisAsReference(*
this);
560 return thisAsReference = aValue;
565 using escapedIO::operator>>;
566 aStream >> std::setbase(0) >> *
this;
570 using escapedIO::operator<<;
579 using escapedIO::operator>>;
580 aStream >> std::setbase(0) >> std::noskipws >> *
this;
581 if (aStream.fail()) {
599 single(
char aShortName,
const std::string& aLongName,
const std::string& aExplanation,
bool aDefault =
false) :
601 base(aShortName, aLongName, aExplanation, 0),
610 void fWriteValue(std::ostream& aStream)
const override;
623 namespace escapedIO {
624 std::istream&
operator>> (std::istream &aStream,
const char*& aCstring);
635 std::map<const T*, const internal::sourceItem>
lSources;
637 baseForMap(
char aShortName, std::string aLongName, std::string aExplanation,
short aNargs) :
638 typed_base<T>(aShortName, aLongName, aExplanation, aNargs) {};
640 lSources.insert(std::make_pair(aValueLocation, aSource));
643 auto it =
lSources.find(aValueLocation);
657 aStream.ignore(std::numeric_limits<std::streamsize>::max(),
' ');
671 template <
typename T,
typename Container = std::map<std::
string, T>>
class map:
public internal::baseForMap<T>,
public Container {
673 map(
char aShortName,
const std::string& aLongName,
const std::string& aExplanation,
674 std::initializer_list<typename Container::value_type> aDefault = {}) :
676 for (
const auto& defaultValue : aDefault) {
677 this->insert(this->end(), defaultValue);
685 for (
const auto& it : *
this) {
689 using escapedIO::operator<<;
690 aStream << it.second <<
"\n";
692 if (!source.fIsUnset()) {
693 aStream <<
"# set from " << source <<
"\n";
699 using escapedIO::operator<<;
703 for (
const auto& it : *
this) {
708 template <
typename C = Container>
709 typename std::enable_if<std::is_same<std::map<typename std::remove_const<typename Container::value_type::first_type>::type,
710 typename Container::value_type::second_type>,
712 typename C::iterator>::type
714 (*this)[aPair.first] = aPair.second;
715 return this->find(aPair.first);
717 template <
typename C = Container>
718 typename std::enable_if < !std::is_same<std::map<typename std::remove_const<typename Container::value_type::first_type>::type,
719 typename Container::value_type::second_type>,
721 typename Container::iterator >::type
723 return this->insert(this->end(), aPair);
733 using escapedIO::operator>>;
734 aStream >> std::setbase(0) >> value;
735 if (aStream.fail()) {
741 typename std::remove_const<typename Container::value_type::first_type>::type key;
742 std::istringstream conversionStream(name);
743 conversionStream >> key;
744 if (conversionStream.fail()) {
747 auto result = (*this).insertOrUpdate(std::make_pair(key, value));
752 for (
const auto& pair : *
this) {
757 typename std::add_rvalue_reference<std::add_const<Container>>::type
fGetValue()
const {
758 return *
static_cast<typename std::add_pointer<std::add_const<Container>
>::type>(
this);
770 baseForContainer(
char aShortName, std::string aLongName, std::string aExplanation,
short aNargs) :
771 typed_base<T>(aShortName, aLongName, aExplanation, aNargs) {};
779 aStream.ignore(std::numeric_limits<std::streamsize>::max(),
' ');
791 container(
char aShortName,
const std::string& aLongName,
const std::string& aExplanation,
792 std::initializer_list<typename Container::value_type> aDefault = {}) :
794 for (
const auto& defaultValue : aDefault) {
795 this->push_back(defaultValue);
801 aStream << aPrefix << this->
lLongName <<
"=value\n";
804 for (
auto it = this->begin(); it != this->end(); ++it, ++it2) {
805 aStream << (it2->fIsUnset() ? aPrefix :
"") << this->
lLongName <<
"=";
807 using escapedIO::operator<<;
808 aStream << *it <<
"\n";
810 if (!it2->fIsUnset()) {
811 aStream <<
"# set from " << *it2 <<
"\n";
822 for (
auto it = this->begin(); it != this->end(); ++it) {
823 using escapedIO::operator<<;
824 aStream << *it <<
" ";
831 aStream >> std::setbase(0);
833 using namespace escapedIO;
836 if (aStream.fail()) {
842 this->push_back(value);
847 for (
const auto& value : *
this) {
868 void fWriteOriginalString(std::ostream& aStream)
const;
870 return lOriginalString;
878 template <
class ... Types>
positional(
int aOrderingNumber, Types ... args) :
880 internal::positional_base(aOrderingNumber, this) {
882 typename T::valueType
operator=(
const typename T::valueType& aValue) {
883 return *
this = aValue;
890 template<
class ... Types>
withAction(std::function<
void(T&)> aAction, Types ... args) :
895 T::fSetMe(aStream, aSource);
900 T::fSetMeNoarg(aSource);
~rangeError() override=default
void fHelp()
print help, normally automatically called by the –help option or in case of problems.
T::valueType operator=(const typename T::valueType &aValue)
bool lMinusMinusJustEndsOptions
static void fPrintEscapedString(std::ostream &aStream, const std::string &aString)
void fSetPreserveWorthyStuff(std::vector< std::string > *aStuff)
virtual void fSetMeNoarg(const internal::sourceItem &)
std::ostream * lMessageStream
class that contains the parser, i.e. does that option handling
generic option class with any type that can be used with std::istream and std::ostream
void fWriteCfgFile(const std::string &aFileName)
std::vector< std::string > lUnusedOptions
bool fIsParsingDone() const
~optionError() override=default
std::enable_if< std::is_same< std::map< typename std::remove_const< typename Container::value_type::first_type >::type, typename Container::value_type::second_type >, C >::value, typename C::iterator >::type insertOrUpdate(typename C::value_type aPair)
const std::string & fGetBadValue() const
postFixedNumber & operator=(const T aValue)
std::string lExecutableName
postFixedNumber(T aValue)
rangeError(const base *aOffendingOption)
int fGetHelpReturnValue() const
fundamental_wrapper(T aValue)
virtual void fAddToRange(rangeValueType aValue)
add a value to the range of allowed values
const std::string & fGetLongName() const
returns long name of option, usually only for internal use.
interface class that is used for options where the original string rather than the streamed value is ...
const std::vector< std::string > & fParse(int argc, const char *argv[])
parse the options on the command line
void fCheckRange() const override
decltype(lFile) fGetFile() const
void fCheckRange() const override
std::vector< std::string > lStuffAfterMinusMinus
baseForContainer(char aShortName, std::string aLongName, std::string aExplanation, short aNargs)
conversionError(const base *aOffendingOption, const std::string &aBadArgument, const std::type_info &aType)
std::conditional< std::is_same< T, const char * >::value||forceRangeValueTypeString, std::string, T >::type rangeValueType
virtual void fCheckValueForRange(const compareValueType &aValue) const
virtual bool fIsSet() const
check if this option was set, regardless of from command line or config file
const std::vector< std::string > lSearchPaths
std::string lOriginalString
typedRangeError(const base *aOffendingOption, const T &aBadValue)
void fAddToRange(InputIt aBegin, InputIt aEnd)
add values from the iterator range [aBegin,aEnd) to the range of allowed values
void fForbid(InputIt aBegin, InputIt aEnd)
add all options from the pair of iterators [aBegin,aEnd) to the list of forbidden options
void fSetMe(std::istream &aStream, const internal::sourceItem &aSource) override
function to set the value from a string, remembering the source
const std::string lLongName
container(char aShortName, const std::string &aLongName, const std::string &aExplanation, std::initializer_list< typename Container::value_type > aDefault={})
positional_base(int aOrderingNumber, base *aAsBase)
const std::string & fGetOriginalString() const
void fAddToRange(const std::vector< TT > &aRange)
add values from a vector (may be given as initializer list) to the range of allowed values
std::enable_if< !std::is_same< std::map< typename std::remove_const< typename Container::value_type::first_type >::type, typename Container::value_type::second_type >, C >::value, typename Container::iterator >::type insertOrUpdate(typename C::value_type aPair)
void fReadConfigFiles()
read config files if present
void fPrintOptionHelp(std::ostream &aMessageStream, const base &aOption, std::size_t aMaxName, std::size_t aMaxExplain, size_t lineLenght) const
std::vector< std::string > * lPreserveWorthyStuff
bool fIsSet() const override
check if this option was set, regardless of from command line or config file
typed_base(Types ... args)
T operator=(const T &aValue)
std::vector< internal::sourceItem > lSources
virtual void fAddDefaultFromStream(std::istream &aStream)=0
special for use in the shellScriptOptionParser
positional(int aOrderingNumber, Types ... args)
const std::string & fGetArgument() const
internal::sourceItem lSource
withAction(std::function< void(T &)> aAction, Types ... args)
void conCatStr(std::ostringstream &msg, const T &begin)
template for map-based options.
void fSetErrorStream(std::ostream *aStream)
virtual void fWriteCfgLines(std::ostream &aStream, const char *aPrefix) const
char fGetSecondaryAssignment() const
void fSetMe(std::istream &aStream, const internal::sourceItem &aSource) override
function to set the value from a string, remembering the source
virtual void fForbid(const base *aOtherOption)
forbid aOtherOption when this option is set
void fDisable()
disable option by removing it from the maps
void fHide()
hide option, will be respected by help
void fReadCfgFile(const std::string &aFileName, const options::internal::sourceItem &aSource, bool aMayBeAbsent=false)
const std::string lDescription
const std::vector< std::string > & fGetStuffAfterMinusMinus()
get trailong part of command line as a vector od strings, requires that fSetMinusMinusStartsExtraList...
std::conditional< std::is_fundamental< T >::value||std::is_same< T, const char * >::value, fundamental_wrapper< T >, T >::type deriveFromType
char lSecondaryAssignment
std::istream & operator>>(std::istream &aStream, const char *&aCstring)
std::vector< const base * > lRequiredOptions
void(* valuePrinterType)(std::ostream &, const T &)
virtual void fSetValuePrinter(valuePrinterType aValuePrinter)
virtual void fRequire(const base *aOtherOption)
require aOtherOption when this option is set
virtual void fWriteRange(std::ostream &) const
base(char aShortName, const std::string &aLongName, const std::string &aExplanation, short aNargs)
construct an object of type base
template for container-based options.
const std::type_info & fGetType() const
void fSetMe(std::istream &aStream, const internal::sourceItem &aSource) override
static const sourceFile gUnsetSource
static void fReCaptureEscapedString(std::string &aDest, const std::string &aSource)
template interface class for options that provide a value printer
std::ostream & operator<<(std::ostream &aStream, const std::string &aString)
single(char aShortName, const std::string &aLongName, const std::string &aExplanation, bool aDefault=false)
void fSetAssignmentChars(char aPrimary='=', char aSecondary=':')
void fWriteValue(std::ostream &aStream) const override
write textual representation of value to a std::ostream
single(char aShortName, const std::string &aLongName, const std::string &aExplanation, T aDefault, const std::vector< T > &aRange={})
construct an object of single<T>
fundamental_wrapper & operator=(const T aValue)
const T & fGetValue() const
const std::string lExplanation
std::ostream * lErrorStream
bool operator=(const bool &aValue)
static const sourceFile gCmdLine
virtual void fWriteValue(std::ostream &aStream) const =0
write textual representation of value to a std::ostream
std::ostream & fGetErrorStream() const
single(char aShortName, const std::string &aLongName, const std::string &aExplanation)
virtual void fSetMe(std::istream &aStream, const internal::sourceItem &aSource)=0
function to set the value from a string, remembering the source
valuePrinter(valuePrinterType aValuePrinter)
void fSetHelpReturnValue(int aValue)
std::ostream & operator<<(std::ostream &aStream, const internal::sourceItem &aItem)
operator to write sourceItems to a stream
virtual bool fIsContainer() const
wrapper class for fundamental types
const std::string & fGetProgName() const
map(char aShortName, const std::string &aLongName, const std::string &aExplanation, std::initializer_list< typename Container::value_type > aDefault={})
std::function< void(T &)> action
std::enable_if<(!std::is_same< rangeValueType, std::string >::value) &&std::is_same< TT, std::string >::value, void >::type fAddToRange(const TT &aString)
void fSetMinusMinusStartsExtraList()
switch on use of – to separate a trailer on the command line that is not to be parsed
std::string conCat(const Args &... args)
void fRequire(InputIt aBegin, InputIt aEnd)
add all options from the pair of iterators [aBegin,aEnd) to the list of required options
const base & offendingOption
static std::map< int, base * > & fGetPositonalArgs()
static std::map< std::string, base * > & fGetOptionMap()
void fAddDefaultFromStream(std::istream &aStream) override
special for use in the shellScriptOptionParser
void fWriteRange(std::ostream &aStream) const override
void fWriteCfgLines(std::ostream &aStream, const char *aPrefix) const override
std::add_rvalue_reference< std::add_const< Container > >::type fGetValue() const
T operator=(const T &aValue)
const sourceFile & lParent
class to remember from which line (or item) of a file/line an option was set from
const std::string lTrailer
decltype(lLineNumber) fGetLineNumber() const
~typedRangeError() override=default
static parser * fGetInstance()
get the only allwed instance of the option parser.
const base & fGetOption() const
void fAddToRangeFromStream(std::istream &) override
special for use in the shellScriptOptionParser
void fAddToRangeFromStream(std::istream &aStream) override
This class is an intermediate helper class for options that are container-based.
static std::map< char, base * > & fGetShortOptionMap()
void fWriteValue(std::ostream &aStream) const override
write textual representation of value to a std::ostream
void fSetMe(std::istream &aStream, const internal::sourceItem &aSource) override
function to set the value from a string, remembering the source
optionError(const base *aOffendingOption, const std::string &aWhat)
void fCheckRange() const override
void fWriteCfgLines(std::ostream &aStream, const char *aPrefix) const override
virtual void fComplainAndLeave(bool aWithHelp=true)
print help (if required) and exit.
std::set< const base * > lRequiredOptions
parser(const std::string &aDescription="", const std::string &aTrailer="", const std::vector< std::string > &aSearchPaths={"/etc/", "~/.", "~/.config/", "./."})
void fCheckRange() const override
bool fIsContainer() const override
virtual void fCheckRange() const =0
virtual void fAddToRangeFromStream(std::istream &aStream)=0
special for use in the shellScriptOptionParser
void fAddDefaultFromStream(std::istream &aStream) override
special for use in the shellScriptOptionParser
void fSetMessageStream(std::ostream *aStream)
const std::type_info & type
virtual void fSetSource(const internal::sourceItem &aSource)
remember the source that provided the value, e.g. commandline or a config file
class to remember the file (or cmd line) an option was set from
sourceFile(const std::string &aName, decltype(lParent) aParent)
void fSetExecutableName(const char *aName)
std::istream & operator>>(std::istream &aStream, postFixedNumber< T > &aNumber)
sourceItem(decltype(lFile) aFile, decltype(lLineNumber) aLineNumber)
void fWriteValue(std::ostream &aStream) const override
write textual representation of value to a std::ostream
std::multiset< rangeValueType > lRange
std::vector< const base * > lForbiddenOptions
~conversionError() override=default
void fSetMeNoarg(const internal::sourceItem &aSource) override
valuePrinterType lValuePrinter
const std::string & fGetName() const
std::conditional< forceRangeValueTypeString, std::string, T >::type compareValueType
virtual void fHandleOption(int argc, const char *argv[], int *i)
virtual void fRequire(const base *aOtherOption)