source: trunk/lib/Gnuplot.cc @ 39

Last change on this file since 39 was 39, checked in by Jari Häkkinen, 16 years ago

Gnuplot working.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 2.9 KB
Line 
1// $Id: Gnuplot.cc 39 2006-01-13 15:02:31Z jari $
2
3#include "Gnuplot.h"
4
5#include <cstdio>
6#include <fstream>
7#include <vector>
8#include <unistd.h>
9
10
11namespace theplu {
12namespace svnstat {
13
14
15  Gnuplot::Gnuplot(void)
16    : linestyle_("steps"), pipe_(NULL)
17  {
18    acquire_program_path("gnuplot");
19    if (gnuplot_binary_.empty())
20      throw GnuplotException("Can't find gnuplot in your PATH");
21
22    pipe_=popen(gnuplot_binary_.c_str(),"w");
23    if (!pipe_)
24      throw GnuplotException("Could'nt open connection to gnuplot");
25  }
26
27
28  Gnuplot::~Gnuplot(void)
29  {
30    if (pclose(pipe_) == -1)
31      throw GnuplotException("Problem closing communication to gnuplot");
32    for (std::list<std::string>::iterator i=tempfiles_.begin();
33         i!=tempfiles_.end(); i++)
34      remove(i->c_str());
35  }
36
37
38  void Gnuplot::acquire_program_path(const std::string& progname)
39  {
40    char* env_path=getenv("PATH");  // is there a need to free this memory?
41    if (!env_path)
42      throw GnuplotException("Environment variable PATH is not set");
43
44    std::list<std::string> paths;
45    tokenizer(env_path,paths);
46    for (std::list<std::string>::const_iterator i=paths.begin();
47         i!=paths.end(); ++i) {
48      std::string tmp((*i) + '/' + progname);
49      if (!access(tmp.c_str(),X_OK)) {
50        gnuplot_binary_=tmp;
51        break;
52      }
53    }
54
55    if (gnuplot_binary_.empty())
56      throw GnuplotException("Cannot find '" + progname + "' in PATH");
57  }
58
59
60  void Gnuplot::tokenizer(const std::string& in,
61                          std::list<std::string>& tokens,
62                          const std::string& delimiters)
63  {
64    std::string::size_type previous_pos=in.find_first_not_of(delimiters,0);
65    std::string::size_type position=in.find_first_of(delimiters,previous_pos);
66    while ((std::string::npos!=position) || (std::string::npos!=previous_pos)) {
67      tokens.push_back(in.substr(previous_pos, position-previous_pos));
68      previous_pos=in.find_first_not_of(delimiters,position);
69      position=in.find_first_of(delimiters,previous_pos);
70    }
71  }
72
73
74  void Gnuplot::command(std::string cmdstr)
75  {
76    if (*(cmdstr.rbegin())!='\n')
77      cmdstr+='\n';
78    fputs(cmdstr.c_str(),pipe_);
79    fflush(pipe_);
80  }
81
82
83  void Gnuplot::plot(const std::vector<double>& y, const std::vector<double>& x,
84                     const std::string& plotcmd)
85  {
86    char name[]="/tmp/svnstatXXXXXX";
87    if (mkstemp(name) == -1)
88      throw GnuplotException(std::string("Failed to get unique filename: ") +
89                             name);
90    std::ofstream tmp(name);
91    if (tmp.bad())
92      throw GnuplotException(std::string("Failed to create file: ") + name);
93    for (std::vector<double>::size_type i=0; i<y.size(); ++i)
94      if (x.empty())
95        tmp << y[i] << '\n';
96      else
97        tmp << x[i] << '\t' << y[i] << '\n';
98    tmp.close();
99    std::string cmdstring(plotcmd + " '" + name + "' title '" + linetitle_ +
100                          "' with " + linestyle_ + "\n");
101    command(cmdstring);
102
103    // need to keep track of created files since the gnuplot command
104    // is not executed until pclose on MacOSX, shouldn't the fflush
105    // fix this in the command() member function?
106    tempfiles_.push_back(name);
107  }
108
109
110}} // end of namespace svnstat and namespace theplu
Note: See TracBrowser for help on using the repository browser.