| //===- 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; | |
| static bool isExact(StringRef Pattern) { | |
| return Pattern.size() > 2 && Pattern.starts_with("\"") && | |
| Pattern.ends_with("\""); | |
| } | |
| SingleStringMatcher::SingleStringMatcher(StringRef Pattern) | |
| : ExactMatch(isExact(Pattern)) { | |
| if (ExactMatch) { | |
| ExactPattern = Pattern.substr(1, Pattern.size() - 2); | |
| } else { | |
| Expected<GlobPattern> Glob = GlobPattern::create(Pattern); | |
| if (!Glob) { | |
| error(toString(Glob.takeError()) + ": " + Pattern); | |
| return; | |
| } | |
| 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; | |
| } |