]> git.cameronkatri.com Git - cgit.git/blobdiff - ui-shared.c
ui-blame: free read_sha1_file() buffer after use
[cgit.git] / ui-shared.c
index b1a6c46be57f18576d3c1a57008029382f2417cb..9d8f66b9fab89ad63e5bfaac22eb6956567f10dd 100644 (file)
@@ -1,6 +1,6 @@
 /* ui-shared.c: common web output functions
  *
- * Copyright (C) 2006-2014 cgit Development Team <cgit@lists.zx2c4.com>
+ * Copyright (C) 2006-2017 cgit Development Team <cgit@lists.zx2c4.com>
  *
  * Licensed under GNU General Public License v2
  *   (see COPYING for full license text)
@@ -66,10 +66,11 @@ char *cgit_hosturl(void)
 
 char *cgit_currenturl(void)
 {
-       if (!ctx.qry.url)
-               return xstrdup(cgit_rooturl());
        const char *root = cgit_rooturl();
        size_t len = strlen(root);
+
+       if (!ctx.qry.url)
+               return xstrdup(root);
        if (len && root[len - 1] == '/')
                return fmtalloc("%s%s", root, ctx.qry.url);
        return fmtalloc("%s/%s", root, ctx.qry.url);
@@ -253,7 +254,7 @@ static char *repolink(const char *title, const char *class, const char *page,
                }
                delim = "&amp;";
        }
-       if (head && strcmp(head, ctx.repo->defbranch)) {
+       if (head && ctx.repo->defbranch && strcmp(head, ctx.repo->defbranch)) {
                html(delim);
                html("h=");
                html_url_arg(head);
@@ -303,6 +304,12 @@ void cgit_plain_link(const char *name, const char *title, const char *class,
        reporevlink("plain", name, title, class, head, rev, path);
 }
 
+void cgit_blame_link(const char *name, const char *title, const char *class,
+                    const char *head, const char *rev, const char *path)
+{
+       reporevlink("blame", name, title, class, head, rev, path);
+}
+
 void cgit_log_link(const char *name, const char *title, const char *class,
                   const char *head, const char *rev, const char *path,
                   int ofs, const char *grep, const char *pattern, int showmsg,
@@ -346,16 +353,9 @@ void cgit_log_link(const char *name, const char *title, const char *class,
        html("</a>");
 }
 
-void cgit_commit_link(char *name, const char *title, const char *class,
+void cgit_commit_link(const char *name, const char *title, const char *class,
                      const char *head, const char *rev, const char *path)
 {
-       if (strlen(name) > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) {
-               name[ctx.cfg.max_msg_len] = '\0';
-               name[ctx.cfg.max_msg_len - 1] = '.';
-               name[ctx.cfg.max_msg_len - 2] = '.';
-               name[ctx.cfg.max_msg_len - 3] = '.';
-       }
-
        char *delim;
 
        delim = repolink(title, class, "commit", head, path);
@@ -386,9 +386,13 @@ void cgit_commit_link(char *name, const char *title, const char *class,
                html("follow=1");
        }
        html("'>");
-       if (name[0] != '\0')
-               html_txt(name);
-       else
+       if (name[0] != '\0') {
+               if (strlen(name) > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) {
+                       html_ntxt(name, ctx.cfg.max_msg_len - 3);
+                       html("...");
+               } else
+                       html_txt(name);
+       } else
                html_txt("(no commit message)");
        html("</a>");
 }
@@ -480,6 +484,10 @@ static void cgit_self_link(char *name, const char *title, const char *class)
                cgit_plain_link(name, title, class, ctx.qry.head,
                                ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
                                ctx.qry.path);
+       else if (!strcmp(ctx.qry.page, "blame"))
+               cgit_blame_link(name, title, class, ctx.qry.head,
+                               ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
+                               ctx.qry.path);
        else if (!strcmp(ctx.qry.page, "log"))
                cgit_log_link(name, title, class, ctx.qry.head,
                              ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
@@ -714,13 +722,14 @@ static void print_rel_vcs_link(const char *url)
 
 void cgit_print_docstart(void)
 {
+       char *host = cgit_hosturl();
+
        if (ctx.cfg.embedded) {
                if (ctx.cfg.header)
                        html_include(ctx.cfg.header);
                return;
        }
 
-       char *host = cgit_hosturl();
        html(cgit_doctype);
        html("<html lang='en'>\n");
        html("<head>\n");
@@ -984,8 +993,12 @@ void cgit_print_pageheader(void)
                cgit_log_link("log", NULL, hc("log"), ctx.qry.head,
                              NULL, ctx.qry.vpath, 0, NULL, NULL,
                              ctx.qry.showmsg, ctx.qry.follow);
-               cgit_tree_link("tree", NULL, hc("tree"), ctx.qry.head,
-                              ctx.qry.sha1, ctx.qry.vpath);
+               if (ctx.qry.page && !strcmp(ctx.qry.page, "blame"))
+                       cgit_blame_link("blame", NULL, hc("blame"), ctx.qry.head,
+                                       ctx.qry.sha1, ctx.qry.vpath);
+               else
+                       cgit_tree_link("tree", NULL, hc("tree"), ctx.qry.head,
+                                      ctx.qry.sha1, ctx.qry.vpath);
                cgit_commit_link("commit", NULL, hc("commit"),
                                 ctx.qry.head, ctx.qry.sha1, ctx.qry.vpath);
                cgit_diff_link("diff", NULL, hc("diff"), ctx.qry.head,
@@ -1014,7 +1027,7 @@ void cgit_print_pageheader(void)
                html_option("committer", "committer", ctx.qry.grep);
                html_option("range", "range", ctx.qry.grep);
                html("</select>\n");
-               html("<input class='txt' type='text' size='10' name='q' value='");
+               html("<input class='txt' type='search' size='10' name='q' value='");
                html_attr(ctx.qry.search);
                html("'/>\n");
                html("<input type='submit' value='search'/>\n");
@@ -1029,7 +1042,7 @@ void cgit_print_pageheader(void)
                html("<form method='get' action='");
                html_attr(currenturl);
                html("'>\n");
-               html("<input type='text' name='q' size='10' value='");
+               html("<input type='search' name='q' size='10' value='");
                html_attr(ctx.qry.search);
                html("'/>\n");
                html("<input type='submit' value='search'/>\n");
@@ -1037,7 +1050,7 @@ void cgit_print_pageheader(void)
                free(currenturl);
        }
        html("</td></tr></table>\n");
-       if (ctx.env.authenticated && ctx.qry.vpath) {
+       if (ctx.env.authenticated && ctx.repo && ctx.qry.vpath) {
                html("<div class='path'>");
                html("path: ");
                cgit_print_path_crumbs(ctx.qry.vpath);
@@ -1072,18 +1085,18 @@ void cgit_print_filemode(unsigned short mode)
 void cgit_compose_snapshot_prefix(struct strbuf *filename, const char *base,
                                  const char *ref)
 {
-       unsigned char sha1[20];
+       struct object_id oid;
 
        /*
         * Prettify snapshot names by stripping leading "v" or "V" if the tag
         * name starts with {v,V}[0-9] and the prettify mapping is injective,
         * i.e. each stripped tag can be inverted without ambiguities.
         */
