Changeset 118


Ignore:
Timestamp:
Jul 3, 2006, 9:44:49 AM (15 years ago)
Author:
Peter Johansson
Message:

fixes #46 #45 #26 #40

Location:
trunk/lib
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/CommitStat.cc

    r84 r118  
    3737  {
    3838    std::string system_call = "svn log -q -r HEAD:1 " + path +
    39       " > svnstat.log.tmp";
     39      " > /tmp/svnstat.log.tmp";
    4040    int system_return = system(system_call.c_str());
    4141    if (system_return)
     
    5050    int system_return = log(path);
    5151   
    52     std::ifstream is("svnstat.log.tmp");
     52    std::ifstream is("/tmp/svnstat.log.tmp");
    5353    std::string line;
    5454    typedef std::vector<std::string>::iterator DateIter;
  • trunk/lib/Directory.cc

    r112 r118  
    176176      os << "<tr class=\"light\">\n";
    177177    os << "<td>Total</td>\n";
    178     os << "<td>" << stats_.rows() << "</td>\n";
    179     os << "<td>---</td>\n";
    180     os << "<td>---</td>\n";
     178    os << "<td>" << stats_.lines() << "</td>\n";
     179    os << "<td>" << stats_.code() << "</td>\n";
     180    os << "<td>" << stats_.comments() << "</td>\n";
    181181    os << "<td>" << stats_.last_changed_rev() << "</td>\n";
    182182    os << "<td>" << author() << "</td>\n";
  • trunk/lib/File.cc

    r101 r118  
    6767       << file_name(stats_.plot(output_name()+".png",output_name()))
    6868       << "' alt='[plot]' border=0>\n</p>";
     69
     70    os << "<table class=\"listings\">\n";
     71    os << "<thead>";
     72    os << "<tr>\n";
     73    os << "<th>Author</th>\n";
     74    os << "<th>Lines</th>\n";
     75    os << "<th>Code</th>\n";
     76    os << "<th>Comments</th>\n";
     77    os << "</tr>\n</thead>\n";
     78    os << "<tbody>";
     79
     80    bool dark=false;
     81    os << "<tr class=\"light\">\n";
     82    os << "<td colspan=\"5\"><a href=\"index.html\">../</a></td>\n";
     83    os << "</tr>\n";
     84    dark=!dark;
     85   
     86
     87    // print authors
     88    for (std::set<std::string>::const_iterator i=stats_.authors().begin();
     89         i!=stats_.authors().end(); ++i){
     90      if (dark)
     91        os << "<tr class=\"dark\"><td>" << *i
     92           << "</td><td>" << stats_.lines(*i)
     93           << "</td><td>" << stats_.code(*i)
     94           << "</td><td>" << stats_.comments(*i)
     95           << "</td></tr>\n";
     96      else
     97        os << "<tr class=\"light\"><td>" << *i
     98           << "</td><td>" << stats_.lines(*i)
     99           << "</td><td>" << stats_.code(*i)
     100           << "</td><td>" << stats_.comments(*i)
     101           << "</td></tr>\n";
     102      dark=!dark;
     103    }
     104    if (dark)
     105      os << "<tr class=\"dark\">\n";
     106    else
     107      os << "<tr class=\"light\">\n";
     108    os << "<td>Total</td>\n";
     109    os << "<td>" << stats_.lines() << "</td>\n";
     110    os << "<td>" << stats_.code() << "</td>\n";
     111    os << "<td>" << stats_.comments() << "</td>\n";
     112    os << "</tr>\n";
     113    os << "</table>\n";
     114    os << "</p>\n";
     115
    69116    print_footer(os);
    70117    os.close();
    71 
    72118  }
    73119
  • trunk/lib/Node.cc

    r112 r118  
    5151    ss << "<tr class=\"" << css_class << "\">\n"
    5252       << "<td" << html_link() << "</td>\n"
    53        << "<td>" << stats_.rows() << "</td>\n"
    54        << "<td>" << "---" << "</td>\n"
    55        << "<td>" << "---" << "</td>\n"
     53       << "<td>" << stats_.lines() << "</td>\n"
     54       << "<td>" << stats_.code() << "</td>\n"
     55       << "<td>" << stats_.comments() << "</td>\n"
    5656       << "<td>" << stats_.last_changed_rev() << "</td>\n"
    5757       << "<td>" << author() << "</td>\n"
     
    7070       << "by <a href=http://lev.thep.lu.se/trac/svnstat/>"
    7171       << PACKAGE_STRING << "</a>"
    72        << "</font>\n</p>\n</body>\n</html>\n";
     72       << "</font>\n</p>\n</div>\n</body>\n</html>\n";
    7373  }
    7474
     
    8888    for (u_int i=0; i<level_; ++i)
    8989      os << "../";
    90     os << "svnstat.css\" type=\"text/css\" />\n";
     90    os << "svnstat.css\" type=\"text/css\" />\n"
     91       << "<body>\n"
     92       << "<div id=\"menu\">"
     93       << "<ul><li></li>"
     94       << "<li><a href=\"";
     95    for (u_int i=0; i<level_; ++i)
     96      os << "../";
     97    os << "index.html\">Home</li>"
     98       << "</ul></div>"
     99       << "<div id=\"main\">"
     100       << "<h2>" << output_name() << "</h2>\n";
    91101  }
    92102
  • trunk/lib/Parser.cc

    r107 r118  
    2323
    2424#include "Parser.h"
     25#include "utility.h"
    2526
    2627#include <algorithm>
     
    2829#include <fstream>
    2930#include <iostream>
     31#include <string>
    3032
    3133namespace theplu{
     
    3335
    3436
    35   Parser::Parser(std::istream& is)
     37  Parser::Parser(const std::string& path)
     38  {
     39    std::ifstream is(path.c_str());
     40    cc_mode(is);
     41    is.close();
     42  }
     43
     44
     45  void Parser::cc_mode(std::istream& is)
    3646  {
    3747    std::string str;
    3848    while(getline(is,str)) {
    39       std::string::const_iterator where;
     49      std::string::iterator where;
    4050      where = std::find_if(str.begin(), str.end(), std::not1(WhiteSpace()));
    4151      if (where==str.end())
    4252        type_.push_back(empty);
    43       else if (*where=='/' && ((where++)!=str.end()) && *where=='/')
    44         type_.push_back(comment);
    45       else
     53      else if (match_begin(where, str.end(), "//")) {
     54        where = std::find_if(where, str.end(), AlphaNum());
     55        if (where==str.end())
     56          type_.push_back(empty);
     57        else
     58          type_.push_back(comment);
     59      }
     60      else {
    4661        type_.push_back(code);
     62      }
    4763    }
    4864  }
  • trunk/lib/Parser.h

    r114 r118  
    2626
    2727#include <fstream>
     28#include <string>
    2829#include <vector>
    2930
     
    5455    /// @brief Constructor
    5556    ///
    56     explicit Parser(std::istream&);
     57    explicit Parser(const std::string&);
    5758
    5859    ///
     
    6768    Parser(const Parser& other);
    6869
     70    void cc_mode(std::istream&);
     71
    6972    std::vector<line_type> type_;
    7073
     
    7275
    7376  ///
     77  /// @return true if @a c is [a-z], [A-Z] or numerical.
     78  ///
     79  struct AlphaNum : public std::unary_function<char,bool>
     80  {
     81    inline bool operator()(const char c) const
     82    {
     83      return isalnum(c);
     84    }
     85  };
     86
     87  ///
    7488  /// Functor for white space identification
    7589  ///
    76   /// @return true if @a c is '\t', ' ' or '\n'.
     90  /// @see isspace
     91  ///
     92  /// @return true if @a c is '\t', '\n', '\v', '\f' or ' '.
    7793  ///
    7894  struct WhiteSpace : public std::unary_function<char,bool>
  • trunk/lib/Stats.cc

    r113 r118  
    5858
    5959
    60   std::vector<u_int> Stats::accumulated(void) const
     60  std::vector<u_int> Stats::accumulated(const Map_& map) const
    6161  {
    6262    // sum of all users
    63     std::vector<u_int> sum(revision_+1, 0);
    64     sum=std::accumulate(map_.begin(), map_.end(), sum,
     63    std::vector<u_int> sum(revision_+1);
     64    sum=std::accumulate(map.begin(), map.end(), sum,
    6565                        PairValuePlus<std::string,u_int>());
    6666
     
    7272  }
    7373
    74   std::vector<u_int> Stats::accumulated(const std::string& user) const
    75   {
    76     if (!map_.count(user))
     74  std::vector<u_int> Stats::accumulated(const Map_& map,
     75                                        const std::string& user) const
     76  {
     77    if (!map.count(user))
    7778      return std::vector<u_int>();
    78     std::vector<u_int> vec=(map_.find(user))->second;
     79    std::vector<u_int> vec=(map.find(user))->second;
    7980 
    8081    if (vec.size() < revision_+1)
     
    8687  }
    8788
    88   void Stats::add(const std::string& user, const u_int& rev)
    89   {
    90     std::vector<u_int>* vec = &(map_[user]);
    91     if (vec->size() < rev+1){
    92       vec->reserve(revision_ + 1);
    93       vec->insert(vec->end(), rev - vec->size(),0);
    94       vec->push_back(1);
     89  void Stats::add(const std::string& user, const u_int& rev,
     90                  const Parser::line_type lt)
     91  {
     92    authors_.insert(user);
     93
     94    std::vector<u_int>* total = &(total_[user]);
     95    if (total->size() < rev+1){
     96      total->reserve(revision_ + 1);
     97      total->insert(total->end(), rev - total->size(), 0);
     98      total->push_back(1);
    9599    }
    96100    else
    97       (*vec)[rev]++;
     101      (*total)[rev]++;
     102
     103    std::vector<u_int>* code = &(code_[user]);
     104    if (code->size() < rev+1){
     105      code->reserve(revision_ + 1);
     106      code->insert(code->end(), rev - code->size(), 0);
     107      if (lt == Parser::code)
     108        code->push_back(1);
     109      else
     110        code->push_back(0);
     111    }
     112    else if (lt == Parser::code)
     113      (*code)[rev]++;
     114
     115    std::vector<u_int>* comments = &(comments_[user]);
     116    if (comments->size() < rev+1){
     117      comments->reserve(revision_ + 1);
     118      comments->insert(comments->end(), rev - comments->size(), 0);
     119      if (lt == Parser::comment)
     120        comments->push_back(1);
     121      else
     122        comments->push_back(0);
     123    }
     124    else if (lt == Parser::comment)
     125      (*comments)[rev]++;
    98126  }
    99127
     
    106134
    107135    // Check if file is binary
    108     std::ifstream is("svnstat.tmp");
     136    std::ifstream is("/tmp/svnstat.tmp");
    109137    std::string line;
    110138    getline(is,line,' ');
     
    118146    is.close();
    119147
    120     is.open("svnstat.tmp");
     148    Parser parser(path);
     149    std::vector<Parser::line_type>::const_iterator count=parser.type().begin();
     150
     151    is.open("/tmp/svnstat.tmp");
    121152    while (getline(is,line, '\n')){
    122153      if (!line.size()) // skip empty line
     
    127158      ss >> revision;
    128159      ss >> user;
    129       add(user, revision);
     160      // to handle symbolic links
     161      if (count==parser.type().end())
     162        add(user, revision, Parser::empty);
     163      else
     164        add(user, revision, *count);
     165      count++;
    130166    }
    131167    is.close();
     168   
    132169    return false;
    133170  }
     
    146183    gp->command("set key left Left reverse");
    147184    gp->command("set multiplot");
    148     std::vector<u_int> total=accumulated();   
     185    std::vector<u_int> total=accumulated(total_);   
    149186    double yrange_max=1.03*total.back()+1;
    150187    gp->yrange(yrange_max);
    151188    size_t plotno=1;
    152189    std::stringstream ss;
    153     for (MapConstIter_ i= map_.begin(); i != map_.end(); i++) {
     190    for (MapConstIter_ i= total_.begin(); i != total_.end(); i++) {
    154191      ss.str("");
    155192      ss << "set key height " << 2*plotno;
    156193      gp->command(ss.str());
    157       std::vector<u_int> x=accumulated(i->first);
     194      std::vector<u_int> x=accumulated(total_, i->first);
    158195      ss.str("");
    159196      ss << x.back() << " " << i->first;
     
    178215  }
    179216
     217
    180218  Stats& Stats::operator+=(const Stats& other)
    181219  {
    182     for (MapConstIter_ o_i= other.map_.begin(); o_i != other.map_.end(); ++o_i)
     220    for (MapConstIter_ o_i= other.code_.begin();
     221         o_i != other.code_.end(); ++o_i)
    183222    {
    184       std::pair<MapIter_,bool> result = map_.insert(*o_i);
     223      std::pair<MapIter_,bool> result = code_.insert(*o_i);
    185224      if (!result.second)
    186         map_[(*(result.first)).first] =
     225        code_[(*(result.first)).first] =
    187226          VectorPlus<u_int>()( (*(result.first)).second, (*o_i).second );
    188227 
    189228    }
     229 
     230    for (MapConstIter_ o_i= other.comments_.begin();
     231         o_i != other.comments_.end(); ++o_i)
     232    {
     233      std::pair<MapIter_,bool> result = comments_.insert(*o_i);
     234      if (!result.second)
     235        comments_[(*(result.first)).first] =
     236          VectorPlus<u_int>()( (*(result.first)).second, (*o_i).second );
     237 
     238    }
     239   
     240    for (MapConstIter_ o_i= other.total_.begin();
     241         o_i != other.total_.end(); ++o_i)
     242    {
     243      std::pair<MapIter_,bool> result = total_.insert(*o_i);
     244      if (!result.second)
     245        total_[(*(result.first)).first] =
     246          VectorPlus<u_int>()( (*(result.first)).second, (*o_i).second );
     247 
     248    }
     249   
     250    if (!other.authors().empty())
     251      authors_.insert(other.authors().begin(), other.authors().end());
    190252    return *this;
    191253  }
  • trunk/lib/Stats.h

    r112 r118  
    2626#define _theplu_svnstat_stats_
    2727
     28#include "Parser.h"
     29
    2830#include <iostream>
    2931#include <map>
    3032#include <ostream>
     33#include <set>
    3134#include <string>
    3235#include <vector>
     
    4548    ///
    4649    explicit Stats(const std::string& path);
     50
     51    ///
     52    /// @return set of authors
     53    ///
     54    inline const std::set<std::string>& authors(void) const { return authors_; }
     55
     56    ///
     57    ///
     58    ///
     59    inline u_int code(void) const { return accumulated(code_).back(); }
     60
     61    ///
     62    ///
     63    ///
     64    inline u_int code(const std::string& user) const
     65    { return accumulated(code_, user).back(); }
     66
     67    ///
     68    ///
     69    ///
     70    inline u_int comments(void) const { return accumulated(comments_).back(); }
     71
     72    ///
     73    ///
     74    ///
     75    inline u_int comments(const std::string& user) const
     76    { return accumulated(comments_, user).back(); }
    4777
    4878    ///
     
    6494    /// @brief Clear all statistics
    6595    ///
    66     inline void reset(void) { map_.clear(); }
     96    inline void reset(void)
     97    { code_.clear(); comments_.clear(); total_.clear(); authors_.clear();}
    6798
    6899    ///
     
    72103
    73104    ///
     105    ///
    74106    ///
     107    inline u_int lines(void) const { return accumulated(total_).back(); }
     108
    75109    ///
    76     inline u_int rows(void) const { return accumulated().back(); }
     110    ///
     111    ///
     112    inline u_int lines(const std::string& user) const
     113    { return accumulated(total_, user).back(); }
    77114
    78115    ///
     
    82119
    83120  private:
     121    // Peter, if the vector is sparse make it a map
     122    typedef std::map<std::string, std::vector<u_int> > Map_;
     123    typedef Map_::iterator MapIter_;
     124    typedef Map_::const_iterator MapConstIter_;
     125
    84126    ///
    85127    /// Copy constructor (not implemented)
     
    90132    /// @return accumulated vector of total
    91133    ///
    92     std::vector<u_int> accumulated(void) const;
     134    std::vector<u_int> accumulated(const Map_&) const;
    93135
    94136    ///
    95137    /// @return accumulated vector of stats_[user]
    96138    ///
    97     std::vector<u_int> accumulated(const std::string& user) const;
     139    std::vector<u_int> accumulated(const Map_&,
     140                                   const std::string& user) const;
    98141
    99142    ///
    100143    /// @brief adding a line to user from revision to the stats
    101144    ///
    102     void add(const std::string& user, const u_int& revision);
     145    void add(const std::string& user, const u_int& revision,
     146             const Parser::line_type);
    103147
    104148
     
    106150    u_int last_changed_rev_; // Should be the latest revision for file
    107151
    108     // Peter, if the vector is sparse make it a map
    109     typedef std::map<std::string, std::vector<u_int> > Map_;
    110     typedef Map_::iterator MapIter_;
    111     typedef Map_::const_iterator MapConstIter_;
    112     Map_ map_;
     152    std::set<std::string> authors_;
     153    Map_ code_;
     154    Map_ comments_;
     155    Map_ total_;
    113156  };
    114157}} // end of namespace svnstat end of namespace theplu
  • trunk/lib/utility.cc

    r115 r118  
    3939  int blame(const std::string& path)
    4040  {
    41     std::string system_call="svn blame " + path + " 1> svnstat.tmp 2> /dev/null";
     41    std::string mod_path = mod_str(path);
     42    std::string system_call="svn blame " + mod_path +
     43      " 1> /tmp/svnstat.tmp 2> /dev/null";
    4244    int system_return = system(system_call.c_str());
    4345    if (system_return)
     
    6567  std::map<std::string, std::string> info(const std::string& path)
    6668  {
    67     std::string system_call="svn info " + path + " 1> svnstat.tmp 2> /dev/null";
     69    std::string mod_path=mod_str(path);
     70    std::string system_call="svn info " + mod_path +
     71      " 1> /tmp/svnstat.tmp 2> /dev/null";
    6872    int system_return = system(system_call.c_str());
    6973    if (system_return)
    7074      return std::map<std::string, std::string>();
    7175
    72     std::ifstream is("svnstat.tmp");
     76    std::ifstream is("/tmp/svnstat.tmp");
    7377    std::string line;
    7478    std::map<std::string, std::string> svn_info;
     
    8286  }
    8387
     88  std::string mod_str(const std::string& str)
     89  {
     90    std::string mod_str="";
     91    for (size_t i=0; i<str.size(); ++i){
     92      if (str[i]==' ')
     93        mod_str+="\\ ";
     94      else
     95        mod_str+=str[i];
     96    }
     97    return mod_str;
     98  }
     99
    84100  void print_css(std::ostream& s)
    85101  {
     
    87103    s << " background: #fff; \n";
    88104    s << " color: #000; \n";
    89     s << " margin: 10px; \n";
     105    s << " margin: 0px; \n";
    90106    s << " padding: 0; \n";
    91107    s << "} \n";
     108    s << "\n";
     109    s << "#menu {\n";
     110    s << " background: #eee;\n";
     111    s << " width: 100%;\n";
     112    s << " margin: 0px;\n";
     113    s << " padding: 0px;\n";
     114    s << "}\n\n";
     115    s << "#menu ul\n";
     116    s << "{ \n";
     117    s << "padding: 0px;\n";
     118    s << "margin: 0px;list-style-type: none; text-align: center;"
     119      << "border-bottom: 1px solid black;}\n";
     120    s << "#menu ul li { display: inline; border-right: 1px solid black;}\n";
     121    s << "#menu ul li a {text-decoration: none; padding-right: 1em;"
     122      << "padding-left: 1em; margin: 0px;}\n";
     123    s << "#menu ul li a:hover{ color: #000; background: #ddd;}\n";
     124    s << "\n";
     125    s << "#main {\n";
     126    s << " margin: 10px; \n";
     127    s << "}\n";
    92128    s << "\n";
    93129    s << "body, th, td {\n";
     
    141177    s << "table.listings tbody tr.light { background-color: #fcfcfc }\n";
    142178    s << "table.listings tbody tr.dark { background-color: #f7f7f7 }\n";
    143     s << "table.listings tbody tr.hover { background: #eed }\n";
     179    s << "table.listings tbody tr:hover { background: #eed }\n";
    144180    s << "\n";
    145181    s << "\n";
  • trunk/lib/utility.h

    r115 r118  
    6161
    6262  ///
     63  /// stupid function needed for systems calls to be correct for
     64  /// filenames containing spaces.
     65  /// @note this function will be removed.
     66  ///
     67  /// @return passed string with ' ' changed to '\ '
     68  ///
     69  std::string mod_str(const std::string&);
     70
     71  ///
    6372  /// @return the current working directory.
    6473  ///
     
    6978  ///
    7079  void print_css(std::ostream& s);
     80
     81  inline bool match_begin(std::string::iterator first,
     82                          std::string::iterator last,
     83                          const std::string& str)
     84  { return (std::distance(first, last)>=static_cast<int>(str.size()) &&
     85            std::equal(str.begin(), str.end(), first));
     86  }
     87
     88  inline bool match_end(std::string::iterator first,
     89                        std::string::iterator last,
     90                        const std::string& str)
     91  { return (std::distance(first,last)>=static_cast<int>(str.size()) &&
     92            std::equal(str.rbegin(), str.rend(), first));
     93  }
     94
     95  inline std::string::iterator search(std::string::iterator& first,
     96                                      std::string::iterator& last,
     97                                      const std::string& str)
     98  { return std::search(first, last, str.begin(), str.end()); }
    7199
    72100  ///
Note: See TracChangeset for help on using the changeset viewer.