mirror of
https://github.com/znc/znc.git
synced 2026-08-04 16:03:25 +02:00
Add string formatting function with named params.
In addition to the formatting function, a matching Escape type is added.
This commit is contained in:
+13
-1
@@ -27,6 +27,7 @@ using std::pair;
|
||||
#define _SQL(s) CString("'" + CString(s).Escape_n(CString::ESQL) + "'")
|
||||
#define _URL(s) CString(s).Escape_n(CString::EURL)
|
||||
#define _HTML(s) CString(s).Escape_n(CString::EHTML)
|
||||
#define _NAMEDFMT(s) CString(s).Escape_n(CString::ENAMEDFMT)
|
||||
|
||||
class CString;
|
||||
class MCString;
|
||||
@@ -68,7 +69,8 @@ public:
|
||||
EASCII,
|
||||
EURL,
|
||||
EHTML,
|
||||
ESQL
|
||||
ESQL,
|
||||
ENAMEDFMT
|
||||
} EEscape;
|
||||
|
||||
explicit CString(bool b) : string(b ? "true" : "false") {}
|
||||
@@ -282,6 +284,16 @@ public:
|
||||
const CString& sLeft = "", const CString& sRight = "", bool bTrimQuotes = true,
|
||||
bool bTrimWhiteSpace = false) const;
|
||||
|
||||
/** Build a string from a format string, replacing values from a map.
|
||||
* The format specification can contain simple named parameters that match
|
||||
* keys in the given map. For example in the string "a {b} c", the key "b"
|
||||
* is looked up in the map, and inserted for "{b}".
|
||||
* @param sFormat The format specification.
|
||||
* @param msValues A map of named parameters to their values.
|
||||
* @return The string with named parameters replaced.
|
||||
*/
|
||||
static CString NamedFormat(const CString& sFormat, const MCString& msValues);
|
||||
|
||||
/** Produces a random string.
|
||||
* @param uLength The length of the resulting string.
|
||||
* @return A random string.
|
||||
|
||||
@@ -171,6 +171,8 @@ CString::EEscape CString::ToEscape(const CString& sEsc) {
|
||||
return EURL;
|
||||
} else if (sEsc.Equals("SQL")) {
|
||||
return ESQL;
|
||||
} else if (sEsc.Equals("NAMEDFMT")) {
|
||||
return ENAMEDFMT;
|
||||
}
|
||||
|
||||
return EASCII;
|
||||
@@ -276,6 +278,16 @@ CString CString::Escape_n(EEscape eFrom, EEscape eTo) const {
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case ENAMEDFMT:
|
||||
if (*p != '\\' || iLength < (a +1)) {
|
||||
ch = *p;
|
||||
} else {
|
||||
a++;
|
||||
p++;
|
||||
ch = *p;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -316,6 +328,13 @@ CString CString::Escape_n(EEscape eFrom, EEscape eTo) const {
|
||||
} else if (ch == '\\') { sRet += '\\'; sRet += '\\';
|
||||
} else { sRet += ch; }
|
||||
|
||||
break;
|
||||
case ENAMEDFMT:
|
||||
if (ch == '\\') { sRet += '\\'; sRet += '\\';
|
||||
} else if (ch == '{') { sRet += '\\'; sRet += '{';
|
||||
} else if (ch == '}') { sRet += '\\'; sRet += '}';
|
||||
} else { sRet += ch; }
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -639,6 +658,51 @@ unsigned int CString::Split(const CString& sDelim, SCString& ssRet, bool bAllowE
|
||||
return ssRet.size();
|
||||
}
|
||||
|
||||
CString CString::NamedFormat(const CString& sFormat, const MCString& msValues) {
|
||||
CString sRet;
|
||||
|
||||
CString sKey;
|
||||
bool bEscape = false;
|
||||
bool bParam = false;
|
||||
const char* p = sFormat.c_str();
|
||||
|
||||
while (*p) {
|
||||
if (!bParam) {
|
||||
if (bEscape) {
|
||||
sRet += *p;
|
||||
bEscape = false;
|
||||
} else if (*p == '\\') {
|
||||
bEscape = true;
|
||||
} else if (*p == '{') {
|
||||
bParam = true;
|
||||
sKey.clear();
|
||||
} else {
|
||||
sRet += *p;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (bEscape) {
|
||||
sKey += *p;
|
||||
bEscape = false;
|
||||
} else if (*p == '\\') {
|
||||
bEscape = true;
|
||||
} else if (*p == '}') {
|
||||
bParam = false;
|
||||
MCString::const_iterator it = msValues.find(sKey);
|
||||
if (it != msValues.end()) {
|
||||
sRet += (*it).second;
|
||||
}
|
||||
} else {
|
||||
sKey += *p;
|
||||
}
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
return sRet;
|
||||
}
|
||||
|
||||
CString CString::RandomString(unsigned int uLength) {
|
||||
const char chars[] = "abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
Reference in New Issue
Block a user