Diffstat (limited to 'ui-stats.c')
| -rw-r--r-- | ui-stats.c | 160 |
1 files changed, 75 insertions, 85 deletions
@@ -1,17 +1,15 @@ -/* ui-stats.c: generate stats view - * - * Copyright (C) 2006-2014 cgit Development Team <cgit@lists.zx2c4.com> - * - * Licensed under GNU General Public License v2 - * (see COPYING for full license text) - */ - -#define USE_THE_REPOSITORY_VARIABLE - #include "cgit.h" -#include "ui-stats.h" #include "html.h" #include "ui-shared.h" +#include "ui-stats.h" + +#ifdef NO_C99_FORMAT +#define SZ_FMT "%u" +#else +#define SZ_FMT "%zu" +#endif + +#define MONTHS 6 struct authorstat { long total; @@ -25,21 +23,21 @@ static void trunc_week(struct tm *tm) { time_t t = timegm(tm); t -= ((tm->tm_wday + 6) % 7) * DAY_SECS; - gmtime_r(&t, tm); + gmtime_r(&t, tm); } static void dec_week(struct tm *tm) { time_t t = timegm(tm); t -= WEEK_SECS; - gmtime_r(&t, tm); + gmtime_r(&t, tm); } static void inc_week(struct tm *tm) { time_t t = timegm(tm); t += WEEK_SECS; - gmtime_r(&t, tm); + gmtime_r(&t, tm); } static char *pretty_week(struct tm *tm) @@ -85,7 +83,7 @@ static char *pretty_month(struct tm *tm) static void trunc_quarter(struct tm *tm) { trunc_month(tm); - while (tm->tm_mon % 3 != 0) + while(tm->tm_mon % 3 != 0) dec_month(tm); } @@ -129,7 +127,7 @@ static char *pretty_year(struct tm *tm) return fmt("%d", tm->tm_year + 1900); } -static const struct cgit_period periods[] = { +struct cgit_period periods[] = { {'w', "week", 12, 4, trunc_week, dec_week, inc_week, pretty_week}, {'m', "month", 12, 4, trunc_month, dec_month, inc_month, pretty_month}, {'q', "quarter", 12, 4, trunc_quarter, dec_quarter, inc_quarter, pretty_quarter}, @@ -140,7 +138,7 @@ static const struct cgit_period periods[] = { * and update the period pointer to the correcsponding struct. * If no matching code is found, return 0. */ -int cgit_find_stats_period(const char *expr, const struct cgit_period **period) +int cgit_find_stats_period(const char *expr, struct cgit_period **period) { int i; char code = '\0'; @@ -155,7 +153,7 @@ int cgit_find_stats_period(const char *expr, const struct cgit_period **period) if (periods[i].code == code || !strcmp(periods[i].name, expr)) { if (period) *period = &periods[i]; - return i + 1; + return i+1; } return 0; } @@ -169,16 +167,15 @@ const char *cgit_find_stats_periodname(int idx) } static void add_commit(struct string_list *authors, struct commit *commit, - const struct cgit_period *period) + struct cgit_period *period) { struct commitinfo *info; struct string_list_item *author, *item; struct authorstat *authorstat; struct string_list *items; char *tmp; - struct tm date; + struct tm *date; time_t t; - uintptr_t *counter; info = cgit_parse_commit(commit); tmp = xstrdup(info->author); @@ -190,15 +187,13 @@ static void add_commit(struct string_list *authors, struct commit *commit, authorstat = author->util; items = &authorstat->list; t = info->committer_date; - gmtime_r(&t, &date); - period->trunc(&date); - tmp = xstrdup(period->pretty(&date)); + date = gmtime(&t); + period->trunc(date); + tmp = xstrdup(period->pretty(date)); item = string_list_insert(items, tmp); - counter = (uintptr_t *)&item->util; - if (*counter) + if (item->util) free(tmp); - (*counter)++; - + item->util++; authorstat->total++; cgit_free_commitinfo(info); } @@ -216,34 +211,35 @@ static int cmp_total_commits(const void *a1, const void *a2) /* Walk the commit DAG and collect number of commits per author per * timeperiod into a nested string_list collection. */ -static struct string_list collect_stats(const struct cgit_period *period) +struct string_list collect_stats(struct cgit_context *ctx, + struct cgit_period *period) { struct string_list authors; struct rev_info rev; struct commit *commit; - const char *argv[] = {NULL, ctx.qry.head, NULL, NULL, NULL, NULL}; + const char *argv[] = {NULL, ctx->qry.head, NULL, NULL, NULL, NULL}; int argc = 3; time_t now; long i; - struct tm tm; + struct tm *tm; char tmp[11]; time(&now); - gmtime_r(&now, &tm); - period->trunc(&tm); + tm = gmtime(&now); + period->trunc(tm); for (i = 1; i < period->count; i++) - period->dec(&tm); - strftime(tmp, sizeof(tmp), "%Y-%m-%d", &tm); + period->dec(tm); + strftime(tmp, sizeof(tmp), "%Y-%m-%d", tm); argv[2] = xstrdup(fmt("--since=%s", tmp)); - if (ctx.qry.path) { + if (ctx->qry.path) { argv[3] = "--"; - argv[4] = ctx.qry.path; + argv[4] = ctx->qry.path; argc += 2; } - repo_init_revisions(the_repository, &rev, NULL); + init_revisions(&rev, NULL); rev.abbrev = DEFAULT_ABBREV; rev.commit_format = CMIT_FMT_DEFAULT; - rev.max_parents = 1; + rev.no_merges = 1; rev.verbose_header = 1; rev.show_root_diff = 0; setup_revisions(argc, argv, &rev, NULL); @@ -251,18 +247,15 @@ static struct string_list collect_stats(const struct cgit_period *period) memset(&authors, 0, sizeof(authors)); while ((commit = get_revision(&rev)) != NULL) { add_commit(&authors, commit, period); - release_commit_memory(the_repository->parsed_objects, commit); - commit->parents = NULL; + free(commit->buffer); + free_commit_list(commit->parents); } return authors; } -static void print_combined_authorrow(struct string_list *authors, int from, - int to, const char *name, - const char *leftclass, - const char *centerclass, - const char *rightclass, - const struct cgit_period *period) +void print_combined_authorrow(struct string_list *authors, int from, int to, + const char *name, const char *leftclass, const char *centerclass, + const char *rightclass, struct cgit_period *period) { struct string_list_item *author; struct authorstat *authorstat; @@ -270,21 +263,21 @@ static void print_combined_authorrow(struct string_list *authors, int from, struct string_list_item *date; time_t now; long i, j, total, subtotal; - struct tm tm; + struct tm *tm; char *tmp; time(&now); - gmtime_r(&now, &tm); - period->trunc(&tm); + tm = gmtime(&now); + period->trunc(tm); for (i = 1; i < period->count; i++) - period->dec(&tm); + period->dec(tm); total = 0; htmlf("<tr><td class='%s'>%s</td>", leftclass, fmt(name, to - from + 1)); for (j = 0; j < period->count; j++) { - tmp = period->pretty(&tm); - period->inc(&tm); + tmp = period->pretty(tm); + period->inc(tm); subtotal = 0; for (i = from; i <= to; i++) { author = &authors->items[i]; @@ -292,7 +285,7 @@ static void print_combined_authorrow(struct string_list *authors, int from, items = &authorstat->list; date = string_list_lookup(items, tmp); if (date) - subtotal += (uintptr_t)date->util; + subtotal += (size_t)date->util; } htmlf("<td class='%s'>%ld</td>", centerclass, subtotal); total += subtotal; @@ -300,8 +293,8 @@ static void print_combined_authorrow(struct string_list *authors, int from, htmlf("<td class='%s'>%ld</td></tr>", rightclass, total); } -static void print_authors(struct string_list *authors, int top, - const struct cgit_period *period) +void print_authors(struct string_list *authors, int top, + struct cgit_period *period) { struct string_list_item *author; struct authorstat *authorstat; @@ -309,20 +302,20 @@ static void print_authors(struct string_list *authors, int top, struct string_list_item *date; time_t now; long i, j, total; - struct tm tm; + struct tm *tm; char *tmp; time(&now); - gmtime_r(&now, &tm); - period->trunc(&tm); + tm = gmtime(&now); + period->trunc(tm); for (i = 1; i < period->count; i++) - period->dec(&tm); + period->dec(tm); html("<table class='stats'><tr><th>Author</th>"); for (j = 0; j < period->count; j++) { - tmp = period->pretty(&tm); + tmp = period->pretty(tm); htmlf("<th>%s</th>", tmp); - period->inc(&tm); + period->inc(tm); } html("<th>Total</th></tr>\n"); @@ -338,16 +331,16 @@ static void print_authors(struct string_list *authors, int top, items = &authorstat->list; total = 0; for (j = 0; j < period->count; j++) - period->dec(&tm); + period->dec(tm); for (j = 0; j < period->count; j++) { - tmp = period->pretty(&tm); - period->inc(&tm); + tmp = period->pretty(tm); + period->inc(tm); date = string_list_lookup(items, tmp); if (!date) html("<td>0</td>"); else { - htmlf("<td>%lu</td>", (uintptr_t)date->util); - total += (uintptr_t)date->util; + htmlf("<td>"SZ_FMT"</td>", (size_t)date->util); + total += (size_t)date->util; } } htmlf("<td class='sum'>%ld</td></tr>", total); @@ -366,45 +359,43 @@ static void print_authors(struct string_list *authors, int top, * for each author is another string_list which is used to calculate the * number of commits per time-interval. */ -void cgit_show_stats(void) +void cgit_show_stats(struct cgit_context *ctx) { struct string_list authors; - const struct cgit_period *period; + struct cgit_period *period; int top, i; const char *code = "w"; - if (ctx.qry.period) - code = ctx.qry.period; + if (ctx->qry.period) + code = ctx->qry.period; i = cgit_find_stats_period(code, &period); if (!i) { - cgit_print_error_page(404, "Not found", - "Unknown statistics type: %c", code[0]); + cgit_print_error(fmt("Unknown statistics type: %c", code[0])); return; } - if (i > ctx.repo->max_stats) { - cgit_print_error_page(400, "Bad request", - "Statistics type disabled: %s", period->name); + if (i > ctx->repo->max_stats) { + cgit_print_error(fmt("Statistics type disabled: %s", + period->name)); return; } - authors = collect_stats(period); + authors = collect_stats(ctx, period); qsort(authors.items, authors.nr, sizeof(struct string_list_item), cmp_total_commits); - top = ctx.qry.ofs; + top = ctx->qry.ofs; if (!top) top = 10; - cgit_print_layout_start(); html("<div class='cgit-panel'>"); html("<b>stat options</b>"); - html("<form method='get'>"); + html("<form method='get' action=''>"); cgit_add_hidden_formfields(1, 0, "stats"); html("<table><tr><td colspan='2'/></tr>"); - if (ctx.repo->max_stats > 1) { + if (ctx->repo->max_stats > 1) { html("<tr><td class='label'>Period:</td>"); html("<td class='ctrl'><select name='period' onchange='this.form.submit();'>"); - for (i = 0; i < ctx.repo->max_stats; i++) + for (i = 0; i < ctx->repo->max_stats; i++) html_option(fmt("%c", periods[i].code), periods[i].name, fmt("%c", period->code)); html("</select></td></tr>"); @@ -423,13 +414,12 @@ void cgit_show_stats(void) html("</form>"); html("</div>"); htmlf("<h2>Commits per author per %s", period->name); - if (ctx.qry.path) { + if (ctx->qry.path) { html(" (path '"); - html_txt(ctx.qry.path); + html_txt(ctx->qry.path); html("')"); } html("</h2>"); print_authors(&authors, top, period); - cgit_print_layout_end(); } |