1 //===- Reproduce.cpp - Utilities for creating reproducers -----------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lld/Common/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" 15 16 using namespace lld; 17 using namespace llvm; 18 using namespace llvm::sys; 19 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. relativeToRoot(StringRef Path)25std::string lld::relativeToRoot(StringRef Path) { 26 SmallString<128> Abs = Path; 27 if (fs::make_absolute(Abs)) 28 return Path; 29 path::remove_dots(Abs, /*remove_dot_dot=*/true); 30 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 33 // of the result. 34 SmallString<128> Res; 35 StringRef Root = path::root_name(Abs); 36 if (Root.endswith(":")) 37 Res = Root.drop_back(); 38 else if (Root.startswith("//")) 39 Res = Root.substr(2); 40 41 path::append(Res, path::relative_path(Abs)); 42 return path::convert_to_slash(Res); 43 } 44 45 // Quote a given string if it contains a space character. quote(StringRef S)46std::string lld::quote(StringRef S) { 47 if (S.contains(' ')) 48 return ("\"" + S + "\"").str(); 49 return S; 50 } 51 rewritePath(StringRef S)52std::string lld::rewritePath(StringRef S) { 53 if (fs::exists(S)) 54 return relativeToRoot(S); 55 return S; 56 } 57 toString(const opt::Arg & Arg)58std::string lld::toString(const opt::Arg &Arg) { 59 std::string K = Arg.getSpelling(); 60 if (Arg.getNumValues() == 0) 61 return K; 62 std::string V = quote(Arg.getValue()); 63 if (Arg.getOption().getRenderStyle() == opt::Option::RenderJoinedStyle) 64 return K + V; 65 return K + " " + V; 66 } 67