aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/fmt.cc
blob: 3dd93d73e18914cf7b8f03c5ab264f37158f7389 (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
#include "fmt.hh"

#include <regex>

namespace nix {

std::string hiliteMatches(
    std::string_view s,
    std::vector<std::smatch> matches,
    std::string_view prefix,
    std::string_view postfix)
{
    // Avoid copy on zero matches
    if (matches.size() == 0)
        return (std::string) s;

    std::sort(matches.begin(), matches.end(), [](const auto & a, const auto & b) {
        return a.position() < b.position();
    });

    std::string out;
    ssize_t last_end = 0;

    for (auto it = matches.begin(); it != matches.end();) {
        auto m = *it;
        size_t start = m.position();
        out.append(s.substr(last_end, m.position() - last_end));
        // Merge continous matches
        ssize_t end = start + m.length();
        while (++it != matches.end() && (*it).position() <= end) {
            auto n = *it;
            ssize_t nend = start + (n.position() - start + n.length());
            if (nend > end)
                end = nend;
        }
        out.append(prefix);
        out.append(s.substr(start, end - start));
        out.append(postfix);
        last_end = end;
    }

    out.append(s.substr(last_end));
    return out;
}

}