Diffstat (limited to 'ui-shared.c')
| -rw-r--r-- | ui-shared.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/ui-shared.c b/ui-shared.c index 4250b89..97d1839 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -1,6 +1,12 @@ /* ui-shared.c: common web output functions * * Copyright (C) 2006-2017 cgit Development Team <cgit@lists.zx2c4.com> + * Copyright (C) 2026 Saya Andy <saya.andy@posteo.com> + * + * Modified 2026 by Saya Andy: + * Implement ci link tab + * Check repo existence + * Replace memrchr() for macOS compatibility * * Licensed under GNU General Public License v2 * (see COPYING for full license text) @@ -12,6 +18,7 @@ #include "ui-shared.h" #include "cmd.h" #include "html.h" +#include "ui-ci.h" #include "version.h" static const char cgit_doctype[] = @@ -342,6 +349,12 @@ void cgit_tag_link(const char *name, const char *title, const char *class, reporevlink("tag", name, title, class, tag, NULL, NULL); } +void cgit_ci_link(const char *name, const char *title, const char *class, + const char *head) +{ + reporevlink("ci", name, title, class, head, NULL, NULL); +} + void cgit_tree_link(const char *name, const char *title, const char *class, const char *head, const char *rev, const char *path) { @@ -832,7 +845,7 @@ void cgit_print_docstart(void) else emit_js_link(NULL, "/cgit.js"); - if (ctx.cfg.favicon) { + if (ctx.cfg.favicon && *ctx.cfg.favicon) { html("<link rel='shortcut icon' href='"); html_attr(ctx.cfg.favicon); html("'/>\n"); @@ -877,7 +890,7 @@ void cgit_print_docend(void) if (ctx.cfg.footer) html_include(ctx.cfg.footer); else { - htmlf("<div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit %s</a> " + htmlf("<div class='footer'>generated by <a href='https://sayag.it/cgitext.git/about/'>cgitext %s</a> " "(<a href='https://git-scm.com/'>git %s</a>) at ", cgit_version, git_version_string); html_txt(show_date(time(NULL), 0, cgit_date_mode(DATE_ISO8601))); html("</div>\n"); @@ -889,13 +902,18 @@ void cgit_print_docend(void) void cgit_print_error_page(int code, const char *msg, const char *fmt, ...) { va_list ap; + va_start(ap, fmt); + cgit_vprint_error_page(code, msg, fmt, ap); + va_end(ap); +} + +void cgit_vprint_error_page(int code, const char *msg, const char *fmt, va_list ap) +{ ctx.page.expires = ctx.cfg.cache_dynamic_ttl; ctx.page.status = code; ctx.page.statusmsg = msg; cgit_print_layout_start(); - va_start(ap, fmt); cgit_vprint_error(fmt, ap); - va_end(ap); cgit_print_layout_end(); } @@ -936,10 +954,9 @@ void cgit_add_clone_urls(void (*fn)(const char *)) add_clone_urls(fn, ctx.cfg.clone_prefix, ctx.repo->url); } -static int print_branch_option(const char *refname, const char *referent UNUSED, - const struct object_id *oid, int flags, void *cb_data) +static int print_branch_option(const struct reference *ref, void *cb_data) { - char *name = (char *)refname; + char *name = (char *)ref->name; html_option(name, name, ctx.qry.head); return 0; } @@ -1038,7 +1055,7 @@ static void print_header(void) cgit_index_link("index", NULL, NULL, NULL, NULL, 0, 1); html(" : "); cgit_summary_link(ctx.repo->name, NULL, NULL, NULL); - if (ctx.env.authenticated) { + if (ctx.env.authenticated && cgit_have_repository()) { html("</td><td class='form'>"); html("<form method='get'>\n"); cgit_add_hidden_formfields(0, 1, ctx.qry.page); @@ -1106,6 +1123,8 @@ void cgit_print_pageheader(void) if (ctx.repo->max_stats) cgit_stats_link("stats", NULL, hc("stats"), ctx.qry.head, ctx.qry.vpath); + if (cgit_ci_available()) + cgit_ci_link("ci", NULL, hc("ci"), ctx.qry.head); if (ctx.repo->homepage) { html("<a href='"); html_attr(ctx.repo->homepage); @@ -1154,7 +1173,7 @@ void cgit_print_pageheader(void) html("<div class='path'>"); html("path: "); cgit_print_path_crumbs(ctx.qry.vpath); - if (ctx.cfg.enable_follow_links && !strcmp(ctx.qry.page, "log")) { + if (ctx.repo->enable_follow_links && !strcmp(ctx.qry.page, "log")) { html(" ("); ctx.qry.follow = !ctx.qry.follow; cgit_self_link(ctx.qry.follow ? "follow" : "unfollow", @@ -1243,6 +1262,17 @@ void cgit_print_snapshot_links(const struct cgit_repo *repo, const char *ref, strbuf_release(&filename); } +/* Locate the last '/' within the first len bytes of path, or NULL if + * there is none. Avoids memrchr(), which is a GNU extension. + */ +static const char *find_last_slash(const char *path, size_t len) +{ + while (len > 0) + if (path[--len] == '/') + return path + len; + return NULL; +} + void cgit_set_title_from_path(const char *path) { struct strbuf sb = STRBUF_INIT; @@ -1251,7 +1281,7 @@ void cgit_set_title_from_path(const char *path) if (!path) return; - for (last_slash = path + strlen(path); (slash = memrchr(path, '/', last_slash - path)) != NULL; last_slash = slash) { + for (last_slash = path + strlen(path); (slash = find_last_slash(path, last_slash - path)) != NULL; last_slash = slash) { strbuf_add(&sb, slash + 1, last_slash - slash - 1); strbuf_addstr(&sb, " \xc2\xab "); } |