Skip to content

Commit

Permalink
Add string formatting function with named params.
Browse files Browse the repository at this point in the history
In addition to the formatting function, a matching Escape type is added.
  • Loading branch information
Stéphan Kochen committed Oct 27, 2011
1 parent f7e5b41 commit 2fdf54d
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
14 changes: 13 additions & 1 deletion include/znc/ZNCString.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ using std::pair;
#define _SQL(s) CString("'" + CString(s).Escape_n(CString::ESQL) + "'") #define _SQL(s) CString("'" + CString(s).Escape_n(CString::ESQL) + "'")
#define _URL(s) CString(s).Escape_n(CString::EURL) #define _URL(s) CString(s).Escape_n(CString::EURL)
#define _HTML(s) CString(s).Escape_n(CString::EHTML) #define _HTML(s) CString(s).Escape_n(CString::EHTML)
#define _NAMEDFMT(s) CString(s).Escape_n(CString::ENAMEDFMT)


class CString; class CString;
class MCString; class MCString;
Expand Down Expand Up @@ -68,7 +69,8 @@ class CString : public string {
EASCII, EASCII,
EURL, EURL,
EHTML, EHTML,
ESQL ESQL,
ENAMEDFMT
} EEscape; } EEscape;


explicit CString(bool b) : string(b ? "true" : "false") {} explicit CString(bool b) : string(b ? "true" : "false") {}
Expand Down Expand Up @@ -282,6 +284,16 @@ class CString : public string {
const CString& sLeft = "", const CString& sRight = "", bool bTrimQuotes = true, const CString& sLeft = "", const CString& sRight = "", bool bTrimQuotes = true,
bool bTrimWhiteSpace = false) const; 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. /** Produces a random string.
* @param uLength The length of the resulting string. * @param uLength The length of the resulting string.
* @return A random string. * @return A random string.
Expand Down
64 changes: 64 additions & 0 deletions src/ZNCString.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ CString::EEscape CString::ToEscape(const CString& sEsc) {
return EURL; return EURL;
} else if (sEsc.Equals("SQL")) { } else if (sEsc.Equals("SQL")) {
return ESQL; return ESQL;
} else if (sEsc.Equals("NAMEDFMT")) {
return ENAMEDFMT;
} }


return EASCII; return EASCII;
Expand Down Expand Up @@ -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; break;
} }


Expand Down Expand Up @@ -316,6 +328,13 @@ CString CString::Escape_n(EEscape eFrom, EEscape eTo) const {
} else if (ch == '\\') { sRet += '\\'; sRet += '\\'; } else if (ch == '\\') { sRet += '\\'; sRet += '\\';
} else { sRet += ch; } } else { sRet += ch; }


break;
case ENAMEDFMT:
if (ch == '\\') { sRet += '\\'; sRet += '\\';
} else if (ch == '{') { sRet += '\\'; sRet += '{';
} else if (ch == '}') { sRet += '\\'; sRet += '}';
} else { sRet += ch; }

break; break;
} }
} }
Expand Down Expand Up @@ -639,6 +658,51 @@ unsigned int CString::Split(const CString& sDelim, SCString& ssRet, bool bAllowE
return ssRet.size(); 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) { CString CString::RandomString(unsigned int uLength) {
const char chars[] = "abcdefghijklmnopqrstuvwxyz" const char chars[] = "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Expand Down

0 comments on commit 2fdf54d

Please sign in to comment.