xref: /aosp_15_r20/external/eigen/scripts/eigen_gen_credits.cpp (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Li #include <string>
2*bf2c3715SXin Li #include <sstream>
3*bf2c3715SXin Li #include <iostream>
4*bf2c3715SXin Li #include <fstream>
5*bf2c3715SXin Li #include <iomanip>
6*bf2c3715SXin Li #include <map>
7*bf2c3715SXin Li #include <list>
8*bf2c3715SXin Li 
9*bf2c3715SXin Li using namespace std;
10*bf2c3715SXin Li 
11*bf2c3715SXin Li // this function takes a line that may contain a name and/or email address,
12*bf2c3715SXin Li // and returns just the name, while fixing the "bad cases".
contributor_name(const std::string & line)13*bf2c3715SXin Li std::string contributor_name(const std::string& line)
14*bf2c3715SXin Li {
15*bf2c3715SXin Li   string result;
16*bf2c3715SXin Li 
17*bf2c3715SXin Li   // let's first take care of the case of isolated email addresses, like
18*bf2c3715SXin Li   // "[email protected]" entries
19*bf2c3715SXin Li   if(line.find("[email protected]") != string::npos)
20*bf2c3715SXin Li   {
21*bf2c3715SXin Li     return "Mark Borgerding";
22*bf2c3715SXin Li   }
23*bf2c3715SXin Li 
24*bf2c3715SXin Li   if(line.find("[email protected]") != string::npos)
25*bf2c3715SXin Li   {
26*bf2c3715SXin Li     return "Guillaume Saupin";
27*bf2c3715SXin Li   }
28*bf2c3715SXin Li 
29*bf2c3715SXin Li   // from there on we assume that we have a entry of the form
30*bf2c3715SXin Li   // either:
31*bf2c3715SXin Li   //   Bla bli Blurp
32*bf2c3715SXin Li   // or:
33*bf2c3715SXin Li   //   Bla bli Blurp <[email protected]>
34*bf2c3715SXin Li 
35*bf2c3715SXin Li   size_t position_of_email_address = line.find_first_of('<');
36*bf2c3715SXin Li   if(position_of_email_address != string::npos)
37*bf2c3715SXin Li   {
38*bf2c3715SXin Li     // there is an e-mail address in <...>.
39*bf2c3715SXin Li 
40*bf2c3715SXin Li     // Hauke once committed as "John Smith", fix that.
41*bf2c3715SXin Li     if(line.find("hauke.heibel") != string::npos)
42*bf2c3715SXin Li       result = "Hauke Heibel";
43*bf2c3715SXin Li     else
44*bf2c3715SXin Li     {
45*bf2c3715SXin Li       // just remove the e-mail address
46*bf2c3715SXin Li       result = line.substr(0, position_of_email_address);
47*bf2c3715SXin Li     }
48*bf2c3715SXin Li   }
49*bf2c3715SXin Li   else
50*bf2c3715SXin Li   {
51*bf2c3715SXin Li     // there is no e-mail address in <...>.
52*bf2c3715SXin Li 
53*bf2c3715SXin Li     if(line.find("convert-repo") != string::npos)
54*bf2c3715SXin Li       result = "";
55*bf2c3715SXin Li     else
56*bf2c3715SXin Li       result = line;
57*bf2c3715SXin Li   }
58*bf2c3715SXin Li 
59*bf2c3715SXin Li   // remove trailing spaces
60*bf2c3715SXin Li   size_t length = result.length();
61*bf2c3715SXin Li   while(length >= 1 && result[length-1] == ' ') result.erase(--length);
62*bf2c3715SXin Li 
63*bf2c3715SXin Li   return result;
64*bf2c3715SXin Li }
65*bf2c3715SXin Li 
66*bf2c3715SXin Li // parses hg churn output to generate a contributors map.
contributors_map_from_churn_output(const char * filename)67*bf2c3715SXin Li map<string,int> contributors_map_from_churn_output(const char *filename)
68*bf2c3715SXin Li {
69*bf2c3715SXin Li   map<string,int> contributors_map;
70*bf2c3715SXin Li 
71*bf2c3715SXin Li   string line;
72*bf2c3715SXin Li   ifstream churn_out;
73*bf2c3715SXin Li   churn_out.open(filename, ios::in);
74*bf2c3715SXin Li   while(!getline(churn_out,line).eof())
75*bf2c3715SXin Li   {
76*bf2c3715SXin Li     // remove the histograms "******" that hg churn may draw at the end of some lines
77*bf2c3715SXin Li     size_t first_star = line.find_first_of('*');
78*bf2c3715SXin Li     if(first_star != string::npos) line.erase(first_star);
79*bf2c3715SXin Li 
80*bf2c3715SXin Li     // remove trailing spaces
81*bf2c3715SXin Li     size_t length = line.length();
82*bf2c3715SXin Li     while(length >= 1 && line[length-1] == ' ') line.erase(--length);
83*bf2c3715SXin Li 
84*bf2c3715SXin Li     // now the last space indicates where the number starts
85*bf2c3715SXin Li     size_t last_space = line.find_last_of(' ');
86*bf2c3715SXin Li 
87*bf2c3715SXin Li     // get the number (of changesets or of modified lines for each contributor)
88*bf2c3715SXin Li     int number;
89*bf2c3715SXin Li     istringstream(line.substr(last_space+1)) >> number;
90*bf2c3715SXin Li 
91*bf2c3715SXin Li     // get the name of the contributor
92*bf2c3715SXin Li     line.erase(last_space);
93*bf2c3715SXin Li     string name = contributor_name(line);
94*bf2c3715SXin Li 
95*bf2c3715SXin Li     map<string,int>::iterator it = contributors_map.find(name);
96*bf2c3715SXin Li     // if new contributor, insert
97*bf2c3715SXin Li     if(it == contributors_map.end())
98*bf2c3715SXin Li       contributors_map.insert(pair<string,int>(name, number));
99*bf2c3715SXin Li     // if duplicate, just add the number
100*bf2c3715SXin Li     else
101*bf2c3715SXin Li       it->second += number;
102*bf2c3715SXin Li   }
103*bf2c3715SXin Li   churn_out.close();
104*bf2c3715SXin Li 
105*bf2c3715SXin Li   return contributors_map;
106*bf2c3715SXin Li }
107*bf2c3715SXin Li 
108*bf2c3715SXin Li // find the last name, i.e. the last word.
109*bf2c3715SXin Li // for "van den Schbling" types of last names, that's not a problem, that's actually what we want.
lastname(const string & name)110*bf2c3715SXin Li string lastname(const string& name)
111*bf2c3715SXin Li {
112*bf2c3715SXin Li   size_t last_space = name.find_last_of(' ');
113*bf2c3715SXin Li   if(last_space >= name.length()-1) return name;
114*bf2c3715SXin Li   else return name.substr(last_space+1);
115*bf2c3715SXin Li }
116*bf2c3715SXin Li 
117*bf2c3715SXin Li struct contributor
118*bf2c3715SXin Li {
119*bf2c3715SXin Li   string name;
120*bf2c3715SXin Li   int changedlines;
121*bf2c3715SXin Li   int changesets;
122*bf2c3715SXin Li   string url;
123*bf2c3715SXin Li   string misc;
124*bf2c3715SXin Li 
contributorcontributor125*bf2c3715SXin Li   contributor() : changedlines(0), changesets(0) {}
126*bf2c3715SXin Li 
operator <contributor127*bf2c3715SXin Li   bool operator < (const contributor& other)
128*bf2c3715SXin Li   {
129*bf2c3715SXin Li     return lastname(name).compare(lastname(other.name)) < 0;
130*bf2c3715SXin Li   }
131*bf2c3715SXin Li };
132*bf2c3715SXin Li 
add_online_info_into_contributors_list(list<contributor> & contributors_list,const char * filename)133*bf2c3715SXin Li void add_online_info_into_contributors_list(list<contributor>& contributors_list, const char *filename)
134*bf2c3715SXin Li {
135*bf2c3715SXin Li   string line;
136*bf2c3715SXin Li   ifstream online_info;
137*bf2c3715SXin Li   online_info.open(filename, ios::in);
138*bf2c3715SXin Li   while(!getline(online_info,line).eof())
139*bf2c3715SXin Li   {
140*bf2c3715SXin Li     string hgname, realname, url, misc;
141*bf2c3715SXin Li 
142*bf2c3715SXin Li     size_t last_bar = line.find_last_of('|');
143*bf2c3715SXin Li     if(last_bar == string::npos) continue;
144*bf2c3715SXin Li     if(last_bar < line.length())
145*bf2c3715SXin Li       misc = line.substr(last_bar+1);
146*bf2c3715SXin Li     line.erase(last_bar);
147*bf2c3715SXin Li 
148*bf2c3715SXin Li     last_bar = line.find_last_of('|');
149*bf2c3715SXin Li     if(last_bar == string::npos) continue;
150*bf2c3715SXin Li     if(last_bar < line.length())
151*bf2c3715SXin Li       url = line.substr(last_bar+1);
152*bf2c3715SXin Li     line.erase(last_bar);
153*bf2c3715SXin Li 
154*bf2c3715SXin Li     last_bar = line.find_last_of('|');
155*bf2c3715SXin Li     if(last_bar == string::npos) continue;
156*bf2c3715SXin Li     if(last_bar < line.length())
157*bf2c3715SXin Li       realname = line.substr(last_bar+1);
158*bf2c3715SXin Li     line.erase(last_bar);
159*bf2c3715SXin Li 
160*bf2c3715SXin Li     hgname = line;
161*bf2c3715SXin Li 
162*bf2c3715SXin Li     // remove the example line
163*bf2c3715SXin Li     if(hgname.find("MercurialName") != string::npos) continue;
164*bf2c3715SXin Li 
165*bf2c3715SXin Li     list<contributor>::iterator it;
166*bf2c3715SXin Li     for(it=contributors_list.begin(); it != contributors_list.end() && it->name != hgname; ++it)
167*bf2c3715SXin Li     {}
168*bf2c3715SXin Li 
169*bf2c3715SXin Li     if(it == contributors_list.end())
170*bf2c3715SXin Li     {
171*bf2c3715SXin Li       contributor c;
172*bf2c3715SXin Li       c.name = realname;
173*bf2c3715SXin Li       c.url = url;
174*bf2c3715SXin Li       c.misc = misc;
175*bf2c3715SXin Li       contributors_list.push_back(c);
176*bf2c3715SXin Li     }
177*bf2c3715SXin Li     else
178*bf2c3715SXin Li     {
179*bf2c3715SXin Li       it->name = realname;
180*bf2c3715SXin Li       it->url = url;
181*bf2c3715SXin Li       it->misc = misc;
182*bf2c3715SXin Li     }
183*bf2c3715SXin Li   }
184*bf2c3715SXin Li }
185*bf2c3715SXin Li 
main()186*bf2c3715SXin Li int main()
187*bf2c3715SXin Li {
188*bf2c3715SXin Li   // parse the hg churn output files
189*bf2c3715SXin Li   map<string,int> contributors_map_for_changedlines = contributors_map_from_churn_output("churn-changedlines.out");
190*bf2c3715SXin Li   //map<string,int> contributors_map_for_changesets = contributors_map_from_churn_output("churn-changesets.out");
191*bf2c3715SXin Li 
192*bf2c3715SXin Li   // merge into the contributors list
193*bf2c3715SXin Li   list<contributor> contributors_list;
194*bf2c3715SXin Li   map<string,int>::iterator it;
195*bf2c3715SXin Li   for(it=contributors_map_for_changedlines.begin(); it != contributors_map_for_changedlines.end(); ++it)
196*bf2c3715SXin Li   {
197*bf2c3715SXin Li     contributor c;
198*bf2c3715SXin Li     c.name = it->first;
199*bf2c3715SXin Li     c.changedlines = it->second;
200*bf2c3715SXin Li     c.changesets = 0; //contributors_map_for_changesets.find(it->first)->second;
201*bf2c3715SXin Li     contributors_list.push_back(c);
202*bf2c3715SXin Li   }
203*bf2c3715SXin Li 
204*bf2c3715SXin Li   add_online_info_into_contributors_list(contributors_list, "online-info.out");
205*bf2c3715SXin Li 
206*bf2c3715SXin Li   contributors_list.sort();
207*bf2c3715SXin Li 
208*bf2c3715SXin Li   cout << "{| cellpadding=\"5\"\n";
209*bf2c3715SXin Li   cout << "!\n";
210*bf2c3715SXin Li   cout << "! Lines changed\n";
211*bf2c3715SXin Li   cout << "!\n";
212*bf2c3715SXin Li 
213*bf2c3715SXin Li   list<contributor>::iterator itc;
214*bf2c3715SXin Li   int i = 0;
215*bf2c3715SXin Li   for(itc=contributors_list.begin(); itc != contributors_list.end(); ++itc)
216*bf2c3715SXin Li   {
217*bf2c3715SXin Li     if(itc->name.length() == 0) continue;
218*bf2c3715SXin Li     if(i%2) cout << "|-\n";
219*bf2c3715SXin Li     else cout << "|- style=\"background:#FFFFD0\"\n";
220*bf2c3715SXin Li     if(itc->url.length())
221*bf2c3715SXin Li       cout << "| [" << itc->url << " " << itc->name << "]\n";
222*bf2c3715SXin Li     else
223*bf2c3715SXin Li       cout << "| " << itc->name << "\n";
224*bf2c3715SXin Li     if(itc->changedlines)
225*bf2c3715SXin Li       cout << "| " << itc->changedlines << "\n";
226*bf2c3715SXin Li     else
227*bf2c3715SXin Li       cout << "| (no information)\n";
228*bf2c3715SXin Li     cout << "| " << itc->misc << "\n";
229*bf2c3715SXin Li     i++;
230*bf2c3715SXin Li   }
231*bf2c3715SXin Li   cout << "|}" << endl;
232*bf2c3715SXin Li }
233