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

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

File:
1 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 
Note: See TracChangeset for help on using the changeset viewer.