]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/configparser.cpp
Remove deprecated config checker and make <die> actually useful.
[user/henk/code/inspircd.git] / src / configparser.cpp
index 7c03fe58a1ad4869c6fc8acd8704f8e7a0cf5da1..437b3cdb0c3822a8ad8691d3f50db8b14ce68f51 100644 (file)
@@ -213,25 +213,25 @@ struct Parser
                        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\">)");
@@ -241,12 +241,12 @@ struct Parser
                                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);
@@ -286,7 +286,8 @@ struct Parser
                                                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");
                                }
@@ -402,13 +403,98 @@ bool ConfigTag::readString(const std::string& key, std::string& value, bool allo
        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;
@@ -420,50 +506,49 @@ long ConfigTag::getInt(const std::string &key, long def, long min, long max)
        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)
@@ -499,6 +584,11 @@ ConfigTag::ConfigTag(const std::string& Tag, const std::string& file, int line)
 {
 }
 
+OperInfo::OperInfo(const std::string& Name)
+       : name(Name)
+{
+}
+
 std::string OperInfo::getConfig(const std::string& key)
 {
        std::string rv;