From 00f07eb977302554bfd70552bca07341d8639ceb Mon Sep 17 00:00:00 2001 From: macbishop Date: Thu, 14 Jun 2007 21:02:01 +0000 Subject: [PATCH] Use ArgTraits instead of ValueExtractor specialization Bug 1711487 --- examples/Makefile.am | 5 +- examples/test11.cpp | 52 +++++ examples/test12.cpp | 68 +++++++ include/tclap/Arg.h | 94 +++++++++ include/tclap/MultiArg.h | 419 ++++++++++++++------------------------- include/tclap/ValueArg.h | 158 ++------------- tests/runtests.sh | 3 +- tests/test63.out | 9 + tests/test63.sh | 13 ++ tests/test64.out | 1 + tests/test64.sh | 13 ++ tests/test65.out | 9 + tests/test65.sh | 14 ++ tests/test66.out | 9 + tests/test66.sh | 13 ++ tests/test67.out | 9 + tests/test67.sh | 13 ++ tests/testCheck.sh | 2 +- 18 files changed, 488 insertions(+), 416 deletions(-) create mode 100644 examples/test11.cpp create mode 100644 examples/test12.cpp create mode 100644 tests/test63.out create mode 100644 tests/test63.sh create mode 100644 tests/test64.out create mode 100644 tests/test64.sh create mode 100644 tests/test65.out create mode 100644 tests/test65.sh create mode 100644 tests/test66.out create mode 100644 tests/test66.sh create mode 100644 tests/test67.out create mode 100644 tests/test67.sh diff --git a/examples/Makefile.am b/examples/Makefile.am index 12db091..1f559be 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,5 +1,6 @@ -noinst_PROGRAMS = test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 +noinst_PROGRAMS = test1 test2 test3 test4 test5 test6 test7 test8 test9 \ + test10 test11 test12 test1_SOURCES = test1.cpp test2_SOURCES = test2.cpp @@ -11,6 +12,8 @@ test7_SOURCES = test7.cpp test8_SOURCES = test8.cpp test9_SOURCES = test9.cpp test10_SOURCES = test10.cpp +test11_SOURCES = test11.cpp +test12_SOURCES = test12.cpp INCLUDES = -I$(top_srcdir)/include diff --git a/examples/test11.cpp b/examples/test11.cpp new file mode 100644 index 0000000..f7d06fe --- /dev/null +++ b/examples/test11.cpp @@ -0,0 +1,52 @@ +#include "tclap/CmdLine.h" +#include + +using namespace TCLAP; + +// Define a simple 3D vector type +struct Vect3D { + double v[3]; + + // operator= will be used to assign to the vector + Vect3D& operator=(const std::string &str) + { + std::istringstream iss(str); + if (!(iss >> v[0] >> v[1] >> v[2])) + throw TCLAP::ArgParseException(str + " is not a 3D vector"); + + return *this; + } + + std::ostream& print(std::ostream &os) const + { + std::copy(v, v + 3, std::ostream_iterator(os, " ")); + return os; + } +}; + +// Create an ArgTraits for the 3D vector type that declares it to be +// of string like type +namespace TCLAP { +template<> +struct ArgTraits { + typedef StringLike ValueCategory; +}; +} + +int main(int argc, char *argv[]) +{ + CmdLine cmd("Command description message", ' ', "0.9"); + ValueArg vec("v", "vect", "vector", + true, Vect3D(), "3D vector", cmd); + + try { + cmd.parse(argc, argv); + } catch(std::exception &e) { + std::cout << e.what() << std::endl; + return EXIT_FAILURE; + } + + vec.getValue().print(std::cout); + std::cout << std::endl; +} + diff --git a/examples/test12.cpp b/examples/test12.cpp new file mode 100644 index 0000000..21016ea --- /dev/null +++ b/examples/test12.cpp @@ -0,0 +1,68 @@ +#include "tclap/CmdLine.h" +#include +#include + +using namespace TCLAP; + +// Define a simple 3D vector type +struct Vect3D { + double v[3]; + + // operator= will be used to assign to the vector + Vect3D& operator=(const std::string &str) + { + std::istringstream iss(str); + if (!(iss >> v[0] >> v[1] >> v[2])) + throw TCLAP::ArgParseException(str + " is not a 3D vector"); + + return *this; + } + + std::ostream& print(std::ostream &os) const + { + std::copy(v, v + 3, std::ostream_iterator(os, " ")); + return os; + } + +}; + +std::ostream& operator<<(std::ostream &os, const Vect3D &v) +{ + return v.print(os); +} + +// Create an ArgTraits for the 3D vector type that declares it to be +// of string like type +namespace TCLAP { +template<> +struct ArgTraits { + typedef StringLike ValueCategory; +}; +} + +int main(int argc, char *argv[]) +{ + CmdLine cmd("Command description message", ' ', "0.9"); + MultiArg vec("v", "vect", "vector", + true, "3D vector", cmd); + + try { + cmd.parse(argc, argv); + } catch(std::exception &e) { + std::cout << e.what() << std::endl; + return EXIT_FAILURE; + } + + std::copy(vec.begin(), vec.end(), + std::ostream_iterator(std::cout, "\n")); + + std::cout << "REVERSED" << std::endl; + + // use alt. form getValue() + std::vector v(vec.getValue()); + std::reverse(v.begin(), v.end()); + + std::copy(v.begin(), v.end(), + std::ostream_iterator(std::cout, "\n")); +} + diff --git a/include/tclap/Arg.h b/include/tclap/Arg.h index 5a66754..4223917 100644 --- a/include/tclap/Arg.h +++ b/include/tclap/Arg.h @@ -24,11 +24,27 @@ #ifndef TCLAP_ARGUMENT_H #define TCLAP_ARGUMENT_H +#ifdef HAVE_CONFIG_H +#include +#else +#define HAVE_SSTREAM +#endif + #include #include #include #include +#if defined(HAVE_SSTREAM) +#include +typedef std::istringstream istringstream; +#elif defined(HAVE_STRSTREAM) +#include +typedef std::istrstream istringstream; +#else +#error "Need a stringstream (sstream or strstream) to compile!" +#endif + #include #include #include @@ -350,6 +366,84 @@ typedef std::vector::iterator ArgVectorIterator; */ typedef std::list::iterator VisitorListIterator; +// We use two empty structs to get compile type specialization +// function to work + +/** + * A value like argument value type is a value that can be set using + * operator>>. This is the default value type. + */ +struct ValueLike {}; + +/** + * A string like argument value type is a value that can be set using + * operator=(string). Usefull if the value type contains spaces which + * will be broken up into individual tokens by operator>>. + */ +struct StringLike {}; + +/** + * Arg traits are used to get compile type specialization when parsing + * argument values. Using an ArgTraits you can specify the way that + * values gets assigned to any particular type during parsing. The two + * supported types are string like and value like. + */ +template +struct ArgTraits { + typedef ValueLike ValueCategory; +}; + +/** + * Strings have string like argument traits. + */ +template<> +struct ArgTraits { + typedef StringLike ValueCategory; +}; + +/* + * Extract a value of type T from it's string representation contained + * in strVal. The ValueLike parameter used to select the correct + * specialization of ExtractValue depending on the value traits of T. + * ValueLike traits use operator>> to assign the value from strVal. + */ +template void +ExtractValue(T &destVal, const std::string& strVal, ValueLike vl) +{ + std::istringstream is(strVal); + + int valuesRead = 0; + while ( is.good() ) { + if ( is.peek() != EOF ) + is >> destVal; + else + break; + + valuesRead++; + } + + if ( is.fail() ) + throw( ArgParseException("Couldn't read argument value " + "from string '" + strVal + "'")); + + + if ( valuesRead > 1 ) + throw( ArgParseException("More than one valid value parsed from " + "string '" + strVal + "'")); + +} + +/* + * Extract a value of type T from it's string representation contained + * in strVal. The ValueLike parameter used to select the correct + * specialization of ExtractValue depending on the value traits of T. + * StringLike uses assignment (operator=) to assign from strVal. + */ +template void +ExtractValue(T &destVal, const std::string& strVal, StringLike sl) +{ + destVal = strVal; +} ////////////////////////////////////////////////////////////////////// //BEGIN Arg.cpp diff --git a/include/tclap/MultiArg.h b/include/tclap/MultiArg.h index 341e0e4..53115c2 100644 --- a/include/tclap/MultiArg.h +++ b/include/tclap/MultiArg.h @@ -29,135 +29,7 @@ #include #include -#ifdef HAVE_CONFIG_H -#include -#else -#define HAVE_SSTREAM -#endif - -#if defined(HAVE_SSTREAM) -#include -#elif defined(HAVE_STRSTREAM) -#include -#else -#error "Need a stringstream (sstream or strstream) to compile!" -#endif - namespace TCLAP { - -template class MultiArg; - -namespace MULTI_ARG_HELPER { - -enum Error_e { EXTRACT_FAILURE = 1000, EXTRACT_TOO_MANY }; - -/** - * This class is used to extract a value from an argument. - * It is used because we need a special implementation to - * deal with std::string and making a specialiced function - * puts it in the T segment, thus generating link errors. - * Having a specialiced class makes the symbols weak. - * This is not pretty but I don't know how to make it - * work any other way. - */ -template -class ValueExtractor -{ - friend class MultiArg; - - private: - - /** - * Reference to the vector of values where the result of the - * extraction will be put. - */ - std::vector &_values; - - /** - * Constructor. - * \param values - Where the values extracted will be put. - */ - ValueExtractor(std::vector &values) : _values(values) {} - - /** - * Method that will attempt to parse the input stream for values - * of type T. - * \param val - Where the values parsed will be put. - */ - int extractValue( const std::string& val ) - { - T temp; - -#if defined(HAVE_SSTREAM) - std::istringstream is(val); -#elif defined(HAVE_STRSTREAM) - std::istrstream is(val.c_str()); -#else -#error "Need a stringstream (sstream or strstream) to compile!" -#endif - - int valuesRead = 0; - - while ( is.good() ) - { - if ( is.peek() != EOF ) - is >> temp; - else - break; - - valuesRead++; - } - - if ( is.fail() ) - return EXTRACT_FAILURE; - - if ( valuesRead > 1 ) - return EXTRACT_TOO_MANY; - - _values.push_back(temp); - - return 0; - } -}; - -/** - * Specialization for string. This is necessary because istringstream - * operator>> is not able to ignore spaces... meaning -x "X Y" will only - * read 'X'... and thus the specialization. - */ -template<> -class ValueExtractor -{ - friend class MultiArg; - - private: - - /** - * Reference to the vector of strings where the result of the - * extraction will be put. - */ - std::vector &_values; - - /** - * Constructor. - * \param values - Where the strings extracted will be put. - */ - ValueExtractor(std::vector &values) : _values(values) {} - - /** - * Method that will attempt to parse the input stream for values - * of type std::string. - * \param val - Where the values parsed will be put. - */ - int extractValue( const std::string& val ) - { - _values.push_back( val ); - return 0; - } -}; - -} //namespace MULTI_ARG_HELPER - /** * An argument that allows multiple values of type T to be specified. Very * similar to a ValueArg, except a vector of values will be returned @@ -166,78 +38,83 @@ class ValueExtractor template class MultiArg : public Arg { - protected: +public: + typedef std::vector container_type; + typedef typename container_type::iterator iterator; + typedef typename container_type::const_iterator const_iterator; - /** - * The list of values parsed from the CmdLine. - */ - std::vector _values; +protected: - /** - * The description of type T to be used in the usage. - */ - std::string _typeDesc; + /** + * The list of values parsed from the CmdLine. + */ + std::vector _values; - /** - * A list of constraint on this Arg. - */ - Constraint* _constraint; + /** + * The description of type T to be used in the usage. + */ + std::string _typeDesc; - /** - * Extracts the value from the string. - * Attempts to parse string as type T, if this fails an exception - * is thrown. - * \param val - The string to be read. - */ - void _extractValue( const std::string& val ); + /** + * A list of constraint on this Arg. + */ + Constraint* _constraint; - bool _allowMore; + /** + * Extracts the value from the string. + * Attempts to parse string as type T, if this fails an exception + * is thrown. + * \param val - The string to be read. + */ + void _extractValue( const std::string& val ); - public: + bool _allowMore; - /** - * Constructor. - * \param flag - The one character flag that identifies this - * argument on the command line. - * \param name - A one word name for the argument. Can be - * used as a long flag on the command line. - * \param desc - A description of what the argument is for or - * does. - * \param req - Whether the argument is required on the command - * line. - * \param typeDesc - A short, human readable description of the - * type that this object expects. This is used in the generation - * of the USAGE statement. The goal is to be helpful to the end user - * of the program. - * \param v - An optional visitor. You probably should not - * use this unless you have a very good reason. - */ - MultiArg( const std::string& flag, +public: + + /** + * Constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param typeDesc - A short, human readable description of the + * type that this object expects. This is used in the generation + * of the USAGE statement. The goal is to be helpful to the end user + * of the program. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + MultiArg( const std::string& flag, const std::string& name, const std::string& desc, bool req, const std::string& typeDesc, Visitor* v = NULL); - /** - * Constructor. - * \param flag - The one character flag that identifies this - * argument on the command line. - * \param name - A one word name for the argument. Can be - * used as a long flag on the command line. - * \param desc - A description of what the argument is for or - * does. - * \param req - Whether the argument is required on the command - * line. - * \param typeDesc - A short, human readable description of the - * type that this object expects. This is used in the generation - * of the USAGE statement. The goal is to be helpful to the end user - * of the program. - * \param parser - A CmdLine parser object to add this Arg to - * \param v - An optional visitor. You probably should not - * use this unless you have a very good reason. - */ - MultiArg( const std::string& flag, + /** + * Constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param typeDesc - A short, human readable description of the + * type that this object expects. This is used in the generation + * of the USAGE statement. The goal is to be helpful to the end user + * of the program. + * \param parser - A CmdLine parser object to add this Arg to + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + MultiArg( const std::string& flag, const std::string& name, const std::string& desc, bool req, @@ -245,45 +122,45 @@ class MultiArg : public Arg CmdLineInterface& parser, Visitor* v = NULL ); - /** - * Constructor. - * \param flag - The one character flag that identifies this - * argument on the command line. - * \param name - A one word name for the argument. Can be - * used as a long flag on the command line. - * \param desc - A description of what the argument is for or - * does. - * \param req - Whether the argument is required on the command - * line. - * \param constraint - A pointer to a Constraint object used - * to constrain this Arg. - * \param v - An optional visitor. You probably should not - * use this unless you have a very good reason. - */ - MultiArg( const std::string& flag, + /** + * Constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + MultiArg( const std::string& flag, const std::string& name, const std::string& desc, bool req, Constraint* constraint, Visitor* v = NULL ); - /** - * Constructor. - * \param flag - The one character flag that identifies this - * argument on the command line. - * \param name - A one word name for the argument. Can be - * used as a long flag on the command line. - * \param desc - A description of what the argument is for or - * does. - * \param req - Whether the argument is required on the command - * line. - * \param constraint - A pointer to a Constraint object used - * to constrain this Arg. - * \param parser - A CmdLine parser object to add this Arg to - * \param v - An optional visitor. You probably should not - * use this unless you have a very good reason. - */ - MultiArg( const std::string& flag, + /** + * Constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. + * \param parser - A CmdLine parser object to add this Arg to + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + MultiArg( const std::string& flag, const std::string& name, const std::string& desc, bool req, @@ -291,41 +168,53 @@ class MultiArg : public Arg CmdLineInterface& parser, Visitor* v = NULL ); - /** - * Handles the processing of the argument. - * This re-implements the Arg version of this method to set the - * _value of the argument appropriately. It knows the difference - * between labeled and unlabeled. - * \param i - Pointer the the current argument in the list. - * \param args - Mutable list of strings. Passed from main(). - */ - virtual bool processArg(int* i, std::vector& args); + /** + * Handles the processing of the argument. + * This re-implements the Arg version of this method to set the + * _value of the argument appropriately. It knows the difference + * between labeled and unlabeled. + * \param i - Pointer the the current argument in the list. + * \param args - Mutable list of strings. Passed from main(). + */ + virtual bool processArg(int* i, std::vector& args); - /** - * Returns a vector of type T containing the values parsed from - * the command line. - */ - const std::vector& getValue(); + /** + * Returns a vector of type T containing the values parsed from + * the command line. + */ + const std::vector& getValue(); - /** - * Returns the a short id string. Used in the usage. - * \param val - value to be used. - */ - virtual std::string shortID(const std::string& val="val") const; + /** + * Returns an iterator over the values parsed from the command + * line. + */ + const_iterator begin() const { return _values.begin(); } - /** - * Returns the a long id string. Used in the usage. - * \param val - value to be used. - */ - virtual std::string longID(const std::string& val="val") const; + /** + * Returns the end of the values parsed from the command + * line. + */ + const_iterator end() const { return _values.end(); } - /** - * Once we've matched the first value, then the arg is no longer - * required. - */ - virtual bool isRequired() const; + /** + * Returns the a short id string. Used in the usage. + * \param val - value to be used. + */ + virtual std::string shortID(const std::string& val="val") const; - virtual bool allowMore(); + /** + * Returns the a long id string. Used in the usage. + * \param val - value to be used. + */ + virtual std::string longID(const std::string& val="val") const; + + /** + * Once we've matched the first value, then the arg is no longer + * required. + */ + virtual bool isRequired() const; + + virtual bool allowMore(); }; @@ -492,24 +381,20 @@ bool MultiArg::isRequired() const template void MultiArg::_extractValue( const std::string& val ) { - MULTI_ARG_HELPER::ValueExtractor ve(_values); - - int err = ve.extractValue(val); + try { + T tmp; + ExtractValue(tmp, val, typename ArgTraits::ValueCategory()); + _values.push_back(tmp); + } catch( ArgParseException &e) { + throw ArgParseException(e.error(), toString()); + } - if ( err == MULTI_ARG_HELPER::EXTRACT_FAILURE ) - throw( ArgParseException("Couldn't read argument value " - "from string '" + val + "'", toString() ) ); - - if(err == MULTI_ARG_HELPER::EXTRACT_TOO_MANY) - throw( ArgParseException("More than one valid value " - "parsed from string '" + val + "'", - toString() ) ); - if ( _constraint != NULL ) - if ( ! _constraint->check( _values.back() ) ) - throw( CmdLineParseException( "Value '" + val + - "' does not meet constraint: " + - _constraint->description(), - toString() ) ); + if ( _constraint != NULL ) + if ( ! _constraint->check( _values.back() ) ) + throw( CmdLineParseException( "Value '" + val + + "' does not meet constraint: " + + _constraint->description(), + toString() ) ); } template diff --git a/include/tclap/ValueArg.h b/include/tclap/ValueArg.h index 1f5aa36..5a383d5 100644 --- a/include/tclap/ValueArg.h +++ b/include/tclap/ValueArg.h @@ -29,135 +29,8 @@ #include #include -#ifdef HAVE_CONFIG_H -#include -#else -#define HAVE_SSTREAM -#endif - -#if defined(HAVE_SSTREAM) -#include -#elif defined(HAVE_STRSTREAM) -#include -#else -#error "Need a stringstream (sstream or strstream) to compile!" -#endif - namespace TCLAP { -template class ValueArg; - -namespace VALUE_ARG_HELPER { - -enum Error_e { EXTRACT_FAILURE = 1000, EXTRACT_TOO_MANY }; - -/** - * This class is used to extract a value from an argument. - * It is used because we need a special implementation to - * deal with std::string and making a specialiced function - * puts it in the T segment, thus generating link errors. - * Having a specialiced class makes the symbols weak. - * This is not pretty but I don't know how to make it - * work any other way. - */ -template class ValueExtractor -{ - /** - * - */ - friend class ValueArg; - - private: - - /** - * Reference to the value where the result of the extraction will - * be put. - */ - T &_value; - - /** - * Constructor. - * \param value - Where the value extracted will be put. - */ - ValueExtractor(T &value) : _value(value) { } - - /** - * Method that will attempt to parse the input stream for a value - * of type T. - * \param val - Where the value parsed will be put. - */ - int extractValue( const std::string& val ) - { - -#if defined(HAVE_SSTREAM) - std::istringstream is(val); -#elif defined(HAVE_STRSTREAM) - std::istrstream is(val.c_str()); -#else -#error "Need a stringstream (sstream or strstream) to compile!" -#endif - - int valuesRead = 0; - while ( is.good() ) - { - if ( is.peek() != EOF ) - is >> _value; - else - break; - - valuesRead++; - } - - if ( is.fail() ) - return EXTRACT_FAILURE; - - if ( valuesRead > 1 ) - return EXTRACT_TOO_MANY; - - return 0; - } -}; - -/** - * Specialization for string. This is necessary because istringstream - * operator>> is not able to ignore spaces... meaning -x "X Y" will only - * read 'X'... and thus the specialization. - */ -template<> class ValueExtractor -{ - /** - * - */ - friend class ValueArg; - - private: - - /** - * Reference to the value where the result of the extraction will - * be put. - */ - std::string &_value; - - /** - * Constructor. - * \param value - Where the value extracted will be put. - */ - ValueExtractor(std::string &value) : _value(value) {} - - /** - * Method that will attempt to parse the input stream for a value - * of type std::string. - * \param val - Where the string parsed will be put. - */ - int extractValue( const std::string& val ) - { - _value = val; - return 0; - } -}; - -} //namespace VALUE_ARG_HELPER - /** * The basic labeled argument that parses a value. * This is a template class, which means the type T defines the type @@ -500,25 +373,18 @@ std::string ValueArg::longID(const std::string& val) const template void ValueArg::_extractValue( const std::string& val ) { - VALUE_ARG_HELPER::ValueExtractor ve(_value); - - int err = ve.extractValue(val); - - if ( err == VALUE_ARG_HELPER::EXTRACT_FAILURE ) - throw( ArgParseException("Couldn't read argument value from string '" + - val + "'", toString() ) ); - - if ( err == VALUE_ARG_HELPER::EXTRACT_TOO_MANY ) - throw( ArgParseException( - "More than one valid value parsed from string '" + - val + "'", toString() ) ); - - if ( _constraint != NULL ) - if ( ! _constraint->check( _value ) ) - throw( CmdLineParseException( "Value '" + val + - "' does not meet constraint: " + - _constraint->description(), - toString() ) ); + try { + ExtractValue(_value, val, typename ArgTraits::ValueCategory()); + } catch( ArgParseException &e) { + throw ArgParseException(e.error(), toString()); + } + + if ( _constraint != NULL ) + if ( ! _constraint->check( _value ) ) + throw( CmdLineParseException( "Value '" + val + + + "' does not meet constraint: " + + _constraint->description(), + toString() ) ); } } // namespace TCLAP diff --git a/tests/runtests.sh b/tests/runtests.sh index 17b7fa7..e4e64e4 100644 --- a/tests/runtests.sh +++ b/tests/runtests.sh @@ -2,8 +2,9 @@ let "suc = 0" let "fail = 0" +NUMTEST=67 -for (( tno = 1 ; $tno < 62 ; tno = $tno + 1 )); do +for (( tno = 1 ; $tno <= $NUMTEST ; tno = $tno + 1 )); do ./testCheck.sh $tno if [ "$?" -eq "0" ]; then echo "OK" diff --git a/tests/test63.out b/tests/test63.out new file mode 100644 index 0000000..b391217 --- /dev/null +++ b/tests/test63.out @@ -0,0 +1,9 @@ +PARSE ERROR: + Required argument missing: vect + +Brief USAGE: + ../examples/test11 -v <3D vector> [--] [--version] [-h] + +For complete USAGE and HELP type: + ../examples/test11 --help + diff --git a/tests/test63.sh b/tests/test63.sh new file mode 100644 index 0000000..69947d3 --- /dev/null +++ b/tests/test63.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +# this tests whether all required args are listed as +# missing when no arguments are specified +# failure +../examples/test11 > tmp.out 2>&1 + +if cmp -s tmp.out $srcdir/test63.out; then + exit 0 +else + exit 1 +fi + diff --git a/tests/test64.out b/tests/test64.out new file mode 100644 index 0000000..46786e9 --- /dev/null +++ b/tests/test64.out @@ -0,0 +1 @@ +1 2 3 diff --git a/tests/test64.sh b/tests/test64.sh new file mode 100644 index 0000000..0090f81 --- /dev/null +++ b/tests/test64.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +# this tests whether all required args are listed as +# missing when no arguments are specified +# failure +../examples/test11 -v "1 2 3" > tmp.out 2>&1 + +if cmp -s tmp.out $srcdir/test64.out; then + exit 0 +else + exit 1 +fi + diff --git a/tests/test65.out b/tests/test65.out new file mode 100644 index 0000000..acab2e6 --- /dev/null +++ b/tests/test65.out @@ -0,0 +1,9 @@ +1 2 3 +4 5 6 +7 8 9 +-1 0.2 0.4 +REVERSED +-1 0.2 0.4 +7 8 9 +4 5 6 +1 2 3 diff --git a/tests/test65.sh b/tests/test65.sh new file mode 100644 index 0000000..1b737c7 --- /dev/null +++ b/tests/test65.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +# this tests whether all required args are listed as +# missing when no arguments are specified +# failure +../examples/test12 -v "1 2 3" -v "4 5 6" -v "7 8 9" -v "-1 0.2 0.4" \ + > tmp.out 2>&1 + +if cmp -s tmp.out $srcdir/test65.out; then + exit 0 +else + exit 1 +fi + diff --git a/tests/test66.out b/tests/test66.out new file mode 100644 index 0000000..507762b --- /dev/null +++ b/tests/test66.out @@ -0,0 +1,9 @@ +PARSE ERROR: + Required argument missing: vect + +Brief USAGE: + ../examples/test12 -v <3D vector> ... [--] [--version] [-h] + +For complete USAGE and HELP type: + ../examples/test12 --help + diff --git a/tests/test66.sh b/tests/test66.sh new file mode 100644 index 0000000..99ca94e --- /dev/null +++ b/tests/test66.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +# this tests whether all required args are listed as +# missing when no arguments are specified +# failure +../examples/test12 > tmp.out 2>&1 + +if cmp -s tmp.out $srcdir/test66.out; then + exit 0 +else + exit 1 +fi + diff --git a/tests/test67.out b/tests/test67.out new file mode 100644 index 0000000..dccc0ab --- /dev/null +++ b/tests/test67.out @@ -0,0 +1,9 @@ +PARSE ERROR: Argument: -v (--vect) + a 1 0.3 is not a 3D vector + +Brief USAGE: + ../examples/test12 -v <3D vector> ... [--] [--version] [-h] + +For complete USAGE and HELP type: + ../examples/test12 --help + diff --git a/tests/test67.sh b/tests/test67.sh new file mode 100644 index 0000000..72bf285 --- /dev/null +++ b/tests/test67.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +# this tests whether all required args are listed as +# missing when no arguments are specified +# failure +../examples/test12 -v "a 1 0.3" > tmp.out 2>&1 + +if cmp -s tmp.out $srcdir/test67.out; then + exit 0 +else + exit 1 +fi + diff --git a/tests/testCheck.sh b/tests/testCheck.sh index 81d7414..efe21c3 100755 --- a/tests/testCheck.sh +++ b/tests/testCheck.sh @@ -7,7 +7,7 @@ if [ "$1" == "" ] then echo "USAGE: testCheck.sh " else - cmd="./test$1.sh" + cmd="sh ./test$1.sh" out="test$1.out" $cmd if cmp -s tmp.out $out