xref: /freebsd-src/contrib/llvm-project/lld/Common/Strings.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===- Strings.cpp -------------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "lld/Common/Strings.h"
100b57cec5SDimitry Andric #include "lld/Common/ErrorHandler.h"
110b57cec5SDimitry Andric #include "lld/Common/LLVM.h"
1206c3fb27SDimitry Andric #include "llvm/ADT/StringExtras.h"
135ffd83dbSDimitry Andric #include "llvm/Support/FileSystem.h"
140b57cec5SDimitry Andric #include "llvm/Support/GlobPattern.h"
150b57cec5SDimitry Andric #include <algorithm>
160b57cec5SDimitry Andric #include <mutex>
170b57cec5SDimitry Andric #include <vector>
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric using namespace llvm;
200b57cec5SDimitry Andric using namespace lld;
210b57cec5SDimitry Andric 
SingleStringMatcher(StringRef Pattern)225ffd83dbSDimitry Andric SingleStringMatcher::SingleStringMatcher(StringRef Pattern) {
2306c3fb27SDimitry Andric   if (Pattern.size() > 2 && Pattern.starts_with("\"") &&
2406c3fb27SDimitry Andric       Pattern.ends_with("\"")) {
255ffd83dbSDimitry Andric     ExactMatch = true;
265ffd83dbSDimitry Andric     ExactPattern = Pattern.substr(1, Pattern.size() - 2);
275ffd83dbSDimitry Andric   } else {
285ffd83dbSDimitry Andric     Expected<GlobPattern> Glob = GlobPattern::create(Pattern);
295ffd83dbSDimitry Andric     if (!Glob) {
30*5f757f3fSDimitry Andric       error(toString(Glob.takeError()) + ": " + Pattern);
315ffd83dbSDimitry Andric       return;
320b57cec5SDimitry Andric     }
335ffd83dbSDimitry Andric     ExactMatch = false;
345ffd83dbSDimitry Andric     GlobPatternMatcher = *Glob;
355ffd83dbSDimitry Andric   }
365ffd83dbSDimitry Andric }
375ffd83dbSDimitry Andric 
match(StringRef s) const385ffd83dbSDimitry Andric bool SingleStringMatcher::match(StringRef s) const {
395ffd83dbSDimitry Andric   return ExactMatch ? (ExactPattern == s) : GlobPatternMatcher.match(s);
400b57cec5SDimitry Andric }
410b57cec5SDimitry Andric 
match(StringRef s) const420b57cec5SDimitry Andric bool StringMatcher::match(StringRef s) const {
435ffd83dbSDimitry Andric   for (const SingleStringMatcher &pat : patterns)
440b57cec5SDimitry Andric     if (pat.match(s))
450b57cec5SDimitry Andric       return true;
460b57cec5SDimitry Andric   return false;
470b57cec5SDimitry Andric }
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric // Converts a hex string (e.g. "deadbeef") to a vector.
parseHex(StringRef s)50bdd1243dSDimitry Andric SmallVector<uint8_t, 0> lld::parseHex(StringRef s) {
51bdd1243dSDimitry Andric   SmallVector<uint8_t, 0> hex;
520b57cec5SDimitry Andric   while (!s.empty()) {
530b57cec5SDimitry Andric     StringRef b = s.substr(0, 2);
540b57cec5SDimitry Andric     s = s.substr(2);
550b57cec5SDimitry Andric     uint8_t h;
560b57cec5SDimitry Andric     if (!to_integer(b, h, 16)) {
570b57cec5SDimitry Andric       error("not a hexadecimal value: " + b);
580b57cec5SDimitry Andric       return {};
590b57cec5SDimitry Andric     }
600b57cec5SDimitry Andric     hex.push_back(h);
610b57cec5SDimitry Andric   }
620b57cec5SDimitry Andric   return hex;
630b57cec5SDimitry Andric }
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric // Returns true if S is valid as a C language identifier.
isValidCIdentifier(StringRef s)660b57cec5SDimitry Andric bool lld::isValidCIdentifier(StringRef s) {
67fe6060f1SDimitry Andric   return !s.empty() && !isDigit(s[0]) &&
68fe6060f1SDimitry Andric          llvm::all_of(s, [](char c) { return isAlnum(c) || c == '_'; });
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric // Write the contents of the a buffer to a file
saveBuffer(StringRef buffer,const Twine & path)720b57cec5SDimitry Andric void lld::saveBuffer(StringRef buffer, const Twine &path) {
730b57cec5SDimitry Andric   std::error_code ec;
7485868e8aSDimitry Andric   raw_fd_ostream os(path.str(), ec, sys::fs::OpenFlags::OF_None);
750b57cec5SDimitry Andric   if (ec)
760b57cec5SDimitry Andric     error("cannot create " + path + ": " + ec.message());
770b57cec5SDimitry Andric   os << buffer;
780b57cec5SDimitry Andric }
79