eigen_gen_credits.cpp
Go to the documentation of this file.
00001 #include <string>
00002 #include <sstream>
00003 #include <iostream>
00004 #include <fstream>
00005 #include <iomanip>
00006 #include <map>
00007 #include <list>
00008 
00009 using namespace std;
00010 
00011 // this function takes a line that may contain a name and/or email address,
00012 // and returns just the name, while fixing the "bad cases".
00013 std::string contributor_name(const std::string& line)
00014 {
00015   string result;
00016 
00017   // let's first take care of the case of isolated email addresses, like
00018   // "user@localhost.localdomain" entries
00019   if(line.find("markb@localhost.localdomain") != string::npos)
00020   {
00021     return "Mark Borgerding";
00022   }
00023 
00024   if(line.find("kayhman@contact.intra.cea.fr") != string::npos)
00025   {
00026     return "Guillaume Saupin";
00027   }
00028 
00029   // from there on we assume that we have a entry of the form
00030   // either:
00031   //   Bla bli Blurp
00032   // or:
00033   //   Bla bli Blurp <bblurp@email.com>
00034   
00035   size_t position_of_email_address = line.find_first_of('<');
00036   if(position_of_email_address != string::npos)
00037   {
00038     // there is an e-mail address in <...>.
00039     
00040     // Hauke once committed as "John Smith", fix that.
00041     if(line.find("hauke.heibel") != string::npos)
00042       result = "Hauke Heibel";
00043     else
00044     {
00045       // just remove the e-mail address
00046       result = line.substr(0, position_of_email_address);
00047     }
00048   }
00049   else
00050   {
00051     // there is no e-mail address in <...>.
00052     
00053     if(line.find("convert-repo") != string::npos)
00054       result = "";
00055     else
00056       result = line;
00057   }
00058 
00059   // remove trailing spaces
00060   size_t length = result.length();
00061   while(length >= 1 && result[length-1] == ' ') result.erase(--length);
00062 
00063   return result;
00064 }
00065 
00066 // parses hg churn output to generate a contributors map.
00067 map<string,int> contributors_map_from_churn_output(const char *filename)
00068 {
00069   map<string,int> contributors_map;
00070 
00071   string line;
00072   ifstream churn_out;
00073   churn_out.open(filename, ios::in);
00074   while(!getline(churn_out,line).eof())
00075   {
00076     // remove the histograms "******" that hg churn may draw at the end of some lines
00077     size_t first_star = line.find_first_of('*');
00078     if(first_star != string::npos) line.erase(first_star);
00079     
00080     // remove trailing spaces
00081     size_t length = line.length();
00082     while(length >= 1 && line[length-1] == ' ') line.erase(--length);
00083 
00084     // now the last space indicates where the number starts
00085     size_t last_space = line.find_last_of(' ');
00086     
00087     // get the number (of changesets or of modified lines for each contributor)
00088     int number;
00089     istringstream(line.substr(last_space+1)) >> number;
00090 
00091     // get the name of the contributor
00092     line.erase(last_space);    
00093     string name = contributor_name(line);
00094     
00095     map<string,int>::iterator it = contributors_map.find(name);
00096     // if new contributor, insert
00097     if(it == contributors_map.end())
00098       contributors_map.insert(pair<string,int>(name, number));
00099     // if duplicate, just add the number
00100     else
00101       it->second += number;
00102   }
00103   churn_out.close();
00104 
00105   return contributors_map;
00106 }
00107 
00108 // find the last name, i.e. the last word.
00109 // for "van den Schbling" types of last names, that's not a problem, that's actually what we want.
00110 string lastname(const string& name)
00111 {
00112   size_t last_space = name.find_last_of(' ');
00113   if(last_space >= name.length()-1) return name;
00114   else return name.substr(last_space+1);
00115 }
00116 
00117 struct contributor
00118 {
00119   string name;
00120   int changedlines;
00121   int changesets;
00122   string url;
00123   string misc;
00124   
00125   contributor() : changedlines(0), changesets(0) {}
00126   
00127   bool operator < (const contributor& other)
00128   {
00129     return lastname(name).compare(lastname(other.name)) < 0;
00130   }
00131 };
00132 
00133 void add_online_info_into_contributors_list(list<contributor>& contributors_list, const char *filename)
00134 {
00135   string line;
00136   ifstream online_info;
00137   online_info.open(filename, ios::in);
00138   while(!getline(online_info,line).eof())
00139   {
00140     string hgname, realname, url, misc;
00141     
00142     size_t last_bar = line.find_last_of('|');
00143     if(last_bar == string::npos) continue;
00144     if(last_bar < line.length())
00145       misc = line.substr(last_bar+1);
00146     line.erase(last_bar);
00147     
00148     last_bar = line.find_last_of('|');
00149     if(last_bar == string::npos) continue;
00150     if(last_bar < line.length())
00151       url = line.substr(last_bar+1);
00152     line.erase(last_bar);
00153 
00154     last_bar = line.find_last_of('|');
00155     if(last_bar == string::npos) continue;
00156     if(last_bar < line.length())
00157       realname = line.substr(last_bar+1);
00158     line.erase(last_bar);
00159 
00160     hgname = line;
00161     
00162     // remove the example line
00163     if(hgname.find("MercurialName") != string::npos) continue;
00164     
00165     list<contributor>::iterator it;
00166     for(it=contributors_list.begin(); it != contributors_list.end() && it->name != hgname; ++it)
00167     {}
00168     
00169     if(it == contributors_list.end())
00170     {
00171       contributor c;
00172       c.name = realname;
00173       c.url = url;
00174       c.misc = misc;
00175       contributors_list.push_back(c);
00176     }
00177     else
00178     {
00179       it->name = realname;
00180       it->url = url;
00181       it->misc = misc;
00182     }
00183   }
00184 }
00185 
00186 int main()
00187 {
00188   // parse the hg churn output files
00189   map<string,int> contributors_map_for_changedlines = contributors_map_from_churn_output("churn-changedlines.out");
00190   //map<string,int> contributors_map_for_changesets = contributors_map_from_churn_output("churn-changesets.out");
00191   
00192   // merge into the contributors list
00193   list<contributor> contributors_list;
00194   map<string,int>::iterator it;
00195   for(it=contributors_map_for_changedlines.begin(); it != contributors_map_for_changedlines.end(); ++it)
00196   {
00197     contributor c;
00198     c.name = it->first;
00199     c.changedlines = it->second;
00200     c.changesets = 0; //contributors_map_for_changesets.find(it->first)->second;
00201     contributors_list.push_back(c);
00202   }
00203   
00204   add_online_info_into_contributors_list(contributors_list, "online-info.out");
00205   
00206   contributors_list.sort();
00207   
00208   cout << "{| cellpadding=\"5\"\n";
00209   cout << "!\n";
00210   cout << "! Lines changed\n";
00211   cout << "!\n";
00212 
00213   list<contributor>::iterator itc;
00214   int i = 0;
00215   for(itc=contributors_list.begin(); itc != contributors_list.end(); ++itc)
00216   {
00217     if(itc->name.length() == 0) continue;
00218     if(i%2) cout << "|-\n";
00219     else cout << "|- style=\"background:#FFFFD0\"\n";
00220     if(itc->url.length())
00221       cout << "| [" << itc->url << " " << itc->name << "]\n";
00222     else
00223       cout << "| " << itc->name << "\n";
00224     if(itc->changedlines)
00225       cout << "| " << itc->changedlines << "\n";
00226     else
00227       cout << "| (no information)\n";
00228     cout << "| " << itc->misc << "\n";
00229     i++;
00230   }
00231   cout << "|}" << endl;
00232 }


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:31:06