82 lines · cpp
1//===- Strings.cpp -------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lld/Common/Strings.h"10#include "lld/Common/ErrorHandler.h"11#include "lld/Common/LLVM.h"12#include "llvm/ADT/StringExtras.h"13#include "llvm/Support/FileSystem.h"14#include "llvm/Support/GlobPattern.h"15#include <algorithm>16#include <mutex>17#include <vector>18 19using namespace llvm;20using namespace lld;21 22static bool isExact(StringRef Pattern) {23 return Pattern.size() > 2 && Pattern.starts_with("\"") &&24 Pattern.ends_with("\"");25}26 27SingleStringMatcher::SingleStringMatcher(StringRef Pattern)28 : ExactMatch(isExact(Pattern)) {29 if (ExactMatch) {30 ExactPattern = Pattern.substr(1, Pattern.size() - 2);31 } else {32 Expected<GlobPattern> Glob = GlobPattern::create(Pattern);33 if (!Glob) {34 error(toString(Glob.takeError()) + ": " + Pattern);35 return;36 }37 GlobPatternMatcher = *Glob;38 }39}40 41bool SingleStringMatcher::match(StringRef s) const {42 return ExactMatch ? (ExactPattern == s) : GlobPatternMatcher.match(s);43}44 45bool StringMatcher::match(StringRef s) const {46 for (const SingleStringMatcher &pat : patterns)47 if (pat.match(s))48 return true;49 return false;50}51 52// Converts a hex string (e.g. "deadbeef") to a vector.53SmallVector<uint8_t, 0> lld::parseHex(StringRef s) {54 SmallVector<uint8_t, 0> hex;55 while (!s.empty()) {56 StringRef b = s.substr(0, 2);57 s = s.substr(2);58 uint8_t h;59 if (!to_integer(b, h, 16)) {60 error("not a hexadecimal value: " + b);61 return {};62 }63 hex.push_back(h);64 }65 return hex;66}67 68// Returns true if S is valid as a C language identifier.69bool lld::isValidCIdentifier(StringRef s) {70 return !s.empty() && !isDigit(s[0]) &&71 llvm::all_of(s, [](char c) { return isAlnum(c) || c == '_'; });72}73 74// Write the contents of the a buffer to a file75void lld::saveBuffer(StringRef buffer, const Twine &path) {76 std::error_code ec;77 raw_fd_ostream os(path.str(), ec, sys::fs::OpenFlags::OF_None);78 if (ec)79 error("cannot create " + path + ": " + ec.message());80 os << buffer;81}82