15 #include "llvm/Config/config.h"
22 cl::desc(
"Execute graph viewer in the background. Creates tmp file litter."));
25 std::string Str(Label);
26 for (
unsigned i = 0; i != Str.length(); ++i)
29 Str.insert(Str.begin()+i,
'\\');
34 Str.insert(Str.begin()+i,
' ');
39 if (i+1 != Str.length())
42 case '|':
case '{':
case '}':
43 Str.erase(Str.begin()+i);
continue;
49 Str.insert(Str.begin()+i,
'\\');
59 static const int NumColors = 20;
60 static const char* Colors[NumColors] = {
61 "aaaaaa",
"aa0000",
"00aa00",
"aa5500",
"0055ff",
"aa00aa",
"00aaaa",
62 "555555",
"ff5555",
"55ff55",
"ffff55",
"5555ff",
"ff55ff",
"55ffff",
63 "ffaaaa",
"aaffaa",
"ffffaa",
"aaaaff",
"ffaaff",
"aaffff"};
64 return Colors[ColorNumber % NumColors];
72 errs() <<
"Error: " << EC.message() <<
"\n";
76 errs() <<
"Writing '" << Filename <<
"'... ";
77 return Filename.
str();
83 std::string &ErrMsg) {
84 assert(args.back() ==
nullptr);
88 errs() <<
"Error: " << ErrMsg <<
"\n";
92 errs() <<
" done. \n";
95 errs() <<
"Remember to erase graph file: " << Filename <<
"\n";
101 struct GraphSession {
102 std::string LogBuffer;
103 bool TryFindProgram(
StringRef Names, std::string &ProgramPath) {
106 Names.
split(parts,
"|");
107 for (
auto Name : parts) {
112 Log <<
" Tried '" <<
Name <<
"'\n";
137 std::string Filename = FilenameRef;
139 std::string ViewerPath;
144 if (S.TryFindProgram(
"open", ViewerPath)) {
145 std::vector<const char *> args;
146 args.push_back(ViewerPath.c_str());
148 args.push_back(
"-W");
149 args.push_back(Filename.c_str());
150 args.push_back(
nullptr);
151 errs() <<
"Trying 'open' program... ";
156 if (S.TryFindProgram(
"xdg-open", ViewerPath)) {
157 std::vector<const char *> args;
158 args.push_back(ViewerPath.c_str());
159 args.push_back(Filename.c_str());
160 args.push_back(
nullptr);
161 errs() <<
"Trying 'xdg-open' program... ";
167 if (S.TryFindProgram(
"Graphviz", ViewerPath)) {
168 std::vector<const char *> args;
169 args.push_back(ViewerPath.c_str());
170 args.push_back(Filename.c_str());
171 args.push_back(
nullptr);
173 errs() <<
"Running 'Graphviz' program... ";
178 if (S.TryFindProgram(
"xdot|xdot.py", ViewerPath)) {
179 std::vector<const char *> args;
180 args.push_back(ViewerPath.c_str());
181 args.push_back(Filename.c_str());
183 args.push_back(
"-f");
186 args.push_back(
nullptr);
188 errs() <<
"Running 'xdot.py' program... ";
192 enum PSViewerKind { PSV_None, PSV_OSXOpen, PSV_XDGOpen, PSV_Ghostview };
193 PSViewerKind PSViewer = PSV_None;
195 if (!PSViewer && S.TryFindProgram(
"open", ViewerPath))
196 PSViewer = PSV_OSXOpen;
198 if (!PSViewer && S.TryFindProgram(
"gv", ViewerPath))
199 PSViewer = PSV_Ghostview;
200 if (!PSViewer && S.TryFindProgram(
"xdg-open", ViewerPath))
201 PSViewer = PSV_XDGOpen;
204 std::string GeneratorPath;
207 S.TryFindProgram(
"dot|fdp|neato|twopi|circo", GeneratorPath))) {
208 std::string PSFilename = Filename +
".ps";
210 std::vector<const char *> args;
211 args.push_back(GeneratorPath.c_str());
212 args.push_back(
"-Tps");
213 args.push_back(
"-Nfontname=Courier");
214 args.push_back(
"-Gsize=7.5,10");
215 args.push_back(Filename.c_str());
216 args.push_back(
"-o");
217 args.push_back(PSFilename.c_str());
218 args.push_back(
nullptr);
220 errs() <<
"Running '" << GeneratorPath <<
"' program... ";
226 args.push_back(ViewerPath.c_str());
229 args.push_back(
"-W");
230 args.push_back(PSFilename.c_str());
234 args.push_back(PSFilename.c_str());
237 args.push_back(
"--spartan");
238 args.push_back(PSFilename.c_str());
243 args.push_back(
nullptr);
250 if (S.TryFindProgram(
"dotty", ViewerPath)) {
251 std::vector<const char *> args;
252 args.push_back(ViewerPath.c_str());
253 args.push_back(Filename.c_str());
254 args.push_back(
nullptr);
260 errs() <<
"Running 'dotty' program... ";
264 errs() <<
"Error: Couldn't find a usable graph viewer program:\n";
265 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)
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
ProcessInfo ExecuteNoWait(StringRef Program, const char **args, const char **env=nullptr, const StringRef **redirects=nullptr, unsigned memoryLimit=0, std::string *ErrMsg=nullptr, bool *ExecutionFailed=nullptr)
Similar to ExecuteAndWait, but returns immediately.
ErrorOr< std::string > findProgramByName(StringRef Name, ArrayRef< StringRef > Paths=ArrayRef< StringRef >())
Find the first executable file Name in Paths.
static bool ExecGraphViewer(StringRef ExecPath, std::vector< const char * > &args, StringRef Filename, bool wait, std::string &ErrMsg)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
int ExecuteAndWait(StringRef Program, const char **args, const char **env=nullptr, const StringRef **redirects=nullptr, unsigned secondsToWait=0, unsigned memoryLimit=0, std::string *ErrMsg=nullptr, bool *ExecutionFailed=nullptr)
This function executes the program using the arguments provided.
std::string EscapeString(const std::string &Label)
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)
StringRef getColorString(unsigned NodeNumber)
Get a color string for this node number.
StringRef str() const
Explicit conversion to StringRef.
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.
A raw_ostream that writes to an std::string.
StringRef - Represent a constant reference to a string, i.e.