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