|  | //===- Strings.cpp -------------------------------------------------------===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "lld/Common/Strings.h" | 
|  | #include "lld/Common/ErrorHandler.h" | 
|  | #include "lld/Common/LLVM.h" | 
|  | #include "llvm/ADT/StringExtras.h" | 
|  | #include "llvm/Support/FileSystem.h" | 
|  | #include "llvm/Support/GlobPattern.h" | 
|  | #include <algorithm> | 
|  | #include <mutex> | 
|  | #include <vector> | 
|  |  | 
|  | using namespace llvm; | 
|  | using namespace lld; | 
|  |  | 
|  | SingleStringMatcher::SingleStringMatcher(StringRef Pattern) { | 
|  | if (Pattern.size() > 2 && Pattern.starts_with("\"") && | 
|  | Pattern.ends_with("\"")) { | 
|  | ExactMatch = true; | 
|  | ExactPattern = Pattern.substr(1, Pattern.size() - 2); | 
|  | } else { | 
|  | Expected<GlobPattern> Glob = GlobPattern::create(Pattern); | 
|  | if (!Glob) { | 
|  | error(toString(Glob.takeError())); | 
|  | return; | 
|  | } | 
|  | ExactMatch = false; | 
|  | GlobPatternMatcher = *Glob; | 
|  | } | 
|  | } | 
|  |  | 
|  | bool SingleStringMatcher::match(StringRef s) const { | 
|  | return ExactMatch ? (ExactPattern == s) : GlobPatternMatcher.match(s); | 
|  | } | 
|  |  | 
|  | bool StringMatcher::match(StringRef s) const { | 
|  | for (const SingleStringMatcher &pat : patterns) | 
|  | if (pat.match(s)) | 
|  | return true; | 
|  | return false; | 
|  | } | 
|  |  | 
|  | // Converts a hex string (e.g. "deadbeef") to a vector. | 
|  | SmallVector<uint8_t, 0> lld::parseHex(StringRef s) { | 
|  | SmallVector<uint8_t, 0> hex; | 
|  | while (!s.empty()) { | 
|  | StringRef b = s.substr(0, 2); | 
|  | s = s.substr(2); | 
|  | uint8_t h; | 
|  | if (!to_integer(b, h, 16)) { | 
|  | error("not a hexadecimal value: " + b); | 
|  | return {}; | 
|  | } | 
|  | hex.push_back(h); | 
|  | } | 
|  | return hex; | 
|  | } | 
|  |  | 
|  | // Returns true if S is valid as a C language identifier. | 
|  | bool lld::isValidCIdentifier(StringRef s) { | 
|  | return !s.empty() && !isDigit(s[0]) && | 
|  | llvm::all_of(s, [](char c) { return isAlnum(c) || c == '_'; }); | 
|  | } | 
|  |  | 
|  | // Write the contents of the a buffer to a file | 
|  | void lld::saveBuffer(StringRef buffer, const Twine &path) { | 
|  | std::error_code ec; | 
|  | raw_fd_ostream os(path.str(), ec, sys::fs::OpenFlags::OF_None); | 
|  | if (ec) | 
|  | error("cannot create " + path + ": " + ec.message()); | 
|  | os << buffer; | 
|  | } |