Changeset 60
- Timestamp:
- Jan 16, 2006, 11:03:04 AM (18 years ago)
- Location:
- trunk
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/bin/Parameter.cc
r54 r60 57 57 void Parameter::analyse(void) 58 58 { 59 // should check that root is a directory 59 60 } 60 61 -
trunk/bin/svnstat.cc
r58 r60 2 2 3 3 #include "Parameter.h" 4 #include "CommitStat.h" 4 5 #include "Directory.h" 5 6 #include "Gnuplot.h" … … 34 35 } 35 36 36 Directory tree(option.root()); 37 tree.purge(); 38 tree.parse(); 37 if (option.verbose()) 38 std::cout << "Parsing the log." << std::endl; 39 CommitStat cs; 40 cs.parse(option.root()); 41 Stats::gnuplot_pipe_.set_dates(cs.date()); 42 43 string prefix("svnstat_"); 44 Directory tree(option.root(),prefix); 45 tree.purge(option.verbose()); 46 tree.parse(option.verbose()); 39 47 40 48 Stats::gnuplot_pipe_.command(string("cd '")+option.targetdir()+"'"); 41 49 chdir(option.targetdir().c_str()); 42 tree.print(); 43 44 string htmltopnode=option.root()+".html"; 50 try { 51 tree.print(option.verbose()); 52 } 53 catch (const std::runtime_error& x) { 54 std::cerr << "svnstat: " << x.what() << std::endl; 55 } 56 string htmltopnode=tree.output_name()+".html"; 45 57 symlink(htmltopnode.c_str(),"index.html"); 46 58 -
trunk/lib/CommitStat.cc
r48 r60 3 3 #include "CommitStat.h" 4 4 5 #include <algorithm> 5 6 #include <fstream> 6 7 #include <iostream> … … 14 15 { 15 16 std::string system_call = "svn log -q " + path + " > svnstat.log.tmp"; 17 std::cout << system_call << std::endl; 16 18 int system_return = system(system_call.c_str()); 17 19 if (system_return) … … 34 36 35 37 if (ss.get() == 'r'){ 36 u_int revision;38 size_t revision; 37 39 ss >> revision; 38 40 std::string tmp; … … 45 47 std::string time; 46 48 ss >> time; 49 50 date_.resize(std::max(revision+1, date_.size())); 51 date_[revision] = date; 47 52 } 48 53 } 49 54 is.close(); 55 56 for(std::vector<std::string>::reverse_iterator i=date_.rbegin(); 57 i!=date_.rend(); ++i) 58 if (i->empty()){ 59 assert(i!=date_.rbegin()); 60 *i = *(i-1); 61 } 50 62 51 63 return system_return; -
trunk/lib/CommitStat.h
r48 r60 5 5 6 6 #include <string> 7 #include <vector> 7 8 8 9 namespace theplu{ … … 27 28 int parse(const std::string& path); 28 29 30 inline const std::vector<std::string> date(void) const { return date_; } 31 29 32 private: 30 33 /// … … 34 37 35 38 inline void reset(void) {}; 39 40 std::vector<std::string> date_; 36 41 }; 37 42 }} -
trunk/lib/Directory.cc
r58 r60 47 47 lstat(fullpath.c_str(),&nodestat); // C api from sys/stat.h 48 48 if (S_ISDIR(nodestat.st_mode)) // C api from sys/stat.h 49 daughters_.push_back(new Directory(fullpath, output_name _+"_"));49 daughters_.push_back(new Directory(fullpath, output_name()+"_")); 50 50 else 51 daughters_.push_back(new File(fullpath,output_name _+"_"));51 daughters_.push_back(new File(fullpath,output_name()+"_")); 52 52 } 53 53 } … … 61 61 62 62 63 const Stats& Directory::parse( void)63 const Stats& Directory::parse(const bool verbose) 64 64 { 65 65 stats_.reset(); 66 66 67 // empty directory treated as one-liner file 68 if (daughters_.empty()) 69 stats_.parse(path_,true); 70 67 71 for (NodeIterator i=daughters_.begin(); i!=daughters_.end(); i++) 68 stats_ += (*i)->parse( );72 stats_ += (*i)->parse(verbose); 69 73 return stats_; 70 74 } 71 75 72 76 73 void Directory::print( void) const77 void Directory::print(const bool verbose) const 74 78 { 75 std::string output(output_name_ + ".html"); 79 std::string output(output_name() + ".html"); 80 if (verbose) 81 std::cout << "Printing output for " << path_ << std::endl; 76 82 std::ofstream os(output.c_str()); 77 83 print_header(os); … … 90 96 // Peter, use STL algo. 91 97 for (NodeConstIter_ i=daughters_.begin();i!=daughters_.end();i++) 92 (*i)->print( );98 (*i)->print(verbose); 93 99 } 94 100 95 void Directory::purge(void) { 101 void Directory::purge(const bool verbose) 102 { 103 if (verbose) 104 std::cout << "Purging " << path_ << std::endl; 96 105 for (NodeIterator i=daughters_.begin(); i!=daughters_.end(); ) 97 106 if (!((*i)->subversion_controlled())) { … … 100 109 } 101 110 else { 102 (*i)->purge( );111 (*i)->purge(verbose); 103 112 i++; 104 113 } -
trunk/lib/Directory.h
r58 r60 37 37 ~Directory(void); 38 38 39 const Stats& parse( void);39 const Stats& parse(const bool verbose=false); 40 40 41 void print( void) const;41 void print(const bool verbose=false) const; 42 42 43 void purge( void);43 void purge(const bool verbose=false); 44 44 45 45 private: -
trunk/lib/File.cc
r58 r60 4 4 #include "Node.h" 5 5 #include "Stats.h" 6 #include "utility.h" 6 7 7 8 #include <fstream> 8 9 #include <iostream> 10 #include <map> 9 11 #include <sstream> 10 12 #include <string> … … 13 15 namespace svnstat{ 14 16 15 bool File::blame() const17 const Stats& File::parse(const bool verbose) 16 18 { 17 std::string system_call = "svn blame " + path_ + " > svnstat.tmp"; 18 int system_return = system(system_call.c_str()); 19 if (system_return) 20 std::cerr << "Error: svn blame " << path_ << std::endl; 21 return !system_return; 22 } 19 if (verbose) 20 std::cout << "Parsing " << path_ << std::endl; 21 stats_.reset(); 23 22 24 void File::info(void) 25 { 26 std::string system_call = "svn info " + path_ + " > svnstat.tmp"; 27 int system_return = system(system_call.c_str()); 28 if (system_return){ 29 // Jari, throw exception. 30 std::cerr << "svnstat: svn info " << path_ << std::endl; 31 exit(-1); 32 } 33 std::ifstream is("svnstat.tmp"); 34 std::string line; 35 while (getline(is,line)){ 36 std::stringstream ss(line); 37 std::string tag; 38 getline(ss,tag,':'); 39 if (tag == std::string("Last Changed Author")) 40 ss >> author_; 41 else if (tag == std::string("Last Changed Rev")) 42 ss >> revision_; 43 } 44 } 23 std::map<std::string,std::string> svn_info = info(path_); 24 author_ = svn_info["Last Changed Author"]; 25 std::stringstream ss(svn_info["Last Changed Rev"]); 26 ss >> revision_; 45 27 46 47 const Stats& File::parse(void) 48 { 49 stats_.reset(); 50 info(); 51 52 if (binary_){ 53 stats_.add(author_,revision_); 54 return stats_; 55 } 56 57 // Calling svn blame 58 if (!blame()) 59 return stats_; 60 61 // Check if file is binary 62 std::ifstream is("svnstat.tmp"); 63 std::string line; 64 getline(is,line,' '); 65 if (line==std::string("Skipping")){ 66 getline(is,line,' '); 67 if (line==std::string("binary")){ 68 is.close(); 69 binary_ = true; 70 return parse(); 71 } 72 } 73 is.close(); 74 75 is.open("svnstat.tmp"); 76 while (getline(is,line, '\n')){ 77 if (!line.size()) // skip empty line 78 continue; 79 std::stringstream ss(line); 80 u_int revision; 81 std::string user; 82 ss >> revision; 83 ss >> user; 84 stats_.add(user, revision); 85 } 86 is.close(); 28 binary_ = stats_.parse(path_, binary_); 87 29 return stats_; 88 30 } 89 31 90 void File::print( void) const32 void File::print(const bool verbose) const 91 33 { 92 std::string output(output_name_ + ".html"); 34 std::string output(output_name() + ".html"); 35 if (verbose) 36 std::cout << "Printing output for " << path_ << std::endl; 93 37 std::ofstream os(output.c_str()); 94 38 print_header(os); -
trunk/lib/File.h
r58 r60 25 25 /// @return true if succesful 26 26 /// 27 const Stats& parse( void);27 const Stats& parse(const bool verbose=false); 28 28 29 29 /// 30 30 /// 31 31 /// 32 void print( void) const;32 void print(const bool verbose=false) const; 33 33 34 34 private: … … 45 45 File(const File&); 46 46 47 ///48 /// Extracts information from 'svn info <node>'49 ///50 /// @note <node> must be in subversion control.51 ///52 void info(void);53 54 47 std::string author_; 55 48 bool binary_; -
trunk/lib/Gnuplot.cc
r39 r60 4 4 5 5 #include <cstdio> 6 #include <fstream>7 #include <vector>8 6 #include <unistd.h> 7 #include <string> 9 8 9 #include <iostream> 10 10 11 11 namespace theplu { … … 57 57 } 58 58 59 60 void Gnuplot::date_plot(const std::vector<double>& y, 61 const std::string& format) 62 { 63 command(std::string("set xdata time")); 64 command("set timefmt '" + date_input_format_ + "'"); 65 command("set format x '" + format + "'"); 66 plot(y,date_,"plot"); 67 } 68 69 70 void Gnuplot::date_replot(const std::vector<double>& y, 71 const std::string& format) 72 { 73 // Peter is this working, really? 74 //command(std::string("set xdata time")); 75 //command("set format x '" + format + "'"); 76 plot(y,date_,"replot"); 77 } 78 59 79 60 80 void Gnuplot::tokenizer(const std::string& in, … … 81 101 82 102 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 else97 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 command104 // is not executed until pclose on MacOSX, shouldn't the fflush105 // fix this in the command() member function?106 tempfiles_.push_back(name);107 }108 109 110 103 }} // end of namespace svnstat and namespace theplu -
trunk/lib/Gnuplot.h
r39 r60 5 5 6 6 #include <cstdio> 7 #include <fstream> 7 8 #include <list> 8 9 #include <stdexcept> … … 55 56 56 57 /// 57 /// Set the \a style of the line in the subsequent plot_xy or 58 /// plot_y calls. The setting applies until this function is 58 /// @return input format for date 59 /// 60 // Peter, obsolete ? 61 const std::string& date_input_format(void) { return date_input_format_; } 62 63 /// 64 /// 65 /// 66 void date_plot(const std::vector<double>& y, 67 const std::string& format="%y-%b"); 68 /// 69 /// 70 /// 71 void date_replot(const std::vector<double>& y, 72 const std::string& format="%y-%b"); 73 74 /// 75 /// Set the \a style of the line in the subsequent plot or 76 /// replot calls. The setting applies until this function is 59 77 /// called again. 60 78 /// … … 64 82 65 83 /// 66 /// Set the \a title of the line in the subsequent plot _xyor67 /// plot_ycalls. The setting applies until this function is84 /// Set the \a title of the line in the subsequent plot or 85 /// replot calls. The setting applies until this function is 68 86 /// called again. 69 87 /// … … 75 93 /// Gnuplot usage. 76 94 /// 95 // Peter, do we have to set xdata for replot 77 96 inline void 78 97 plot(const std::vector<double>& y, 79 98 const std::vector<double>& x=std::vector<double>()) 80 { plot(y,x,"plot"); }99 { command("set xdata"); plot(y,x,"plot"); } 81 100 82 101 /// … … 88 107 replot(const std::vector<double>& y, 89 108 const std::vector<double>& x=std::vector<double>()) 90 { plot(y,x,"replot"); } 109 { command("set xdata"); plot(y,x,"replot"); } 110 111 /// 112 /// sets format of date output 113 /// 114 inline void set_date_format(const std::string& format) 115 { date_output_format_ = format;} 116 117 /// 118 /// Function setting the dates. \a format must comply with strings 119 /// in date 120 /// 121 inline void set_dates(const std::vector<std::string>& date, 122 const std::string& format="%Y-%m-%d") 123 { date_=date; date_input_format_=format; } 91 124 92 125 private: … … 101 134 /// @param \a plotcmd must be "plot" or "replot". 102 135 /// 103 void plot(const std::vector<double>& y, const std::vector<double>& x, 104 const std::string& plotcmd); 136 template <class T1, class T2> 137 void plot(const std::vector<T1>& y, const std::vector<T2>& x, 138 const std::string& plotcmd) 139 { 140 assert(x.size()==y.size() || x.empty()); 141 assert(plotcmd=="plot" || plotcmd=="replot"); 142 char name[]="/tmp/svnstatXXXXXX"; 143 if (mkstemp(name) == -1){ 144 throw GnuplotException(std::string("Failed to get unique filename: ") + 145 name); 146 } 147 std::ofstream tmp(name); 148 if (tmp.bad()) 149 throw GnuplotException(std::string("Failed to create file: ") + name); 150 151 for (size_t i = 0; i<y.size() && (i<x.size() || x.empty()); ++i ){ 152 if (x.empty()) 153 tmp << y[i] << '\n'; 154 else 155 tmp << x[i] << '\t' << y[i] << '\n'; 156 } 157 tmp.close(); 158 std::string cmdstring(plotcmd + " '" + name + "' u 1:2 title '" + 159 linetitle_ + "' with " + linestyle_ + "\n"); 160 command(cmdstring); 161 162 // need to keep track of created files since the gnuplot command 163 // is not executed until pclose on MacOSX, shouldn't the fflush 164 // fix this in the command() member function? 165 tempfiles_.push_back(name); 166 } 105 167 106 168 void tokenizer(const std::string& in, std::list<std::string>& tokens, … … 111 173 // fix this in the command() member function? 112 174 std::list<std::string> tempfiles_; 175 std::vector<std::string> date_; 176 std::string date_input_format_; 177 std::string date_output_format_; 113 178 std::string gnuplot_binary_; 114 179 std::string linestyle_; -
trunk/lib/Makefile.am
r48 r60 5 5 noinst_LIBRARIES = libsvnstat.a 6 6 libsvnstat_a_SOURCES = \ 7 CommitStat.cc Directory.cc File.cc Gnuplot.cc Node.cc Stats.cc 7 CommitStat.cc Directory.cc File.cc Gnuplot.cc Node.cc Stats.cc utility.cc -
trunk/lib/Node.h
r58 r60 28 28 virtual inline ~Node(void) {}; 29 29 30 const std::string& output_name(void) const { return output_name_; } 31 30 32 /// 31 33 /// @brief parsing file using svn blame. 32 34 /// 33 virtual const Stats& parse( void)=0;35 virtual const Stats& parse(const bool verbose=false)=0; 34 36 35 37 /// 36 38 /// Function printing HTML in current working directory 37 39 /// 38 virtual void print( void) const=0;40 virtual void print(const bool verbose=false) const=0; 39 41 40 42 /// … … 42 44 /// 43 45 inline void print_link(std::ostream& os) const 44 { os << "<a href=\"" << output_name _<< ".html\">" << name() << "</a>"; }46 { os << "<a href=\"" << output_name() << ".html\">" << name() << "</a>"; } 45 47 46 48 /// 47 49 /// 48 50 /// 49 inline virtual void purge(void) { /* Nothing to be done */ }; 51 inline virtual void purge(const bool verbose=false) 52 { /* Nothing to be done */ }; 50 53 51 54 /// -
trunk/lib/Stats.cc
r44 r60 6 6 7 7 #include <algorithm> 8 #include <iostream> 8 9 #include <map> 9 10 #include <numeric> … … 22 23 std::vector<double> Stats::accumulated(void) const 23 24 { 24 if (map_.empty())25 return std::vector<double>();26 27 25 // sum of all users 28 std::vector<u_int> sum(latest_revision_+1, 0);26 std::vector<u_int> sum(latest_revision_+1, 0); 29 27 sum=std::accumulate(map_.begin(), map_.end(), sum, 30 28 PairValuePlus<std::string,u_int>()); … … 32 30 // calculate accumulated sum 33 31 std::vector<double> accum(sum.size()); 34 std::partial_sum(sum.begin(),sum.end(),accum.begin()); 32 std::partial_sum(sum.begin(),sum.end(),accum.begin()); 35 33 return accum; 36 34 } … … 63 61 } 64 62 63 64 bool Stats::parse(const std::string& path, const bool binary) 65 { 66 if (binary){ 67 std::map<std::string,std::string> svn_info = info(path); 68 std::stringstream ss(svn_info["Last Changed Rev"]); 69 u_int revision; 70 ss >> revision; 71 add(svn_info["Last Changed Author"],revision); 72 return true; 73 } 74 75 // Calling svn blame 76 if (blame(path)) 77 return true; 78 79 // Check if file is binary 80 std::ifstream is("svnstat.tmp"); 81 std::string line; 82 getline(is,line,' '); 83 if (line==std::string("Skipping")){ 84 getline(is,line,' '); 85 if (line==std::string("binary")){ 86 is.close(); 87 return parse(path,true); 88 } 89 } 90 is.close(); 91 92 is.open("svnstat.tmp"); 93 while (getline(is,line, '\n')){ 94 if (!line.size()) // skip empty line 95 continue; 96 std::stringstream ss(line); 97 u_int revision; 98 std::string user; 99 ss >> revision; 100 ss >> user; 101 add(user, revision); 102 } 103 is.close(); 104 return false; 105 } 106 107 65 108 std::string Stats::plot(void) const 66 109 { 67 110 char name[]="svnstat_XXXXXX.png"; 68 if (mkstemps(name,4)==-1) 111 if (mkstemps(name,4)==-1){ 69 112 throw std::runtime_error(std::string("Failed to get unique filename: ") + 70 name); 113 name); 114 } 71 115 std::string cmd=std::string("set term png; set output '")+name+"'"; 72 116 gnuplot_pipe_.command(cmd); 73 117 gnuplot_pipe_.command("set key left Left reverse"); 74 std::vector<double> x=accumulated(); 118 std::vector<double> x=accumulated(); 75 119 std::stringstream sa; 76 120 sa << x.back() << " total"; 77 121 gnuplot_pipe_.linetitle(sa.str()); 78 gnuplot_pipe_. plot(x);122 gnuplot_pipe_.date_plot(x); 79 123 for (MapConstIter_ i= map_.begin(); i != map_.end(); i++) { 80 124 x=accumulated(i->first); … … 82 126 s << x.back() << " " << i->first; 83 127 gnuplot_pipe_.linetitle(s.str()); 84 gnuplot_pipe_. replot(x);128 gnuplot_pipe_.date_replot(x); 85 129 } 86 130 -
trunk/lib/Stats.h
r44 r60 4 4 #define _theplu_svnstat_stats_ 5 5 6 #include <iostream> 6 7 #include <map> 7 8 #include <ostream> … … 25 26 inline Stats(void) {} 26 27 27 28 /// @brief adding a line to user from revision to the stats 29 30 void add(const std::string& user, const u_int& revision); 28 /// 29 /// @return true if file is binary 30 /// 31 bool parse(const std::string&, const bool); 31 32 32 33 /// … … 72 73 std::vector<double> accumulated(const std::string& user) const; 73 74 75 /// 76 /// @brief adding a line to user from revision to the stats 77 /// 78 void add(const std::string& user, const u_int& revision); 79 74 80 std::string plot(void) const; 75 81 -
trunk/lib/utility.h
r39 r60 6 6 #include <algorithm> 7 7 #include <functional> 8 #include <map> 8 9 #include <string> 9 10 #include <utility> … … 12 13 namespace theplu{ 13 14 namespace svnstat{ 15 16 /// 17 /// @return 0 if ok 18 /// 19 int blame(const std::string&); 20 21 /// 22 /// Extracts information from 'svn info <node>' 23 /// 24 /// @note <node> must be in subversion control. 25 /// 26 std::map<std::string, std::string> info(const std::string&); 27 28 // int log(const std::string&); 14 29 15 30 ///
Note: See TracChangeset
for help on using the changeset viewer.