Changeset 138


Ignore:
Timestamp:
Aug 3, 2006, 11:40:15 PM (17 years ago)
Author:
Jari Häkkinen
Message:

Fixes #23. No system calls to svn are done anymore.

Location:
trunk
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/bin/Makefile.am

    r100 r138  
    2929
    3030LDADD = @top_srcdir@/lib/libsvnstat.a -L$(APR_PATH)/lib -L$(SVN_PATH)/lib \
    31   -lsvn_client-1 -lsvn_wc-1 -lsvn_ra-1 -lsvn_subr-1 -lapr-0
     31  -lsvn_client-1 -lsvn_diff-1 -lsvn_wc-1 -lsvn_ra-1 -lsvn_subr-1 -lapr-0
    3232
    3333INCLUDES = -I@top_srcdir@/lib \
    3434  -I$(SVN_PATH)/include/subversion-1 -I$(APR_PATH)/include/apr-0
    3535
    36 # Needed to compile svn API stuff
    37 svnstat_CXXFLAGS = -Wno-long-long
    38 
    3936clean-local:
    40   rm -rf svnstat_output *~
     37  rm -rf svnstat *~
  • trunk/configure.ac

    r96 r138  
    4242AC_PROG_RANLIB
    4343
    44 CXXFLAGS="-g -O -Wall -pedantic"
     44# -Wno-long-long is needed to suppress compiler diagnostics regarding
     45# using extension beyond the C++ standard (usage of non C++ standard
     46# 'long long' types).
     47CXXFLAGS="-g -O -Wall -pedantic -Wno-long-long"
    4548CPPFLAGS="-DHAVE_INLINE=1"
    4649# Use these flags when compiling a production library
    47 #CXXFLAGS="-O3 -Wall -pedantic"
     50#CXXFLAGS="-O3 -Wall -pedantic -Wno-long-long"
    4851#CPPFLAGS="-DNDEBUG -DGSL_RANGE_CHECK_OFF -DHAVE_INLINE=1"
    4952
  • trunk/lib/Makefile.am

    r129 r138  
    2626
    2727noinst_HEADERS = Directory.h File.h Gnuplot.h GnuplotFE.h Node.h  \
    28   Parser.h rmdirhier.h Stats.h SVN.h SVNinfo.h utility.h
     28  Parser.h rmdirhier.h Stats.h SVN.h SVNblame.h SVNinfo.h utility.h
    2929
    3030libsvnstat_a_SOURCES = Directory.cc File.cc Gnuplot.cc GnuplotFE.cc \
    31   Node.cc Parser.cc rmdirhier.cc Stats.cc SVN.cc SVNinfo.cc utility.cc
     31  Node.cc Parser.cc rmdirhier.cc Stats.cc SVN.cc SVNblame.cc        \
     32  SVNinfo.cc utility.cc
    3233
    3334INCLUDES = -I$(SVN_PATH)/include/subversion-1 -I$(APR_PATH)/include/apr-0
    34 
    35 # Needed to compile svn API stuff
    36 libsvnstat_a_CXXFLAGS = -Wno-long-long
  • trunk/lib/Node.h

    r129 r138  
    3030
    3131#include <ostream>
    32 #include <sstream>
    3332#include <stdexcept>
    3433#include <string>
  • trunk/lib/SVN.cc

    r129 r138  
    103103                                                    APR_HASH_KEY_STRING)),
    104104                                          context_->cancel_func,
    105                                           context_->cancel_baton, pool_)))
    106       svn_handle_error2(err, stderr, TRUE, "svnstat: ");
     105                                          context_->cancel_baton, pool_))) {
     106      svn_handle_error2(err, stderr, false, "svnstat: ");
     107      svn_error_clear(err);
     108      throw SVNException("SVN(void): svn_cmdline_setup_auth_baton failed");
     109    }
    107110  }
    108111
     
    115118    // at program exit, ok since SVN is a singleton
    116119    delete instance_;
     120  }
     121
     122
     123  svn_error_t* SVN::client_blame(const std::string& path,
     124                                 svn_client_blame_receiver_t receiver,
     125                                 void *baton)
     126  {
     127    // Setup to use all revisions
     128    svn_opt_revision_t peg, start, head;
     129    peg.kind=svn_opt_revision_unspecified;
     130    start.kind=svn_opt_revision_number;
     131    start.value.number=0;
     132    head.kind=svn_opt_revision_head;
     133    svn_error_t* err=svn_client_blame3(path.c_str(), &peg, &start, &head,
     134                                       // Jari, below line creates memory leaks
     135                                       svn_diff_file_options_create(pool_),
     136                                       false, receiver, baton, context_, pool_);
     137    if (err && err->apr_err!=SVN_ERR_CLIENT_IS_BINARY_FILE) {
     138      svn_handle_error2(err, stderr, false, "svnstat: ");
     139      svn_error_clear(err);
     140      throw SVNException("SVN::client_blame: svn_client_blame3 failed");
     141    }
     142    return err;
    117143  }
    118144
  • trunk/lib/SVN.h

    r129 r138  
    7070
    7171    ///
    72     /// @Brief Call the underlying svn_client_info for \a path with \a
     72    /// @brief Call the underlying svn_client_blame3 for \a path with
     73    /// \a receiver and \a baton.
     74    ///
     75    /// This function is called from SVNblame to do 'svn blame' on an
     76    /// item. The \a receiver and \a baton is defined in SVNblame and
     77    /// the \a receiver is called by the underlying subversion API for
     78    /// every line in \a path provided it the item is under subversion
     79    /// control. The \a baton is used to communicate anonymous
     80    /// information through the API to the \a receiver. If \a path is
     81    /// a binary object an error is returned, all other errors will
     82    /// generate an SVNException.
     83    ///
     84    /// @return SVN_NO_ERROR or SVN_ERR_CLIENT_IS_BINARY_FILE, the
     85    /// latter can be used to trigger on binary files. Note that
     86    /// errors return from underlying subversion API must be cleared
     87    /// by the receiver.
     88    ///
     89    /// @see Subversion API (svn_error_clear).
     90    ///
     91    svn_error_t * client_blame(const std::string& path,
     92                               svn_client_blame_receiver_t receiver,
     93                               void *baton);
     94
     95    ///
     96    /// @brief Call the underlying svn_client_info for \a path with \a
    7397    /// receiver and \a baton.
    7498    ///
  • trunk/lib/SVNinfo.cc

    r135 r138  
    3232
    3333  SVNinfo::SVNinfo(const std::string& path)
     34    : instance_(SVN::instance())
    3435  {
    35     instance_=SVN::instance();
    3636    instance_->client_info(path.c_str(), info_receiver,
    3737                           static_cast<void*>(&info_receiver_baton_));
     
    4141  svn_error_t *
    4242  SVNinfo::info_receiver(void *baton, const char *, const svn_info_t *info,
    43                          apr_pool_t *pool)
     43                         apr_pool_t *pool)
    4444  {
    4545    if (!info)
  • trunk/lib/Stats.cc

    r131 r138  
    2626
    2727#include "GnuplotFE.h"
     28#include "SVNblame.h"
    2829#include "SVNinfo.h"
    2930#include "utility.h"
     
    3233#include <cassert>
    3334#include <cstdlib>
    34 #include <fstream>
    3535#include <iostream>
    3636#include <map>
    3737#include <numeric>
    3838#include <string>
     39#include <sstream>
    3940#include <unistd.h>
    4041#include <utility>
     
    8687
    8788  void Stats::add(const std::string& user, const u_int& rev,
    88                   const Parser::line_type lt)
     89                  const Parser::line_type& lt)
    8990  {
    9091    authors_.insert(user);
     
    127128  bool Stats::parse(const std::string& path)
    128129  {
    129     // Calling svn blame
    130     if (blame(path))
    131       return true;
    132 
    133     // Check if file is binary
    134     std::ifstream is("/tmp/svnstat.tmp");
    135     std::string line;
    136     getline(is,line,' ');
    137     if (line==std::string("Skipping")){
    138       getline(is,line,' ');
    139       if (line==std::string("binary")){
    140         is.close();
    141         return true;
    142       }
    143     }
    144     is.close();
     130    SVNblame svn_blame(path);
     131    if (svn_blame.binary())
     132      return true;
    145133
    146134    Parser parser(path);
    147135    std::vector<Parser::line_type>::const_iterator count=parser.type().begin();
    148136
    149     is.open("/tmp/svnstat.tmp");
    150     while (getline(is,line, '\n')){
    151       if (!line.size()) // skip empty line
     137    while (const SVNblame::blame_information * bi=svn_blame.next()) {
     138      if (!bi->line.size()) { // skip empty line
     139        ++count; // keep Parser information in sync with Stats parsing
    152140        continue;
    153       std::stringstream ss(line);
    154       u_int revision;
    155       std::string user;
    156       ss >> revision;
    157       ss >> user;
     141      }
    158142      // to handle symbolic links
    159143      if (count==parser.type().end())
    160         add(user, revision, Parser::empty);
     144        add(bi->author, bi->revision, Parser::empty);
    161145      else
    162         add(user, revision, *count);
     146        add(bi->author, bi->revision, *count);
    163147      count++;
    164     }
    165     is.close();
     148    }
    166149   
    167150    return false;
  • trunk/lib/Stats.h

    r129 r138  
    144144    ///
    145145    void add(const std::string& user, const u_int& revision,
    146              const Parser::line_type);
     146             const Parser::line_type&);
    147147
    148148
  • trunk/lib/utility.cc

    r129 r138  
    3434namespace svnstat{
    3535
    36   int blame(const std::string& path)
    37   {
    38     std::string mod_path = mod_str(path);
    39     std::string system_call="svn blame " + mod_path +
    40       " 1> /tmp/svnstat.tmp 2> /dev/null";
    41     int system_return = system(system_call.c_str());
    42     if (system_return)
    43       std::cerr << "Error: svn blame " << path << std::endl;     
    44     return system_return;
    45   }
    46 
    4736  std::string file_name(const std::string& full_path)
    4837  {
     
    5140    while (getline(ss,name,'/')) {}
    5241    return name;
    53   }
    54 
    55   std::string mod_str(const std::string& str)
    56   {
    57     std::string mod_str="";
    58     for (size_t i=0; i<str.size(); ++i){
    59       if (str[i]==' ')
    60         mod_str+="\\ ";
    61       else
    62         mod_str+=str[i];
    63     }
    64     return mod_str;
    6542  }
    6643
  • trunk/lib/utility.h

    r129 r138  
    3838
    3939  ///
    40   /// @return 0 if ok
    41   ///
    42   int blame(const std::string&);
    43 
    44   ///
    4540  /// Create directory \a dir. The call can fail in many ways, cf. 'man
    4641  /// mkdir'.
     
    5247  ///
    5348  std::string file_name(const std::string&);
    54 
    55   ///
    56   /// stupid function needed for systems calls to be correct for
    57   /// filenames containing spaces.
    58   /// @note this function will be removed.
    59   ///
    60   /// @return passed string with ' ' changed to '\ '
    61   ///
    62   std::string mod_str(const std::string&);
    6349
    6450  ///
Note: See TracChangeset for help on using the changeset viewer.