smallut: new pcSubst with callback param

This commit is contained in:
Jean-Francois Dockes 2022-09-05 10:44:10 +02:00
parent c86cb9438b
commit 6aa5ef9064
2 changed files with 39 additions and 24 deletions

View File

@ -33,6 +33,7 @@
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <functional>
#ifdef _WIN32
#define strncasecmp _strnicmp
@ -52,6 +53,7 @@
#endif
using namespace std;
using namespace std::placeholders;
namespace MedocUtils {
@ -62,7 +64,7 @@ int stringicmp(const string& s1, const string& s2)
void stringtolower(string& io)
{
std::transform(io.begin(), io.end(), io.begin(), [](unsigned char c) { return std::tolower(c); });
std::transform(io.begin(), io.end(), io.begin(), [](unsigned char c) {return std::tolower(c);});
}
string stringtolower(const string& i)
@ -624,7 +626,8 @@ bool pcSubst(const string& in, string& out, const map<char, string>& subs)
return true;
}
bool pcSubst(const string& in, string& out, const map<string, string>& subs)
bool pcSubst(const std::string& in, std::string& out,
std::function<std::string(const std::string&)> mapper)
{
out.erase();
string::size_type i;
@ -647,7 +650,7 @@ bool pcSubst(const string& in, string& out, const map<string, string>& subs)
string::size_type j = in.find_first_of(')', i);
if (j == string::npos) {
// ??concatenate remaining part and stop
out += std::string("%") + in.substr(i - 2);
out += in.substr(i - 2);
break;
}
key = in.substr(i, j - i);
@ -655,12 +658,7 @@ bool pcSubst(const string& in, string& out, const map<string, string>& subs)
} else {
key = in[i];
}
map<string, string>::const_iterator tr;
if ((tr = subs.find(key)) != subs.end()) {
out += tr->second;
} else {
out += std::string("%") + (key.size()==1? key : string("(") + key + string(")"));
}
out += mapper(key);
} else {
out += in[i];
}
@ -668,6 +666,26 @@ bool pcSubst(const string& in, string& out, const map<string, string>& subs)
return true;
}
class PcSubstMapMapper {
public:
PcSubstMapMapper(const std::map<std::string, std::string>& subs)
: m_subs(subs) {}
std::string domap(const std::string& key) {
auto it = m_subs.find(key);
if (it != m_subs.end())
return it->second;
return std::string("%") + (key.size() == 1 ? key : string("(") + key + string(")"));
}
const std::map<std::string, std::string>& m_subs;
};
bool pcSubst(const std::string& in, std::string& out,
const std::map<std::string, std::string>& subs)
{
PcSubstMapMapper mapper(subs);
return pcSubst(in, out, std::bind(&PcSubstMapMapper::domap, &mapper, _1));
}
void ulltodecstr(uint64_t val, string& buf)
{
buf.clear();
@ -1208,8 +1226,7 @@ std::string SimpleRegexp::simpleSub(
if (!ok()) {
return std::string();
}
return regex_replace(
in, m->expr, repl, std::regex_constants::format_first_only);
return regex_replace(in, m->expr, repl, std::regex_constants::format_first_only);
}
string SimpleRegexp::getMatch(const string&, int i) const
@ -1224,9 +1241,9 @@ public:
Internal(const string& exp, int flags, int nm) : nmatch(nm) {
ok = regcomp(&expr, exp.c_str(), REG_EXTENDED |
((flags & SRE_ICASE) ? REG_ICASE : 0) |
((flags & SRE_ICASE) ? REG_ICASE : 0) |
((flags & SRE_NOSUB) ? REG_NOSUB : 0)) == 0;
((flags & SRE_NOSUB) ? REG_NOSUB : 0)) == 0;
matches.resize(nmatch+1);
}
~Internal() {

View File

@ -23,6 +23,7 @@
#include <string>
#include <vector>
#include <map>
#include <functional>
struct tm;
@ -137,8 +138,7 @@ template <class T> std::string stringsToString(const T& tokens);
* " inside tokens is escaped as "" ([word "quote"] =>["word ""quote"""]
* See instantiation note above.
*/
template <class T> void stringsToCSV(const T& tokens, std::string& s,
char sep = ',');
template <class T> void stringsToCSV(const T& tokens, std::string& s, char sep = ',');
/** Find longest common prefix for bunch of strings */
template <class T> std::string commonprefix(const T& values);
@ -183,8 +183,7 @@ extern std::string escapeShell(const std::string& in);
/** Truncate a string to a given maxlength, avoiding cutting off midword
* if reasonably possible. */
extern std::string truncate_to_word(const std::string& input,
std::string::size_type maxlen);
extern std::string truncate_to_word(const std::string& input, std::string::size_type maxlen);
void ulltodecstr(uint64_t val, std::string& buf);
void lltodecstr(int64_t val, std::string& buf);
@ -195,15 +194,16 @@ std::string ulltodecstr(uint64_t val);
std::string displayableBytes(int64_t size);
/** Break big string into lines */
std::string breakIntoLines(const std::string& in, unsigned int ll = 100,
unsigned int maxlines = 50);
std::string breakIntoLines(const std::string& in, unsigned int ll = 100, unsigned int maxlines = 50);
/** Small utility to substitute printf-like percents cmds in a string */
bool pcSubst(const std::string& in, std::string& out,
const std::map<char, std::string>& subs);
bool pcSubst(const std::string& in, std::string& out, const std::map<char, std::string>& subs);
/** Substitute printf-like percents and also %(key) */
bool pcSubst(const std::string& in, std::string& out,
const std::map<std::string, std::string>& subs);
/** Substitute printf-like percents and %(nm), using result of function call */
bool pcSubst(const std::string& i, std::string& o, std::function<std::string(const std::string&)>);
/** Append system error message */
void catstrerror(std::string *reason, const char *what, int _errno);
@ -249,7 +249,6 @@ public:
/// Check after construction
bool ok() const;
class Internal;
private:
Internal *m;
@ -272,8 +271,7 @@ struct CharFlags {
#define CHARFLAGENTRY(NM) {NM, #NM}
/// Translate a bitfield into string description
extern std::string flagsToString(const std::vector<CharFlags>&,
unsigned int val);
extern std::string flagsToString(const std::vector<CharFlags>&, unsigned int val);
/// Translate a value into a name
extern std::string valToString(const std::vector<CharFlags>&, unsigned int val);