Changeset 60


Ignore:
Timestamp:
Jan 16, 2006, 11:03:04 AM (16 years ago)
Author:
Peter Johansson
Message:

plotting vs date rather than revision

Location:
trunk
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/bin/Parameter.cc

    r54 r60  
    5757  void Parameter::analyse(void)
    5858  {
     59    // should check that root is a directory
    5960  }
    6061
  • trunk/bin/svnstat.cc

    r58 r60  
    22
    33#include "Parameter.h"
     4#include "CommitStat.h"
    45#include "Directory.h"
    56#include "Gnuplot.h"
     
    3435  }
    3536
    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());
    3947
    4048  Stats::gnuplot_pipe_.command(string("cd '")+option.targetdir()+"'");
    4149  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";
    4557  symlink(htmltopnode.c_str(),"index.html");
    4658
  • trunk/lib/CommitStat.cc

    r48 r60  
    33#include "CommitStat.h"
    44
     5#include <algorithm>
    56#include <fstream>
    67#include <iostream>
     
    1415  {
    1516    std::string system_call = "svn log -q " + path + " > svnstat.log.tmp";
     17    std::cout << system_call << std::endl;
    1618    int system_return = system(system_call.c_str());
    1719    if (system_return)
     
    3436
    3537      if (ss.get() == 'r'){
    36         u_int revision;
     38        size_t revision;
    3739        ss >> revision;
    3840        std::string tmp;
     
    4547        std::string time;
    4648        ss >> time;
     49
     50        date_.resize(std::max(revision+1, date_.size()));
     51        date_[revision] = date;
    4752      }
    4853    }
    4954    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      }
    5062
    5163    return system_return;
  • trunk/lib/CommitStat.h

    r48 r60  
    55
    66#include <string>
     7#include <vector>
    78
    89namespace theplu{
     
    2728    int parse(const std::string& path);
    2829
     30    inline const std::vector<std::string> date(void) const { return date_; }
     31
    2932  private:
    3033    ///
     
    3437
    3538    inline void reset(void) {};
     39
     40    std::vector<std::string> date_;
    3641  };
    3742}}
  • trunk/lib/Directory.cc

    r58 r60  
    4747        lstat(fullpath.c_str(),&nodestat);   // C api from sys/stat.h
    4848        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()+"_"));
    5050        else
    51           daughters_.push_back(new File(fullpath,output_name_+"_"));
     51          daughters_.push_back(new File(fullpath,output_name()+"_"));
    5252      }
    5353  }
     
    6161
    6262
    63   const Stats& Directory::parse(void)
     63  const Stats& Directory::parse(const bool verbose)
    6464  {
    6565    stats_.reset();
    6666
     67    // empty directory treated as one-liner file
     68    if (daughters_.empty())
     69      stats_.parse(path_,true);
     70
    6771    for (NodeIterator i=daughters_.begin(); i!=daughters_.end(); i++)
    68       stats_ += (*i)->parse();
     72      stats_ += (*i)->parse(verbose);
    6973    return stats_;
    7074  }
    7175
    7276
    73   void Directory::print(void) const
     77  void Directory::print(const bool verbose) const
    7478  {
    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;
    7682    std::ofstream os(output.c_str());
    7783    print_header(os);
     
    9096    // Peter, use STL algo.
    9197    for (NodeConstIter_ i=daughters_.begin();i!=daughters_.end();i++)
    92       (*i)->print();
     98      (*i)->print(verbose);
    9399  }
    94100
    95   void Directory::purge(void) {
     101  void Directory::purge(const bool verbose)
     102  {
     103    if (verbose)
     104      std::cout << "Purging " << path_ << std::endl;
    96105    for (NodeIterator i=daughters_.begin(); i!=daughters_.end(); )
    97106      if (!((*i)->subversion_controlled())) {
     
    100109      }
    101110      else {
    102         (*i)->purge();
     111        (*i)->purge(verbose);
    103112        i++;
    104113      }
  • trunk/lib/Directory.h

    r58 r60  
    3737    ~Directory(void);
    3838
    39     const Stats& parse(void);
     39    const Stats& parse(const bool verbose=false);
    4040
    41     void print(void) const;
     41    void print(const bool verbose=false) const;
    4242
    43     void purge(void);
     43    void purge(const bool verbose=false);
    4444
    4545  private:
  • trunk/lib/File.cc

    r58 r60  
    44#include "Node.h"
    55#include "Stats.h"
     6#include "utility.h"
    67
    78#include <fstream>
    89#include <iostream>
     10#include <map>
    911#include <sstream>
    1012#include <string>
     
    1315namespace svnstat{
    1416
    15   bool File::blame() const
     17  const Stats& File::parse(const bool verbose)
    1618  {
    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();
    2322
    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_;
    4527
    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_);
    8729    return stats_;
    8830  }
    8931
    90   void File::print(void) const
     32  void File::print(const bool verbose) const
    9133  {
    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;
    9337    std::ofstream os(output.c_str());
    9438    print_header(os);
  • trunk/lib/File.h

    r58 r60  
    2525    /// @return true if succesful
    2626    ///
    27     const Stats& parse(void);
     27    const Stats& parse(const bool verbose=false);
    2828
    2929    ///
    3030    ///
    3131    ///
    32     void print(void) const;
     32    void print(const bool verbose=false) const;
    3333
    3434  private:
     
    4545    File(const File&);
    4646
    47     ///
    48     /// Extracts information from 'svn info <node>'
    49     ///
    50     /// @note <node> must be in subversion control.
    51     ///
    52     void info(void);
    53 
    5447    std::string author_;
    5548    bool binary_;
  • trunk/lib/Gnuplot.cc

    r39 r60  
    44
    55#include <cstdio>
    6 #include <fstream>
    7 #include <vector>
    86#include <unistd.h>
     7#include <string>
    98
     9#include <iostream>
    1010
    1111namespace theplu {
     
    5757  }
    5858
     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
    5979
    6080  void Gnuplot::tokenizer(const std::string& in,
     
    81101
    82102
    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 
    110103}} // end of namespace svnstat and namespace theplu
  • trunk/lib/Gnuplot.h

    r39 r60  
    55
    66#include <cstdio>
     7#include <fstream>
    78#include <list>
    89#include <stdexcept>
     
    5556
    5657    ///
    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
    5977    /// called again.
    6078    ///
     
    6482
    6583    ///
    66     /// Set the \a title of the line in the subsequent plot_xy or
    67     /// plot_y calls. The setting applies until this function is
     84    /// Set the \a title of the line in the subsequent plot or
     85    /// replot calls. The setting applies until this function is
    6886    /// called again.
    6987    ///
     
    7593    /// Gnuplot usage.
    7694    ///
     95    // Peter, do we have to set xdata for replot
    7796    inline void
    7897    plot(const std::vector<double>& y,
    7998         const std::vector<double>& x=std::vector<double>())
    80     { plot(y,x,"plot"); }
     99    { command("set xdata"); plot(y,x,"plot"); }
    81100
    82101    ///
     
    88107    replot(const std::vector<double>& y,
    89108           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; }
    91124
    92125  private:
     
    101134    /// @param \a plotcmd must be "plot" or "replot".
    102135    ///
    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    }
    105167
    106168    void tokenizer(const std::string& in, std::list<std::string>& tokens,
     
    111173    // fix this in the command() member function?
    112174    std::list<std::string> tempfiles_;
     175    std::vector<std::string> date_;
     176    std::string date_input_format_;
     177    std::string date_output_format_;
    113178    std::string gnuplot_binary_;
    114179    std::string linestyle_;
  • trunk/lib/Makefile.am

    r48 r60  
    55noinst_LIBRARIES = libsvnstat.a
    66libsvnstat_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  
    2828    virtual inline ~Node(void) {};
    2929
     30    const std::string& output_name(void) const { return output_name_; }
     31
    3032    ///
    3133    /// @brief parsing file using svn blame.
    3234    ///
    33     virtual const Stats& parse(void)=0;
     35    virtual const Stats& parse(const bool verbose=false)=0;
    3436
    3537    ///
    3638    /// Function printing HTML in current working directory
    3739    ///
    38     virtual void print(void) const=0;
     40    virtual void print(const bool verbose=false) const=0;
    3941
    4042    ///
     
    4244    ///
    4345    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>"; }
    4547 
    4648    ///
    4749    ///
    4850    ///
    49     inline virtual void purge(void) { /* Nothing to be done */ };
     51    inline virtual void purge(const bool verbose=false)
     52    { /* Nothing to be done */ };
    5053
    5154    ///
  • trunk/lib/Stats.cc

    r44 r60  
    66
    77#include <algorithm>
     8#include <iostream>
    89#include <map>
    910#include <numeric>
     
    2223  std::vector<double> Stats::accumulated(void) const
    2324  {
    24     if (map_.empty())
    25       return std::vector<double>();
    26 
    2725    // sum of all users
    28     std::vector<u_int> sum(latest_revision_+1,0);
     26    std::vector<u_int> sum(latest_revision_+1, 0);
    2927    sum=std::accumulate(map_.begin(), map_.end(), sum,
    3028                        PairValuePlus<std::string,u_int>());
     
    3230    // calculate accumulated sum
    3331    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());
    3533    return accum;
    3634  }
     
    6361  }
    6462
     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
    65108  std::string Stats::plot(void) const
    66109  {
    67110    char name[]="svnstat_XXXXXX.png";
    68     if (mkstemps(name,4)==-1)
     111    if (mkstemps(name,4)==-1){
    69112      throw std::runtime_error(std::string("Failed to get unique filename: ") +
    70                                name);
     113                             name);
     114    }
    71115    std::string cmd=std::string("set term png; set output '")+name+"'";
    72116    gnuplot_pipe_.command(cmd);
    73117    gnuplot_pipe_.command("set key left Left reverse");
    74     std::vector<double> x=accumulated();
     118    std::vector<double> x=accumulated();   
    75119    std::stringstream sa;
    76120    sa << x.back() << " total";
    77121    gnuplot_pipe_.linetitle(sa.str());
    78     gnuplot_pipe_.plot(x);
     122    gnuplot_pipe_.date_plot(x);
    79123    for (MapConstIter_ i= map_.begin(); i != map_.end(); i++) {
    80124      x=accumulated(i->first);
     
    82126      s << x.back() << " " << i->first;
    83127      gnuplot_pipe_.linetitle(s.str());
    84       gnuplot_pipe_.replot(x);
     128      gnuplot_pipe_.date_replot(x);
    85129    }
    86130
  • trunk/lib/Stats.h

    r44 r60  
    44#define _theplu_svnstat_stats_
    55
     6#include <iostream>
    67#include <map>
    78#include <ostream>
     
    2526    inline Stats(void) {}
    2627
    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);
    3132
    3233    ///
     
    7273    std::vector<double> accumulated(const std::string& user) const;
    7374
     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
    7480    std::string plot(void) const;
    7581
  • trunk/lib/utility.h

    r39 r60  
    66#include <algorithm>
    77#include <functional>
     8#include <map>
    89#include <string>
    910#include <utility>
     
    1213namespace theplu{
    1314namespace 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&);
    1429
    1530  ///
Note: See TracChangeset for help on using the changeset viewer.