|
a/src/smallut.cpp |
|
b/src/smallut.cpp |
|
... |
|
... |
29 |
#include <errno.h>
|
29 |
#include <errno.h>
|
30 |
#include <time.h>
|
30 |
#include <time.h>
|
31 |
#include <string.h>
|
31 |
#include <string.h>
|
32 |
#include <math.h>
|
32 |
#include <math.h>
|
33 |
|
33 |
|
|
|
34 |
// Older compilers don't support stdc++ regex, but Windows does not
|
|
|
35 |
// have the Linux one. Have a simple class to solve the simple cases.
|
|
|
36 |
#if defined(_WIN32)
|
|
|
37 |
#define USE_STD_REGEX
|
|
|
38 |
#include <regex>
|
|
|
39 |
#else
|
|
|
40 |
#define USE_LINUX_REGEX
|
|
|
41 |
#include <regex.h>
|
|
|
42 |
#endif
|
|
|
43 |
|
34 |
#include <string>
|
44 |
#include <string>
|
35 |
#include <iostream>
|
45 |
#include <iostream>
|
36 |
#include <list>
|
46 |
#include <list>
|
37 |
#include UNORDERED_MAP_INCLUDE
|
47 |
#include UNORDERED_MAP_INCLUDE
|
38 |
#include UNORDERED_SET_INCLUDE
|
48 |
#include UNORDERED_SET_INCLUDE
|
|
... |
|
... |
85 |
{
|
95 |
{
|
86 |
string o = i;
|
96 |
string o = i;
|
87 |
stringtolower(o);
|
97 |
stringtolower(o);
|
88 |
return o;
|
98 |
return o;
|
89 |
}
|
99 |
}
|
|
|
100 |
|
|
|
101 |
void stringtoupper(string& io)
|
|
|
102 |
{
|
|
|
103 |
string::iterator it = io.begin();
|
|
|
104 |
string::iterator ite = io.end();
|
|
|
105 |
while (it != ite) {
|
|
|
106 |
*it = ::toupper(*it);
|
|
|
107 |
it++;
|
|
|
108 |
}
|
|
|
109 |
}
|
|
|
110 |
string stringtoupper(const string& i)
|
|
|
111 |
{
|
|
|
112 |
string o = i;
|
|
|
113 |
stringtoupper(o);
|
|
|
114 |
return o;
|
|
|
115 |
}
|
|
|
116 |
|
90 |
extern int stringisuffcmp(const string& s1, const string& s2)
|
117 |
extern int stringisuffcmp(const string& s1, const string& s2)
|
91 |
{
|
118 |
{
|
92 |
string::const_reverse_iterator r1 = s1.rbegin(), re1 = s1.rend(),
|
119 |
string::const_reverse_iterator r1 = s1.rbegin(), re1 = s1.rend(),
|
93 |
r2 = s2.rbegin(), re2 = s2.rend();
|
120 |
r2 = s2.rbegin(), re2 = s2.rend();
|
94 |
while (r1 != re1 && r2 != re2) {
|
121 |
while (r1 != re1 && r2 != re2) {
|
|
... |
|
... |
539 |
}
|
566 |
}
|
540 |
out += "\"";
|
567 |
out += "\"";
|
541 |
return out;
|
568 |
return out;
|
542 |
}
|
569 |
}
|
543 |
|
570 |
|
|
|
571 |
// Escape value to be suitable as C++ source double-quoted string (for
|
|
|
572 |
// generating a c++ program
|
|
|
573 |
string makeCString(const string& in)
|
|
|
574 |
{
|
|
|
575 |
string out;
|
|
|
576 |
out += "\"";
|
|
|
577 |
for (string::size_type pos = 0; pos < in.length(); pos++) {
|
|
|
578 |
switch (in.at(pos)) {
|
|
|
579 |
case '"':
|
|
|
580 |
out += "\\\"";
|
|
|
581 |
break;
|
|
|
582 |
case '\n':
|
|
|
583 |
out += "\\n";
|
|
|
584 |
break;
|
|
|
585 |
case '\r':
|
|
|
586 |
out += "\\r";
|
|
|
587 |
break;
|
|
|
588 |
case '\\':
|
|
|
589 |
out += "\\\\";
|
|
|
590 |
break;
|
|
|
591 |
default:
|
|
|
592 |
out += in.at(pos);
|
|
|
593 |
}
|
|
|
594 |
}
|
|
|
595 |
out += "\"";
|
|
|
596 |
return out;
|
|
|
597 |
}
|
|
|
598 |
|
544 |
|
599 |
|
545 |
// Substitute printf-like percent cmds inside a string
|
600 |
// Substitute printf-like percent cmds inside a string
|
546 |
bool pcSubst(const string& in, string& out, const map<char, string>& subs)
|
601 |
bool pcSubst(const string& in, string& out, const map<char, string>& subs)
|
547 |
{
|
602 |
{
|
548 |
string::const_iterator it;
|
603 |
string::const_iterator it;
|
|
... |
|
... |
1105 |
// normally default to the posix version.
|
1160 |
// normally default to the posix version.
|
1106 |
// At worse we get no message at all here.
|
1161 |
// At worse we get no message at all here.
|
1107 |
errbuf[0] = 0;
|
1162 |
errbuf[0] = 0;
|
1108 |
// We don't use ret, it's there to silence a cc warning
|
1163 |
// We don't use ret, it's there to silence a cc warning
|
1109 |
char *ret = (char *)strerror_r(_errno, errbuf, ERRBUFSZ);
|
1164 |
char *ret = (char *)strerror_r(_errno, errbuf, ERRBUFSZ);
|
|
|
1165 |
(void)ret;
|
1110 |
reason->append(errbuf);
|
1166 |
reason->append(errbuf);
|
1111 |
#endif
|
1167 |
#endif
|
1112 |
}
|
1168 |
}
|
1113 |
|
1169 |
|
1114 |
|
1170 |
|
|
... |
|
... |
1171 |
string::size_type under = locale.find_first_of("_");
|
1227 |
string::size_type under = locale.find_first_of("_");
|
1172 |
if (under == string::npos) {
|
1228 |
if (under == string::npos) {
|
1173 |
return locale;
|
1229 |
return locale;
|
1174 |
}
|
1230 |
}
|
1175 |
return locale.substr(0, under);
|
1231 |
return locale.substr(0, under);
|
|
|
1232 |
}
|
|
|
1233 |
|
|
|
1234 |
#ifdef USE_STD_REGEX
|
|
|
1235 |
|
|
|
1236 |
class SimpleRegexp::Internal {
|
|
|
1237 |
public:
|
|
|
1238 |
Internal(const string& exp, int flags, int nm)
|
|
|
1239 |
: expr(exp,
|
|
|
1240 |
basic_regex<char>::flag_type(regex_constants::extended |
|
|
|
1241 |
((flags&SRE_ICASE) ? regex_constants::icase : 0) |
|
|
|
1242 |
((flags&SRE_NOSUB) ? regex_constants::nosubs : 0)
|
|
|
1243 |
)), ok(true), nmatch(nm) {
|
|
|
1244 |
}
|
|
|
1245 |
bool ok;
|
|
|
1246 |
std::regex expr;
|
|
|
1247 |
std::smatch res;
|
|
|
1248 |
int nmatch;
|
|
|
1249 |
};
|
|
|
1250 |
|
|
|
1251 |
bool SimpleRegexp::simpleMatch(const string& val) const
|
|
|
1252 |
{
|
|
|
1253 |
if (!ok())
|
|
|
1254 |
return false;
|
|
|
1255 |
return regex_match(val, m->res, m->expr);
|
|
|
1256 |
}
|
|
|
1257 |
|
|
|
1258 |
string SimpleRegexp::getMatch(const string& val, int i) const
|
|
|
1259 |
{
|
|
|
1260 |
return m->res.str(i);
|
|
|
1261 |
}
|
|
|
1262 |
|
|
|
1263 |
#else // -> !WIN32
|
|
|
1264 |
|
|
|
1265 |
class SimpleRegexp::Internal {
|
|
|
1266 |
public:
|
|
|
1267 |
Internal(const string& exp, int flags, int nm) : nmatch(nm) {
|
|
|
1268 |
if (regcomp(&expr, exp.c_str(), REG_EXTENDED |
|
|
|
1269 |
((flags&SRE_ICASE) ? REG_ICASE : 0) |
|
|
|
1270 |
((flags&SRE_NOSUB) ? REG_NOSUB : 0)) == 0) {
|
|
|
1271 |
ok = true;
|
|
|
1272 |
} else {
|
|
|
1273 |
ok = false;
|
|
|
1274 |
}
|
|
|
1275 |
matches.reserve(nmatch+1);
|
|
|
1276 |
}
|
|
|
1277 |
~Internal() {
|
|
|
1278 |
regfree(&expr);
|
|
|
1279 |
}
|
|
|
1280 |
bool ok;
|
|
|
1281 |
regex_t expr;
|
|
|
1282 |
int nmatch;
|
|
|
1283 |
vector<regmatch_t> matches;
|
|
|
1284 |
};
|
|
|
1285 |
|
|
|
1286 |
bool SimpleRegexp::simpleMatch(const string& val) const
|
|
|
1287 |
{
|
|
|
1288 |
if (!ok())
|
|
|
1289 |
return false;
|
|
|
1290 |
if (regexec(&m->expr, val.c_str(), m->nmatch+1, &m->matches[0], 0) == 0) {
|
|
|
1291 |
return true;
|
|
|
1292 |
} else {
|
|
|
1293 |
return false;
|
|
|
1294 |
}
|
|
|
1295 |
}
|
|
|
1296 |
|
|
|
1297 |
string SimpleRegexp::getMatch(const string& val, int i) const
|
|
|
1298 |
{
|
|
|
1299 |
if (i > m->nmatch) {
|
|
|
1300 |
return string();
|
|
|
1301 |
}
|
|
|
1302 |
return val.substr(m->matches[i].rm_so,
|
|
|
1303 |
m->matches[i].rm_eo - m->matches[i].rm_so);
|
|
|
1304 |
}
|
|
|
1305 |
|
|
|
1306 |
#endif // win/notwinf
|
|
|
1307 |
|
|
|
1308 |
SimpleRegexp::SimpleRegexp(const string& exp, int flags, int nmatch)
|
|
|
1309 |
: m(new Internal(exp, flags, nmatch))
|
|
|
1310 |
{
|
|
|
1311 |
}
|
|
|
1312 |
|
|
|
1313 |
SimpleRegexp::~SimpleRegexp()
|
|
|
1314 |
{
|
|
|
1315 |
delete m;
|
|
|
1316 |
}
|
|
|
1317 |
|
|
|
1318 |
bool SimpleRegexp::ok() const
|
|
|
1319 |
{
|
|
|
1320 |
return m->ok;
|
|
|
1321 |
}
|
|
|
1322 |
|
|
|
1323 |
bool SimpleRegexp::operator() (const string& val) const
|
|
|
1324 |
{
|
|
|
1325 |
return simpleMatch(val);
|
1176 |
}
|
1326 |
}
|
1177 |
|
1327 |
|
1178 |
// Initialization for static stuff to be called from main thread before going
|
1328 |
// Initialization for static stuff to be called from main thread before going
|
1179 |
// multiple
|
1329 |
// multiple
|
1180 |
void smallut_init_mt()
|
1330 |
void smallut_init_mt()
|
|
... |
|
... |
1247 |
int main(int argc, char **argv)
|
1397 |
int main(int argc, char **argv)
|
1248 |
{
|
1398 |
{
|
1249 |
thisprog = *argv++;
|
1399 |
thisprog = *argv++;
|
1250 |
argc--;
|
1400 |
argc--;
|
1251 |
|
1401 |
|
1252 |
#if 1
|
1402 |
#if 0
|
1253 |
if (argc <= 0) {
|
1403 |
if (argc <= 0) {
|
1254 |
cerr << "Usage: smallut <stringtosplit>" << endl;
|
1404 |
cerr << "Usage: smallut <stringtosplit>" << endl;
|
1255 |
exit(1);
|
1405 |
exit(1);
|
1256 |
}
|
1406 |
}
|
1257 |
string s = *argv++;
|
1407 |
string s = *argv++;
|
|
... |
|
... |
1398 |
for (vector<pair<string, string> >::const_iterator it = cmps.begin();
|
1548 |
for (vector<pair<string, string> >::const_iterator it = cmps.begin();
|
1399 |
it != cmps.end(); it++) {
|
1549 |
it != cmps.end(); it++) {
|
1400 |
cout << it->first << " " << it->second << " " <<
|
1550 |
cout << it->first << " " << it->second << " " <<
|
1401 |
stringuppercmp(it->first, it->second) << endl;
|
1551 |
stringuppercmp(it->first, it->second) << endl;
|
1402 |
}
|
1552 |
}
|
1403 |
|
1553 |
#elif 0
|
|
|
1554 |
SimpleRegexp exp("[ \t]*#[ \t]*([a-zA-Z0-9]+)[ \t]*=.*", 0, 1);
|
|
|
1555 |
//SimpleRegexp exp(" # ([a-zA-Z0-9]+) =.*", 0, 10);
|
|
|
1556 |
//SimpleRegexp exp(" # (varnm) = sdf sdf sdf ", 0, 10);
|
|
|
1557 |
//SimpleRegexp exp(".*", 0);
|
|
|
1558 |
string tomatch(" # varnm = sdf sdf sdf ");
|
|
|
1559 |
if (exp.simpleMatch(tomatch)) {
|
|
|
1560 |
cout << "Match !\n";
|
|
|
1561 |
cout << "Submatch[0]: [" << exp.getMatch(tomatch, 0) << "]\n";
|
|
|
1562 |
cout << "Submatch[1]: [" << exp.getMatch(tomatch, 1) << "]\n";
|
|
|
1563 |
return 0;
|
|
|
1564 |
} else {
|
|
|
1565 |
cerr << "No match\n";
|
|
|
1566 |
return 1;
|
|
|
1567 |
}
|
|
|
1568 |
#elif 1
|
|
|
1569 |
cout << makeCString("\"hello\" world\n2nd line") << endl;
|
1404 |
#endif
|
1570 |
#endif
|
1405 |
}
|
1571 |
}
|
1406 |
|
1572 |
|
1407 |
#endif
|
1573 |
#endif
|