aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/fmt.cc
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2022-03-10 15:48:14 +0000
committerJohn Ericson <John.Ericson@Obsidian.Systems>2022-03-10 15:48:14 +0000
commit8ba089597fa19bfd49ba5f22a5e821740ca4eb5d (patch)
treeb4f2299b9c973ef7636f8ce1bab0299dee4cc389 /src/libutil/fmt.cc
parent13b6b645897fd2edaa0f09fa48d6fe8dd6287b55 (diff)
parent4d98143914120d0163f5c50f30ce8a5289433f8f (diff)
Merge remote-tracking branch 'upstream/master' into path-info
Diffstat (limited to 'src/libutil/fmt.cc')
-rw-r--r--src/libutil/fmt.cc46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/libutil/fmt.cc b/src/libutil/fmt.cc
new file mode 100644
index 000000000..3dd93d73e
--- /dev/null
+++ b/src/libutil/fmt.cc
@@ -0,0 +1,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;
+}
+
+}