Changeset 318
- Timestamp:
- May 18, 2007, 11:35:45 AM (16 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/bin/svndigest.cc
r315 r318 2 2 3 3 /* 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 6 5 7 6 This file is part of svndigest, http://lev.thep.lu.se/trac/svndigest … … 90 89 } 91 90 92 // Make sure that root directory is under subversion control. 93 SVN* svn=SVN::instance(); 91 SVN* svn=NULL; 94 92 try { 95 93 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()); 98 96 } 99 97 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; 103 101 exit(-1); 104 102 } … … 127 125 } 128 126 129 // build directory tree already here ... if WC is upto date with127 // build directory tree already here ... if WC is not upto date with 130 128 // repo an exception is thrown. This avoids several costly 131 129 // statements below and will not remove a digest tree below if a … … 146 144 Stats stats(option->root()); 147 145 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);160 146 161 147 // remove target if needed … … 169 155 std::cout << "Generating output" << std::endl; 170 156 if (!option->revisions()) 171 GnuplotFE::instance()->set_dates( svnlog.date());157 GnuplotFE::instance()->set_dates(SVNlog(repo).date()); 172 158 chdir(option->targetdir().c_str()); 173 159 mkdir(tree->name()); … … 187 173 mkdir(*i); 188 174 touch(std::string(*i+"/index.html")); 189 175 } 190 176 try { 191 177 tree->print(option->verbose()); -
trunk/lib/SVN.cc
r305 r318 47 47 48 48 49 SVN::SVN( void)49 SVN::SVN(const std::string& path) 50 50 : adm_access_(NULL), allocator_(NULL), context_(NULL), pool_(NULL) 51 51 { … … 58 58 // memorywise but what about APR internal counters?) 59 59 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"); 61 61 62 62 /// create top-level pool 63 63 if (apr_allocator_create(&allocator_)) 64 throw SVNException("SVN( void): apr_allocator_create failed");64 throw SVNException("SVN(_allocator_create failed"); 65 65 apr_allocator_max_free_set(allocator_,SVN_ALLOCATOR_RECOMMENDED_MAX_FREE); 66 66 pool_ = svn_pool_create_ex(NULL, allocator_); … … 69 69 // initialize the repository access library 70 70 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"); 72 72 73 73 // Check that users .subversion exist. Should this really be done? … … 76 76 // stuff (compare with the svn binary). 77 77 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"); 79 79 80 80 // create a client context object 81 81 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"); 83 83 84 84 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"); 86 86 87 87 // set up authentication stuff … … 93 93 context_->cancel_func, 94 94 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"); 96 112 } 97 113 … … 108 124 109 125 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 110 146 svn_error_t* SVN::client_blame(const std::string& path, 111 147 svn_client_blame_receiver_t receiver, … … 117 153 start.kind=svn_opt_revision_number; 118 154 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 ); 120 157 apr_pool_t *subpool = svn_pool_create(pool_); 121 158 svn_error_t* err=svn_client_blame3(path.c_str(), &peg, &start, &head, … … 143 180 144 181 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 145 208 void SVN::client_proplist(const std::string& path, 146 209 std::map<std::string, std::string>& property) … … 148 211 svn_opt_revision_t peg, revision; 149 212 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 ); 151 215 apr_pool_t *subpool = svn_pool_create(pool_); 152 216 apr_array_header_t * properties; … … 180 244 181 245 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; 278 276 } 279 277 … … 299 297 } 300 298 301 302 299 }} // end of namespace svndigest and namespace theplu -
trunk/lib/SVN.h
r271 r318 46 46 { inline SVNException(const std::string& msg) : runtime_error(msg) {} }; 47 47 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 */ 58 69 class SVN { 59 70 public: … … 65 76 }; 66 77 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 */ 87 100 svn_error_t * client_blame(const std::string& path, 88 101 svn_client_blame_receiver_t receiver, 89 102 void *baton); 90 103 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 */ 104 119 void client_info(const std::string& path, svn_info_receiver_t receiver, 105 120 void *baton); 106 121 107 122 /** 123 \a path can be either a URL or an WC target. 124 108 125 \todo doc 109 126 */ 110 void client_log( std::string path, log_receiver_baton* lb);111 112 113 /** 114 @brief Get theproperties 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. 115 132 116 133 The retrieved properties are stored in \a properties. To check 117 134 whether \a is a binary item use SVNproperty::binary(void). 135 136 \a path can be either a URL or an WC target. 118 137 */ 119 138 void client_proplist(const std::string& path, 120 139 std::map<std::string, std::string>& properties); 121 140 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); 160 182 161 183 /// … … 168 190 169 191 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); 177 200 178 201 /// … … 218 241 // Subversion API stuff 219 242 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); 224 263 225 264 svn_wc_adm_access_t* adm_access_; … … 230 269 }; 231 270 232 // Log message receiver233 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 240 271 }} // end of namespace svndigest and namespace theplu 241 272 -
trunk/lib/SVNinfo.cc
r312 r318 32 32 33 33 SVNinfo::SVNinfo(const std::string& path) 34 : instance_(SVN::instance())35 34 { 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_)); 38 37 } 39 38 40 39 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*) 44 42 { 45 43 if (!info) … … 62 60 } 63 61 64 65 62 }} // end of namespace svndigest and namespace theplu -
trunk/lib/SVNinfo.h
r312 r318 86 86 SVNinfo(const SVNinfo&); 87 87 88 SVN* instance_;89 90 88 /// 91 89 /// svn info is stored in the info_receiver_baton_. The … … 111 109 /// @see Subversion API documentation 112 110 /// 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) 113 114 static svn_error_t * info_receiver(void *baton, const char *path, 114 115 const svn_info_t *info, apr_pool_t *pool); -
trunk/lib/SVNlog.cc
r282 r318 35 35 36 36 37 SVNlog::SVNlog( std::stringpath)37 SVNlog::SVNlog(const std::string& path) 38 38 { 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_)); 41 41 assert(date().size()==author().size()); 42 42 assert(date().size()==revision().size()); 43 43 assert(date().size()==message().size()); 44 45 44 } 46 45 … … 82 81 } 83 82 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 84 107 }} // end of namespace svndigest and namespace theplu -
trunk/lib/SVNlog.h
r282 r318 53 53 stores the information for later access. 54 54 */ 55 explicit SVNlog( std::stringpath);55 explicit SVNlog(const std::string& path); 56 56 57 57 /** … … 107 107 SVNlog(const SVNlog&); 108 108 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. 110 113 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); 111 140 }; 112 141
Note: See TracChangeset
for help on using the changeset viewer.