18 #include "llvm/Config/config.h" 27 #include <system_error> 34 cl::desc(
"Execute graph viewer in the background. Creates tmp file litter."));
37 std::string Str(Label);
38 for (
unsigned i = 0; i != Str.length(); ++i)
41 Str.insert(Str.begin()+i,
'\\');
46 Str.insert(Str.begin()+i,
' ');
51 if (i+1 != Str.length())
54 case '|':
case '{':
case '}':
55 Str.erase(Str.begin()+i);
continue;
62 Str.insert(Str.begin()+i,
'\\');
72 static const int NumColors = 20;
73 static const char* Colors[NumColors] = {
74 "aaaaaa",
"aa0000",
"00aa00",
"aa5500",
"0055ff",
"aa00aa",
"00aaaa",
75 "555555",
"ff5555",
"55ff55",
"ffff55",
"5555ff",
"ff55ff",
"55ffff",
76 "ffaaaa",
"aaffaa",
"ffffaa",
"aaaaff",
"ffaaff",
"aaffff"};
77 return Colors[ColorNumber % NumColors];
85 errs() <<
"Error: " << EC.message() <<
"\n";
89 errs() <<
"Writing '" << Filename <<
"'... ";
90 return Filename.
str();
96 std::string &ErrMsg) {
99 errs() <<
"Error: " << ErrMsg <<
"\n";
103 errs() <<
" done. \n";
106 errs() <<
"Remember to erase graph file: " << Filename <<
"\n";
113 struct GraphSession {
114 std::string LogBuffer;
116 bool TryFindProgram(
StringRef Names, std::string &ProgramPath) {
119 Names.
split(parts,
'|');
120 for (
auto Name : parts) {
125 Log <<
" Tried '" <<
Name <<
"'\n";
151 std::string Filename = FilenameRef;
153 std::string ViewerPath;
158 if (S.TryFindProgram(
"open", ViewerPath)) {
159 std::vector<StringRef> args;
160 args.push_back(ViewerPath);
162 args.push_back(
"-W");
163 args.push_back(Filename);
164 errs() <<
"Trying 'open' program... ";
169 if (S.TryFindProgram(
"xdg-open", ViewerPath)) {
170 std::vector<StringRef> args;
171 args.push_back(ViewerPath);
172 args.push_back(Filename);
173 errs() <<
"Trying 'xdg-open' program... ";
179 if (S.TryFindProgram(
"Graphviz", ViewerPath)) {
180 std::vector<StringRef> args;
181 args.push_back(ViewerPath);
182 args.push_back(Filename);
184 errs() <<
"Running 'Graphviz' program... ";
189 if (S.TryFindProgram(
"xdot|xdot.py", ViewerPath)) {
190 std::vector<StringRef> args;
191 args.push_back(ViewerPath);
192 args.push_back(Filename);
194 args.push_back(
"-f");
197 errs() <<
"Running 'xdot.py' program... ";
208 ViewerKind Viewer = VK_None;
210 if (!Viewer && S.TryFindProgram(
"open", ViewerPath))
213 if (!Viewer && S.TryFindProgram(
"gv", ViewerPath))
214 Viewer = VK_Ghostview;
215 if (!Viewer && S.TryFindProgram(
"xdg-open", ViewerPath))
218 if (!Viewer && S.TryFindProgram(
"cmd", ViewerPath)) {
219 Viewer = VK_CmdStart;
224 std::string GeneratorPath;
227 S.TryFindProgram(
"dot|fdp|neato|twopi|circo", GeneratorPath))) {
229 Filename + (Viewer == VK_CmdStart ?
".pdf" :
".ps");
231 std::vector<StringRef> args;
232 args.push_back(GeneratorPath);
233 if (Viewer == VK_CmdStart)
234 args.push_back(
"-Tpdf");
236 args.push_back(
"-Tps");
237 args.push_back(
"-Nfontname=Courier");
238 args.push_back(
"-Gsize=7.5,10");
239 args.push_back(Filename);
240 args.push_back(
"-o");
241 args.push_back(OutputFilename);
243 errs() <<
"Running '" << GeneratorPath <<
"' program... ";
250 std::string StartArg;
253 args.push_back(ViewerPath);
256 args.push_back(
"-W");
257 args.push_back(OutputFilename);
261 args.push_back(OutputFilename);
264 args.push_back(
"--spartan");
265 args.push_back(OutputFilename);
268 args.push_back(
"/S");
269 args.push_back(
"/C");
271 (
StringRef(
"start ") + (wait ?
"/WAIT " :
"") + OutputFilename).str();
272 args.push_back(StartArg);
279 return ExecGraphViewer(ViewerPath, args, OutputFilename, wait, ErrMsg);
283 if (S.TryFindProgram(
"dotty", ViewerPath)) {
284 std::vector<StringRef> args;
285 args.push_back(ViewerPath);
286 args.push_back(Filename);
292 errs() <<
"Running 'dotty' program... ";
296 errs() <<
"Error: Couldn't find a usable graph viewer program:\n";
297 errs() << S.LogBuffer <<
"\n";
Represents either an error or a value T.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
static cl::opt< bool > ViewBackground("view-background", cl::Hidden, cl::desc("Execute graph viewer in the background. Creates tmp file litter."))
static const char * getProgramName(GraphProgram::Name program)
This class represents lattice values for constants.
ProcessInfo ExecuteNoWait(StringRef Program, ArrayRef< StringRef > Args, Optional< ArrayRef< StringRef >> Env, ArrayRef< Optional< StringRef >> Redirects={}, unsigned MemoryLimit=0, std::string *ErrMsg=nullptr, bool *ExecutionFailed=nullptr)
Similar to ExecuteAndWait, but returns immediately.
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
ErrorOr< std::string > findProgramByName(StringRef Name, ArrayRef< StringRef > Paths={})
Find the first executable file Name in Paths.
int ExecuteAndWait(StringRef Program, ArrayRef< StringRef > Args, Optional< ArrayRef< StringRef >> Env=None, ArrayRef< Optional< StringRef >> Redirects={}, unsigned SecondsToWait=0, unsigned MemoryLimit=0, std::string *ErrMsg=nullptr, bool *ExecutionFailed=nullptr)
This function executes the program using the arguments provided.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static cl::opt< std::string > OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"))
StringRef str() const
Explicit conversion to StringRef.
std::string EscapeString(const std::string &Label)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
std::string createGraphFilename(const Twine &Name, int &FD)
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
StringRef getColorString(unsigned NodeNumber)
Get a color string for this node number.
bool DisplayGraph(StringRef Filename, bool wait=true, GraphProgram::Name program=GraphProgram::DOT)
std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, SmallVectorImpl< char > &ResultPath)
Create a file in the system temporary directory.
Provides ErrorOr<T> smart pointer.
static bool ExecGraphViewer(StringRef ExecPath, std::vector< StringRef > &args, StringRef Filename, bool wait, std::string &ErrMsg)
A raw_ostream that writes to an std::string.
StringRef - Represent a constant reference to a string, i.e.