1 /* Kernel changelog analysis
4 * This code is licenced under the GPL.
13 #define MAXDATE 0xffffffff
15 /* Matching string with people's mail information. Instead of search string in
16 * whole mail information, we can strictly demand conv_cnt() to match the
17 * string with appointed field of mail information. There are 5 fields:
18 * 1.FIRSTNAME, 2.MIDNAME, 3.LASTNAME, 4.ACCOUNT, 5.DOMAIN
19 * We can still search the keyword in whole mail info by assigning field to 0
22 ALL
, /* search a string in whole mail infor, match a substr */
23 FIRST
, /* strictly, but not casesensitively match a string with first name */
24 MID
, /* strictly, but not casesensitively match a string with mid name */
25 LAST
, /* strictly, but not casesensitively match a string with last name */
26 ACCOUNT
,/* strictly, but not casesensitively match a string with mail account */
27 DOMAIN
, /* match a sub string with mail domain */
28 NAME
/* strictly, but not casesensitively match a string with one word of name */
34 /* which field of "FIRSTNAME MIDNAME LASTNAME <ACCOUNT@DOMAIN>" should
35 * match the compared keyword.
37 enum mail_field field
;
49 /* Some people move to another company but not change mail address.
50 * To known these people's commits attribution to which company, we
51 * need to known the people attribution to where in some time range.
53 unsigned int begin
; /* attribution from when */
54 unsigned int end
; /* attribution to when */
55 char *name
; /* to fore the name */
58 #define CONV_CNT(_mail, _country) {\
60 .country = _country, \
64 #define CONV_NAME_CNT(_mail, _country) {\
66 .country = _country, \
70 #define CONV_FIRST_CNT(_mail, _country) {\
72 .country = _country, \
76 #define CONV_MID_CNT(_mail, _country) {\
78 .country = _country, \
82 #define CONV_LAST_CNT(_mail, _country) {\
84 .country = _country, \
88 #define CONV_ACCOUNT_CNT(_mail, _country) {\
90 .country = _country, \
94 #define CONV_DOMAIN_CNT(_mail, _country) {\
96 .country = _country, \
100 #define CONV_COM(_from, _to) {\
105 /* This define is used when declaring a people who didn't ever change
108 #define CONV_PER(_from, _to, _to_com) {\
117 /* This define is used when declaring a people who changed attribution
120 #define CONV_PER_TIME(_from, _to, _to_com, _begin, _end) {\
129 /* This define is used when declaring a people who didn't ever change
130 * attribution and need a force name.
132 #define CONV_PER_NAME(_from, _to, _to_com, _name) {\
141 /* This define is used when declaring a people who changed attribution
142 * sometime and need a force name.
144 #define CONV_PER_TIME_NAME(_from, _to, _to_com, _begin, _end, _name) {\
153 inline static int date_ok(unsigned int date
, struct conv_per conv_per
)
155 if (date
<= conv_per
.end
&& date
>= conv_per
.begin
)
164 static int convt_name(char **from
, char *name
)
171 ret
= mail_from_per(&mail
, *from
);
176 /* between name and mail, there is a whitespace */
179 if (init_str(&tmp
, len
+1))
184 /* Copy name to new string */
185 memcpy(tmp
, name
, strlen(name
));
186 /* Copy white space to new string */
187 tmp
= strchr(*from
, '\0');
189 /* Copy mail to new string */
190 tmp
= strchr(*from
, '\0');
191 memcpy(tmp
, mail
, strlen(mail
));
197 static int convt_per(char **from
, char *mail
)
200 int len
= 0, len_name
= 0;
202 /* Get len of author's name */
203 while ((tmp
!= NULL
) && (*tmp
!= '\0') &&
204 (*tmp
!= '\n') && (*tmp
!= '<')) {
208 len
= len_name
+ strlen(mail
);
209 if (init_str(&tmp
, len
+1))
211 /* Copy name to new string */
212 memcpy(tmp
, *from
, len_name
);
215 /* Copy mail to new string */
216 tmp
= strchr(*from
, '\0');
217 memcpy(tmp
, mail
, strlen(mail
));
221 static int convt_com(char **from
, char *to
)
224 if (init_str(from
, strlen(to
)+1))
226 memcpy(*from
, to
, strlen(to
));
230 /* Find out one's country name by his/her mail infor.
231 * @per: mail infor as formast(FIRSTNAME MIDNAME LASTNAME <ACCOUNT@DOMAIN>)
232 * @cnt: country name string
234 int conv_cnt(char *per
, char **cnt
)
237 const char *unknown
= "Unknown";
240 for (i
= 0; conv_country
[i
].mail
!= NULL
; i
++) {
241 switch (conv_country
[i
].field
) {
243 if (strcasestr(per
, conv_country
[i
].mail
))
247 if (firstname(&str
, per
))
248 if (strcasecmp(conv_country
[i
].mail
, str
) == 0)
252 if (midname(&str
, per
))
253 if (strcasecmp(conv_country
[i
].mail
, str
) == 0)
257 if (lastname(&str
, per
))
258 if (strcasecmp(conv_country
[i
].mail
, str
) == 0)
262 if (account(&str
, per
))
263 if (strcasecmp(conv_country
[i
].mail
, str
) == 0)
267 if (domain(&str
, per
))
268 if (strcasestr(str
, conv_country
[i
].mail
))
272 if (firstname(&str
, per
))
273 if (strcasecmp(conv_country
[i
].mail
, str
) == 0)
275 if (str
) {free(str
); str
= NULL
;}
276 if (midname(&str
, per
))
277 if (strcasecmp(conv_country
[i
].mail
, str
) == 0)
279 if (str
) {free(str
); str
= NULL
;}
280 if (lastname(&str
, per
))
281 if (strcasecmp(conv_country
[i
].mail
, str
) == 0)
287 if (str
) {free(str
); str
= NULL
;}
291 if (str
) {free(str
); str
= NULL
;}
292 if (conv_country
[i
].mail
!= NULL
) {
293 if (init_str(cnt
, strlen(conv_country
[i
].country
)+1))
295 memcpy(*cnt
, conv_country
[i
].country
,
296 strlen(conv_country
[i
].country
));
298 if (init_str(cnt
, strlen(unknown
)+1))
300 memcpy(*cnt
, unknown
, strlen(unknown
));
306 static void conv_mail2lower(char *per
)
308 while (*per
!= '<' && *per
!= '\0') {
313 *per
= tolower(*per
);
314 } while (*per
!= '>' && *per
!= '\0');
318 * conv_per_com: Convert mail addresses for one person and attribution an
319 * engineer to employer.
320 * @per: Engineer's name and mail address which needs convert. Convert result
322 * @com: Engineer's employer which automaticlly matched but maybe not correct.
323 * Convert result store in it.
324 * @date:This commit's date which used to tell an engineer attribution to which
325 * employer in that date.
326 * Return: 0 - successful
329 int conv_per_com(char **per
, char **com
, unsigned int date
)
334 conv_mail2lower(*per
);
335 if (mail_from_per(&mail
, *per
) < 0) {
340 /* Whether this company needs conversion.
341 * Should do this conversion before mail conversion.
343 for (i
= 0; conv_com
[i
].from
!= NULL
; i
++)
344 if (strcasestr(*com
, conv_com
[i
].from
))
346 if (conv_com
[i
].from
!= NULL
) {
347 if (convt_com(com
, conv_com
[i
].to
)) {
352 if (convt_com(com
, "Unknown")) {
358 /* Whether this mail or name needs conversion */
359 for (i
= 0; conv_per
[i
].from
!= NULL
; i
++) {
360 if ( (*mail
!= '\0') &&
361 (strncasecmp(conv_per
[i
].from
, mail
, strlen(mail
)) == 0)) {
363 if (conv_per
[i
].to
!= NULL
)
364 if (convt_per(per
, conv_per
[i
].to
)) {
369 if (conv_per
[i
].name
!= NULL
)
370 if (convt_name(per
, conv_per
[i
].name
)) {
374 /* employer convert */
375 if (conv_per
[i
].to_com
!= NULL
) {
376 if ((conv_per
[i
].begin
+ conv_per
[i
].end
== 0) ||
377 date_ok(date
, conv_per
[i
])) {
378 if (convt_com(com
, conv_per
[i
].to_com
)) {