Switch to unified view

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