]> gitweb.hamatoma.de Git - reqt/commitdiff
ReProgArgs works
authorhama <hama@siduction.net>
Tue, 1 Dec 2015 23:38:28 +0000 (00:38 +0100)
committerhama <hama@siduction.net>
Tue, 1 Dec 2015 23:38:28 +0000 (00:38 +0100)
base/ReProgramArgs.cpp
base/ReProgramArgs.hpp
cunit/allTests.cpp
cunit/cunit.pro

index 5e90c2cbde9c0f9a51e8f9e303e266df253ac1ef..81ec08d5b5584e2370708b9984af55b66ae5f481 100644 (file)
@@ -12,6 +12,7 @@
 #include "base/rebase.hpp"
 
 const char* ReProgramArgs::PREFIX_LINE_OPTION = "   ";
+QByteArray ReProgramArgs::UNDEFINED_STRING("\01");
 
 /** @brief Constructor.
  *
@@ -122,6 +123,37 @@ void ReProgramArgs::setUsage(const char* usage[]) {
        for (int ix = 0; usage[ix] != NULL; ix++)
                m_usage.append(usage[ix]);
 }
+
+/**
+ * Converts a type into a string.
+ *
+ * @param dataType     type to convert
+ * @return                     the type as string
+ */
+const char*ReProgramArgs::typeToString(ReProgramArgs::DataType dataType)
+{
+       const char* rc;
+       static QByteArray s_buffer;
+       switch(dataType){
+       case DT_BOOL:
+               rc = "bool";
+               break;
+       case DT_INT:
+               rc = "int";
+               break;
+       case DT_STRING:
+               rc = "string";
+               break;
+       case DT_STRING_EMPTY:
+               rc = "string(empty)";
+               break;
+       default:
+               s_buffer = "unknown type (" + QByteArray::number(dataType) + ")";
+               rc = s_buffer.constData();
+               break;
+       }
+       return rc;
+}
 /** @brief Puts the property infos into the property string.
  *
  * The <strong>property string</strong> is a string stored in the hashlist.
@@ -137,14 +169,14 @@ void ReProgramArgs::setUsage(const char* usage[]) {
  */
 void ReProgramArgs::addProperties(const char*name, const char* description,
        char shortOpt, const char* longOpt, DataType dataType,
-       const char* defaultValue, size_t lengthValue) {
+       const char* defaultValue) {
        ReProgOptionMap::const_iterator it;
        for (it = m_options.cbegin(); it != m_options.cend(); ++it){
                if (name == it.key()){
                        throw ReOptionException(this, QObject::tr("name defined twice: %1").arg(name));
                } else {
                        ReProgOption* opt = it.value();
-                       if (shortOpt == opt->m_shortName)
+                       if (shortOpt != 0 && shortOpt == opt->m_shortName)
                                throw ReOptionException(this, QObject::tr("short option defined twice: %1").arg(shortOpt));
                        else if (opt->m_longName == longOpt)
                                throw ReOptionException(this, QObject::tr("long option defined twice: %1").arg(longOpt));
@@ -156,8 +188,10 @@ void ReProgramArgs::addProperties(const char*name, const char* description,
        opt->m_defaultValue = defaultValue;
        opt->m_shortName = shortOpt;
        opt->m_type = dataType;
+       opt->m_description = description;
        // Mark current value as default:
-       opt->m_value = QByteArray("!") + defaultValue;
+       opt->m_value = defaultValue;
+       m_options[name] = opt;
 }
 
 /** @brief Adds an option with a boolean value.
@@ -173,7 +207,7 @@ void ReProgramArgs::addProperties(const char*name, const char* description,
 void ReProgramArgs::addBool(const char* name, const char* description,
        char shortOpt, const char* longOpt, bool defaultVal) {
        addProperties(name, description, shortOpt, longOpt, DT_BOOL,
-               defaultVal ? "t" : "f", 1);
+               defaultVal ? "t" : "f");
 }
 
 /** @brief Adds an option with an integer value.
@@ -189,8 +223,7 @@ void ReProgramArgs::addBool(const char* name, const char* description,
 void ReProgramArgs::addInt(const char* name, const char* description,
        char shortOpt, const char* longOpt, int defaultVal) {
        QByteArray number = QByteArray::number(defaultVal);
-       addProperties(name, description, shortOpt, longOpt, DT_INT, number.constData(),
-               number.length());
+       addProperties(name, description, shortOpt, longOpt, DT_INT, number.constData());
 }
 
 /** @brief Adds an option with a string value.
@@ -207,8 +240,8 @@ void ReProgramArgs::addString(const char* name, const char* description,
        char shortOpt, const char* longOpt, bool mayBeEmpty,
        const char* defaultVal) {
        addProperties(name, description, shortOpt, longOpt,
-               mayBeEmpty ? DT_STRING_EMPTY : DT_STRING, defaultVal,
-               defaultVal == NULL ? 0 : strlen(defaultVal));
+               mayBeEmpty ? DT_STRING_EMPTY : DT_STRING,
+                                 defaultVal == NULL ? UNDEFINED_STRING.constData() : defaultVal);
 }
 
 /** @brief Analyses a long name option.
@@ -228,8 +261,10 @@ void ReProgramArgs::analyseLong(const char* opt) {
                name = QByteArray(opt).mid(0, value - opt);
                value++;
        }
-       ReProgOption* option = m_options[name];
-
+       ReProgOption* option = search(0, name);
+       if (option == NULL)
+               throw ReOptionException(this, QObject::tr("unknown option: %1")
+                                                               .arg(name.constData()));
        switch (option->m_type) {
        case DT_INT:
                if (value == NULL)
@@ -242,6 +277,9 @@ void ReProgramArgs::analyseLong(const char* opt) {
                if (value == NULL)
                        throw ReOptionException(this,
                                QObject::tr("Option %1: parameter expected. Use --%1=string").arg(name.constData()));
+               else if (value[0] == '\0')
+                       throw ReOptionException(this,
+                               QObject::tr("Option %1: empty string is not allowed. Use --%1=string").arg(name.constData()));
                option->m_value = value;
                break;
        case DT_STRING_EMPTY:
@@ -249,23 +287,21 @@ void ReProgramArgs::analyseLong(const char* opt) {
                        value = "";
                option->m_value = value;
                break;
-       case DT_BOOL: {
-               const char* boolValue = "f";
-               if (value == NULL
-                       || ReStringUtils::isInList(value, ";y;yes;t;true", true,
+       case DT_BOOL:
+               if (value == NULL){
+                       // Invert the default value:
+                       option->m_value = option->m_defaultValue == "t" ? "f" : "t";
+               } else if (ReStringUtils::isInList(value, ";y;yes;t;true", true,
                                ReStringUtils::AUTO_SEPARATOR))
-                       boolValue = "t";
-               else if (!ReStringUtils::isInList(value, ";n;no;f;false",
-                       true, ReStringUtils::AUTO_SEPARATOR))
+                       option->m_value = "t";
+               else if (ReStringUtils::isInList(value, ";n;no;f;false",
+                                       true, ReStringUtils::AUTO_SEPARATOR))
+                       option->m_value = "f";
+               else
                        throw ReOptionException(this,
                                QObject::tr("Option %1: Not a boolean value: %2. Use true or false")
                                .arg(name.constData()).arg(value));
-               // Invert the default value:
-               if (option->m_defaultValue == "t")
-                       boolValue = boolValue[0] == 't' ? "f" : "t";
-               option->m_value = boolValue;
                break;
-       }
        default:
                break;
        }
@@ -304,18 +340,18 @@ bool ReProgramArgs::analyseShort(const char* opt, const char* nextArg) {
                case DT_STRING:
                case DT_STRING_EMPTY:
                        if (opt[0] != '\0') {
-                               setValue(opt->m_name, opt, option->m_type);
+                               setValue(option->m_name, opt, option->m_type);
                        } else {
                                if (nextArg == NULL || nextArg[0] == '-') {
-                                       if (dataType[0] == DT_STRING_EMPTY)
-                                               setValue(nameStr, "", dataType);
+                                       if (option->m_type == DT_STRING_EMPTY)
+                                               setValue(option->m_name, "", option->m_type);
                                        else
                                                throw ReOptionException(this,
-                                                       i18n(
-                                                               "Option $1 has type $2! There is no parameter."),
-                                                       nameStr, dataType);
+                                                       QObject::tr(
+                                                               "Option %1 has type %2! There is no parameter.")
+                                                       .arg(option->m_name.constData()).arg(typeToString(option->m_type)));
                                } else {
-                                       setValue(nameStr, nextArg, dataType);
+                                       setValue(option->m_name.constData(), nextArg, option->m_type);
                                        rc = true;
                                }
                        }
@@ -329,9 +365,9 @@ bool ReProgramArgs::analyseShort(const char* opt, const char* nextArg) {
                        } else if (opt[0] == '+')
                                opt++;
                        // Invert the default value:
-                       if (properties.strOf(IxDefault)[0] == 't')
+                       if (option->m_defaultValue == "t")
                                value = value[0] == 't' ? "f" : "t";
-                       setValue(nameStr, value, dataType);
+                       setValue(option->m_name, value, option->m_type);
                        again = opt[0] != '\0';
                        break;
                }
@@ -380,8 +416,8 @@ bool ReProgramArgs::getBool(const char* name) {
        if (option->m_type != DT_BOOL)
                throw ReOptionException(this,
                        QObject::tr("%1 is not an boolean option. Type is %2").arg(name)
-                       .arg(option->m_type));
-       bool rc = option->m_value.at(1) == 't';
+                       .arg(typeToString(option->m_type)));
+       bool rc = option->m_value == "t";
        return rc;
 }
 
@@ -397,20 +433,20 @@ int ReProgramArgs::getInt(const char* name) {
        ReProgOption* option = m_options.value(name, NULL);
        if (option == NULL)
                throw ReOptionException(this, QObject::tr("%1 is not an option name").arg(name));
-       if (option->m_type != DT_BOOL)
+       if (option->m_type != DT_INT)
                throw ReOptionException(this,
                        QObject::tr("%1 is not an integer option. Type is %2").arg(name)
-                       .arg(option->m_type));
-       // Note: first char is a tag: '!': default
-       int rc = atoi(option->m_value.constData() + 1);
+                       .arg(typeToString(option->m_type)));
+       int rc = atoi(option->m_value.constData());
        return rc;
 }
 
 /** @brief Returns the value of a string option.
  *
- * @param name Name of the option.
+ * @param name the name of the option
  *
- * @return The value of the option set in the programs arguments or the default value.
+ * @return             NULL: default value is NULL and no argument has been given<br>
+ *                             the value of the option set in the programs arguments or the default value.
  *
  * @throws ReOptionException   Unknown name or wrong type.
  */
@@ -421,10 +457,9 @@ const char* ReProgramArgs::getString(const char* name, QByteArray& buffer) {
        if (option->m_type != DT_STRING && option->m_type != DT_STRING_EMPTY)
                throw ReOptionException(this,
                        QObject::tr("%1 is not an string option. Type is %2").arg(name)
-                       .arg(option->m_type));
-       // Note: first char is a tag: '!': default
-       buffer = option->m_value.mid(1);
-       return buffer.constData();
+                       .arg(typeToString(option->m_type)));
+       buffer = option->m_value;
+       return buffer == UNDEFINED_STRING ? NULL : buffer.constData();
 }
 
 /**
@@ -435,72 +470,67 @@ const char* ReProgramArgs::getString(const char* name, QByteArray& buffer) {
  * @param lines                                OUT: a stringlist for the help message
  */
 void ReProgramArgs::help(const char* message, bool issueLastError,
-       ReStringList& lines) const {
+       QByteArrayList& lines) const {
        lines.append(m_usage);
        lines.append("");
 
-       ReArrayPosition position;
-       if (m_properties.next(position, NULL, NULL)) {
-               lines.append(i18n("<options>:"));
+       if (m_options.size() > 0) {
+               lines.append(QObject::tr("<options>:").toUtf8());
        }
-       QByteArray name;
-       QByteArray prop;
        QByteArray line;
        QByteArray param;
-
-       while (m_properties.next(position, &name, &prop)) {
-               ReStringList properties(512, 1024, 2, 2);
-               properties.split(prop.constData(), '\1');
-               line.setLength(0);
-               DataType dataType = DataType(properties.strOf(IxType)[0]);
-               const char* shortName = properties.strOf(IxShort);
-               param.setLength(0);
-               switch (dataType) {
+       ReProgOptionMap::const_iterator it;
+       for (it = m_options.cbegin(); it != m_options.cend(); ++it){
+               ReProgOption* opt = it.value();
+               param.resize(0);
+               switch (opt->m_type) {
                case DT_INT:
-                       param.append(i18n("<number>"), -1);
+                       param.append(QObject::tr("<number>"));
                        break;
                case DT_STRING:
-                       param.append(i18n("<not empty string>"), -1);
+                       param.append(QObject::tr("<not empty string>"));
                        break;
                case DT_STRING_EMPTY:
-                       param.append(i18n("[<string>]"), -1);
+                       param.append(QObject::tr("[<string>]"));
                        break;
                default:
                        break;
                }
-               if (shortName[0] != HIDDEN_SHORT_NAME) {
-                       line.append("-", 1).append(shortName, 1);
-                       line.append(param.constData(), -1).appendChar(' ').append(i18n(" or "),
-                               -1);
+               if (opt->m_shortName != HIDDEN_SHORT_NAME) {
+                       line.append("-").append(opt->m_shortName);
+                       line.append(param).append(' ').append(QObject::tr(" or ").toUtf8());
                }
-               line.append(i18n("--"), -1).append(properties.strOf(IxLong), -1);
+               line.append("--").append(opt->m_longName);
                if (param.length() > 0) {
                        line.append("=", -1).append(param.constData(), -1);
-                       if (dataType != DT_STRING
-                               || properties.strLengthOf(IxDefault) > 0) {
-                               line.append(i18n(" Default value: "), -1);
-                               if (dataType == DT_STRING)
-                                       line.appendChar('\'');
-                               line.append(properties.strOf(IxDefault), -1);
-                               if (dataType == DT_STRING)
-                                       line.appendChar('\'');
+                       if (opt->m_type != DT_STRING
+                                       || ! opt->m_defaultValue.isEmpty()) {
+                               line.append(QObject::tr(" Default value: ").toUtf8());
+                               if (opt->m_type == DT_STRING)
+                                       line.append('\'');
+                               line.append(opt->m_defaultValue);
+                               if (opt->m_type == DT_STRING)
+                                       line.append('\'');
                        }
                }
                lines.append(line.constData());
-               line.set(PREFIX_LINE_OPTION, -1).append(properties.strOf(IxDescr), -1);
+               line.resize(0);
+               line.append(PREFIX_LINE_OPTION).append(opt->m_description);
                lines.append(line.constData());
        }
        if (m_examples.count() > 0) {
-               lines.append(i18n("Example(s):"));
+               lines.append(QObject::tr("Example(s):").toUtf8());
                lines.append(m_examples);
        }
        if (issueLastError && m_lastError.length() > 0) {
-               line.set("+++ ", 4).append(m_lastError.constData(), -1);
+               line.resize(0);
+               line.append("+++ ").append(m_lastError.constData());
                lines.append(line.constData());
        }
 
        if (message != NULL && message[0] != '\0') {
-               line.set("+++ ", 4).append(message, -1);
+               line.resize(0);
+               line.append("+++ ").append(message);
                lines.append(line.constData());
        }
 }
@@ -513,10 +543,10 @@ void ReProgramArgs::help(const char* message, bool issueLastError,
  */
 void ReProgramArgs::help(const char* message, bool issueLastError,
        FILE* stream) const {
-       ReStringList lines(512, 1024, 8, 2);
+       QByteArrayList lines;
        help(message, issueLastError, lines);
-       for (size_t ii = 0; ii < lines.count(); ii++) {
-               fputs(lines.strOf(ii), stream);
+       for (int ii = 0; ii < lines.count(); ii++) {
+               fputs(lines.at(ii).constData(), stream);
                fputc('\n', stream);
        }
 }
@@ -560,43 +590,31 @@ const char* ReProgramArgs::programName() const {
 
 /** @brief Search the property string of an option.
  *
- * @param shortName            The option`s short name. Not relevant if <code>longName != NULL</code>.
- * @param LongName             The option`s long name. Not relevant if <code>longName == NULL</code>.
- * @param name                 Out: The name of the option.
- * @param list                 Out: The properties are returned in this list.
+ * @param shortName            the option`s short name. Not relevant if <code>longName != NULL</code>
+ * @param longName             the option`s long name. Not relevant if <code>longName == NULL</code>
+ * @return                             the option
  *
  * @throws ReOptionException   Unknown option.
  */
-void ReProgramArgs::search(char shortName, const char* longName,
-       QByteArray& name, ReStringList& list) {
-       ReArrayPosition position;
-       QByteArray properties;
-       bool found = false;
-       size_t lengthLongName = 0;
-       if (longName != NULL) {
-               const char* ptr;
-               if ((ptr = strchr(longName, '=')) != NULL)
-                       lengthLongName = ptr - longName;
-               else
-                       lengthLongName = strlen(longName);
-       }
-       while (!found && m_properties.next(position, &name, &properties)) {
-               list.split(properties.constData(), '\1');
-               if (longName == NULL && list.count() > IxShort
-                       && shortName == list.strOf(IxShort)[0])
-                       found = true;
-               else if (lengthLongName > 0 && list.count() > IxLong
-                       && list.sizeOf(IxLong) == lengthLongName + 1
-                       && strncmp(longName, list.strOf(IxLong), lengthLongName) == 0)
-                       found = true;
+ReProgOption* ReProgramArgs::search(char shortName, const char* longName) {
+       ReProgOptionMap::const_iterator it;
+       ReProgOption* rc = NULL;
+       ReProgOption* opt;
+       for (it = m_options.cbegin(); rc == NULL && it != m_options.cend(); ++it){
+               opt = it.value();
+               if ( (shortName != 0 && shortName == opt->m_shortName)
+                               || longName == opt->m_longName)
+                       rc = opt;
        }
-       if (!found) {
+       if (rc == NULL) {
+               QByteArray name;
                if (longName == NULL)
-                       name.set(&shortName, 1);
+                       name.append(shortName);
                else
-                       name.set(longName, lengthLongName);
-               throw ReOptionException(this, i18n("Unknown option: $1"), name.constData());
+                       name = longName;
+               throw ReOptionException(this, QObject::tr("Unknown option: %1").arg(name.constData()));
        }
+       return rc;
 }
 
 /** @brief Sets the last error message.
@@ -640,9 +658,7 @@ void ReProgramArgs::setValue(const char* name, const char* value,
        default:
                break;
        }
-       QByteArray buffer;
-       // First character says: defined.
-       buffer.appendChar(' ').append(value, -1);
-       m_values.put(name, buffer.constData());
+       ReProgOption* opt = m_options.value(name);
+       opt->m_value = value;
 }
 
index cdd6af8a2febd100474262ed8e0d36c37477457b..ce5da5e50ac6bc2308cbabca7f0acc0e7829f30e 100644 (file)
@@ -43,6 +43,7 @@ typedef QMap<QByteArray, ReProgOption*> ReProgOptionMap;
  */
 class ReProgramArgs {
        static const char* PREFIX_LINE_OPTION;
+       static QByteArray UNDEFINED_STRING;
 public:
        enum DataType {
                DT_UNDEF = 0,
@@ -78,10 +79,10 @@ public:
        void setLastError(const char* message);
        void setLastError(const QByteArray& message);
        void setUsage(const char* usage[]);
+       const char* typeToString(DataType dataType);
 private:
        void addProperties(const char*name, const char* description, char shortOpt,
-               const char* longOpt, DataType dataType, const char* defaultValue,
-               size_t lengthValue);
+               const char* longOpt, DataType dataType, const char* defaultValue);
        void analyseLong(const char* opt);
        bool analyseShort(const char* opt, const char* nextArg);
        ReProgOption* search(char shortName, const char* longName);
@@ -104,6 +105,7 @@ public:
        char m_shortName;
        QByteArray m_value;
        QByteArray m_defaultValue;
+       QByteArray m_description;
 };
 
 #endif /* REPROGRAMARGS_H_ */
index de40ce22d7f0c4f8751bc421f4c741fa4a3b2afe..e82c18a8fefb528b6f964e92052d8819f0f57831 100644 (file)
@@ -30,6 +30,7 @@ static void testGui() {
 }
 
 static void testBase() {
+       void testReProgArgs();
        void testReProcess();
        void testReRandomizer();
        void testReByteStorage();
@@ -43,6 +44,7 @@ static void testBase() {
        void testReWriter();
        void testReFile();
        void testReMatcher();
+       testReProgArgs();
        testReProcess();
        testReRandomizer();
        testReFileUtils();
index a3195c853573fa65292115fbbaa8680ac074fc9f..181449cdc55ed289bc3f0de519f84ec4e4a64f9d 100644 (file)
@@ -17,6 +17,7 @@ INCLUDEPATH = ..
 
 SOURCES += main.cpp \
        cuReLexer.cpp \
+       cuReProgArgs.cpp \
         cuReFileSystem.cpp \
         cuReCryptFileSystem.cpp \
         cuReRandomizer.cpp \
@@ -59,7 +60,7 @@ SOURCES += main.cpp \
         allTests.cpp \
        ../base/ReProcess.cpp \
        cuReProcess.cpp \
-    ../base/ReProgramArgs.cpp
+       ../base/ReProgramArgs.cpp
 
 HEADERS += \
         ../base/ReFile.hpp \