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