1 //===- Reproduce.cpp - Utilities for creating reproducers -----------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lld/Core/Reproduce.h"
11 #include "llvm/Option/Arg.h"
12 #include "llvm/Support/Error.h"
13 #include "llvm/Support/FileSystem.h"
14 #include "llvm/Support/Path.h"
18 using namespace llvm::sys;
20 // Makes a given pathname an absolute path first, and then remove
21 // beginning /. For example, "../foo.o" is converted to "home/john/foo.o",
22 // assuming that the current directory is "/home/john/bar".
23 // Returned string is a forward slash separated path even on Windows to avoid
24 // a mess with backslash-as-escape and backslash-as-path-separator.
25 std::string lld::relativeToRoot(StringRef Path) {
26 SmallString<128> Abs = Path;
27 if (fs::make_absolute(Abs))
29 path::remove_dots(Abs, /*remove_dot_dot=*/true);
31 // This is Windows specific. root_name() returns a drive letter
32 // (e.g. "c:") or a UNC name (//net). We want to keep it as part
35 StringRef Root = path::root_name(Abs);
36 if (Root.endswith(":"))
37 Res = Root.drop_back();
38 else if (Root.startswith("//"))
41 path::append(Res, path::relative_path(Abs));
42 return convertToUnixPathSeparator(Res);
45 // Quote a given string if it contains a space character.
46 std::string lld::quote(StringRef S) {
47 if (S.find(' ') == StringRef::npos)
49 return ("\"" + S + "\"").str();
52 std::string lld::rewritePath(StringRef S) {
54 return relativeToRoot(S);
58 std::string lld::toString(opt::Arg *Arg) {
59 std::string K = Arg->getSpelling();
60 if (Arg->getNumValues() == 0)
62 std::string V = quote(Arg->getValue());
63 if (Arg->getOption().getRenderStyle() == opt::Option::RenderJoinedStyle)
68 std::string lld::convertToUnixPathSeparator(StringRef S) {
70 std::string Ret = S.str();
71 std::replace(Ret.begin(), Ret.end(), '\\', '/');