1 //===-- GraphWriter.cpp - Implements GraphWriter support routines ---------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements misc. GraphWriter support routines.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/Support/GraphWriter.h"
15 #include "llvm/Support/Streams.h"
16 #include "llvm/System/Path.h"
17 #include "llvm/System/Program.h"
18 #include "llvm/Config/config.h"
19 using namespace llvm;
20 
21 void llvm::DisplayGraph(const sys::Path &Filename, bool wait) {
22   std::string ErrMsg;
23 #if HAVE_GRAPHVIZ
24   sys::Path Graphviz(LLVM_PATH_GRAPHVIZ);
25 
26   std::vector<const char*> args;
27   args.push_back(Graphviz.c_str());
28   args.push_back(Filename.c_str());
29   args.push_back(0);
30 
31   cerr << "Running 'Graphviz' program... " << std::flush;
32   if (sys::Program::ExecuteAndWait(Graphviz, &args[0],0,0,0,0,&ErrMsg)) {
33      cerr << "Error viewing graph " << Filename << ": " << ErrMsg << "\n";
34   }
35   else {
36      Filename.eraseFromDisk();
37   }
38 
39 #elif (HAVE_GV && (HAVE_DOT || HAVE_FDP))
40   sys::Path PSFilename = Filename;
41   PSFilename.appendSuffix("ps");
42 
43 #if HAVE_FDP
44   sys::Path prog(LLVM_PATH_FDP);
45 #else
46   sys::Path prog(LLVM_PATH_DOT);
47 #endif
48 
49   std::vector<const char*> args;
50   args.push_back(prog.c_str());
51   args.push_back("-Tps");
52   args.push_back("-Nfontname=Courier");
53   args.push_back("-Gsize=7.5,10");
54   args.push_back(Filename.c_str());
55   args.push_back("-o");
56   args.push_back(PSFilename.c_str());
57   args.push_back(0);
58 
59   cerr << "Running '" << prog << "' program... " << std::flush;
60 
61   if (sys::Program::ExecuteAndWait(prog, &args[0],0,0,0,0,&ErrMsg)) {
62      cerr << "Error viewing graph " << Filename << ": '" << ErrMsg << "\n";
63   } else {
64     cerr << " done. \n";
65 
66     sys::Path gv(LLVM_PATH_GV);
67     args.clear();
68     args.push_back(gv.c_str());
69     args.push_back(PSFilename.c_str());
70     args.push_back("-spartan");
71     args.push_back(0);
72 
73     ErrMsg.clear();
74     if (wait) {
75        if (sys::Program::ExecuteAndWait(gv, &args[0],0,0,0,0,&ErrMsg)) {
76           cerr << "Error viewing graph: " << ErrMsg << "\n";
77        }
78        Filename.eraseFromDisk();
79        PSFilename.eraseFromDisk();
80     }
81     else {
82        sys::Program::ExecuteNoWait(gv, &args[0],0,0,0,&ErrMsg);
83        cerr << "Remember to erase graph files: " << Filename << " " << PSFilename << "\n";
84     }
85   }
86 #elif HAVE_DOTTY
87   sys::Path dotty(LLVM_PATH_DOTTY);
88 
89   std::vector<const char*> args;
90   args.push_back(dotty.c_str());
91   args.push_back(Filename.c_str());
92   args.push_back(0);
93 
94   cerr << "Running 'dotty' program... " << std::flush;
95   if (sys::Program::ExecuteAndWait(dotty, &args[0],0,0,0,0,&ErrMsg)) {
96      cerr << "Error viewing graph " << Filename << ": " << ErrMsg << "\n";
97   } else {
98 #ifdef __MINGW32__ // Dotty spawns another app and doesn't wait until it returns
99     return;
100 #endif
101     Filename.eraseFromDisk();
102   }
103 #endif
104 }
105