Permalink
Browse files

Add string formatting function with named params.

In addition to the formatting function, a matching Escape type is added.
  • Loading branch information...
1 parent f7e5b41 commit 2fdf54d43d4bffba89f56491bc6468a9cb9a765d @stephank stephank committed Oct 16, 2011
Showing with 77 additions and 1 deletion.
  1. +13 −1 include/znc/ZNCString.h
  2. +64 −0 src/ZNCString.cpp
View
@@ -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 @@ class CString : public string {
EASCII,
EURL,
EHTML,
- ESQL
+ ESQL,
+ ENAMEDFMT
} EEscape;
explicit CString(bool b) : string(b ? "true" : "false") {}
@@ -282,6 +284,16 @@ class CString : public string {
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.
View
@@ -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;
@@ -277,6 +279,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;
}
switch (eTo) {
@@ -317,6 +329,13 @@ CString CString::Escape_n(EEscape eFrom, EEscape eTo) const {
} 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"

0 comments on commit 2fdf54d

Please sign in to comment.