diff options
-rw-r--r-- | conf/inspircd.conf.example | 5 | ||||
-rw-r--r-- | conf/modules.conf.example | 4 | ||||
-rw-r--r-- | include/configparser.h | 5 | ||||
-rw-r--r-- | src/configparser.cpp | 26 |
4 files changed, 35 insertions, 5 deletions
diff --git a/conf/inspircd.conf.example b/conf/inspircd.conf.example index d5c9874df..47ecd5889 100644 --- a/conf/inspircd.conf.example +++ b/conf/inspircd.conf.example @@ -71,6 +71,10 @@ # Variables may be redefined and may reference other variables. # # Value expansion happens at the time the tag is read. # # # +# Using variable definitions REQUIRES that the config format be # +# changed to "xml" from the default "compat" that uses escape # +# sequences such as "\"" and "\n", and does not support <define> # +<config format="xml"> <define name="bindip" value="1.2.2.3"> <define name="localips" value="&bindip;/24"> @@ -478,6 +482,7 @@ # prefixpart: What (if anything) a users' part message # should be prefixed with. prefixpart=""" + # NOTE: Use "\"" instead of """ if not using <config format="xml"> # suffixpart: What (if anything) a users' part message # should be suffixed with. diff --git a/conf/modules.conf.example b/conf/modules.conf.example index e9a306e3f..91e45eb91 100644 --- a/conf/modules.conf.example +++ b/conf/modules.conf.example @@ -126,7 +126,9 @@ # "baz qux quz" and $2 will contain "bar". You may # # also use the special variables: $nick, $ident, # # $host and $vhost, and you may separate multiple # -# commands with a newline (&nl;). # +# commands with a newline (which can be written in # +# the file literally, or encoded as &nl; or \n # +# depending on the config format setting). # # # # requires - If you provide a value for 'requires' this means # # the given nickname MUST be online for the alias # diff --git a/include/configparser.h b/include/configparser.h index a1d7aff5b..3240ff5f9 100644 --- a/include/configparser.h +++ b/include/configparser.h @@ -12,8 +12,9 @@ struct fpos enum ParseFlags { - FLAG_NO_EXEC = 1, - FLAG_NO_INC = 2 + FLAG_USE_XML = 1, + FLAG_NO_EXEC = 2, + FLAG_NO_INC = 4 }; struct ParseStack diff --git a/src/configparser.cpp b/src/configparser.cpp index 1373ae5af..495d38fff 100644 --- a/src/configparser.cpp +++ b/src/configparser.cpp @@ -18,7 +18,7 @@ struct Parser { ParseStack& stack; - const int flags; + int flags; FILE* const file; fpos current; fpos last_tag; @@ -112,7 +112,7 @@ struct Parser while (1) { ch = next(); - if (ch == '&') + if (ch == '&' && (flags & FLAG_USE_XML)) { std::string varname; while (1) @@ -134,6 +134,16 @@ struct Parser throw CoreException("Undefined XML entity reference '&" + varname + ";'"); value.append(var->second); } + else if (ch == '\\' && !(flags & FLAG_USE_XML)) + { + int esc = next(); + if (esc == 'n') + value.push_back('\n'); + else if (isalpha(esc)) + throw CoreException("Unknown escape character \\" + std::string(1, esc)); + else + value.push_back(esc); + } else if (ch == '"') break; else @@ -169,12 +179,24 @@ struct Parser } else if (name == "define") { + if (!(flags & FLAG_USE_XML)) + throw CoreException("<define> tags may only be used in XML-style config (add <config format=\"xml\">)"); std::string varname = tag->getString("name"); std::string value = tag->getString("value"); if (varname.empty()) throw CoreException("Variable definition must include variable name"); stack.vars[varname] = value; } + else if (name == "config") + { + std::string format = tag->getString("format"); + if (format == "xml") + flags |= FLAG_USE_XML; + else if (format == "compat") + flags &= ~FLAG_USE_XML; + else if (!format.empty()) + throw CoreException("Unknown configuration format " + format); + } else { stack.output.insert(std::make_pair(name, tag)); |