Changeset 318


Ignore:
Timestamp:
May 18, 2007, 11:35:45 AM (16 years ago)
Author:
Jari Häkkinen
Message:

Fixes #167 and addresses #74. Interfaces have changed. SVN::instance usage has changed, read SVN class documentation.

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/bin/svndigest.cc

    r315 r318  
    22
    33/*
    4   Copyright (C) 2006 Jari Häkkinen, Peter Johansson
    5   Copyright (C) 2007 Peter Johansson
     4  Copyright (C) 2006, 2007 Jari Häkkinen, Peter Johansson
    65
    76  This file is part of svndigest, http://lev.thep.lu.se/trac/svndigest
     
    9089  }
    9190
    92   // Make sure that root directory is under subversion control.
    93   SVN* svn=SVN::instance();
     91  SVN* svn=NULL;
    9492  try {
    9593    if (option->verbose())
    96       std::cout << "Connecting to WC administrative area" << std::endl;
    97     svn->setup_wc_adm_access(option->root());
     94      std::cout << "Initializing SVN singleton." << std::endl;
     95    svn=SVN::instance(option->root());
    9896  }
    9997  catch (SVNException e) {
    100     std::cerr << "\nsvndigest: " << e.what() << "\nsvndigest: "
    101               << option->root()
    102               << " is not under subversion control\n" << std::endl;
     98    std::cerr << "\nsvndigest: " << e.what()
     99              << "\nsvndigest: failed to initilize subversion access for "
     100              << option->root() << std::endl;
    103101    exit(-1);
    104102  }
     
    127125  }
    128126
    129   // build directory tree already here ... if WC is upto date with
     127  // build directory tree already here ... if WC is not upto date with
    130128  // repo an exception is thrown. This avoids several costly
    131129  // statements below and will not remove a digest tree below if a
     
    146144  Stats stats(option->root());
    147145  stats+=tree->parse(option->verbose());
    148 
    149   // Retrieve commit dates etc from SVNlog.
    150   try {
    151     if (option->verbose())
    152       std::cout << "Retrieving commit dates" << std::endl;
    153     svn->setup_ra_session(repo);
    154   }
    155   catch (SVNException e) {
    156     std::cerr << "\nsvndigest: " << e.what() << std::endl;
    157     exit(-1);
    158   }
    159   SVNlog svnlog(repo);
    160146
    161147  // remove target if needed
     
    169155    std::cout << "Generating output" << std::endl;
    170156  if (!option->revisions())
    171     GnuplotFE::instance()->set_dates(svnlog.date());
     157    GnuplotFE::instance()->set_dates(SVNlog(repo).date());
    172158  chdir(option->targetdir().c_str());
    173159  mkdir(tree->name());
     
    187173    mkdir(*i);
    188174    touch(std::string(*i+"/index.html"));
    189     }
     175  }
    190176  try {
    191177    tree->print(option->verbose());
  • trunk/lib/SVN.cc

    r305 r318  
    4747
    4848
    49   SVN::SVN(void)
     49  SVN::SVN(const std::string& path)
    5050    : adm_access_(NULL), allocator_(NULL), context_(NULL), pool_(NULL)
    5151  {
     
    5858    // memorywise but what about APR internal counters?)
    5959    if (svn_cmdline_init("svndigest",stderr) != EXIT_SUCCESS)
    60       throw SVNException("SVN(void): svn_cmdline_init failed");
     60      throw SVNException("SVN: svn_cmdline_init failed");
    6161
    6262    /// create top-level pool
    6363    if (apr_allocator_create(&allocator_))
    64       throw SVNException("SVN(void): apr_allocator_create failed");
     64      throw SVNException("SVN(_allocator_create failed");
    6565    apr_allocator_max_free_set(allocator_,SVN_ALLOCATOR_RECOMMENDED_MAX_FREE);
    6666    pool_ = svn_pool_create_ex(NULL, allocator_);
     
    6969    // initialize the repository access library
    7070    if ((err=svn_ra_initialize(pool_)))
    71       cleanup_failed_init(err, "SVN(void): svn_ra_initialize failed");
     71      cleanup_failed_init(err, "SVN: svn_ra_initialize failed");
    7272
    7373    // Check that users .subversion exist. Should this really be done?
     
    7676    // stuff (compare with the svn binary).
    7777    if ((err=svn_config_ensure(NULL, pool_)))
    78       cleanup_failed_init(err, "SVN(void): svn_config_ensure failed");
     78      cleanup_failed_init(err, "SVN: svn_config_ensure failed");
    7979
    8080    // create a client context object
    8181    if ((err=svn_client_create_context(&context_, pool_)))
    82       cleanup_failed_init(err, "SVN(void): svn_client_create_context failed");
     82      cleanup_failed_init(err, "SVN: svn_client_create_context failed");
    8383
    8484    if ((err=svn_config_get_config(&(context_->config), NULL, pool_)))
    85       cleanup_failed_init(err, "SVN(void): svn_config_get_config failed");
     85      cleanup_failed_init(err, "SVN: svn_config_get_config failed");
    8686
    8787    // set up authentication stuff
     
    9393                                          context_->cancel_func,
    9494                                          context_->cancel_baton, pool_)))
    95       cleanup_failed_init(err, "SVN(void): svn_cmdline_setup_auth_baton failed");
     95      cleanup_failed_init(err, "SVN: svn_cmdline_setup_auth_baton failed");
     96
     97    // Set up svn administration area access. The whole structure is
     98    // setup, maybe this is unnecessary?
     99    const char* canonical_path=svn_path_internal_style(path.c_str(), pool_);
     100    if (svn_error_t *err=svn_wc_adm_open3(&adm_access_, NULL, canonical_path,
     101                                          false, -1, context_->cancel_func,
     102                                          context_->cancel_baton, pool_))
     103      cleanup_failed_init(err, "SVN: svn_wc_adm_open3 failed");
     104
     105    // get a session to the repository
     106    struct root_url_receiver_baton rurb;
     107    client_info(path, root_url_receiver, static_cast<void*>(&rurb));
     108    if (svn_error_t *err=svn_client_open_ra_session(&ra_session_,
     109                                                    rurb.path.c_str(),
     110                                                    context_, pool_))
     111      cleanup_failed_init(err, "SVN: svn_client_open_ra_session failed");
    96112  }
    97113
     
    108124
    109125
     126  void SVN::cleanup(svn_error_t *err,apr_pool_t *pool,
     127                    const std::string& message)
     128  {
     129    svn_handle_error2(err,stderr,false,"svndigest: ");
     130    svn_error_clear(err);
     131    if (pool)
     132      svn_pool_destroy(pool);
     133    if (message.length()>0)
     134      throw SVNException(message);
     135  }
     136
     137
     138  void SVN::cleanup_failed_init(svn_error_t *err, const std::string& message)
     139  {
     140    cleanup(err,pool_);
     141    apr_allocator_destroy(allocator_);
     142    throw SVNException(message);
     143  }
     144
     145
    110146  svn_error_t* SVN::client_blame(const std::string& path,
    111147                                 svn_client_blame_receiver_t receiver,
     
    117153    start.kind=svn_opt_revision_number;
    118154    start.value.number=0;
    119     head.kind=svn_opt_revision_head;
     155    head.kind = ( svn_path_is_url(path.c_str()) ?
     156                  svn_opt_revision_head : svn_opt_revision_base );
    120157    apr_pool_t *subpool = svn_pool_create(pool_);
    121158    svn_error_t* err=svn_client_blame3(path.c_str(), &peg, &start, &head,
     
    143180
    144181
     182  void SVN::client_log(const std::string& path,
     183                       svn_log_message_receiver_t receiver, void *baton)
     184  {
     185    // Allocate space in subpool to pool_ for apr_path (here a string).
     186    apr_pool_t *subpool = svn_pool_create(pool_);
     187    apr_array_header_t* apr_path=apr_array_make(subpool,1,4);
     188    // Copy path to apr_path.
     189    (*((const char **) apr_array_push(apr_path))) =
     190      apr_pstrdup(subpool, svn_path_internal_style(path.c_str(),subpool));
     191
     192    // Setup to retrieve all commit logs.
     193    svn_opt_revision_t peg, start, head;
     194    peg.kind=svn_opt_revision_unspecified;
     195    start.kind=svn_opt_revision_number;
     196    start.value.number=0;
     197    head.kind = ( svn_path_is_url(path.c_str()) ?
     198                  svn_opt_revision_head : svn_opt_revision_base );
     199    svn_error_t* err=NULL;
     200    if ((err=svn_client_log3(apr_path, &peg, &start, &head, 0, false, false,
     201                             receiver, baton, context_, subpool)))
     202      // cleanupp will throw an exception
     203      cleanup(err, subpool, "commit_dates: svn_client_log3 failed");
     204    svn_pool_destroy(subpool);
     205  }
     206
     207
    145208  void SVN::client_proplist(const std::string& path,
    146209                            std::map<std::string, std::string>& property)
     
    148211    svn_opt_revision_t peg, revision;
    149212    peg.kind=svn_opt_revision_unspecified;
    150     revision.kind=svn_opt_revision_head;
     213    revision.kind = ( svn_path_is_url(path.c_str()) ?
     214                      svn_opt_revision_head : svn_opt_revision_base );
    151215    apr_pool_t *subpool = svn_pool_create(pool_);
    152216    apr_array_header_t * properties;
     
    180244
    181245
    182   void SVN::client_log(std::string path, log_receiver_baton* lb)
    183   {
    184     // Allocate space in subpool to pool_ for apr_path (here a string).
    185     apr_pool_t *subpool = svn_pool_create(pool_);
    186     apr_array_header_t* apr_path=apr_array_make(subpool,1,4);
    187     // Copy path to apr_path.
    188     (*((const char **) apr_array_push(apr_path))) =
    189       apr_pstrdup(subpool, svn_path_internal_style(path.c_str(),subpool));
    190 
    191     // Setup to retrieve all commit logs.
    192     svn_opt_revision_t peg, start, head;
    193     peg.kind=svn_opt_revision_unspecified;
    194     start.kind=svn_opt_revision_number;
    195     start.value.number=0;
    196     head.kind=svn_opt_revision_head;
    197     svn_error_t* err=NULL;
    198     // Retrieving the last revision is only needed for the reserve
    199     // call below, not needed for the functionality here.
    200     if ((err=svn_ra_get_latest_revnum(ra_session_, &(head.value.number),
    201                                       subpool)))
    202       cleanup(err, subpool, "commit_dates: svn_ra_get_latest_revnum failed");
    203     // Acctually we do not know the size of vector (and reserve most
    204     // likely over-use memory), perhaps we should use lists instead,
    205     // or do we need the random access?
    206     lb->commit_dates.reserve(head.value.number+1); // revision 0 is also stored.
    207     lb->authors.reserve(head.value.number+1); // revision 0 is also stored.
    208     lb->rev.reserve(head.value.number+1); // revision 0 is also stored.
    209     if ((err=svn_client_log3(apr_path, &peg, &start, &head, 0, false, false,
    210                              log_message_receiver, static_cast<void*>(lb),
    211                              context_, subpool)))
    212       // cleanupp will throw an exception
    213       cleanup(err, subpool, "commit_dates: svn_client_log3 failed");
    214     svn_pool_destroy(subpool);
    215   }
    216 
    217 
    218   void SVN::cleanup(svn_error_t *err,apr_pool_t *pool,
    219                     const std::string& message)
    220   {
    221     svn_handle_error2(err,stderr,false,"svndigest: ");
    222     svn_error_clear(err);
    223     if (pool)
    224       svn_pool_destroy(pool);
    225     if (message.length()>0)
    226       throw SVNException(message);
    227   }
    228 
    229 
    230   void SVN::cleanup_failed_init(svn_error_t *err, const std::string& message)
    231   {
    232     cleanup(err,pool_);
    233     apr_allocator_destroy(allocator_);
    234     throw SVNException(message);
    235   }
    236 
    237 
    238   svn_error_t *
    239   SVN::log_message_receiver(void *baton, apr_hash_t *changed_paths,
    240                             svn_revnum_t rev, const char *author,
    241                             const char *date, const char *msg, apr_pool_t *pool)
    242   {
    243     struct log_receiver_baton *lb=static_cast<struct log_receiver_baton*>(baton);
    244     if (date && date[0])
    245       lb->commit_dates.push_back(date);
    246     else
    247       throw SVNException("No date defined for revision: " + rev);
    248     if (author && author[0])
    249       lb->authors.push_back(author);
    250     else
    251       lb->authors.push_back("");
    252     lb->rev.push_back(rev);
    253     if (msg)
    254       lb->msg.push_back(std::string(msg));
    255     else
    256       lb->msg.push_back(std::string(""));
    257     return SVN_NO_ERROR;
    258   }
    259 
    260 
    261   void SVN::setup_ra_session(const std::string& path) {
    262     // get a session to the repository
    263     if (svn_error_t *err=svn_client_open_ra_session(&ra_session_, path.c_str(),
    264                                                     context_,pool_))
    265       cleanup(err, NULL, "setup_ra_session: svn_client_open_ra_session failed");
    266   }
    267 
    268 
    269   void SVN::setup_wc_adm_access(const std::string& path)
    270   {
    271     // Set up svn administration area access. The whole structure is
    272     // setup, maybe this is unnecessary?
    273     const char* canonical_path=svn_path_internal_style(path.c_str(), pool_);
    274     if (svn_error_t *err=svn_wc_adm_open3(&adm_access_, NULL, canonical_path,
    275                                           false, -1, context_->cancel_func,
    276                                           context_->cancel_baton, pool_))
    277       cleanup(err, NULL, "setup_wc_adm_access: svn_wc_adm_open3 failed");
     246  SVN* SVN::instance(void)
     247  {
     248    if (!instance_)
     249      throw SVNException("SVN::instance(void): SVN singleton not initialized");
     250    return instance_;
     251  }
     252
     253
     254  SVN* SVN::instance(const std::string& url)
     255  {
     256    if (!instance_) {
     257      instance_=new SVN(url);
     258    }
     259    return instance_;
     260  }
     261
     262
     263  svn_error_t* SVN::root_url_receiver(void *baton, const char *,
     264                                      const svn_info_t *info, apr_pool_t*)
     265  {
     266    if (!info)
     267      throw SVNException(std::string("SVN::url_receriver: ") +
     268                         "Failed to acquire an svn info object");
     269
     270    root_url_receiver_baton* rurb=
     271      static_cast<struct root_url_receiver_baton*>(baton);
     272    if (info->repos_root_URL)
     273      rurb->path=info->repos_root_URL;
     274
     275    return SVN_NO_ERROR;
    278276  }
    279277
     
    299297  }
    300298
    301 
    302299}} // end of namespace svndigest and namespace theplu
  • trunk/lib/SVN.h

    r271 r318  
    4646  { inline SVNException(const std::string& msg) : runtime_error(msg) {} };
    4747
    48   ///
    49   /// The SVN class is a front end to the subversion API.
    50   ///
    51   /// SVN provides one single global access point to the underlying
    52   /// subversion API and makes sure that there is only one point of
    53   /// access for the binary.
    54   ///
    55   /// @see Design Patterns (the singleton pattern). Subversion API
    56   /// documents.
    57   ///
     48  /**
     49     \brief The SVN class is a front end to the subversion API.
     50
     51     SVN provides one single global access point to the underlying
     52     subversion API and makes sure that there is only one point of
     53     access for the binary.
     54
     55     The singleton SVN object should be initialized with
     56     SVN::instancs(const std::string& path), rather than
     57     SVN::instance(void), before using any other subversion related
     58     classes or calls. Best practice is to initilize the singleton
     59     object early in the main program. The logic behind this
     60     requirement is that all subverison related classes and calls
     61     expect that repository and WC access is properly set up at
     62     initialization. However, most functionality is available
     63     irrespectively which instance call is made.
     64
     65     \see Design Patterns (the singleton pattern). Subversion API
     66     documents, SVN::instancs(void), SVN::instancs(const
     67     std::string&).
     68  */
    5869  class SVN {
    5970  public:
     
    6576    };
    6677
    67     ///
    68     /// @brief Call the underlying svn_client_blame3 for \a path with
    69     /// \a receiver and \a baton.
    70     ///
    71     /// This function is called from SVNblame to do 'svn blame' on an
    72     /// item. The \a receiver and \a baton is defined in SVNblame and
    73     /// the \a receiver is called by the underlying subversion API for
    74     /// every line in \a path provided it the item is under subversion
    75     /// control. The \a baton is used to communicate anonymous
    76     /// information through the API to the \a receiver. If \a path is
    77     /// a binary object an error is returned, all other errors will
    78     /// generate an SVNException.
    79     ///
    80     /// @return SVN_NO_ERROR or SVN_ERR_CLIENT_IS_BINARY_FILE, the
    81     /// latter can be used to trigger on binary files. Note that
    82     /// errors return from underlying subversion API must be cleared
    83     /// by the receiver.
    84     ///
    85     /// @see Subversion API (svn_error_clear).
    86     ///
     78    /**
     79       \brief Call the underlying svn_client_blame3 for \a path with
     80       \a receiver and \a baton.
     81
     82       This function is called from SVNblame to do 'svn blame' on an
     83       item. The \a receiver and \a baton is defined in SVNblame and
     84       the \a receiver is called by the underlying subversion API for
     85       every line in \a path provided it the item is under subversion
     86       control. The \a baton is used to communicate anonymous
     87       information through the API to the \a receiver. If \a path is a
     88       binary object an error is returned, all other errors will
     89       generate an SVNException.
     90
     91       \a path can be either a URL or an WC target.
     92
     93       \return SVN_NO_ERROR or SVN_ERR_CLIENT_IS_BINARY_FILE, the
     94       latter can be used to trigger on binary files. Note that errors
     95       return from underlying subversion API must be cleared by the
     96       receiver.
     97
     98       \see Subversion API (svn_error_clear).
     99    */
    87100    svn_error_t * client_blame(const std::string& path,
    88101                               svn_client_blame_receiver_t receiver,
    89102                               void *baton);
    90103
    91     ///
    92     /// @brief Call the underlying svn_client_info for \a path with \a
    93     /// receiver and \a baton.
    94     ///
    95     /// This function is called from SVNinfo to do 'svn info' on an
    96     /// item. The \a receiver and \a baton is defined in SVNinfo and
    97     /// the \a receiver is called by the underlying subversion API if
    98     /// \a path is under subversion control. The \a baton is used to
    99     /// communicate anonymous information through the API to the
    100     /// \a receiver.
    101     ///
    102     /// @see Subversion API documentation, SVNinfo
    103     ///
     104    /**
     105       \brief Call the underlying svn_client_info for \a path with \a
     106       receiver and \a baton.
     107
     108       This function is called from SVNinfo to do 'svn info' on an
     109       item. The \a receiver and \a baton is defined in SVNinfo and
     110       the \a receiver is called by the underlying subversion API if
     111       \a path is under subversion control. The \a baton is used to
     112       communicate anonymous information through the API to the \a
     113       receiver.
     114
     115       \a path can be either a URL or an WC target.
     116
     117       \see Subversion API documentation, SVNinfo
     118    */
    104119    void client_info(const std::string& path, svn_info_receiver_t receiver,
    105120                     void *baton);
    106121
    107122    /**
     123       \a path can be either a URL or an WC target.
     124
    108125       \todo doc
    109126    */
    110     void client_log(std::string path, log_receiver_baton* lb);
    111 
    112 
    113     /**
    114        @brief Get the properties for \a path.
     127    void client_log(const std::string& path, svn_log_message_receiver_t receiver,
     128                    void *baton);
     129
     130    /**
     131       \brief Get the subversion properties for \a path.
    115132
    116133       The retrieved properties are stored in \a properties. To check
    117134       whether \a is a binary item use SVNproperty::binary(void).
     135
     136       \a path can be either a URL or an WC target.
    118137    */
    119138    void client_proplist(const std::string& path,
    120139                         std::map<std::string, std::string>& properties);
    121140
    122     ///
    123     /// @brief Get revision dates.
    124     ///
    125     /// Get dates for all commits to the repository. \a root can be a
    126     /// repository path or a path within a working copy. In the latter
    127     /// case the corresponding repository will be used to retrieve
    128     /// commit dates.
    129     ///
    130     /// @return Revision dates in a vector where revision is
    131     /// implicitly defined by vector index, i.e., element 56 in the
    132     /// resulting vector implies revision 56.
    133     ///
    134     /// @note Currently revision 0 (repositoy creation) is not
    135     /// supported.
    136     ///
    137     /// @throw Various error messages generated from the subversion
    138     /// API.
    139     ///
    140     //std::vector<std::string> commit_dates(const std::string& path);
    141 
    142     ///
    143     /// @brief Get an instance of SVN.
    144     ///
    145     /// @throw Throws an SVNException if initialization fails in the
    146     /// underlying subversion API calls.
    147     ///
    148     static SVN* instance(void)
    149     { if (!instance_) instance_=new SVN; return instance_; }
    150 
    151     ///
    152     /// @throws SVNException if session setup fails.
    153     ///
    154     void setup_ra_session(const std::string& path);
    155 
    156     ///
    157     /// @throws SVNException if access setup fails.
    158     ///
    159     void setup_wc_adm_access(const std::string& path);
     141    /**
     142       \brief Get an instance of SVN.
     143
     144       The singleton SVN object should be initialized with
     145       SVN::instancs(const std::string&) before usage of this
     146       function. Best practice is to initilize the singleton object
     147       early in the main program. The logic behind this requirement is
     148       that subverison related classes and calls may expect that
     149       repository and WC access is properly set up at initialization.
     150
     151       \throw An SVNException if the singleton SVN onject is not
     152       already initilized.
     153
     154       \see SVN::instancs(const std::string&)
     155    */
     156    static SVN* instance(void);
     157
     158    /**
     159       \brief Get an instance of SVN setup against repository pointed
     160       to by \a path.
     161
     162       The singleton SVN object should be initialized with this
     163       instance call before any subversion related classes or calls
     164       are made. Best practice is to initilize the singleton object
     165       early in the main program. The logic behind this requirement is
     166       that subverison related classes and calls may expect that
     167       repository and WC access is properly set up at initialization.
     168
     169       \throw Throws an SVNException if initialization fails in the
     170       underlying subversion API calls, or if \a path is a URL.
     171    */
     172    static SVN* instance(const std::string& path);
     173
     174    /**
     175       \brief Set up a repository access session.
     176
     177       \throws SVNException if session setup fails, or if a session is
     178       already set up (i.e., repository cannot be changed during
     179       program lifetime).
     180    */
     181    //    void setup_ra_session(const std::string& path);
    160182
    161183    ///
     
    168190
    169191  private:
    170     ///
    171     /// @brief Constructor
    172     ///
    173     /// The only way to create a object of SVN type is by calling
    174     /// SVN::instance.
    175     ///
    176     SVN(void);
     192    /**
     193       \brief Constructor
     194
     195       The only way to create an object of SVN type is by calling
     196       SVN::instance(const std::string&). \a path must be a WC path,
     197       i.e., not a URL.
     198    */
     199    SVN(const std::string& path);
    177200
    178201    ///
     
    218241    // Subversion API stuff
    219242
    220     static svn_error_t *
    221     log_message_receiver(void *baton, apr_hash_t *changed_paths,
    222                          svn_revnum_t rev, const char *author, const char *date,
    223                          const char *msg, apr_pool_t *pool);
     243    /**
     244       the url is fech with svn info. The ursl is stored in a
     245       url_receiver_baton. The struct is filled in the url_receiver
     246       function.
     247    */
     248    struct root_url_receiver_baton {
     249      std::string path;
     250    };
     251
     252    /**
     253       url_receiver is the function passed to the underlying
     254       subversion API call svn_client_info. This function is called by
     255       the subversion API for every item matched by the conditions of
     256       the API call.
     257
     258       \see Subversion API documentation
     259    */
     260    static svn_error_t*
     261    root_url_receiver(void *baton, const char *path, const svn_info_t *info,
     262                      apr_pool_t *pool);
    224263
    225264    svn_wc_adm_access_t* adm_access_;
     
    230269  };
    231270
    232     // Log message receiver
    233     struct log_receiver_baton {
    234       std::vector<std::string> authors;
    235       std::vector<std::string> commit_dates;
    236       std::vector<std::string> msg;
    237       std::vector<size_t> rev;
    238     };
    239 
    240271}} // end of namespace svndigest and namespace theplu
    241272
  • trunk/lib/SVNinfo.cc

    r312 r318  
    3232
    3333  SVNinfo::SVNinfo(const std::string& path)
    34     : instance_(SVN::instance())
    3534  {
    36     instance_->client_info(path.c_str(), info_receiver,
    37                           static_cast<void*>(&info_receiver_baton_));
     35    SVN::instance()->client_info(path, info_receiver,
     36                                static_cast<void*>(&info_receiver_baton_));
    3837  }
    3938
    4039
    41   svn_error_t *
    42   SVNinfo::info_receiver(void *baton, const char *, const svn_info_t *info,
    43                          apr_pool_t*)
     40  svn_error_t* SVNinfo::info_receiver(void *baton, const char *,
     41                                      const svn_info_t *info, apr_pool_t*)
    4442  {
    4543    if (!info)
     
    6260  }
    6361
    64 
    6562}} // end of namespace svndigest and namespace theplu
  • trunk/lib/SVNinfo.h

    r312 r318  
    8686    SVNinfo(const SVNinfo&);
    8787
    88     SVN* instance_;
    89 
    9088    ///
    9189    /// svn info is stored in the info_receiver_baton_. The
     
    111109    /// @see Subversion API documentation
    112110    ///
     111    // The return type should be svn_log_message_receiver_t but I
     112    // cannot get it to compile (see comment for log_message_receiver
     113    // in SVNlog.h)
    113114    static svn_error_t * info_receiver(void *baton, const char *path,
    114115                                       const svn_info_t *info, apr_pool_t *pool);
  • trunk/lib/SVNlog.cc

    r282 r318  
    3535
    3636
    37   SVNlog::SVNlog(std::string path)
     37  SVNlog::SVNlog(const std::string& path)
    3838  {
    39     SVN* svn = SVN::instance();
    40     svn->client_log(path, &lb_);
     39    SVN::instance()->client_log(path, log_message_receiver,
     40                                static_cast<void*>(&lb_));
    4141    assert(date().size()==author().size());
    4242    assert(date().size()==revision().size());
    4343    assert(date().size()==message().size());
    44 
    4544  }
    4645
     
    8281  }
    8382
     83
     84  svn_error_t*
     85  SVNlog::log_message_receiver(void *baton, apr_hash_t *changed_paths,
     86                               svn_revnum_t rev, const char *author,
     87                               const char *date, const char *msg,
     88                               apr_pool_t *pool)
     89  {
     90    struct log_receiver_baton *lb=static_cast<struct log_receiver_baton*>(baton);
     91    if (date && date[0])
     92      lb->commit_dates.push_back(date);
     93    else
     94      throw SVNException("No date defined for revision: " + rev);
     95    if (author && author[0])
     96      lb->authors.push_back(author);
     97    else
     98      lb->authors.push_back("");
     99    lb->rev.push_back(rev);
     100    if (msg)
     101      lb->msg.push_back(std::string(msg));
     102    else
     103      lb->msg.push_back(std::string(""));
     104    return SVN_NO_ERROR;
     105  }
     106
    84107}} // end of namespace svndigest and namespace theplu
  • trunk/lib/SVNlog.h

    r282 r318  
    5353       stores the information for later access.
    5454    */
    55     explicit SVNlog(std::string path);
     55    explicit SVNlog(const std::string& path);
    5656
    5757    /**
     
    107107    SVNlog(const SVNlog&);
    108108
    109     log_receiver_baton lb_;
     109    /**
     110       log information is stored in the log_receiver_baton. The
     111       information is retrieved with the info_* set of member
     112       functions. The struct is filled in the info_receiver function.
    110113
     114       \see info_receiver
     115    */
     116    struct log_receiver_baton {
     117      std::vector<std::string> authors;
     118      std::vector<std::string> commit_dates;
     119      std::vector<std::string> msg;
     120      std::vector<size_t> rev;
     121    } lb_;
     122
     123    /**
     124       info_receiver is the function passed to the underlying
     125       subversion API. This function is called by the subversion API
     126       for every item matched by the conditions of the API call.
     127
     128       \see Subversion API documentation
     129    */
     130    // The return type should be svn_log_message_receiver_t but I
     131    // cannot get it to compile. The svn API has a typedef like
     132    // typedef svn_error_t*(* svn_log_message_receiver_t)(void *baton,
     133    // apr_hash_t *changed_paths, svn_revnum_t revision, const char
     134    // *author, const char *date,const char *message, apr_pool_t
     135    // *pool) for svn_log_message_receiver_t.
     136    static svn_error_t*
     137    log_message_receiver(void *baton, apr_hash_t *changed_paths,
     138                         svn_revnum_t rev, const char *author, const char *date,
     139                         const char *msg, apr_pool_t *pool);
    111140  };
    112141
Note: See TracChangeset for help on using the changeset viewer.