Changeset 1239


Ignore:
Timestamp:
Oct 24, 2010, 1:57:56 AM (13 years ago)
Author:
Peter Johansson
Message:

move 'update copyright' code from File class to CopyrightVisitor? class.

Location:
trunk/lib
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/CopyrightVisitor.cc

    r1234 r1239  
    2222#include "CopyrightVisitor.h"
    2323
     24#include "Configuration.h"
    2425#include "Directory.h"
    2526#include "File.h"
     
    3839
    3940
     41  std::string
     42  CopyrightVisitor::copyright_block(const std::map<int, std::set<Alias> >& year_authors,
     43                                    const std::string& prefix) const
     44  {
     45    using namespace std;
     46    stringstream ss;
     47    for (map<int, set<Alias> >::const_iterator i(year_authors.begin());
     48         i!=year_authors.end();) {
     49      ss << prefix << Configuration::instance().copyright_string() << " "
     50         << 1900+i->first;
     51      map<int, set<Alias> >::const_iterator j = i;
     52      assert(i!=year_authors.end());
     53      while (++j!=year_authors.end() &&
     54             i->second == j->second){
     55        ss << ", " << 1900+(j->first);
     56      }
     57      // printing authors
     58      std::vector<Alias> vec_alias;
     59      back_insert_iterator<std::vector<Alias> > ii(vec_alias);
     60      std::copy(i->second.begin(), i->second.end(), ii);
     61      // sort with respect to id
     62      std::sort(vec_alias.begin(), vec_alias.end(), IdCompare());
     63      for (std::vector<Alias>::iterator a=vec_alias.begin();
     64           a!=vec_alias.end(); ++a){
     65        if (a!=vec_alias.begin())
     66          ss << ",";
     67        ss << " " << a->name();
     68      }
     69      ss << "\n";
     70      i = j;
     71    }
     72    return ss.str();
     73  }
     74
     75
     76  void CopyrightVisitor::create_year2alias(std::map<int, std::set<Alias> >& m,
     77                                           const File& file)
     78  {
     79    using namespace std;
     80    const Stats& stats = file.stats()["add"];
     81
     82    // loop over all years
     83    for (std::map<int, svn_revnum_t>::const_iterator rev_iter=year2rev_.begin();
     84         rev_iter!=year2rev_.end(); ++rev_iter) {
     85
     86      svn_revnum_t last_rev_this_year = rev_iter->second;
     87      svn_revnum_t last_rev_last_year = 0;
     88      if (rev_iter != year2rev_.begin()) {
     89        last_rev_last_year = (--rev_iter)->second;
     90        ++rev_iter;
     91      }
     92      // do not go beyond BASE rev of file
     93      last_rev_this_year = std::min(last_rev_this_year,file.last_changed_rev());
     94      last_rev_last_year = std::min(last_rev_last_year,file.last_changed_rev());
     95      // loop over authors
     96      for (std::set<std::string>::const_iterator a_iter=stats.authors().begin();
     97           a_iter!=stats.authors().end(); ++a_iter) {
     98
     99        // check if anything has been added since last year
     100        if ( (stats(LineTypeParser::code, *a_iter, last_rev_this_year) >
     101              stats(LineTypeParser::code, *a_iter, last_rev_last_year)) ||
     102             (stats(LineTypeParser::comment, *a_iter, last_rev_this_year) >
     103              stats(LineTypeParser::comment, *a_iter, last_rev_last_year)) ) {
     104       
     105       
     106          // find username in map of aliases
     107          std::map<string,Alias>::iterator name(alias_.lower_bound(*a_iter));
     108         
     109          // if alias exist insert alias
     110          if (name != alias_.end() && name->first==*a_iter)
     111            m[rev_iter->first].insert(name->second);
     112          else {
     113            // else insert user name
     114            Alias a(*a_iter,alias_.size());
     115            m[rev_iter->first].insert(a);
     116            std::cerr << "svncopyright: warning: no copyright alias found for `"
     117                      << *a_iter << "'\n";
     118            // insert alias to avoid multiple warnings.
     119            alias_.insert(name, std::make_pair(*a_iter, a));
     120          }
     121        }
     122      }
     123    }
     124  }
     125
     126
     127  bool CopyrightVisitor::detect_copyright(const std::string& path,
     128                                          std::string& block,
     129                                          size_t& start_at_line,
     130                                          size_t& end_at_line,
     131                                          std::string& prefix) const
     132  {
     133    using namespace std;
     134    LineTypeParser parser(path);
     135    std::ifstream is(path.c_str());
     136    std::string line;
     137    while (std::getline(is, line))
     138      parser.parse(line);
     139    if (!parser.copyright_found())
     140      return false;
     141    block = parser.block();
     142    start_at_line = parser.start_line();
     143    end_at_line = parser.end_line();
     144    prefix = parser.prefix();
     145    return true;
     146  }
     147
     148
    40149  bool CopyrightVisitor::enter(Directory& dir)
    41150  {
     
    51160 
    52161
     162  void CopyrightVisitor::update_copyright(const File& file)
     163  {
     164    std::string old_block;
     165    size_t start_line=0;
     166    size_t end_line=0;
     167    std::string prefix;
     168    if (!detect_copyright(file.path(),old_block, start_line, end_line, prefix)){
     169      if (Configuration::instance().missing_copyright_warning())
     170        std::cerr << "svncopyright: warning: no copyright statement found in `"
     171                  << file.path() << "'\n";
     172      return;
     173    }
     174    std::map<int, std::set<Alias> > map;
     175    create_year2alias(map, file);
     176    std::string new_block = copyright_block(map, prefix);
     177    if (old_block==new_block)
     178      return;
     179    if (verbose_)
     180      std::cout << "Updating copyright in '" << file.path() << "'" << std::endl;
     181    update_copyright(file.path(), new_block, start_line, end_line);
     182  }
     183
     184
     185  void CopyrightVisitor::update_copyright(const std::string& path,
     186                                          const std::string& new_block,
     187                                          size_t start_at_line,
     188                                          size_t end_at_line) const
     189  {
     190    // embrace filename with brackets #filename#
     191    std::string tmpname = concatenate_path(directory_name(path),
     192                                           "#" + file_name(path) + "#");
     193    std::ofstream tmp(tmpname.c_str());
     194    assert(tmp);
     195    using namespace std;
     196    ifstream is(path.c_str());
     197    assert(is.good());
     198    string line;
     199    // Copy lines before block
     200    for (size_t i=1; i<start_at_line; ++i){
     201      assert(is.good());
     202      getline(is, line);
     203      tmp << line << "\n";
     204    }
     205    // Printing copyright statement
     206    tmp << new_block;
     207    // Ignore old block lines
     208    for (size_t i=start_at_line; i<end_at_line; ++i){
     209      assert(is.good());
     210      getline(is, line);
     211    }
     212    // Copy lines after block
     213    while(is.good()) {
     214      char ch=is.get();
     215      if (is.good())
     216        tmp.put(ch);
     217    }
     218
     219    is.close();
     220    tmp.close();
     221   
     222    // finally rename file
     223    rename(tmpname, path);
     224  }
     225
    53226  void CopyrightVisitor::visit(File& file)
    54227  {
     
    56229      return;
    57230    file.parse(verbose_, ignore_cache_);
    58     file.print_copyright(alias_, verbose_, year2rev_);
     231    update_copyright(file);
    59232    file.stats().reset();
    60233  }
    61234
    62235}} // end of namespace svndigest and namespace theplu
    63 
  • trunk/lib/CopyrightVisitor.h

    r1237 r1239  
    2929
    3030#include <map>
     31#include <set>
    3132#include <string>
    3233
     
    5354
    5455    /**
     56       Doing nothing
    5557     */
    5658    void leave(Directory& dir);
    5759
    5860    /**
     61       Updating copyright in \a file
    5962     */
    60     void visit(File& dir);
     63    void visit(File& file);
    6164
    6265  private:
     
    6568    const std::map<int, svn_revnum_t>& year2rev_;
    6669    bool ignore_cache_;
     70
     71    /**
     72       \return copyright block
     73
     74       Create a Copyright block from \a year2auth and prefix each line
     75       with \a prefix.
     76     */
     77    std::string copyright_block(const std::map<int, std::set<Alias> >& year2auth,
     78                                const std::string& prefix) const;
     79
     80    /**
     81       Create a map from year to set of authors.
     82     */
     83    void create_year2alias(std::map<int, std::set<Alias> >&, const File& file);
     84
     85    /**
     86       Look from copyright block in file \a path.
     87
     88       \param path file to look for copyright
     89       \param block found copyright block
     90       \param start_at_line line number of first line in found block
     91       \param end_at_line line number of first line after found block
     92
     93       \return true if Copyright block is found
     94     */
     95    bool detect_copyright(const std::string& path, std::string& block,
     96                          size_t& start_at_line, size_t& end_at_line,
     97                          std::string& prefix) const;
     98
     99
     100    /**
     101       Update the copyright in \a file.
     102     */
     103    void update_copyright(const File& file);
     104
     105    /**
     106       Doing the actual print of copyright statement
     107
     108       \param path to file
     109       \param block new copyright block
     110       \param start_at_line line number of first line in old block
     111       \param end_at_line line number of first line after old block
     112     */
     113    void update_copyright(const std::string& path, const std::string& block,
     114                          size_t start_at_line, size_t end_at_line) const;
    67115  };
    68116}} // end of namespace svndigest and namespace theplu
  • trunk/lib/File.cc

    r1234 r1239  
    6565  {
    6666    return "blame_output/" + local_path() + ".html";
    67   }
    68 
    69 
    70   std::map<int, std::set<Alias> >
    71   File::copyright_map(std::map<std::string, Alias>& alias,
    72                       const std::map<int, svn_revnum_t>& year2rev) const
    73   {
    74     using namespace std;
    75     map<int, set<Alias> > year_authors;
    76     const Stats& stats = stats_["add"];
    77 
    78     // loop over all years
    79     for (std::map<int, svn_revnum_t>::const_iterator rev_iter=year2rev.begin();
    80          rev_iter!=year2rev.end(); ++rev_iter) {
    81 
    82       svn_revnum_t last_rev_this_year = rev_iter->second;
    83       svn_revnum_t last_rev_last_year = 0;
    84       if (rev_iter != year2rev.begin()) {
    85         last_rev_last_year = (--rev_iter)->second;
    86         ++rev_iter;
    87       }
    88       // do not go beyond BASE rev of file
    89       last_rev_this_year = std::min(last_rev_this_year, last_changed_rev());
    90       last_rev_last_year = std::min(last_rev_last_year, last_changed_rev());
    91       // loop over authors
    92       for (std::set<std::string>::const_iterator a_iter=stats.authors().begin();
    93            a_iter!=stats.authors().end(); ++a_iter) {
    94 
    95         // check if anything has been added since last year
    96         if ( (stats(LineTypeParser::code, *a_iter, last_rev_this_year) >
    97               stats(LineTypeParser::code, *a_iter, last_rev_last_year)) ||
    98              (stats(LineTypeParser::comment, *a_iter, last_rev_this_year) >
    99               stats(LineTypeParser::comment, *a_iter, last_rev_last_year)) ) {
    100        
    101        
    102           // find username in map of aliases
    103           std::map<string,Alias>::iterator name(alias.lower_bound(*a_iter));
    104          
    105           // if alias exist insert alias
    106           if (name != alias.end() && name->first==*a_iter)
    107             year_authors[rev_iter->first].insert(name->second);
    108           else {
    109             // else insert user name
    110             Alias a(*a_iter,alias.size());
    111             year_authors[rev_iter->first].insert(a);
    112             std::cerr << "svncopyright: warning: no copyright alias found for `"
    113                       << *a_iter << "'\n";
    114             // insert alias to avoid multiple warnings.
    115             alias.insert(name, std::make_pair(*a_iter, a));
    116           }
    117         }
    118       }
    119     }
    120     return year_authors;
    121   }
    122 
    123 
    124   std::string
    125   File::copyright_block(const std::map<int, std::set<Alias> >& year_authors,
    126                         const std::string& prefix) const
    127   {
    128     using namespace std;
    129     stringstream ss;
    130     for (map<int, set<Alias> >::const_iterator i(year_authors.begin());
    131          i!=year_authors.end();) {
    132       ss << prefix << Configuration::instance().copyright_string() << " "
    133          << 1900+i->first;
    134       map<int, set<Alias> >::const_iterator j = i;
    135       assert(i!=year_authors.end());
    136       while (++j!=year_authors.end() &&
    137              i->second == j->second){
    138         ss << ", " << 1900+(j->first);
    139       }
    140       // printing authors
    141       std::vector<Alias> vec_alias;
    142       back_insert_iterator<std::vector<Alias> > ii(vec_alias);
    143       std::copy(i->second.begin(), i->second.end(), ii);
    144       // sort with respect to id
    145       std::sort(vec_alias.begin(), vec_alias.end(), IdCompare());
    146       for (std::vector<Alias>::iterator a=vec_alias.begin();
    147            a!=vec_alias.end(); ++a){
    148         if (a!=vec_alias.begin())
    149           ss << ",";
    150         ss << " " << a->name();
    151       }
    152       ss << "\n";
    153       i = j;
    154     }
    155     return ss.str();
    156   }
    157 
    158   bool File::detect_copyright(std::string& block, size_t& start_at_line,
    159                               size_t& end_at_line, std::string& prefix) const
    160   {
    161     using namespace std;
    162     LineTypeParser parser(path());
    163     std::ifstream is(path().c_str());
    164     std::string line;
    165     while (std::getline(is, line))
    166       parser.parse(line);
    167     if (!parser.copyright_found())
    168       return false;
    169     block = parser.block();
    170     start_at_line = parser.start_line();
    171     end_at_line = parser.end_line();
    172     prefix = parser.prefix();
    173     return true;
    17467  }
    17568
     
    324217
    325218
    326   void File::print_copyright(std::map<std::string, Alias>& alias,
    327                              bool verbose,
    328                              const std::map<int,svn_revnum_t>& y2rev) const
    329   {
    330     if (ignore() || svncopyright_ignore())
    331       return;
    332 
    333     std::string old_block;
    334     size_t start_line=0;
    335     size_t end_line=0;
    336     std::string prefix;
    337     if (!detect_copyright(old_block, start_line, end_line, prefix)){
    338       if (Configuration::instance().missing_copyright_warning())
    339         std::cerr << "svncopyright: warning: no copyright statement found in `"
    340                   << path_ << "'\n";
    341       return;
    342     }
    343     std::map<int, std::set<Alias> > map=copyright_map(alias, y2rev);
    344     std::string new_block = copyright_block(map, prefix);
    345     if (old_block==new_block)
    346       return;
    347     if (verbose)
    348       std::cout << "Updating copyright in '" << path_ << "'" << std::endl;
    349     update_copyright(new_block, start_line, end_line);
    350   }
    351 
    352 
    353219  void File::print_core(const bool verbose) const
    354220  {
     
    411277  }
    412278
    413 
    414   void File::update_copyright(const std::string& new_block,
    415                               size_t start_at_line, size_t end_at_line) const
    416   {
    417     // embrace filename with brackets #filename#
    418     std::string tmpname = concatenate_path(directory_name(path()),
    419                                            "#" + file_name(path()) + "#");
    420     std::ofstream tmp(tmpname.c_str());
    421     assert(tmp);
    422     using namespace std;
    423     ifstream is(path().c_str());
    424     assert(is.good());
    425     string line;
    426     // Copy lines before block
    427     for (size_t i=1; i<start_at_line; ++i){
    428       assert(is.good());
    429       getline(is, line);
    430       tmp << line << "\n";
    431     }
    432     // Printing copyright statement
    433     tmp << new_block;
    434     // Ignore old block lines
    435     for (size_t i=start_at_line; i<end_at_line; ++i){
    436       assert(is.good());
    437       getline(is, line);
    438     }
    439     // Copy lines after block
    440     while(is.good()) {
    441       char ch=is.get();
    442       if (is.good())
    443         tmp.put(ch);
    444     }
    445 
    446     is.close();
    447     tmp.close();
    448    
    449     // finally rename file
    450     rename(tmpname, path());
    451   }
    452 
    453 
    454279}} // end of namespace svndigest and namespace theplu
  • trunk/lib/File.h

    r1238 r1239  
    7373
    7474    /**
    75        @throw std::runtime_error when a file error is encountered
    76        updating the copyrights.
    77     */
    78     void print_copyright(std::map<std::string, Alias>&, bool verbose,
    79                          const std::map<int, svn_revnum_t>&) const;
    80 
    81     /**
    8275       Let the visitor perform its mission via visitor(*this)
    8376     */
     
    10598
    10699    /**
    107        \return copyright block
    108      */
    109     std::string copyright_block(const std::map<int, std::set<Alias> >& map,
    110                                 const std::string& prefix) const;
    111 
    112     /**
    113        Create a map from year to set of authors.
    114      */
    115     std::map<int, std::set<Alias> >
    116     copyright_map(std::map<std::string, Alias>& alias,
    117                   const std::map<int, svn_revnum_t>&) const;
    118 
    119     /**
    120        Create a map from year to set of authors.
    121 
    122        \return true if Copyright block is found
    123      */
    124     bool detect_copyright(std::string& block, size_t& start_at_line,
    125                           size_t& end_at_line, std::string& prefix) const;
    126 
    127     /**
    128100       @brief Print blame output
    129101    */
     
    139111                    const std::string& line_type, const SVNlog&) const;
    140112
    141     /**
    142        Doing the actual print of copyright statement
    143 
    144        \param block new copyright block
    145        \param start_at_line line number of first line in old block
    146        \param end_at_line line number of first line after old block
    147      */
    148     void update_copyright(const std::string& block,
    149                           size_t start_at_line, size_t end_at_line) const;
    150113  };
    151114
Note: See TracChangeset for help on using the changeset viewer.