added toupper and simpleregexp utils
This commit is contained in:
parent
9a61c47467
commit
c2e7708035
2 changed files with 197 additions and 2 deletions
|
@ -31,6 +31,16 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
// Older compilers don't support stdc++ regex, but Windows does not
|
||||
// have the Linux one. Have a simple class to solve the simple cases.
|
||||
#if defined(_WIN32)
|
||||
#define USE_STD_REGEX
|
||||
#include <regex>
|
||||
#else
|
||||
#define USE_LINUX_REGEX
|
||||
#include <regex.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
|
@ -87,6 +97,23 @@ string stringtolower(const string& i)
|
|||
stringtolower(o);
|
||||
return o;
|
||||
}
|
||||
|
||||
void stringtoupper(string& io)
|
||||
{
|
||||
string::iterator it = io.begin();
|
||||
string::iterator ite = io.end();
|
||||
while (it != ite) {
|
||||
*it = ::toupper(*it);
|
||||
it++;
|
||||
}
|
||||
}
|
||||
string stringtoupper(const string& i)
|
||||
{
|
||||
string o = i;
|
||||
stringtoupper(o);
|
||||
return o;
|
||||
}
|
||||
|
||||
extern int stringisuffcmp(const string& s1, const string& s2)
|
||||
{
|
||||
string::const_reverse_iterator r1 = s1.rbegin(), re1 = s1.rend(),
|
||||
|
@ -541,6 +568,34 @@ string escapeShell(const string& in)
|
|||
return out;
|
||||
}
|
||||
|
||||
// Escape value to be suitable as C++ source double-quoted string (for
|
||||
// generating a c++ program
|
||||
string makeCString(const string& in)
|
||||
{
|
||||
string out;
|
||||
out += "\"";
|
||||
for (string::size_type pos = 0; pos < in.length(); pos++) {
|
||||
switch (in.at(pos)) {
|
||||
case '"':
|
||||
out += "\\\"";
|
||||
break;
|
||||
case '\n':
|
||||
out += "\\n";
|
||||
break;
|
||||
case '\r':
|
||||
out += "\\r";
|
||||
break;
|
||||
case '\\':
|
||||
out += "\\\\";
|
||||
break;
|
||||
default:
|
||||
out += in.at(pos);
|
||||
}
|
||||
}
|
||||
out += "\"";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
// Substitute printf-like percent cmds inside a string
|
||||
bool pcSubst(const string& in, string& out, const map<char, string>& subs)
|
||||
|
@ -1107,6 +1162,7 @@ void catstrerror(string *reason, const char *what, int _errno)
|
|||
errbuf[0] = 0;
|
||||
// We don't use ret, it's there to silence a cc warning
|
||||
char *ret = (char *)strerror_r(_errno, errbuf, ERRBUFSZ);
|
||||
(void)ret;
|
||||
reason->append(errbuf);
|
||||
#endif
|
||||
}
|
||||
|
@ -1175,6 +1231,100 @@ string localelang()
|
|||
return locale.substr(0, under);
|
||||
}
|
||||
|
||||
#ifdef USE_STD_REGEX
|
||||
|
||||
class SimpleRegexp::Internal {
|
||||
public:
|
||||
Internal(const string& exp, int flags, int nm)
|
||||
: expr(exp,
|
||||
basic_regex<char>::flag_type(regex_constants::extended |
|
||||
((flags&SRE_ICASE) ? regex_constants::icase : 0) |
|
||||
((flags&SRE_NOSUB) ? regex_constants::nosubs : 0)
|
||||
)), ok(true), nmatch(nm) {
|
||||
}
|
||||
bool ok;
|
||||
std::regex expr;
|
||||
std::smatch res;
|
||||
int nmatch;
|
||||
};
|
||||
|
||||
bool SimpleRegexp::simpleMatch(const string& val) const
|
||||
{
|
||||
if (!ok())
|
||||
return false;
|
||||
return regex_match(val, m->res, m->expr);
|
||||
}
|
||||
|
||||
string SimpleRegexp::getMatch(const string& val, int i) const
|
||||
{
|
||||
return m->res.str(i);
|
||||
}
|
||||
|
||||
#else // -> !WIN32
|
||||
|
||||
class SimpleRegexp::Internal {
|
||||
public:
|
||||
Internal(const string& exp, int flags, int nm) : nmatch(nm) {
|
||||
if (regcomp(&expr, exp.c_str(), REG_EXTENDED |
|
||||
((flags&SRE_ICASE) ? REG_ICASE : 0) |
|
||||
((flags&SRE_NOSUB) ? REG_NOSUB : 0)) == 0) {
|
||||
ok = true;
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
matches.reserve(nmatch+1);
|
||||
}
|
||||
~Internal() {
|
||||
regfree(&expr);
|
||||
}
|
||||
bool ok;
|
||||
regex_t expr;
|
||||
int nmatch;
|
||||
vector<regmatch_t> matches;
|
||||
};
|
||||
|
||||
bool SimpleRegexp::simpleMatch(const string& val) const
|
||||
{
|
||||
if (!ok())
|
||||
return false;
|
||||
if (regexec(&m->expr, val.c_str(), m->nmatch+1, &m->matches[0], 0) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
string SimpleRegexp::getMatch(const string& val, int i) const
|
||||
{
|
||||
if (i > m->nmatch) {
|
||||
return string();
|
||||
}
|
||||
return val.substr(m->matches[i].rm_so,
|
||||
m->matches[i].rm_eo - m->matches[i].rm_so);
|
||||
}
|
||||
|
||||
#endif // win/notwinf
|
||||
|
||||
SimpleRegexp::SimpleRegexp(const string& exp, int flags, int nmatch)
|
||||
: m(new Internal(exp, flags, nmatch))
|
||||
{
|
||||
}
|
||||
|
||||
SimpleRegexp::~SimpleRegexp()
|
||||
{
|
||||
delete m;
|
||||
}
|
||||
|
||||
bool SimpleRegexp::ok() const
|
||||
{
|
||||
return m->ok;
|
||||
}
|
||||
|
||||
bool SimpleRegexp::operator() (const string& val) const
|
||||
{
|
||||
return simpleMatch(val);
|
||||
}
|
||||
|
||||
// Initialization for static stuff to be called from main thread before going
|
||||
// multiple
|
||||
void smallut_init_mt()
|
||||
|
@ -1249,7 +1399,7 @@ int main(int argc, char **argv)
|
|||
thisprog = *argv++;
|
||||
argc--;
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
if (argc <= 0) {
|
||||
cerr << "Usage: smallut <stringtosplit>" << endl;
|
||||
exit(1);
|
||||
|
@ -1400,7 +1550,23 @@ int main(int argc, char **argv)
|
|||
cout << it->first << " " << it->second << " " <<
|
||||
stringuppercmp(it->first, it->second) << endl;
|
||||
}
|
||||
|
||||
#elif 0
|
||||
SimpleRegexp exp("[ \t]*#[ \t]*([a-zA-Z0-9]+)[ \t]*=.*", 0, 1);
|
||||
//SimpleRegexp exp(" # ([a-zA-Z0-9]+) =.*", 0, 10);
|
||||
//SimpleRegexp exp(" # (varnm) = sdf sdf sdf ", 0, 10);
|
||||
//SimpleRegexp exp(".*", 0);
|
||||
string tomatch(" # varnm = sdf sdf sdf ");
|
||||
if (exp.simpleMatch(tomatch)) {
|
||||
cout << "Match !\n";
|
||||
cout << "Submatch[0]: [" << exp.getMatch(tomatch, 0) << "]\n";
|
||||
cout << "Submatch[1]: [" << exp.getMatch(tomatch, 1) << "]\n";
|
||||
return 0;
|
||||
} else {
|
||||
cerr << "No match\n";
|
||||
return 1;
|
||||
}
|
||||
#elif 1
|
||||
cout << makeCString("\"hello\" world\n2nd line") << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@ extern int stringuppercmp(const std::string& alreadyupper,
|
|||
|
||||
extern void stringtolower(std::string& io);
|
||||
extern std::string stringtolower(const std::string& io);
|
||||
extern void stringtoupper(std::string& io);
|
||||
extern std::string stringtoupper(const std::string& io);
|
||||
|
||||
// Is one string the end part of the other ?
|
||||
extern int stringisuffcmp(const std::string& s1, const std::string& s2);
|
||||
|
@ -141,6 +143,9 @@ extern void trimstring(std::string& s, const char *ws = " \t");
|
|||
/** Escape things like < or & by turning them into entities */
|
||||
extern std::string escapeHtml(const std::string& in);
|
||||
|
||||
/** Double-quote and escape to produce C source code string (prog generation) */
|
||||
extern std::string makeCString(const std::string& in);
|
||||
|
||||
/** Replace some chars with spaces (ie: newline chars). */
|
||||
extern std::string neutchars(const std::string& str, const std::string& chars);
|
||||
extern void neutchars(const std::string& str, std::string& out,
|
||||
|
@ -189,6 +194,30 @@ inline void leftzeropad(std::string& s, unsigned len)
|
|||
}
|
||||
}
|
||||
|
||||
// A class to solve platorm/compiler issues for simple regex
|
||||
// matches. Uses the appropriate native lib under the hood.
|
||||
// This always uses extended regexp syntax.
|
||||
class SimpleRegexp {
|
||||
public:
|
||||
enum Flags {SRE_NONE = 0, SRE_ICASE = 1, SRE_NOSUB = 2};
|
||||
/// @param nmatch must be >= the number of parenthesed subexp in exp
|
||||
SimpleRegexp(const std::string& exp, int flags, int nmatch = 0);
|
||||
~SimpleRegexp();
|
||||
/// Match input against exp, return true if matches
|
||||
bool simpleMatch(const std::string& val) const;
|
||||
/// After simpleMatch success, get nth submatch, 0 is the whole
|
||||
/// match, 1 first parentheses, etc.
|
||||
std::string getMatch(const std::string& val, int matchidx) const;
|
||||
/// Calls simpleMatch()
|
||||
bool operator() (const std::string& val) const;
|
||||
/// Check after construction
|
||||
bool ok() const;
|
||||
|
||||
class Internal;
|
||||
private:
|
||||
Internal *m;
|
||||
};
|
||||
|
||||
// Code for static initialization of an stl map. Somewhat like Boost.assign.
|
||||
// Ref: http://stackoverflow.com/questions/138600/initializing-a-static-stdmapint-int-in-c
|
||||
// Example use: map<int, int> m = create_map<int, int> (1,2) (3,4) (5,6) (7,8);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue