- Timestamp:
- Mar 4, 2006, 7:10:07 PM (17 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ChangeLog
r2 r73 1 1 $Id$ 2 2 3 version 0.2: 4 - Removed usage of temporary files. 5 - Added option to plot changes against time or revision. 6 3 7 version 0.1: 8 - First release. -
trunk/bin/Parameter.cc
r66 r73 11 11 12 12 Parameter::Parameter(const int argc,const char *argv[]) 13 : force_(false), root_("."), targetdir_("svnstat_output"), verbose_(false)14 13 { 15 14 defaults(); 16 15 for (int i=1; i<argc; i++) { 17 16 bool ok=false; … … 30 29 ok=true; 31 30 } 31 } 32 else if (myargv=="-rev" || myargv=="--revisions") { 33 revisions_=true; 34 ok=true; 32 35 } 33 36 else if (myargv=="-t" || myargv=="--target"){ … … 61 64 62 65 66 void Parameter::defaults(void) 67 { 68 force_=false; 69 revisions_=false; 70 root_="."; 71 targetdir_="svnstat_output"; 72 verbose_=false; 73 } 74 75 63 76 void Parameter::help(void) 64 77 { … … 80 93 << " -r [--root] arg : svn controlled directory to perform\n" 81 94 << " statistics calculation on [.]\n" 95 << " -rev [--revisions]: Use revision numbers as time scale\n" 96 << " instead of dates [dates].\n" 82 97 << " -t [--target] arg : output directory [svnstat_output]\n" 83 98 << " -v [--verbose] : explain what is being done\n" -
trunk/bin/Parameter.h
r49 r73 14 14 Parameter(const int argc,const char *argv[]); 15 15 inline bool force(void) const { return force_; } 16 inline bool revisions(void) const { return revisions_; } 16 17 inline const std::string& root(void) const { return root_; } 17 18 inline const std::string& targetdir(void) const { return targetdir_; } … … 20 21 private: 21 22 void analyse(void); 23 void defaults(void); 22 24 void help(void); 23 25 void version(void); 24 26 25 27 bool force_; 28 bool revisions_; 26 29 std::string root_; 27 30 std::string targetdir_; 28 31 bool verbose_; 29 30 32 }; 31 33 -
trunk/bin/svnstat.cc
r63 r73 4 4 #include "CommitStat.h" 5 5 #include "Directory.h" 6 #include "Gnuplot .h"6 #include "GnuplotFE.h" 7 7 #include "rmdirhier.h" 8 8 … … 35 35 } 36 36 37 if (option.verbose()) 38 std::cout << "Parsing the log." << std::endl; 39 CommitStat cs; 40 cs.parse(option.root()); 41 assert(cs.date()[0].size()); 42 Stats::gnuplot_pipe_.set_dates(cs.date()); 37 if (!option.revisions()) { 38 if (option.verbose()) 39 std::cout << "Parsing the log." << std::endl; 40 CommitStat cs; 41 cs.parse(option.root()); 42 GnuplotFE::instance()->set_dates(cs.date()); 43 } 43 44 44 45 string prefix("svnstat_"); … … 47 48 tree.parse(option.verbose()); 48 49 49 Stats::gnuplot_pipe_.command(string("cd '")+option.targetdir()+"'");50 GnuplotFE::instance()->command(string("cd '")+option.targetdir()+"'"); 50 51 chdir(option.targetdir().c_str()); 51 52 try { -
trunk/lib/CommitStat.cc
r65 r73 1 2 //$Id$ 1 // $Id$ 3 2 4 3 #include "CommitStat.h" … … 68 67 is.close(); 69 68 69 assert(date_.size()); 70 assert(date_[0].size()); 70 71 return system_return; 71 72 } -
trunk/lib/CommitStat.h
r63 r73 30 30 int parse(const std::string& path); 31 31 32 inline const std::vector<std::string> date(void) const { return date_; }32 inline const std::vector<std::string>& date(void) const { return date_; } 33 33 34 34 private: -
trunk/lib/Directory.cc
r72 r73 92 92 93 93 // print daughter nodes, i.e, this function is recursive 94 for _each(daughters_.begin(), daughters_.end(),95 std::bind1st(std::mem_fun(&Node::print), verbose));96 94 for (std::list<Node*>::const_iterator i=daughters_.begin(); 95 i!=daughters_.end(); i++) 96 (*i)->print(verbose); 97 97 } 98 98 -
trunk/lib/Gnuplot.cc
r71 r73 6 6 #include <string> 7 7 #include <unistd.h> 8 9 #include <iostream> 8 10 9 11 … … 29 31 if (pclose(pipe_) == -1) 30 32 throw GnuplotException("Problem closing communication to gnuplot"); 31 for (std::list<std::string>::iterator i=tempfiles_.begin();32 i!=tempfiles_.end(); i++)33 remove(i->c_str());34 33 } 35 34 … … 57 56 58 57 59 void Gnuplot::date_plot(const std::vector<double>& y,60 const std::string& format)61 {62 command(std::string("set xdata time"));63 command("set timefmt '" + date_input_format_ + "'");64 command("set format x '" + format + "'");65 plot(y,date_,"plot");66 }67 68 69 void Gnuplot::date_replot(const std::vector<double>& y,70 const std::string& format)71 {72 plot(y,date_,"replot");73 }74 75 76 58 void Gnuplot::tokenizer(const std::string& in, 77 59 std::list<std::string>& tokens, … … 88 70 89 71 90 void Gnuplot::command( std::stringcmdstr)72 void Gnuplot::command(const std::string& cmdstr) 91 73 { 74 fputs(cmdstr.c_str(),pipe_); 92 75 if (*(cmdstr.rbegin())!='\n') 93 cmdstr+='\n'; 94 fputs(cmdstr.c_str(),pipe_); 76 fputc('\n',pipe_); 95 77 fflush(pipe_); 96 78 } -
trunk/lib/Gnuplot.h
r70 r73 6 6 #include <cassert> 7 7 #include <cstdio> 8 #include <fstream>9 8 #include <list> 10 9 #include <stdexcept> 10 #include <sstream> 11 11 #include <string> 12 12 #include <vector> … … 25 25 /// 26 26 /// The Gnuplot class creates a pipe to 'gnuplot' and facilitates 27 /// communication with the binary. 28 /// 29 /// Temporary files are created in directory /tmp. These temporary 30 /// files are removed on a normal program exit. 27 /// communication with the gnuplot binary. 31 28 /// 32 29 class Gnuplot … … 45 42 46 43 /// 47 /// The destructor deletes all temporary files created in the 48 /// calls to plot_xy and plot_x. If the program execution fails to 49 /// reach this destructor the temporary files will not be removed 50 /// from the storage area. 44 /// The destructor, closes the pipe to the gnuplot binary. 51 45 /// 52 ~Gnuplot(void);46 virtual ~Gnuplot(void); 53 47 54 48 /// 55 49 /// Send arbitrary commands to Gnuplot. 56 50 /// 57 void command(std::string); 58 59 /// 60 /// @return input format for date 61 /// 62 // Peter, obsolete ? 63 const std::string& date_input_format(void) { return date_input_format_; } 64 65 /// 66 /// 67 /// 68 void date_plot(const std::vector<double>& y, 69 const std::string& format="%y-%b-%d"); 70 /// 71 /// 72 /// 73 void date_replot(const std::vector<double>& y, 74 const std::string& format="%y-%b-%d"); 51 void command(const std::string&); 75 52 76 53 /// … … 95 72 /// Gnuplot usage. 96 73 /// 97 // Peter, do we have to set xdata for replot 98 inline void 99 plot(const std::vector<double>& y, 100 const std::vector<double>& x=std::vector<double>()) 101 { command("set xdata"); plot(y,x,"plot"); } 74 template <class T1, class T2> 75 void plot(const std::vector<T1>& y, const std::vector<T2>& x) 76 { plot(y,x,"plot"); } 77 78 template <class T1> 79 void plot(const std::vector<T1>& y, 80 const std::vector<T1>& x=std::vector<T1>()) 81 { plot(y,x,"plot"); } 102 82 103 83 /// … … 106 86 /// Gnuplot usage. 107 87 /// 108 inline void 109 replot(const std::vector<double>& y, 110 const std::vector<double>& x=std::vector<double>()) 111 { command("set xdata"); plot(y,x,"replot"); } 88 template <class T1, class T2> 89 void replot(const std::vector<T1>& y, const std::vector<T2>& x) 90 { plot(y,x,"replot"); } 112 91 113 /// 114 /// sets format of date output 115 /// 116 inline void set_date_format(const std::string& format) 117 { date_output_format_ = format;} 118 119 /// 120 /// Function setting the dates. \a format must comply with strings 121 /// in date 122 /// 123 inline void set_dates(const std::vector<std::string>& date, 124 const std::string& format="%Y-%m-%d") 125 { date_=date; date_input_format_=format; } 92 template <class T1> 93 void replot(const std::vector<T1>& y, 94 const std::vector<T1>& x=std::vector<T1>()) 95 { plot(y,x,"replot"); } 126 96 127 97 private: … … 142 112 assert(x.size()==y.size() || x.empty()); 143 113 assert(plotcmd=="plot" || plotcmd=="replot"); 144 char name[]="/tmp/svnstatXXXXXX"; 145 int fd=mkstemp(name); // mkstemp return a file descriptor 146 if (fd == -1) 147 throw GnuplotException(std::string("Failed to get unique filename: ") + 148 name); 149 // Jari would like to do something like 'std::ofstream tmp(fd);' 150 // but has to settle for (which is stupid since the file is 151 // already open for writing. 152 std::ofstream tmp(name); 153 for (size_t i = 0; i<y.size() && (i<x.size() || x.empty()); ++i ) 154 if (x.empty()) 155 tmp << y[i] << '\n'; 114 115 std::ostringstream cmdstring; 116 cmdstring << plotcmd << " '-' u 1:2 title '" << linetitle_ << "' with " 117 << linestyle_ << '\n'; 118 for (size_t i=0; i<y.size(); ++i) { 119 if (!x.empty()) 120 cmdstring << x[i] << '\t'; 156 121 else 157 tmp << x[i] << '\t' << y[i] << '\n'; 158 // Jari, here the stupidity goes beyond everything - the 159 // ofstream must be closed as well as the file descriptor. If 160 // not the program will exhaust the availabe number of 161 // simultaneous open files. 162 tmp.close(); 163 close(fd); 122 cmdstring << i << '\t'; 123 cmdstring << y[i] << '\n'; 124 } 125 cmdstring << "e\n"; 164 126 165 std::string cmdstring(plotcmd + " '" + name + "' u 1:2 title '" + 166 linetitle_ + "' with " + linestyle_ + "\n"); 167 if (x.empty()) 168 cmdstring = plotcmd + " '" + name + "' u 1 title '" + 169 linetitle_ + "' with " + linestyle_ + "\n"; 170 171 command(cmdstring); 172 // need to keep track of created files since the gnuplot command 173 // is not executed until pclose on MacOSX, shouldn't the fflush 174 // fix this in the command() member function? 175 tempfiles_.push_back(name); 127 command(cmdstring.str()); 176 128 } 177 129 … … 179 131 const std::string& delimiters = ":"); 180 132 181 // need to keep track of created files since the gnuplot command182 // is not executed until pclose on MacOSX, shouldn't the fflush183 // fix this in the command() member function?184 std::list<std::string> tempfiles_;185 std::vector<std::string> date_;186 std::string date_input_format_;187 std::string date_output_format_;188 133 std::string gnuplot_binary_; 189 134 std::string linestyle_; -
trunk/lib/Makefile.am
r60 r73 4 4 5 5 noinst_LIBRARIES = libsvnstat.a 6 libsvnstat_a_SOURCES = \7 CommitStat.cc Directory.cc File.cc Gnuplot.cc Node.cc Stats.cc utility.cc6 libsvnstat_a_SOURCES = CommitStat.cc Directory.cc File.cc Gnuplot.cc \ 7 GnuplotFE.cc Node.cc Stats.cc utility.cc -
trunk/lib/Stats.cc
r72 r73 2 2 3 3 #include "Stats.h" 4 #include "Gnuplot .h"4 #include "GnuplotFE.h" 5 5 #include "utility.h" 6 6 … … 8 8 #include <cassert> 9 9 #include <cstdlib> 10 #include <fstream> 10 11 #include <iostream> 11 12 #include <map> … … 21 22 namespace svnstat{ 22 23 23 Gnuplot Stats::gnuplot_pipe_;24 24 u_int Stats::latest_revision_=0; 25 25 … … 104 104 { 105 105 std::string cmd=std::string("set term png; set output '")+name+"'"; 106 gnuplot_pipe_.command(cmd); 107 gnuplot_pipe_.command("set key left Left reverse"); 106 GnuplotFE* gp=GnuplotFE::instance(); 107 gp->command(cmd); 108 gp->command("set key default"); 109 gp->command("set key left Left reverse"); 110 gp->command("set multiplot"); 108 111 std::vector<double> x=accumulated(); 109 112 std::stringstream sa; 110 113 sa << x.back() << " total"; 111 gnuplot_pipe_.linetitle(sa.str()); 112 gnuplot_pipe_.date_plot(x); 114 gp->linetitle(sa.str()); 115 gp->linestyle("steps 1"); 116 gp->plot(x); 117 size_t plotno=2; 113 118 for (MapConstIter_ i= map_.begin(); i != map_.end(); i++) { 119 std::stringstream s0; 120 s0 << "set key height " << plotno; 121 gp->command(s0.str()); 114 122 x=accumulated(i->first); 115 123 std::stringstream s; 116 124 s << x.back() << " " << i->first; 117 gnuplot_pipe_.linetitle(s.str()); 118 gnuplot_pipe_.date_replot(x); 125 gp->linetitle(s.str()); 126 // Jari, reuse the stream above 127 std::stringstream s2; 128 s2 << "steps " << plotno++; 129 gp->linestyle(s2.str()); 130 gp->plot(x); 119 131 } 132 gp->command("unset multiplot"); 120 133 121 // Jari, must rewrite output once since the replots above are not122 // added to the plot. Rather, the plot only contains the result123 // from the first 'plot' call.124 gnuplot_pipe_.command(cmd);125 gnuplot_pipe_.command("replot");126 134 return name; 127 135 } -
trunk/lib/Stats.h
r72 r73 12 12 namespace theplu{ 13 13 namespace svnstat{ 14 15 class Gnuplot;16 14 17 15 /// … … 47 45 Stats& operator+=(const Stats&); 48 46 49 ///50 /// Jari, this is public. Naughty!51 ///52 /// @todo Make this non-public. The issues that gnuplot is started53 /// in cwd, but the main program makes a 'chdir' to another, and54 /// we cannot get gnuplot to change directory if it is55 /// private. Some redesign is needed.56 ///57 static Gnuplot gnuplot_pipe_;58 59 47 private: 60 48 /// … … 80 68 std::string plot(const std::string&) const; 81 69 82 static u_int latest_revision_; // latest rev .for whole project70 static u_int latest_revision_; // latest revision for whole project 83 71 84 72 // Peter, if the vector is sparse make it a map
Note: See TracChangeset
for help on using the changeset viewer.