aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/fmt.cc
diff options
context:
space:
mode:
authorFishhh <hubert.gluchowski19@gmail.com>2022-01-21 16:13:34 +0100
committerFishhh <hubert.gluchowski19@gmail.com>2022-01-21 20:10:46 +0100
commit1e0b7cdc3f3169ae85d71df5b3f80872a8258779 (patch)
tree41c2bf06049fc19f9a820cfd80cc421f0829850a /src/libutil/fmt.cc
parentb03fe13b5bb5ce540215a7e8df0d63a99f389db5 (diff)
Move hilite_all into libutil and rename it to hiliteMatches
The signature was also changed so the function now accepts a vector instead of an iterator
Diffstat (limited to 'src/libutil/fmt.cc')
-rw-r--r--src/libutil/fmt.cc38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/libutil/fmt.cc b/src/libutil/fmt.cc
new file mode 100644
index 000000000..914fb62b2
--- /dev/null
+++ b/src/libutil/fmt.cc
@@ -0,0 +1,38 @@
+#include <regex>
+
+namespace nix {
+
+std::string hiliteMatches(const std::string &s, std::vector<std::smatch> matches, std::string prefix, std::string postfix) {
+ // Avoid copy on zero matches
+ if (matches.size() == 0)
+ return 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;
+}
+
+}