12 void usage(int status
)
15 fprintf(stderr
, "Try '%s -h' for more information.\n",
18 printf("Usage: %s INPUTFILE [options]\n",
21 -a output all the patch info of companies and their person.\n\
22 -c COMNAME output detail patch info of some company.\n\
23 -C TOPX output TOPX company or all company if TOPX is 0.\n\
24 -e Anti Email Spam, this will convert all email addresses to \
26 -I output all the patch info of companies and their most active areas.\n\
27 do not use with -L option.\n\
28 -i output all the patch info of nations and their most active areas.\n\
29 do not use with -L option.\n\
30 -l TailLimit output the longtail of contributor whose patch number are\n\
31 less than TailLimit.\n\
32 -L statistic of changed line instead of changeset number.\n\
33 do not use with -I or -i option.\n\
34 -m PERSON output some person's rank and patch count.\n\
35 -M TOPX output TOPX person or all person if TOPX is 0.\n\
36 -n do not merge different mail addresses to one person.\n\
37 do not merge different domains to one company.\n\
38 -N NATION output all the person who belong to the NATION.\n\
39 -O WHAT output other kind of statistics. Now we support [report], \
40 [review], [test], [ack] and [sof].\n\
41 -r RELEASE Used with -s option, this is the release name which will be \
43 -s SQLFILE output all sql format data to file.\n\
44 -t HTMLFILE Output all nation's contribution to HTML file.\n\
45 -w Report warning about potential duplicated developers. \n\
46 -x THMLFILE output all info as HTML file.\n\
50 Exit status is 0 if OK, 1 if trouble.\n\
52 printf("\nReport bugs to <%s>.\n", BUGREPORT
);
57 int get_info(struct list_head
**com_list_head
,
58 struct list_head
**per_list_head
,
59 const char *tmp_author_file
)
64 struct list_head
*com_list
= STRUCT_INIT(struct list_head
);
65 struct list_head
*per_list
= STRUCT_INIT(struct list_head
);
66 char *com_name
, *per_name
, *mail
, *dir_name
;
67 struct company
*current
;
69 unsigned long long int chgline
;
71 cnty_list
= STRUCT_INIT(struct list_head
);
73 if ((!com_list
) || (!per_list
) || (!cnty_list
)) {
77 INIT_LIST_HEAD(com_list
);
78 INIT_LIST_HEAD(per_list
);
79 INIT_LIST_HEAD(cnty_list
);
81 fp_t
= fopen(tmp_author_file
, "r");
83 printf("[ERROR]: Can not open changelog file %s.\n",
89 while (getline(&line
, &len
, fp_t
) != -1) {
90 char *nextline
= NULL
;
93 struct directory
*dir_current
, *dir
;
94 struct list_head
*dir_list
= STRUCT_INIT(struct list_head
);
95 struct list_head
*dir_cur_list
, *tmp_list
;
97 INIT_LIST_HEAD(dir_list
);
98 if (g_other
!= SELECT
) {
99 if (is_author(line
) != 1)
101 /* after author line is diffstat line */
102 if (getline(&nextline
, &len
, fp_t
) != -1)
103 if (is_diffstat(nextline
) != 1)
105 /* after diffstat line are dirstat lines */
106 INIT_LIST_HEAD(dir_list
);
107 while((getline(&dirline
, &len
, fp_t
) != -1)
108 && is_dirstat(dirline
)) {
109 dir_from_line(&dir_name
, dirline
);
110 list_for_each_entry(dir_current
, dir_list
, list
)
111 if (strcasestr(dir_current
->name
, dir_name
))
113 if (&dir_current
->list
== dir_list
) {
114 NODE_INIT(struct directory
, dir
);
115 NODE_SET_NAME(dir
, dir_name
);
116 list_add_tail(&(dir
->list
), dir_list
);
121 /* it's author line, we get data from it*/
122 if (per_from_line(&per_name
, line
) != 0) {
127 date
= date_from_line(line
);
133 if (mail_from_per(&mail
, per_name
) < 0) {
138 if (com_from_mail(&com_name
, mail
) < 0) {
143 if (g_other
!= SELECT
)
144 chgline
= chg_from_line(nextline
);
148 if (g_notconv
== NSELECT
)
149 conv_per_com(&per_name
, &com_name
, date
);
151 list_for_each_entry(current
, com_list
, list
)
152 if (memcmp(current
->name
, com_name
,
153 strlen(com_name
)+1) == 0)
155 if (&(current
->list
) == com_list
) {
156 if (new_com(com_list
, per_list
, com_name
, per_name
,
157 dir_list
, chgline
)) {
162 if (update_com(current
, com_list
, per_list
, per_name
,
163 dir_list
, chgline
)) {
176 list_for_each_safe(dir_cur_list
, tmp_list
, dir_list
) {
177 dir_current
= list_entry(dir_cur_list
, struct directory
, list
);
178 list_del(dir_cur_list
);
183 *com_list_head
= com_list
;
184 *per_list_head
= per_list
;
203 int main(int argc
, char **argv
)
205 struct list_head
*com_list
= NULL
, *per_list
= NULL
;
208 if (parse_command_line(argc
, argv
) != OPT_OK
)
211 if (g_help
== SELECT
)
214 if (get_info(&com_list
, &per_list
, filename_i
)) {
219 strncpy(statistics_msg
, str_patch
, sizeof(statistics_msg
));
220 if (g_line
== SELECT
)
221 strncpy(statistics_msg
, str_line
, sizeof(statistics_msg
));
223 if (g_other
== SELECT
) {
226 strncpy(statistics_msg
, str_report
,
227 sizeof(statistics_msg
));
230 strncpy(statistics_msg
, str_review
,
231 sizeof(statistics_msg
));
234 strncpy(statistics_msg
, str_test
,
235 sizeof(statistics_msg
));
238 strncpy(statistics_msg
, str_ack
,
239 sizeof(statistics_msg
));
242 strncpy(statistics_msg
, str_sof
,
243 sizeof(statistics_msg
));
250 if (g_all
== SELECT
) {
254 if (g_comtop
== SELECT
)
255 print_com_rank(com_list
, (unsigned int)p_comtop
);
258 print_com_detail(com_list
, p_com
);
260 if (g_cnty
== SELECT
)
261 print_cnty(cnty_list
, p_cnty
);
263 if (g_tail
== SELECT
)
264 print_longtail(per_list
, p_tail
);
266 if (g_nation
== SELECT
)
267 print_per_cnt(per_list
, p_nation
);
269 if (g_interest
== SELECT
)
270 print_com_int(com_list
);
272 if (g_nat_interest
== SELECT
)
273 print_cnty_int(cnty_list
, p_nat_interest
);
275 if (g_person
== SELECT
)
276 print_per_detail(per_list
, p_person
);
278 if (g_pertop
== SELECT
)
279 print_per_rank(per_list
, (unsigned int)p_pertop
);
281 if (g_html
== SELECT
) {
282 if (g_interest
== SELECT
) {
283 if (print_com_int_html(com_list
, p_html
))
286 if (print_html(com_list
, p_html
))
292 if (print_sql(com_list
, p_sql
, p_rls
))