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 <string>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <functional>
#ifdef _WIN32 #ifdef _WIN32
#define strncasecmp _strnicmp #define strncasecmp _strnicmp
@ -52,6 +53,7 @@
#endif #endif
using namespace std; using namespace std;
using namespace std::placeholders;
namespace MedocUtils { namespace MedocUtils {
@ -62,7 +64,7 @@ int stringicmp(const string& s1, const string& s2)
void stringtolower(string& io) 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) string stringtolower(const string& i)
@ -624,7 +626,8 @@ bool pcSubst(const string& in, string& out, const map<char, string>& subs)
return true; 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(); out.erase();
string::size_type i; 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); string::size_type j = in.find_first_of(')', i);
if (j == string::npos) { if (j == string::npos) {
// ??concatenate remaining part and stop // ??concatenate remaining part and stop
out += std::string("%") + in.substr(i - 2); out += in.substr(i - 2);
break; break;
} }
key = in.substr(i, j - i); key = in.substr(i, j - i);
@ -655,12 +658,7 @@ bool pcSubst(const string& in, string& out, const map<string, string>& subs)
} else { } else {
key = in[i]; key = in[i];
} }
map<string, string>::const_iterator tr; out += mapper(key);
if ((tr = subs.find(key)) != subs.end()) {
out += tr->second;
} else {
out += std::string("%") + (key.size()==1? key : string("(") + key + string(")"));
}
} else { } else {
out += in[i]; out += in[i];
} }
@ -668,6 +666,26 @@ bool pcSubst(const string& in, string& out, const map<string, string>& subs)
return true; 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) void ulltodecstr(uint64_t val, string& buf)
{ {
buf.clear(); buf.clear();
@ -1208,8 +1226,7 @@ std::string SimpleRegexp::simpleSub(
if (!ok()) { if (!ok()) {
return std::string(); return std::string();
} }
return regex_replace( return regex_replace(in, m->expr, repl, std::regex_constants::format_first_only);
in, m->expr, repl, std::regex_constants::format_first_only);
} }
string SimpleRegexp::getMatch(const string&, int i) const string SimpleRegexp::getMatch(const string&, int i) const

View File

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