| // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| #include <stdio.h> |
| |
| #include <map> |
| #include <regex> |
| |
| #include "llvm/ADT/StringRef.h" |
| #include "llvm/Support/LineIterator.h" |
| #include "llvm/Support/MemoryBuffer.h" |
| #include "llvm/Support/Path.h" |
| #include "llvm/Support/Regex.h" |
| #include "llvm/Support/WithColor.h" |
| |
| namespace { |
| |
| using namespace llvm; |
| |
| struct Config { |
| StringRef filename; |
| StringRef out_dir; |
| }; |
| |
| StringMap<std::string> GetSubstitutions(const Config& config) { |
| // Compute all of our strings needed for substitutions. |
| StringRef test_dir = sys::path::parent_path(config.filename); |
| StringRef basename = sys::path::filename(config.filename); |
| SmallString<128> tmp_file; |
| sys::path::append(tmp_file, sys::path::Style::native, config.out_dir, |
| basename + ".tmp"); |
| SmallString<128> codegen; |
| sys::path::append(codegen, sys::path::Style::native, BIT_BINARY_DIR, |
| "codegen"); |
| SmallString<128> bit; |
| sys::path::append(bit, sys::path::Style::native, BIT_BINARY_DIR, "bit"); |
| |
| SmallString<128> clang; |
| sys::path::append(clang, sys::path::Style::native, BIT_CLANG_DIR, "clang"); |
| |
| // Set up our substitutions. |
| StringMap<std::string> subs; |
| subs["s"] = config.filename.str(); |
| subs["p"] = test_dir.str(); |
| subs["P"] = test_dir.str(); |
| subs["t"] = tmp_file.str().str(); |
| subs["{codegen}"] = codegen.str().str(); |
| subs["{bit}"] = bit.str().str(); |
| subs["{clang}"] = clang.str().str(); |
| return subs; |
| } |
| |
| std::string PerformSubstitutions(const StringMap<std::string>& subs, |
| StringRef string) { |
| std::string out = string.str(); |
| for (const auto& sub : subs) { |
| std::string key = (Twine("%") + sub.getKeyData()).str(); |
| size_t pos = 0; |
| while ((pos = out.find(key, pos)) != std::string::npos) { |
| if (pos != 0 && out[pos - 1] == '%') { |
| pos += key.size(); |
| continue; |
| } |
| out.replace(pos, key.size(), sub.getValue()); |
| pos += sub.second.size(); |
| } |
| } |
| return out; |
| } |
| |
| Optional<std::string> GetCommand(StringRef line) { |
| static Regex run_line("^;[ ]*RUN:[ ]*(.*)$"); |
| SmallVector<StringRef, 2> cmd; |
| if (!run_line.match(line, &cmd)) return Optional<std::string>{}; |
| assert(cmd.size() == 2); |
| return cmd[1].str(); |
| } |
| |
| } // namespace |