mandatory_tag.clear();
}
- if (name == "include")
+ if (stdalgo::string::equalsci(name, "include"))
{
stack.DoInclude(tag, flags);
}
- else if (name == "files")
+ else if (stdalgo::string::equalsci(name, "files"))
{
for(ConfigItems::iterator i = items->begin(); i != items->end(); i++)
{
stack.DoReadFile(i->first, i->second, flags, false);
}
}
- else if (name == "execfiles")
+ else if (stdalgo::string::equalsci(name, "execfiles"))
{
for(ConfigItems::iterator i = items->begin(); i != items->end(); i++)
{
stack.DoReadFile(i->first, i->second, flags, true);
}
}
- else if (name == "define")
+ else if (stdalgo::string::equalsci(name, "define"))
{
if (flags & FLAG_USE_COMPAT)
throw CoreException("<define> tags may only be used in XML-style config (add <config format=\"xml\">)");
throw CoreException("Variable definition must include variable name");
stack.vars[varname] = value;
}
- else if (name == "config")
+ else if (stdalgo::string::equalsci(name, "config"))
{
std::string format = tag->getString("format");
- if (format == "xml")
+ if (stdalgo::string::equalsci(format, "xml"))
flags &= ~FLAG_USE_COMPAT;
- else if (format == "compat")
+ else if (stdalgo::string::equalsci(format, "compat"))
flags |= FLAG_USE_COMPAT;
else if (!format.empty())
throw CoreException("Unknown configuration format " + format);
break;
case 0xFE:
case 0xFF:
- stack.errstr << "Do not save your files as UTF-16; use ASCII!\n";
+ stack.errstr << "Do not save your files as UTF-16 or UTF-32, use UTF-8!\n";
+ /*@fallthrough@*/
default:
throw CoreException("Syntax error - start of tag expected");
}
return false;
}
-std::string ConfigTag::getString(const std::string& key, const std::string& def)
+std::string ConfigTag::getString(const std::string& key, const std::string& def, const TR1NS::function<bool(const std::string&)>& validator)
{
- std::string res = def;
- readString(key, res);
+ std::string res;
+ if (!readString(key, res))
+ return def;
+
+ if (!validator(res))
+ {
+ ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "WARNING: The value of <%s:%s> is not valid; value set to %s.",
+ tag.c_str(), key.c_str(), def.c_str());
+ return def;
+ }
+ return res;
+}
+
+std::string ConfigTag::getString(const std::string& key, const std::string& def, size_t minlen, size_t maxlen)
+{
+ std::string res;
+ if (!readString(key, res))
+ return def;
+
+ if (res.length() < minlen || res.length() > maxlen)
+ {
+ ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "WARNING: The length of <%s:%s> is not between %ld and %ld; value set to %s.",
+ tag.c_str(), key.c_str(), minlen, maxlen, def.c_str());
+ return def;
+ }
return res;
}
+namespace
+{
+ /** Check for an invalid magnitude specifier. If one is found a warning is logged and the
+ * value is corrected (set to \p def).
+ * @param tag The tag name; used in the warning message.
+ * @param key The key name; used in the warning message.
+ * @param val The full value set in the config as a string.
+ * @param num The value to verify and modify if needed.
+ * @param def The default value, \p res will be set to this if \p tail does not contain a.
+ * valid magnitude specifier.
+ * @param tail The location in the config value at which the magnifier is located.
+ */
+ template <typename Numeric>
+ void CheckMagnitude(const std::string& tag, const std::string& key, const std::string& val, Numeric& num, Numeric def, const char* tail)
+ {
+ // If this is NULL then no magnitude specifier was given.
+ if (!*tail)
+ return;
+
+ switch (toupper(*tail))
+ {
+ case 'K':
+ num *= 1024;
+ return;
+
+ case 'M':
+ num *= 1024 * 1024;
+ return;
+
+ case 'G':
+ num *= 1024 * 1024 * 1024;
+ return;
+ }
+
+ const std::string message = "WARNING: <" + tag + ":" + key + "> value of " + val + " contains an invalid magnitude specifier '"
+ + tail + "'; value set to " + ConvToStr(def) + ".";
+ ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, message);
+ num = def;
+ }
+
+ /** Check for an out of range value. If the value falls outside the boundaries a warning is
+ * logged and the value is corrected (set to \p def).
+ * @param tag The tag name; used in the warning message.
+ * @param key The key name; used in the warning message.
+ * @param num The value to verify and modify if needed.
+ * @param def The default value, \p res will be set to this if (min <= res <= max) doesn't hold true.
+ * @param min Minimum accepted value for \p res.
+ * @param max Maximum accepted value for \p res.
+ */
+ template <typename Numeric>
+ void CheckRange(const std::string& tag, const std::string& key, Numeric& num, Numeric def, Numeric min, Numeric max)
+ {
+ if (num >= min && num <= max)
+ return;
+
+ const std::string message = "WARNING: <" + tag + ":" + key + "> value of " + ConvToStr(num) + " is not between "
+ + ConvToStr(min) + " and " + ConvToStr(max) + "; value set to " + ConvToStr(def) + ".";
+ ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, message);
+ num = def;
+ }
+}
+
long ConfigTag::getInt(const std::string &key, long def, long min, long max)
{
std::string result;
long res = strtol(res_cstr, &res_tail, 0);
if (res_tail == res_cstr)
return def;
- switch (toupper(*res_tail))
- {
- case 'K':
- res = res * 1024;
- break;
- case 'M':
- res = res * 1024 * 1024;
- break;
- case 'G':
- res = res * 1024 * 1024 * 1024;
- break;
- }
- CheckRange(key, res, def, min, max);
+ CheckMagnitude(tag, key, result, res, def, res_tail);
+ CheckRange(tag, key, res, def, min, max);
return res;
}
-void ConfigTag::CheckRange(const std::string& key, long& res, long def, long min, long max)
+unsigned long ConfigTag::getUInt(const std::string& key, unsigned long def, unsigned long min, unsigned long max)
{
- if (res < min || res > max)
- {
- ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "WARNING: <%s:%s> value of %ld is not between %ld and %ld; set to %ld.",
- tag.c_str(), key.c_str(), res, min, max, def);
- res = def;
- }
+ std::string result;
+ if (!readString(key, result))
+ return def;
+
+ const char* res_cstr = result.c_str();
+ char* res_tail = NULL;
+ unsigned long res = strtoul(res_cstr, &res_tail, 0);
+ if (res_tail == res_cstr)
+ return def;
+
+ CheckMagnitude(tag, key, result, res, def, res_tail);
+ CheckRange(tag, key, res, def, min, max);
+ return res;
}
-long ConfigTag::getDuration(const std::string& key, long def, long min, long max)
+unsigned long ConfigTag::getDuration(const std::string& key, unsigned long def, unsigned long min, unsigned long max)
{
std::string duration;
if (!readString(key, duration))
return def;
- long ret = InspIRCd::Duration(duration);
- CheckRange(key, ret, def, min, max);
+ unsigned long ret = InspIRCd::Duration(duration);
+ CheckRange(tag, key, ret, def, min, max);
return ret;
}
-double ConfigTag::getFloat(const std::string &key, double def)
+double ConfigTag::getFloat(const std::string& key, double def, double min, double max)
{
std::string result;
if (!readString(key, result))
return def;
- return strtod(result.c_str(), NULL);
+
+ double res = strtod(result.c_str(), NULL);
+ CheckRange(tag, key, res, def, min, max);
+ return res;
}
bool ConfigTag::getBool(const std::string &key, bool def)
{
}
+OperInfo::OperInfo(const std::string& Name)
+ : name(Name)
+{
+}
+
std::string OperInfo::getConfig(const std::string& key)
{
std::string rv;