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 <string.h>
|
||||||
#include <math.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 <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -87,6 +97,23 @@ string stringtolower(const string& i)
|
||||||
stringtolower(o);
|
stringtolower(o);
|
||||||
return 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)
|
extern int stringisuffcmp(const string& s1, const string& s2)
|
||||||
{
|
{
|
||||||
string::const_reverse_iterator r1 = s1.rbegin(), re1 = s1.rend(),
|
string::const_reverse_iterator r1 = s1.rbegin(), re1 = s1.rend(),
|
||||||
|
@ -541,6 +568,34 @@ string escapeShell(const string& in)
|
||||||
return out;
|
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
|
// Substitute printf-like percent cmds inside a string
|
||||||
bool pcSubst(const string& in, string& out, const map<char, string>& subs)
|
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;
|
errbuf[0] = 0;
|
||||||
// We don't use ret, it's there to silence a cc warning
|
// We don't use ret, it's there to silence a cc warning
|
||||||
char *ret = (char *)strerror_r(_errno, errbuf, ERRBUFSZ);
|
char *ret = (char *)strerror_r(_errno, errbuf, ERRBUFSZ);
|
||||||
|
(void)ret;
|
||||||
reason->append(errbuf);
|
reason->append(errbuf);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1175,6 +1231,100 @@ string localelang()
|
||||||
return locale.substr(0, under);
|
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
|
// Initialization for static stuff to be called from main thread before going
|
||||||
// multiple
|
// multiple
|
||||||
void smallut_init_mt()
|
void smallut_init_mt()
|
||||||
|
@ -1249,7 +1399,7 @@ int main(int argc, char **argv)
|
||||||
thisprog = *argv++;
|
thisprog = *argv++;
|
||||||
argc--;
|
argc--;
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
if (argc <= 0) {
|
if (argc <= 0) {
|
||||||
cerr << "Usage: smallut <stringtosplit>" << endl;
|
cerr << "Usage: smallut <stringtosplit>" << endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -1400,7 +1550,23 @@ int main(int argc, char **argv)
|
||||||
cout << it->first << " " << it->second << " " <<
|
cout << it->first << " " << it->second << " " <<
|
||||||
stringuppercmp(it->first, it->second) << endl;
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,8 @@ extern int stringuppercmp(const std::string& alreadyupper,
|
||||||
|
|
||||||
extern void stringtolower(std::string& io);
|
extern void stringtolower(std::string& io);
|
||||||
extern std::string stringtolower(const 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 ?
|
// Is one string the end part of the other ?
|
||||||
extern int stringisuffcmp(const std::string& s1, const std::string& s2);
|
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 */
|
/** Escape things like < or & by turning them into entities */
|
||||||
extern std::string escapeHtml(const std::string& in);
|
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). */
|
/** Replace some chars with spaces (ie: newline chars). */
|
||||||
extern std::string neutchars(const std::string& str, const std::string& chars);
|
extern std::string neutchars(const std::string& str, const std::string& chars);
|
||||||
extern void neutchars(const std::string& str, std::string& out,
|
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.
|
// 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
|
// 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);
|
// 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