summaryrefslogtreecommitdiff
path: root/src/string.cc
blob: 2345741338771247d8677f3f132475de898a4781 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "string.hh"

#include "exception.hh"

namespace Kakoune
{

std::vector<String> split(const String& str, char separator, char escape)
{
    auto begin = str.begin();
    auto end   = str.begin();

    std::vector<String> res;
    while (end != str.end())
    {
        res.emplace_back();
        String& element = res.back();
        while (end != str.end())
        {
            auto c = *end;
            if (c == escape and end + 1 != end and *(end+1) == separator)
            {
                element += separator;
                end += 2;
            }
            else if (c == separator)
            {
                ++end;
                break;
            }
            else
            {
                element += c;
                ++end;
            }
        }
        begin = end;
    }
    return res;
}

String escape(const String& str, char character, char escape)
{
    String res;
    for (auto& c : str)
    {
        if (c == character)
            res += escape;
        res += c;
    }
    return res;
}

int str_to_int(const String& str)
{
    int res = 0;
    if (sscanf(str.c_str(), "%i", &res) != 1)
        throw runtime_error(str + "is not a number");
    return res;
}

String to_string(int val)
{
    char buf[16];
    sprintf(buf, "%i", val);
    return buf;
}

String option_to_string(const Regex& re)
{
    return String{re.str()};
}

void option_from_string(const String& str, Regex& re)
{
    try
    {
        re = Regex{str.begin(), str.end()};
    }
    catch (boost::regex_error& err)
    {
        throw runtime_error("unable to create regex: "_str + err.what());
    }
}

bool prefix_match(const String& str, const String& prefix)
{
    auto it = str.begin();
    for (auto& c : prefix)
    {
        if (it ==str.end() or *it++ != c)
            return false;
    }
    return true;
}

bool subsequence_match(const String& str, const String& subseq)
{
    auto it = str.begin();
    for (auto& c : subseq)
    {
        if (it == str.end())
            return false;
        while (*it != c)
        {
            if (++it == str.end())
                return false;
        }
        ++it;
    }
    return true;
}

}