-       if (get_sha1(fmt("refs/tags/%s", ref), sha1) == 0 &&
+       if (get_oid(fmt("refs/tags/%s", ref), &oid) == 0 &&
            (ref[0] == 'v' || ref[0] == 'V') && isdigit(ref[1]) &&
-           ((get_sha1(fmt("refs/tags/%s", ref + 1), sha1) == 0) +
-            (get_sha1(fmt("refs/tags/v%s", ref + 1), sha1) == 0) +
-            (get_sha1(fmt("refs/tags/V%s", ref + 1), sha1) == 0) == 1))
+           ((get_oid(fmt("refs/tags/%s", ref + 1), &oid) == 0) +
+            (get_oid(fmt("refs/tags/v%s", ref + 1), &oid) == 0) +
+            (get_oid(fmt("refs/tags/V%s", ref + 1), &oid) == 0) == 1))
                ref++;
 
        strbuf_addf(filename, "%s-%s", base, ref);
@@ -1109,3 +1122,34 @@ void cgit_print_snapshot_links(const char *repo, const char *head,
        }
        strbuf_release(&filename);
 }
+
+void cgit_set_title_from_path(const char *path)
+{
+       size_t path_len, path_index, path_last_end;
+       char *new_title;
+
+       if (!path)
+               return;
+
+       path_len = strlen(path);
+       new_title = xmalloc(path_len + 3 + strlen(ctx.page.title) + 1);
+       new_title[0] = '\0';
+
+       for (path_index = path_len, path_last_end = path_len; path_index-- > 0;) {
+               if (path[path_index] == '/') {
+                       if (path_index == path_len - 1) {
+                               path_last_end = path_index - 1;
+                               continue;
+                       }
+                       strncat(new_title, &path[path_index + 1], path_last_end - path_index - 1);
+                       strcat(new_title, "\\");
+                       path_last_end = path_index;
+               }
+       }
+       if (path_last_end)
+               strncat(new_title, path, path_last_end);
+
+       strcat(new_title, " - ");
+       strcat(new_title, ctx.page.title);
+       ctx.page.title = new_title;
+}