#include "base/rebase.hpp"
const char* ReProgramArgs::PREFIX_LINE_OPTION = " ";
+QByteArray ReProgramArgs::UNDEFINED_STRING("\01");
/** @brief Constructor.
*
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.
*/
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));
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.
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.
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.
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.
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)
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:
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;
}
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;
}
}
} 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;
}
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;
}
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.
*/
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();
}
/**
* @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());
}
}
*/
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);
}
}
/** @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.
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;
}