Diff options
Diffstat (limited to '')
| -rw-r--r-- | source/ui-refs.c | 144 |
1 file changed, 101 insertions, 43 deletions
diff --git a/source/ui-refs.c b/source/ui-refs.c index c8e8f3f..69a2cc1 100644 --- a/source/ui-refs.c +++ b/source/ui-refs.c @@ -3,19 +3,33 @@ * the whole of a repository's refs page. Every row is one ref beside * the commit or tag object it points at, ordered newest first, with branches * then reordered by name unless branch-sort asks for age. A section longer - * than max-ref-count is cut short and ends in a link to a dedicated heads or + * than its cap is cut short and ends in a link to a dedicated heads or * tags page, which walks the same list one offset at a time. */ #define USE_THE_REPOSITORY_VARIABLE #include "cgit.h" -#include "filter.h" #include "html.h" -#include "shared.h" +#include "parsing.h" #include "ui-refs.h" #include "ui-shared.h" +struct refinfo { + const char *refname; + struct object *object; + union { + struct taginfo *tag; + struct commitinfo *commit; + }; +}; + +struct reflist { + struct refinfo **refs; + int alloc; + int count; +}; + // The slice of a sorted ref list that one page shows, with end one past the // last row. size is what a full page holds, so it also decides whether the // list needs a pager. @@ -25,6 +39,68 @@ struct ref_page { int end; }; +static void free_refinfo(struct refinfo *ref) +{ + free((char *)ref->refname); + switch (ref->object->type) { + case OBJ_TAG: + cgit_free_taginfo(ref->tag); + break; + case OBJ_COMMIT: + cgit_free_commitinfo(ref->commit); + break; + } + free(ref); +} + +static struct refinfo *make_refinfo(const char *refname, const struct object_id *oid) +{ + struct refinfo *ref; + + ref = xcalloc(1, sizeof(struct refinfo)); + ref->refname = xstrdup(refname); + ref->object = parse_object(the_repository, oid); + if (!ref->object) { + free((char *)ref->refname); + free(ref); + return NULL; + } + switch (ref->object->type) { + case OBJ_TAG: + ref->tag = cgit_parse_tag((struct tag *)ref->object); + break; + case OBJ_COMMIT: + ref->commit = cgit_parse_commit((struct commit *)ref->object); + break; + } + return ref; +} + +static void free_reflist_inner(struct reflist *list) +{ + int i; + + for (i = 0; i < list->count; i++) + free_refinfo(list->refs[i]); + free(list->refs); +} + +/* + * Matches git's reference iteration callback, and appends each ref it is given + * to the struct reflist passed as cb_data. + */ +static int refs_cb(const struct reference *ref, void *cb_data) +{ + struct reflist *list = (struct reflist *)cb_data; + struct refinfo *info = make_refinfo(ref->name, ref->oid); + + if (info) { + ALLOC_GROW(list->refs, list->count + 1, list->alloc); + list->refs[list->count++] = info; + } + return 0; +} + /* * The tagger date and the committer date live in a union in struct refinfo and * only the member matching the object type is ever filled, so assuming a ref @@ -32,13 +108,11 @@ struct ref_page { */ static timestamp_t ref_date(struct refinfo *ref) { - if (!ref->object) - return 0; switch (ref->object->type) { case OBJ_TAG: return ref->tag ? ref->tag->tagger_date : 0; case OBJ_COMMIT: - return ref->commit ? ref->commit->committer_date : 0; + return ref->commit->committer_date; } return 0; } @@ -71,9 +145,9 @@ static void collect_branches(struct reflist *list) { list->refs = NULL; list->alloc = list->count = 0; - refs_for_each_branch_ref(get_main_ref_store(the_repository), cgit_refs_cb, list); + refs_for_each_branch_ref(get_main_ref_store(the_repository), refs_cb, list); if (ctx.repo->enable_remote_branches) - refs_for_each_remote_ref(get_main_ref_store(the_repository), cgit_refs_cb, list); + refs_for_each_remote_ref(get_main_ref_store(the_repository), refs_cb, list); } /* @@ -99,13 +173,13 @@ static void print_branch_header(int columns) htmlf("<th%s class='left' scope='col'>Age</th></tr>\n", age_colspan(columns)); } -static int print_branch(struct refinfo *ref, int columns) +static void print_branch(struct refinfo *ref, int columns) { struct commitinfo *info = ref->commit; const char *name = ref->refname; if (!info) - return 1; + return; html("<tr class='branch'><td>"); cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0, NULL, NULL, ctx.qry.showmsg, 0); html("</td><td>"); @@ -113,12 +187,7 @@ static int print_branch(struct refinfo *ref, int columns) if (ref->object->type == OBJ_COMMIT) { cgit_commit_link(info->subject, NULL, NULL, name, NULL, NULL); html("</td><td class='col-author'>"); - // A filter must not be handed a NULL argument. - cgit_open_filter( - ctx.repo->email_filter, info->author_email ? info->author_email : "", "refs" - ); - html_txt(info->author); - cgit_close_filter(ctx.repo->email_filter); + cgit_print_person(info->author, info->author_email, "refs", 0); htmlf("</td><td%s>", age_colspan(columns)); cgit_print_age(info->committer_date, info->committer_tz, -1); } else { @@ -128,14 +197,13 @@ static int print_branch(struct refinfo *ref, int columns) htmlf("</td><td class='col-author'></td><td%s>", age_colspan(columns)); } html("</td></tr>\n"); - return 0; } static void collect_tags(struct reflist *list) { list->refs = NULL; list->alloc = list->count = 0; - refs_for_each_tag_ref(get_main_ref_store(the_repository), cgit_refs_cb, list); + refs_for_each_tag_ref(get_main_ref_store(the_repository), refs_cb, list); } static void print_tag_header(int columns) @@ -149,7 +217,7 @@ static void print_tag_header(int columns) htmlf("<th%s class='left' scope='col'>Age</th></tr>\n", age_colspan(columns)); } -static int print_tag(struct refinfo *ref, int columns) +static void print_tag(struct refinfo *ref, int columns) { struct taginfo *info = NULL; const char *name = ref->refname; @@ -163,7 +231,7 @@ static int print_tag(struct refinfo *ref, int columns) obj = tag->tagged; info = ref->tag; if (!info) - return 1; + return; } html("<tr class='tag'><td>"); @@ -175,18 +243,10 @@ static int print_tag(struct refinfo *ref, int columns) cgit_object_link(obj, 0); html("</td><td class='col-author'>"); if (info) { - if (info->tagger) { - cgit_open_filter(ctx.repo->email_filter, info->tagger_email, "refs"); - html_txt(info->tagger); - cgit_close_filter(ctx.repo->email_filter); - } + if (info->tagger) + cgit_print_person(info->tagger, info->tagger_email, "refs", 0); } else if (ref->object->type == OBJ_COMMIT) { - cgit_open_filter( - ctx.repo->email_filter, ref->commit->author_email ? ref->commit->author_email : "", - "refs" - ); - html_txt(ref->commit->author); - cgit_close_filter(ctx.repo->email_filter); + cgit_print_person(ref->commit->author, ref->commit->author_email, "refs", 0); } htmlf("</td><td%s>", age_colspan(columns)); if (info) { @@ -196,8 +256,6 @@ static int print_tag(struct refinfo *ref, int columns) cgit_print_age(ref->commit->commit->date, 0, -1); } html("</td></tr>\n"); - - return 0; } static void print_refs_link(const char *path, int columns) @@ -258,9 +316,9 @@ static void print_branches_page(int pagesize) print_branch_header(REF_COLUMNS); collect_branches(&list); - cgit_qsort(list.refs, list.count, sizeof(*list.refs), cmp_date); + QSORT(list.refs, list.count, cmp_date); if (ctx.repo->branch_sort == 0) - cgit_qsort(list.refs, list.count, sizeof(*list.refs), cmp_name); + QSORT(list.refs, list.count, cmp_name); page = page_bounds(pagesize, list.count); @@ -271,7 +329,7 @@ static void print_branches_page(int pagesize) print_ref_pager(page.start, page.size, list.count, "heads"); html("</tbody>\n"); - cgit_free_reflist_inner(&list); + free_reflist_inner(&list); } static void print_tags_page(int pagesize) @@ -283,7 +341,7 @@ static void print_tags_page(int pagesize) collect_tags(&list); if (list.count == 0) return; - cgit_qsort(list.refs, list.count, sizeof(*list.refs), cmp_date); + QSORT(list.refs, list.count, cmp_date); page = page_bounds(pagesize, list.count); @@ -295,7 +353,7 @@ static void print_tags_page(int pagesize) print_ref_pager(page.start, page.size, list.count, "tags"); html("</tbody>\n"); - cgit_free_reflist_inner(&list); + free_reflist_inner(&list); } void cgit_print_branches(int maxcount, int columns) @@ -312,9 +370,9 @@ void cgit_print_branches(int maxcount, int columns) // The date sort covers the list, the name sort only the rows about to // be shown, so the section holds the newest branches rather than the // first ones by name. - cgit_qsort(list.refs, list.count, sizeof(*list.refs), cmp_date); + QSORT(list.refs, list.count, cmp_date); if (ctx.repo->branch_sort == 0) - cgit_qsort(list.refs, maxcount, sizeof(*list.refs), cmp_name); + QSORT(list.refs, maxcount, cmp_name); for (i = 0; i < maxcount; i++) print_branch(list.refs[i], columns); @@ -323,7 +381,7 @@ void cgit_print_branches(int maxcount, int columns) print_refs_link("heads", columns); html("</tbody>\n"); - cgit_free_reflist_inner(&list); + free_reflist_inner(&list); } void cgit_print_tags(int maxcount, int columns) @@ -334,7 +392,7 @@ void cgit_print_tags(int maxcount, int columns) collect_tags(&list); if (list.count == 0) return; - cgit_qsort(list.refs, list.count, sizeof(*list.refs), cmp_date); + QSORT(list.refs, list.count, cmp_date); if (maxcount <= 0 || maxcount > list.count) maxcount = list.count; print_tag_header(columns); @@ -345,7 +403,7 @@ void cgit_print_tags(int maxcount, int columns) print_refs_link("tags", columns); html("</tbody>\n"); - cgit_free_reflist_inner(&list); + free_reflist_inner(&list); } void cgit_print_refs(void) |
