/* ** Copyright 2012 Kamil Rytarowski < kamil AT mageia DOT org > ** ** This Source Code Form is subject to the terms of the Mozilla Public ** License, v. 2.0. If a copy of the MPL was not distributed with this ** file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pugixml.hpp" typedef std::tuple tuple; int main(int argc, char **argv) { /* ** Read text stream from stdin */ std::cin >> std::noskipws; /* Don't skip whitespaces */ /* ** Use iterators to slurp data from the standard input */ std::istream_iterator it(std::cin); std::istream_iterator end; const std::string input(it, end); pugi::xml_document doc; pugi::xml_parse_result result = doc.load_buffer(input.c_str(), input.size()); #ifndef NDEBUG std::cerr << "Load result: " << result.description() << "\n"; #endif /* ** ** ** ** author ** 2012-01-21T10:00:00.000000Z ** ** */ pugi::xml_node log = doc.child("log"); std::vector table; for (pugi::xml_node logentry: log.children()) { unsigned long revision = std::stoul(logentry.attribute("revision").value()); std::string author = logentry.child("author").text().get(); #ifndef NDEBUG std::cerr << revision << "\t" << author << "\t"; #endif std::string datetime = logentry.child("date").text().get(); boost::posix_time::time_input_facet * facet = new boost::posix_time::time_input_facet("%Y-%m-%dT%H:%M:%sZ"); /* 'Z' stands for UTC */ std::stringstream ss; ss.imbue(std::locale(std::locale(), facet)); ss << datetime; boost::posix_time::ptime date; ss >> date; #ifndef NDEBUG std::cerr << datetime << "\t" << date << "\n"; #endif table.push_back(std::make_tuple(revision, author, date)); } /* ** Statistics: ** ** 1. Overall number of the commiters ** 2. Number of commits per a commiter ** 3. */ /* ** 1. Overall number of the commiters */ unsigned int overall_commiters = 0; { std::set tmp_set; overall_commiters = (unsigned int) count_if(table.begin(), table.end(), [&tmp_set](tuple & t) { std::string author = std::get<1>(t); if (tmp_set.empty()) { tmp_set.insert(author); return true; } else { if (tmp_set.find(author) == tmp_set.end()) { tmp_set.insert(author); return true; } else return false; } } ); } #ifndef NDEBUG std::cerr << "Overall commiters: " << overall_commiters << "\n"; #endif /* ** 2. Number of commits per a commiter */ std::map commits_per_a_commiter; { for(auto t : table) { std::string author = std::get<1>(t); if (commits_per_a_commiter.empty()) commits_per_a_commiter.insert(std::pair(author, 1)); else { auto a = commits_per_a_commiter.find(author); if (a == commits_per_a_commiter.end()) commits_per_a_commiter.insert(std::pair(author, 1)); else commits_per_a_commiter.at(author) = (commits_per_a_commiter.at(author) + 1); } } } #ifndef NDEBUG std::cerr << "Commits per a commiter:\n"; for(auto c : commits_per_a_commiter) { std::cerr << "\t" << (c.first) << "\t" << (c.second) << "\n"; } #endif return EXIT_SUCCESS; }