factored the single object types out into their own sources
authorChristian Thaeter <ct@pipapo.org>
Fri, 18 Jan 2008 13:38:38 +0000 (14:38 +0100)
committerChristian Thaeter <ct@pipapo.org>
Fri, 18 Jan 2008 13:38:38 +0000 (14:38 +0100)
Makefile.am
src/branch.c
src/log.c
src/object.c
src/object.h
src/object_blob.c [new file with mode: 0644]
src/object_commit.c [new file with mode: 0644]
src/object_tag.c [new file with mode: 0644]
src/object_tree.c [new file with mode: 0644]
src/tag.c
src/tag.h

index faef0b3..dec8a54 100644 (file)
@@ -1,5 +1,5 @@
 #  Copyright (C)
-#    2007,               Christian Thaeter <ct@pipapo.org>
+#    2007, 2008                Christian Thaeter <ct@pipapo.org>
 #
 #  This program is free software; you can redistribute it and/or
 #  modify it under the terms of the GNU General Public License as
@@ -46,6 +46,10 @@ webgit_SOURCES =                             \
        $(webgit_srcdir)/summary.c              \
        $(webgit_srcdir)/repo.c                 \
        $(webgit_srcdir)/object.c               \
+       $(webgit_srcdir)/object_commit.c        \
+       $(webgit_srcdir)/object_tree.c          \
+       $(webgit_srcdir)/object_blob.c          \
+       $(webgit_srcdir)/object_tag.c           \
        $(webgit_srcdir)/branch.c               \
        $(webgit_srcdir)/tag.c                  \
        $(webgit_srcdir)/log.c
index a10301d..3a7366e 100644 (file)
@@ -91,7 +91,7 @@ show_branch_ref (const char *refname, const unsigned char *sha1, int flags, void
   struct commit* commit = lookup_commit_reference (sha1);
 
   unsigned long date =
-    webgit_commit_committer_date_parse (commit, NULL);
+    webgit_object_commit_committer_date_parse (commit, NULL);
 
   html_list_append (ctx->table,
                     html (
@@ -118,15 +118,15 @@ show_branch_ref (const char *refname, const unsigned char *sha1, int flags, void
                           html (
                                 html_tag ("td"),
                                 webgit_email_link (
-                                                   webgit_commit_committer_name_parse (commit),
-                                                   webgit_commit_committer_email_parse (commit)
+                                                   webgit_object_commit_committer_name_parse (commit),
+                                                   webgit_object_commit_committer_email_parse (commit)
                                                    )
                                 ),
                           html (
                                 html_tag ("td"),
                                 webgit_object_link (repo->query,
                                                     repo->name, strlen(repo->name),
-                                                    webgit_commit_tree_parse (commit), 40,
+                                                    webgit_object_commit_tree_parse (commit), 40,
                                                     NULL,
                                                     NULL,
                                                     html ("Tree")
index e2b4c64..e285047 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -2,7 +2,7 @@
     cehtehs git web frontend
 
   Copyright (C)
-    2007,               Christian Thaeter <ct@pipapo.org>
+    2007, 2008          Christian Thaeter <ct@pipapo.org>
 
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
@@ -108,7 +108,7 @@ webgit_log_table (struct webgit_query* query, const char* object, int count, int
       /* TODO: check if commit is one of the heads and display that */
 
       struct tm tm;
-      webgit_commit_committer_date_parse (commit, &tm);
+      webgit_object_commit_committer_date_parse (commit, &tm);
 
       char pretty_date[256];
       strftime (pretty_date, 255, "%c", &tm);
@@ -128,7 +128,7 @@ webgit_log_table (struct webgit_query* query, const char* object, int count, int
                                                              40,
                                                              NULL,
                                                              NULL,
-                                                             webgit_commit_header_parse (commit)
+                                                             webgit_object_commit_header_parse (commit)
                                                              )
                                          )
                                     ),
@@ -136,8 +136,8 @@ webgit_log_table (struct webgit_query* query, const char* object, int count, int
                                     html_tag ("tr"),
                                     html(html_tag ("td"),
                                          webgit_email_link (
-                                                            webgit_commit_author_name_parse (commit),
-                                                            webgit_commit_author_email_parse (commit)
+                                                            webgit_object_commit_author_name_parse (commit),
+                                                            webgit_object_commit_author_email_parse (commit)
                                                             )
                                          ),
                                     html (html_tag ("td"),
@@ -147,7 +147,7 @@ webgit_log_table (struct webgit_query* query, const char* object, int count, int
                                               webgit_object_link (query,
                                                                   query->repo,
                                                                   strlen (query->repo),
-                                                                  webgit_commit_tree_parse (commit),
+                                                                  webgit_object_commit_tree_parse (commit),
                                                                   40,
                                                                   NULL,
                                                                   NULL,
@@ -165,7 +165,7 @@ webgit_log_table (struct webgit_query* query, const char* object, int count, int
                                 html_tag ("tr"),
                                 html(html_tag ("td", html_attr ("colspan", "2")),
                                      html(html_tag ("pre"),
-                                          webgit_commit_message_parse (commit)
+                                          webgit_object_commit_message_parse (commit)
                                           ),
                                      html (html_tag ("hr"))
                                      )
index 3b80628..16fd635 100644 (file)
@@ -2,7 +2,7 @@
     cehtehs git web frontend
 
   Copyright (C)
-    2007,               Christian Thaeter <ct@pipapo.org>
+    2007, 2008          Christian Thaeter <ct@pipapo.org>
 
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
 */
 
 #include "object.h"
-#include "repo.h"
-#include "tag.h"
-
-#define SHA1_HEADER <openssl/sha.h>
-#include "git/tag.h"
 
 Html
 webgit_object_link (struct webgit_query* query,
@@ -51,678 +46,3 @@ webgit_object_link (struct webgit_query* query,
                text
                );
 }
-
-
-
-char*
-webgit_commit_tree_parse (struct commit* commit)
-{
-  char* tree = strstr (commit->buffer, "tree ");
-  if (!tree)
-    return NULL;
-  return tree + 5;
-}
-
-time_t
-webgit_commit_author_date_parse (struct commit* commit, struct tm* tm)
-{
-  struct tm tmp;
-  if (!tm)
-    tm = &tmp;
-
-  char* author = strstr (commit->buffer, "author ");
-  if (!author)
-    return (time_t)-1;
-
-  char* beg = strchr (author, '>');
-  if (!beg)
-    return (time_t)-1;
-
-  if (!strptime (beg + 2, "%s %Z", tm))
-    return (time_t)-1;
-
-  return mktime (tm);
-}
-
-Html
-webgit_commit_author_name_parse (struct commit* commit)
-{
-  char* author = strstr (commit->buffer, "author ");
-  if (!author)
-    return NULL;
-
-  char* end = strchr (author, '<');
-  if (!end)
-    return NULL;
-
-  return html_fmt ("%.*s", end-author-8, author+7);
-}
-
-Html
-webgit_commit_author_email_parse (struct commit* commit)
-{
-  char* author = strstr (commit->buffer, "author ");
-  if (!author)
-    return NULL;
-
-  char* beg = strchr (author, '<');
-  if (!beg)
-    return NULL;
-
-  char* end = strchr (beg, '>');
-  if (!end)
-    return NULL;
-
-
-  return html_fmt ("%.*s", end-beg-1, beg+1);
-}
-
-time_t
-webgit_commit_committer_date_parse (struct commit* commit, struct tm* tm)
-{
-  struct tm tmp;
-  if (!tm)
-    tm = &tmp;
-
-  char* committer = strstr (commit->buffer, "committer ");
-  if (!committer)
-    return (time_t)-1;
-
-  char* beg = strchr (committer, '>');
-  if (!beg)
-    return (time_t)-1;
-
-  if (!strptime (beg + 2, "%s %Z", tm))
-    return (time_t)-1;
-
-  return mktime (tm);
-}
-
-Html
-webgit_commit_committer_name_parse (struct commit* commit)
-{
-  char* committer = strstr (commit->buffer, "committer ");
-  if (!committer)
-    return NULL;
-
-  char* end = strchr (committer, '<');
-  if (!end)
-    return NULL;
-
-  return html_fmt ("%.*s", end-committer-11, committer+10);
-}
-
-Html
-webgit_commit_committer_email_parse (struct commit* commit)
-{
-  char* committer = strstr (commit->buffer, "committer ");
-  if (!committer)
-    return NULL;
-
-  char* beg = strchr (committer, '<');
-  if (!beg)
-    return NULL;
-
-  char* end = strchr (beg, '>');
-  if (!end)
-    return NULL;
-
-
-  return html_fmt ("%.*s", end-beg-1, beg+1);
-}
-
-Html
-webgit_commit_header_parse (struct commit* commit)
-{
-  char* header = strstr (commit->buffer, "\n\n");
-  if (!header)
-    return NULL;
-
-  char* end = strchr (header+2, '\n');
-  if (!end)
-    end = header + strlen (header+2);
-  else
-    --end;
-
-  return html_fmt ("%.*s", end-header, header+2);
-}
-
-Html
-webgit_commit_message_parse (struct commit* commit)
-{
-  char* header = strstr (commit->buffer, "\n\n");
-  if (!header)
-    return NULL;
-
-  header = strchr (header+2, '\n');
-  if (!header)
-    return html ();
-  else
-    ++header;
-
-  return html_fmt ("%.*s", strlen (header), header);
-}
-
-
-
-
-/*
-  Display commits
-*/
-
-static Html
-webgit_object_commit_menu_action (struct webgit_repo_info* repo, unsigned char* sha1, void* buf, unsigned long size)
-{
-  (void) repo;
-  (void) sha1;
-  (void) buf;
-  (void) size;
-
-  return html ("TODO: commit-object sidebar");
-}
-
-static Html
-webgit_object_commit_content_action (struct webgit_repo_info* repo, unsigned char* sha1, void* buf, unsigned long size)
-{
-/*
-  TODO pass commit objects instead buf/size, use parsers from above
-*/
-  (void) sha1;
-
-  Html tree = html_list ();
-  Html parents = html_list ();
-  Html author_text = html_list ();
-  Html author = html_list ();
-  Html committer = html_list ();
-
-  const char* author_beg = NULL;
-  const char* author_end = NULL;
-
-  const char* i = buf;
-  while (i && (void*)i < buf+size)
-    {
-      if (*i == '\n')
-        {
-          while (*i == '\n')
-            ++i;
-          break; /* message */
-        }
-      if (!strncmp (i, "tree ", 5))
-        {
-          html_list_append (tree,
-                            "Tree: ",
-                            webgit_object_link (repo->query,
-                                                repo->name, strlen (repo->name),
-                                                i+5, 40,
-                                                NULL,
-                                                NULL,
-                                                html_fmt ("%.40s", i+5))
-                            );
-          if ((i = strchr (i, '\n')))
-            ++i;
-          continue;
-        }
-      else if (!strncmp (i, "parent ", 7))
-        {
-          html_list_append (parents, html (
-                                           "Parent: ",
-                                           webgit_object_link (repo->query,
-                                                               repo->name, strlen (repo->name),
-                                                               i+7, 40,
-                                                               NULL,
-                                                               NULL,
-                                                               html_fmt ("%.40s", i+7))
-                                           )
-                            );
-          if ((i = strchr (i, '\n')))
-            ++i;
-          continue;
-        }
-      else if (!strncmp (i, "author ", 7))
-        {
-          char* email_beg = strchr (i, '<');
-          char* email_end = strchr (email_beg, '>');
-
-          author_beg = i+7;
-          author_end = strchr (author_beg, '\n');
-
-          Html name = html_strndup (i+7, email_beg - i - 8);
-          Html email = html_strndup (email_beg + 1, email_end - email_beg - 1);
-
-          struct tm tm;
-          strptime (email_end + 2, "%s %Z", &tm);
-          char pretty_date[256];
-          strftime (pretty_date, 255, "%c", &tm);
-
-          html_list_append (author_text, "Author");
-
-          html_list_append (author, html (
-                                          html ( author_text ), /*BUG: libcwa bug, must be wraped in html()*/
-                                          webgit_email_link (name, email),
-                                          html_strndup (pretty_date, 255)
-                                          )
-                            );
-          if ((i = strchr (i, '\n')))
-            ++i;
-          continue;
-        }
-      else if (!strncmp (i, "committer ", 10))
-        {
-          char* email_beg = strchr (i, '<');
-          char* email_end = strchr (email_beg, '>');
-
-          if (author_beg && author_end && strncmp (i + 10, author_beg, author_end - author_beg))
-            {
-              Html name = html_strndup (i+10, email_beg - i - 11);
-              Html email = html_strndup (email_beg + 1, email_end - email_beg - 1);
-
-              struct tm tm;
-              strptime (email_end + 2, "%s %Z", &tm);
-              char pretty_date[256];
-              strftime (pretty_date, 255, "%c", &tm);
-
-              html_list_append (committer, html ("Committer: ",
-                                                 webgit_email_link (name, email),
-                                                 html_strndup (pretty_date, 255)
-                                                 )
-                                );
-            }
-          else
-            html_list_append (author_text, " and Committer");
-
-          if ((i = strchr (i, '\n')))
-            ++i;
-          continue;
-        }
-      ++i;
-    }
-
-  html_list_append (author_text, ": ");
-
-  Html headline = html_list ();
-  Html message = html_list ();
-
-  if (i)
-    {
-      const char* message_beg = strchr (i, '\n');
-
-      if (message_beg)
-        {
-          html_list_append (headline,
-                            html_strndup (i, message_beg - i)
-                            );
-
-          while (*message_beg == '\n')
-            ++message_beg;
-
-          html_list_append (message,
-                            html_strndup (message_beg, SIZE_MAX)
-                            );
-        }
-      else
-        {
-          html_list_append (headline,
-                            html_strndup (i, SIZE_MAX)
-                            );
-          html_list_append (message,
-                            html_strndup (i, SIZE_MAX)
-                            );
-        }
-    }
-
-  /* TODO: diffstat */
-
-
-  return html (
-               html (html_tag ("h3"), headline),
-               html (html_tag ("div"), tree), html_nl (),
-               html (html_tag ("div"), parents), html_nl (),
-               html (html_tag ("div"), author), html_nl (),
-               html (html_tag ("div"), committer), html_nl (),
-               html (html_tag ("pre"), message)
-               );
-}
-
-Html
-webgit_object_commit_action (struct webgit_repo_info* repo, unsigned char* sha1)
-{
-  void* buf;
-  unsigned long size;
-
-  buf = read_object_with_reference (sha1, "commit", &size, NULL);
-
-  return html(
-              html(html_tag("div"), webgit_object_commit_menu_action (repo, sha1, buf, size)), html_nl (),
-              html(html_tag("div"), webgit_object_commit_content_action (repo, sha1, buf, size)), html_nl ()
-              );
-}
-
-
-/*
-  Display trees
-*/
-
-static Html
-webgit_object_tree_menu_action (struct webgit_repo_info* repo, unsigned char* sha1, struct tree *tree)
-{
-  (void) repo;
-  (void) sha1;
-  (void) tree;
-  return html ("TODO: tree-object sidebar");
-}
-
-static const char*
-pretty_mode (unsigned mode)
-{
-  if (S_ISGITLINK (mode))
-    return "m---------";
-  else if (S_ISDIR (mode & S_IFMT))
-    return "drwxr-xr-x";
-  else if (S_ISLNK (mode))
-    return "lrwxrwxrwx";
-  else if (S_ISREG (mode))
-    {
-      if (mode & S_IXUSR)
-        return "-rwxr-xr-x";
-      else
-        return "-rw-r--r--";
-    }
-  else
-    return "----------";
-}
-
-/* callback has no user-data pointer! */
-static struct webgit_query* query_in_flight = NULL;
-static Html tree_in_flight = NULL;
-
-static int
-webgit_html_tree (const unsigned char *sha1, const char *base, int baselen,
-                  const char *name, unsigned mode, int stage)
-{
-  (void) stage;
-  char pathname[PATH_MAX];
-
-  snprintf (pathname, PATH_MAX-1, "%.*s%s%s", baselen, base, baselen ? "/": "", name);
-
-  if (S_ISGITLINK(mode))
-    {
-      html_list_append (tree_in_flight, html (
-                                              html (
-                                                    html_tag ("tr"),
-                                                    html (html_tag ("td"), pretty_mode (mode)),
-                                                    html (html_tag ("td"),
-                                                          webgit_repo_link (query_in_flight,
-                                                                            query_in_flight->repo,
-                                                                            strlen (query_in_flight->repo),
-                                                                            name, strlen (pathname),
-                                                                            sha1_to_hex (sha1), 40,
-                                                                            "tree",
-                                                                            html_strndup (pathname, SIZE_MAX))
-                                                          ),
-                                                    html (html_tag ("td"), "history summary")
-                                                    ),
-                                              html_nl ()
-                                              )
-                        );
-    }
-  else if (S_ISDIR(mode))
-    {
-      html_list_append (tree_in_flight, html (
-                                              html (html_tag ("tr"),
-                                                    html (html_tag ("td"), pretty_mode (mode)),
-                                                    html (html_tag ("td"),
-                                                          webgit_object_link (query_in_flight,
-                                                                              query_in_flight->repo,
-                                                                              strlen (query_in_flight->repo),
-                                                                              sha1_to_hex (sha1), 40,
-                                                                              pathname,
-                                                                              NULL,
-                                                                              html_strndup (name, SIZE_MAX))
-                                                          ),
-                                                  html (html_tag ("td"), "history snap")
-                                                  ),
-                                             html_nl ()
-                                             )
-                        );
-    }
-  else
-    {
-      html_list_append (tree_in_flight, html (
-                                              html (html_tag ("tr"),
-                                                    html (html_tag ("td"), pretty_mode (mode)),
-                                                    html (html_tag ("td"),
-                                                          webgit_object_link (query_in_flight,
-                                                                              query_in_flight->repo,
-                                                                              strlen (query_in_flight->repo),
-                                                                              sha1_to_hex (sha1), 40,
-                                                                              pathname,
-                                                                              NULL,
-                                                                              html_strndup (name, SIZE_MAX))
-                                                          ),
-                                                    html (html_tag ("td"),
-                                                          "history ",
-                                                          webgit_object_link (query_in_flight,
-                                                                              query_in_flight->repo,
-                                                                              strlen (query_in_flight->repo),
-                                                                              sha1_to_hex (sha1), 40,
-                                                                              pathname,
-                                                                              "raw",
-                                                                              html ("raw")),
-                                                          " edit")
-                                                    ),
-                                              html_nl()
-                                              )
-                        );
-    }
-
-  return 0;
-}
-
-
-static Html
-webgit_object_tree_content_action (struct webgit_repo_info* repo, unsigned char* sha1, struct tree *tree)
-{
-  (void) sha1;
-  query_in_flight = repo->query;
-  tree_in_flight = html_list ();
-
-  read_tree_recursive (tree, repo->query->path,
-                       repo->query->path ? strlen (repo->query->path) : 0, 0, NULL, webgit_html_tree);
-
-  return html (html_tag ("table"), tree_in_flight);
-}
-
-Html
-webgit_object_tree_action (struct webgit_repo_info* repo, unsigned char* sha1)
-{
-  struct tree *tree;
-
-  tree = parse_tree_indirect (sha1);
-  if (!tree)
-    die("not a tree object");
-
-  return html(
-              html(html_tag("div"), webgit_object_tree_menu_action (repo, sha1, tree)), html_nl (),
-              html(html_tag("div"), webgit_object_tree_content_action (repo, sha1, tree)), html_nl ()
-              );
-}
-
-
-/*
-  Display blobs
-*/
-static Html
-webgit_object_blob_menu_action (struct webgit_repo_info* repo, unsigned char* sha1, void* buf, unsigned long size)
-{
-  (void) repo;
-  (void) sha1;
-  (void) buf;
-  (void) size;
-  return html ("TODO: blob-object sidebar");
-}
-
-static Html
-webgit_object_blob_content_action (struct webgit_repo_info* repo, unsigned char* sha1, void* buf, unsigned long size)
-{
-  (void) sha1;
-
-  if (!memchr(buf, 0, size>8192 ? 8192 : size))
-    {
-      return html (html_tag ("pre"), html_strndup (buf, size));
-    }
-  else
-    {
-      struct webgit_query* query = repo->query;
-      const char* mimetype = webgit_mimetype (query->path);
-
-      Html ret;
-
-      if (mimetype && !strncmp(mimetype, "image/", 6))
-        {
-          /* inline image */
-          ret = html (
-                      html_tag ("img",
-                                html_attr ("src",
-                                           html_fmt ("%s?repo=%s&action=raw&object=%s&path=%s",
-                                                     query->request->script_name,
-                                                     query->repo, query->object, query->path)
-                                           ),
-                                html_attr ("alt", query->path ? query->path : query->object)
-                                )
-                      );
-        }
-      else
-        {
-          /* link to raw data */
-          ret = html ("binary blob");
-        }
-      free ((char*)mimetype);
-
-      return ret;
-    }
-}
-
-
-Html
-webgit_object_blob_action (struct webgit_repo_info* repo, unsigned char* sha1)
-{
-  void* buf;
-  unsigned long size;
-
-  buf = read_object_with_reference (sha1, "blob", &size, NULL);
-
-  return html(
-              html(html_tag("div"), webgit_object_blob_menu_action (repo, sha1, buf, size)), html_nl (),
-              html(html_tag("div"), webgit_object_blob_content_action (repo, sha1, buf, size)), html_nl ()
-              );
-}
-
-
-/*
-  Display Tags
-*/
-static Html
-webgit_object_tag_menu_action (struct webgit_repo_info* repo, struct tag* tag, void *buffer, unsigned long size)
-{
-  (void) repo;
-  (void) tag;
-  (void) buffer;
-  (void) size;
-
-  return html ("TODO: tag-object sidebar");
-}
-
-static Html
-webgit_object_tag_content_action (struct webgit_repo_info* repo, struct tag* tag, void* buf, unsigned long size)
-{
-  /*
-    NAME HEADER
-
-    object | tree
-
-    tagger: Christian ThaeterWed Jan 16 15:55:27 2008
-
-    message
-  */
-
-  struct object* derefed = deref_tag ((struct object*)tag, NULL, 0);
-
-  char type[16];
-
-  webgit_tag_type_parse (type, buf, size);
-
-  char* sha1hex = sha1_to_hex (derefed->sha1);
-
-  struct tm tm;
-  webgit_tag_date_parse (buf, size, &tm);
-  char pretty_date[256];
-  strftime (pretty_date, 255, "%c", &tm);
-
-  Html ret;
-
-  ret= html (
-             html (
-                   html_tag ("h1"),
-                   html_strndup (tag->tag, SIZE_MAX),
-                   " - ",
-                   webgit_tag_header_parse (buf, size)
-                   ),
-             html_fmt ("Type '%s': ", type),
-             webgit_object_link (repo->query,
-                                 repo->name, strlen(repo->name),
-                                 sha1hex, 40,
-                                 NULL,
-                                 NULL,
-                                 html (sha1hex)),
-             !strcmp (type, "commit") ?
-             html (
-                   " ",
-                   webgit_object_link (repo->query,
-                                       repo->name, strlen(repo->name),
-                                       sha1hex, 40,
-                                       NULL,
-                                       "tree",
-                                       html ("Tree"))
-                   ) : html (),
-             html (html_tag ("br")),
-             "Tagger: ",
-             webgit_email_link (
-                                webgit_tag_name_parse (buf, size),
-                                webgit_tag_email_parse (buf, size)
-                                ),
-             html_strndup (pretty_date, 255),
-             html (html_tag ("br")),
-             html (html_tag ("pre"),
-                   webgit_tag_message_parse (buf, size)
-                   )
-             );
-
-
-
-
-
-  return ret;
-}
-
-Html
-webgit_object_tag_action (struct webgit_repo_info* repo, unsigned char* sha1)
-{
-  struct tag* tag = lookup_tag (sha1);
-  enum object_type type;
-  void *buffer;
-  unsigned long size;
-
-  buffer = read_sha1_file (tag->object.sha1, &type, &size);
-
-  if (!tag->object.parsed)
-    parse_tag_buffer (tag, buffer, size);
-
-  parse_tag_buffer (tag, buffer, size);
-
-  return html(
-              html(html_tag("div"), webgit_object_tag_menu_action (repo, tag, buffer, size)), html_nl (),
-              html(html_tag("div"), webgit_object_tag_content_action (repo, tag, buffer, size)), html_nl ()
-              );
-}
-
-
index 96a518d..3201794 100644 (file)
@@ -2,7 +2,7 @@
     cehtehs git web frontend
 
   Copyright (C)
-    2007,               Christian Thaeter <ct@pipapo.org>
+    2007, 2008,         Christian Thaeter <ct@pipapo.org>
 
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
@@ -39,31 +39,49 @@ webgit_object_link (struct webgit_query* query,
                    Html text);
 
 char*
-webgit_commit_tree_parse (struct commit* commit);
+webgit_object_commit_tree_parse (struct commit* commit);
 
 time_t
-webgit_commit_author_date_parse (struct commit* commit, struct tm* tm);
+webgit_object_commit_author_date_parse (struct commit* commit, struct tm* tm);
 
 Html
-webgit_commit_author_name_parse (struct commit* commit);
+webgit_object_commit_author_name_parse (struct commit* commit);
 
 Html
-webgit_commit_author_email_parse (struct commit* commit);
+webgit_object_commit_author_email_parse (struct commit* commit);
 
 time_t
-webgit_commit_committer_date_parse (struct commit* commit, struct tm* tm);
+webgit_object_commit_committer_date_parse (struct commit* commit, struct tm* tm);
 
 Html
-webgit_commit_committer_name_parse (struct commit* commit);
+webgit_object_commit_committer_name_parse (struct commit* commit);
 
 Html
-webgit_commit_committer_email_parse (struct commit* commit);
+webgit_object_commit_committer_email_parse (struct commit* commit);
 
 Html
-webgit_commit_header_parse (struct commit* commit);
+webgit_object_commit_header_parse (struct commit* commit);
 
 Html
-webgit_commit_message_parse (struct commit* commit);
+webgit_object_commit_message_parse (struct commit* commit);
+
+time_t
+webgit_object_tag_date_parse (void* buffer, unsigned long size, struct tm* tm);
+
+int
+webgit_object_tag_type_parse (char* dest, void* buffer, unsigned long size);
+
+Html
+webgit_object_tag_name_parse (void* buffer, unsigned long size);
+
+Html
+webgit_object_tag_email_parse (void* buffer, unsigned long size);
+
+Html
+webgit_object_tag_header_parse (void* buffer, unsigned long size);
+
+Html
+webgit_object_tag_message_parse (void* buffer, unsigned long size);
 
 Html
 webgit_object_commit_action (struct webgit_repo_info* repo, unsigned char* sha1);
diff --git a/src/object_blob.c b/src/object_blob.c
new file mode 100644 (file)
index 0000000..6d351cf
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+    cehtehs git web frontend
+
+  Copyright (C)
+    2007, 2008          Christian Thaeter <ct@pipapo.org>
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "object.h"
+
+/*
+  Display blobs
+*/
+static Html
+webgit_object_blob_menu_action (struct webgit_repo_info* repo, unsigned char* sha1, void* buf, unsigned long size)
+{
+  (void) repo;
+  (void) sha1;
+  (void) buf;
+  (void) size;
+  return html ("TODO: blob-object sidebar");
+}
+
+static Html
+webgit_object_blob_content_action (struct webgit_repo_info* repo, unsigned char* sha1, void* buf, unsigned long size)
+{
+  (void) sha1;
+
+  if (!memchr(buf, 0, size>8192 ? 8192 : size))
+    {
+      return html (html_tag ("pre"), html_strndup (buf, size));
+    }
+  else
+    {
+      struct webgit_query* query = repo->query;
+      const char* mimetype = webgit_mimetype (query->path);
+
+      Html ret;
+
+      if (mimetype && !strncmp(mimetype, "image/", 6))
+        {
+          /* inline image */
+          ret = html (
+                      html_tag ("img",
+                                html_attr ("src",
+                                           html_fmt ("%s?repo=%s&action=raw&object=%s&path=%s",
+                                                     query->request->script_name,
+                                                     query->repo, query->object, query->path)
+                                           ),
+                                html_attr ("alt", query->path ? query->path : query->object)
+                                )
+                      );
+        }
+      else
+        {
+          /* link to raw data */
+          ret = html ("binary blob");
+        }
+      free ((char*)mimetype);
+
+      return ret;
+    }
+}
+
+
+Html
+webgit_object_blob_action (struct webgit_repo_info* repo, unsigned char* sha1)
+{
+  void* buf;
+  unsigned long size;
+
+  buf = read_object_with_reference (sha1, "blob", &size, NULL);
+
+  return html(
+              html(html_tag("div"), webgit_object_blob_menu_action (repo, sha1, buf, size)), html_nl (),
+              html(html_tag("div"), webgit_object_blob_content_action (repo, sha1, buf, size)), html_nl ()
+              );
+}
diff --git a/src/object_commit.c b/src/object_commit.c
new file mode 100644 (file)
index 0000000..215e195
--- /dev/null
@@ -0,0 +1,364 @@
+/*
+    cehtehs git web frontend
+
+  Copyright (C)
+    2007, 2008          Christian Thaeter <ct@pipapo.org>
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "object.h"
+#include "repo.h"
+
+char*
+webgit_object_commit_tree_parse (struct commit* commit)
+{
+  char* tree = strstr (commit->buffer, "tree ");
+  if (!tree)
+    return NULL;
+  return tree + 5;
+}
+
+time_t
+webgit_object_commit_author_date_parse (struct commit* commit, struct tm* tm)
+{
+  struct tm tmp;
+  if (!tm)
+    tm = &tmp;
+
+  char* author = strstr (commit->buffer, "author ");
+  if (!author)
+    return (time_t)-1;
+
+  char* beg = strchr (author, '>');
+  if (!beg)
+    return (time_t)-1;
+
+  if (!strptime (beg + 2, "%s %Z", tm))
+    return (time_t)-1;
+
+  return mktime (tm);
+}
+
+Html
+webgit_object_commit_author_name_parse (struct commit* commit)
+{
+  char* author = strstr (commit->buffer, "author ");
+  if (!author)
+    return NULL;
+
+  char* end = strchr (author, '<');
+  if (!end)
+    return NULL;
+
+  return html_fmt ("%.*s", end-author-8, author+7);
+}
+
+Html
+webgit_object_commit_author_email_parse (struct commit* commit)
+{
+  char* author = strstr (commit->buffer, "author ");
+  if (!author)
+    return NULL;
+
+  char* beg = strchr (author, '<');
+  if (!beg)
+    return NULL;
+
+  char* end = strchr (beg, '>');
+  if (!end)
+    return NULL;
+
+
+  return html_fmt ("%.*s", end-beg-1, beg+1);
+}
+
+time_t
+webgit_object_commit_committer_date_parse (struct commit* commit, struct tm* tm)
+{
+  struct tm tmp;
+  if (!tm)
+    tm = &tmp;
+
+  char* committer = strstr (commit->buffer, "committer ");
+  if (!committer)
+    return (time_t)-1;
+
+  char* beg = strchr (committer, '>');
+  if (!beg)
+    return (time_t)-1;
+
+  if (!strptime (beg + 2, "%s %Z", tm))
+    return (time_t)-1;
+
+  return mktime (tm);
+}
+
+Html
+webgit_object_commit_committer_name_parse (struct commit* commit)
+{
+  char* committer = strstr (commit->buffer, "committer ");
+  if (!committer)
+    return NULL;
+
+  char* end = strchr (committer, '<');
+  if (!end)
+    return NULL;
+
+  return html_fmt ("%.*s", end-committer-11, committer+10);
+}
+
+Html
+webgit_object_commit_committer_email_parse (struct commit* commit)
+{
+  char* committer = strstr (commit->buffer, "committer ");
+  if (!committer)
+    return NULL;
+
+  char* beg = strchr (committer, '<');
+  if (!beg)
+    return NULL;
+
+  char* end = strchr (beg, '>');
+  if (!end)
+    return NULL;
+
+
+  return html_fmt ("%.*s", end-beg-1, beg+1);
+}
+
+Html
+webgit_object_commit_header_parse (struct commit* commit)
+{
+  char* header = strstr (commit->buffer, "\n\n");
+  if (!header)
+    return NULL;
+
+  char* end = strchr (header+2, '\n');
+  if (!end)
+    end = header + strlen (header+2);
+  else
+    --end;
+
+  return html_fmt ("%.*s", end-header, header+2);
+}
+
+Html
+webgit_object_commit_message_parse (struct commit* commit)
+{
+  char* header = strstr (commit->buffer, "\n\n");
+  if (!header)
+    return NULL;
+
+  header = strchr (header+2, '\n');
+  if (!header)
+    return html ();
+  else
+    ++header;
+
+  return html_fmt ("%.*s", strlen (header), header);
+}
+
+
+/*
+  Display commits
+*/
+
+static Html
+webgit_object_commit_menu_action (struct webgit_repo_info* repo, unsigned char* sha1, void* buf, unsigned long size)
+{
+  (void) repo;
+  (void) sha1;
+  (void) buf;
+  (void) size;
+
+  return html ("TODO: commit-object sidebar");
+}
+
+static Html
+webgit_object_commit_content_action (struct webgit_repo_info* repo, unsigned char* sha1, void* buf, unsigned long size)
+{
+/*
+  TODO pass commit objects instead buf/size, use parsers from above
+*/
+  (void) sha1;
+
+  Html tree = html_list ();
+  Html parents = html_list ();
+  Html author_text = html_list ();
+  Html author = html_list ();
+  Html committer = html_list ();
+
+  const char* author_beg = NULL;
+  const char* author_end = NULL;
+
+  const char* i = buf;
+  while (i && (void*)i < buf+size)
+    {
+      if (*i == '\n')
+        {
+          while (*i == '\n')
+            ++i;
+          break; /* message */
+        }
+      if (!strncmp (i, "tree ", 5))
+        {
+          html_list_append (tree,
+                            "Tree: ",
+                            webgit_object_link (repo->query,
+                                                repo->name, strlen (repo->name),
+                                                i+5, 40,
+                                                NULL,
+                                                NULL,
+                                                html_fmt ("%.40s", i+5))
+                            );
+          if ((i = strchr (i, '\n')))
+            ++i;
+          continue;
+        }
+      else if (!strncmp (i, "parent ", 7))
+        {
+          html_list_append (parents, html (
+                                           "Parent: ",
+                                           webgit_object_link (repo->query,
+                                                               repo->name, strlen (repo->name),
+                                                               i+7, 40,
+                                                               NULL,
+                                                               NULL,
+                                                               html_fmt ("%.40s", i+7))
+                                           )
+                            );
+          if ((i = strchr (i, '\n')))
+            ++i;
+          continue;
+        }
+      else if (!strncmp (i, "author ", 7))
+        {
+          char* email_beg = strchr (i, '<');
+          char* email_end = strchr (email_beg, '>');
+
+          author_beg = i+7;
+          author_end = strchr (author_beg, '\n');
+
+          Html name = html_strndup (i+7, email_beg - i - 8);
+          Html email = html_strndup (email_beg + 1, email_end - email_beg - 1);
+
+          struct tm tm;
+          strptime (email_end + 2, "%s %Z", &tm);
+          char pretty_date[256];
+          strftime (pretty_date, 255, "%c", &tm);
+
+          html_list_append (author_text, "Author");
+
+          html_list_append (author, html (
+                                          html ( author_text ), /*BUG: libcwa bug, must be wraped in html()*/
+                                          webgit_email_link (name, email),
+                                          html_strndup (pretty_date, 255)
+                                          )
+                            );
+          if ((i = strchr (i, '\n')))
+            ++i;
+          continue;
+        }
+      else if (!strncmp (i, "committer ", 10))
+        {
+          char* email_beg = strchr (i, '<');
+          char* email_end = strchr (email_beg, '>');
+
+          if (author_beg && author_end && strncmp (i + 10, author_beg, author_end - author_beg))
+            {
+              Html name = html_strndup (i+10, email_beg - i - 11);
+              Html email = html_strndup (email_beg + 1, email_end - email_beg - 1);
+
+              struct tm tm;
+              strptime (email_end + 2, "%s %Z", &tm);
+              char pretty_date[256];
+              strftime (pretty_date, 255, "%c", &tm);
+
+              html_list_append (committer, html ("Committer: ",
+                                                 webgit_email_link (name, email),
+                                                 html_strndup (pretty_date, 255)
+                                                 )
+                                );
+            }
+          else
+            html_list_append (author_text, " and Committer");
+
+          if ((i = strchr (i, '\n')))
+            ++i;
+          continue;
+        }
+      ++i;
+    }
+
+  html_list_append (author_text, ": ");
+
+  Html headline = html_list ();
+  Html message = html_list ();
+
+  if (i)
+    {
+      const char* message_beg = strchr (i, '\n');
+
+      if (message_beg)
+        {
+          html_list_append (headline,
+                            html_strndup (i, message_beg - i)
+                            );
+
+          while (*message_beg == '\n')
+            ++message_beg;
+
+          html_list_append (message,
+                            html_strndup (message_beg, SIZE_MAX)
+                            );
+        }
+      else
+        {
+          html_list_append (headline,
+                            html_strndup (i, SIZE_MAX)
+                            );
+          html_list_append (message,
+                            html_strndup (i, SIZE_MAX)
+                            );
+        }
+    }
+
+  /* TODO: diffstat */
+
+
+  return html (
+               html (html_tag ("h3"), headline),
+               html (html_tag ("div"), tree), html_nl (),
+               html (html_tag ("div"), parents), html_nl (),
+               html (html_tag ("div"), author), html_nl (),
+               html (html_tag ("div"), committer), html_nl (),
+               html (html_tag ("pre"), message)
+               );
+}
+
+Html
+webgit_object_commit_action (struct webgit_repo_info* repo, unsigned char* sha1)
+{
+  void* buf;
+  unsigned long size;
+
+  buf = read_object_with_reference (sha1, "commit", &size, NULL);
+
+  return html(
+              html(html_tag("div"), webgit_object_commit_menu_action (repo, sha1, buf, size)), html_nl (),
+              html(html_tag("div"), webgit_object_commit_content_action (repo, sha1, buf, size)), html_nl ()
+              );
+}
diff --git a/src/object_tag.c b/src/object_tag.c
new file mode 100644 (file)
index 0000000..2e0c5c1
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+    cehtehs git web frontend
+
+  Copyright (C)
+    2007, 2008          Christian Thaeter <ct@pipapo.org>
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "object.h"
+
+#define SHA1_HEADER <openssl/sha.h>
+#include "git/tag.h"
+
+
+time_t
+webgit_object_tag_date_parse (void* buffer, unsigned long size, struct tm* tm)
+{
+  struct tm tmp;
+  if (!tm)
+    tm = &tmp;
+
+  char* tagger = cwa_memmem (buffer, size, "tagger ", 7);
+  if (!tagger)
+    return (time_t)-1;
+
+  char* beg = strchr (tagger, '>');
+  if (!beg)
+    return (time_t)-1;
+
+  if (!strptime (beg + 2, "%s %Z", tm))
+    return (time_t)-1;
+
+  return mktime (tm);
+}
+
+
+int
+webgit_object_tag_type_parse (char* dest, void* buffer, unsigned long size)
+{
+  char* type = cwa_memmem (buffer, size, "type ", 5);
+  if (!type)
+    return -1;
+
+  char* end = strchr (type, '\n');
+  if (!end)
+    return -1;
+
+  return snprintf (dest, 16, "%.*s", end-type-5, type+5);
+}
+
+
+Html
+webgit_object_tag_name_parse (void* buffer, unsigned long size)
+{
+  char* tagger = cwa_memmem (buffer, size, "tagger ", 7);
+  if (!tagger)
+    return NULL;
+
+  char* end = strchr (tagger, '<');
+  if (!end)
+    return NULL;
+
+  return html_fmt ("%.*s", end-tagger-8, tagger+7);
+}
+
+Html
+webgit_object_tag_email_parse (void* buffer, unsigned long size)
+{
+  char* tagger = cwa_memmem (buffer, size, "tagger ", 7);
+  if (!tagger)
+    return NULL;
+
+  char* beg = strchr (tagger, '<');
+  if (!beg)
+    return NULL;
+
+  char* end = strchr (beg, '>');
+  if (!end)
+    return NULL;
+
+
+  return html_fmt ("%.*s", end-beg-1, beg+1);
+}
+
+
+Html
+webgit_object_tag_header_parse (void* buffer, unsigned long size)
+{
+  char* header = cwa_memmem (buffer, size, "\n\n", 2);
+  if (!header)
+    return NULL;
+
+  char* end = strchr (header+2, '\n');
+  if (!end)
+    end = header + strlen (header+2);
+  else
+    --end;
+
+  return html_fmt ("%.*s", end-header, header+2);
+}
+
+
+Html
+webgit_object_tag_message_parse (void* buffer, unsigned long size)
+{
+  char* header = cwa_memmem (buffer, size, "\n\n", 2);
+  if (!header)
+    return NULL;
+
+  char* beg = strchr (header+2, '\n');
+  if (!beg)
+    return html ();
+
+  return html_strndup (beg+1, size - (beg-header) - 1);
+}
+
+
+
+
+
+/*
+  Display Tags
+*/
+static Html
+webgit_object_tag_menu_action (struct webgit_repo_info* repo, struct tag* tag, void *buffer, unsigned long size)
+{
+  (void) repo;
+  (void) tag;
+  (void) buffer;
+  (void) size;
+
+  return html ("TODO: tag-object sidebar");
+}
+
+static Html
+webgit_object_tag_content_action (struct webgit_repo_info* repo, struct tag* tag, void* buf, unsigned long size)
+{
+  struct object* derefed = deref_tag ((struct object*)tag, NULL, 0);
+
+  char type[16];
+
+  webgit_object_tag_type_parse (type, buf, size);
+
+  char* sha1hex = sha1_to_hex (derefed->sha1);
+
+  struct tm tm;
+  webgit_object_tag_date_parse (buf, size, &tm);
+  char pretty_date[256];
+  strftime (pretty_date, 255, "%c", &tm);
+
+  Html ret;
+
+  ret= html (
+             html (
+                   html_tag ("h1"),
+                   html_strndup (tag->tag, SIZE_MAX),
+                   " - ",
+                   webgit_object_tag_header_parse (buf, size)
+                   ),
+             html_fmt ("Type '%s': ", type),
+             webgit_object_link (repo->query,
+                                 repo->name, strlen(repo->name),
+                                 sha1hex, 40,
+                                 NULL,
+                                 NULL,
+                                 html (sha1hex)),
+             !strcmp (type, "commit") ?
+             html (
+                   " ",
+                   webgit_object_link (repo->query,
+                                       repo->name, strlen(repo->name),
+                                       sha1hex, 40,
+                                       NULL,
+                                       "tree",
+                                       html ("Tree"))
+                   ) : html (),
+             html (html_tag ("br")),
+             "Tagger: ",
+             webgit_email_link (
+                                webgit_object_tag_name_parse (buf, size),
+                                webgit_object_tag_email_parse (buf, size)
+                                ),
+             html_strndup (pretty_date, 255),
+             html (html_tag ("br")),
+             html (html_tag ("pre"),
+                   webgit_object_tag_message_parse (buf, size)
+                   )
+             );
+
+  return ret;
+}
+
+Html
+webgit_object_tag_action (struct webgit_repo_info* repo, unsigned char* sha1)
+{
+  struct tag* tag = lookup_tag (sha1);
+  enum object_type type;
+  void *buffer;
+  unsigned long size;
+
+  buffer = read_sha1_file (tag->object.sha1, &type, &size);
+
+  if (!tag->object.parsed)
+    parse_tag_buffer (tag, buffer, size);
+
+  parse_tag_buffer (tag, buffer, size);
+
+  return html(
+              html(html_tag("div"), webgit_object_tag_menu_action (repo, tag, buffer, size)), html_nl (),
+              html(html_tag("div"), webgit_object_tag_content_action (repo, tag, buffer, size)), html_nl ()
+              );
+}
+
+
diff --git a/src/object_tree.c b/src/object_tree.c
new file mode 100644 (file)
index 0000000..808daba
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+    cehtehs git web frontend
+
+  Copyright (C)
+    2007, 2008          Christian Thaeter <ct@pipapo.org>
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "object.h"
+
+/*
+  Display trees
+*/
+
+static Html
+webgit_object_tree_menu_action (struct webgit_repo_info* repo, unsigned char* sha1, struct tree *tree)
+{
+  (void) repo;
+  (void) sha1;
+  (void) tree;
+  return html ("TODO: tree-object sidebar");
+}
+
+static const char*
+pretty_mode (unsigned mode)
+{
+  if (S_ISGITLINK (mode))
+    return "m---------";
+  else if (S_ISDIR (mode & S_IFMT))
+    return "drwxr-xr-x";
+  else if (S_ISLNK (mode))
+    return "lrwxrwxrwx";
+  else if (S_ISREG (mode))
+    {
+      if (mode & S_IXUSR)
+        return "-rwxr-xr-x";
+      else
+        return "-rw-r--r--";
+    }
+  else
+    return "----------";
+}
+
+/* callback has no user-data pointer! */
+static struct webgit_query* query_in_flight = NULL;
+static Html tree_in_flight = NULL;
+
+static int
+webgit_html_tree (const unsigned char *sha1, const char *base, int baselen,
+                  const char *name, unsigned mode, int stage)
+{
+  (void) stage;
+  char pathname[PATH_MAX];
+
+  snprintf (pathname, PATH_MAX-1, "%.*s%s%s", baselen, base, baselen ? "/": "", name);
+
+  if (S_ISGITLINK(mode))
+    {
+      html_list_append (tree_in_flight, html (
+                                              html (
+                                                    html_tag ("tr"),
+                                                    html (html_tag ("td"), pretty_mode (mode)),
+                                                    html (html_tag ("td"),
+                                                          webgit_repo_link (query_in_flight,
+                                                                            query_in_flight->repo,
+                                                                            strlen (query_in_flight->repo),
+                                                                            name, strlen (pathname),
+                                                                            sha1_to_hex (sha1), 40,
+                                                                            "tree",
+                                                                            html_strndup (pathname, SIZE_MAX))
+                                                          ),
+                                                    html (html_tag ("td"), "history summary")
+                                                    ),
+                                              html_nl ()
+                                              )
+                        );
+    }
+  else if (S_ISDIR(mode))
+    {
+      html_list_append (tree_in_flight, html (
+                                              html (html_tag ("tr"),
+                                                    html (html_tag ("td"), pretty_mode (mode)),
+                                                    html (html_tag ("td"),
+                                                          webgit_object_link (query_in_flight,
+                                                                              query_in_flight->repo,
+                                                                              strlen (query_in_flight->repo),
+                                                                              sha1_to_hex (sha1), 40,
+                                                                              pathname,
+                                                                              NULL,
+                                                                              html_strndup (name, SIZE_MAX))
+                                                          ),
+                                                  html (html_tag ("td"), "history snap")
+                                                  ),
+                                             html_nl ()
+                                             )
+                        );
+    }
+  else
+    {
+      html_list_append (tree_in_flight, html (
+                                              html (html_tag ("tr"),
+                                                    html (html_tag ("td"), pretty_mode (mode)),
+                                                    html (html_tag ("td"),
+                                                          webgit_object_link (query_in_flight,
+                                                                              query_in_flight->repo,
+                                                                              strlen (query_in_flight->repo),
+                                                                              sha1_to_hex (sha1), 40,
+                                                                              pathname,
+                                                                              NULL,
+                                                                              html_strndup (name, SIZE_MAX))
+                                                          ),
+                                                    html (html_tag ("td"),
+                                                          "history ",
+                                                          webgit_object_link (query_in_flight,
+                                                                              query_in_flight->repo,
+                                                                              strlen (query_in_flight->repo),
+                                                                              sha1_to_hex (sha1), 40,
+                                                                              pathname,
+                                                                              "raw",
+                                                                              html ("raw")),
+                                                          " edit")
+                                                    ),
+                                              html_nl()
+                                              )
+                        );
+    }
+
+  return 0;
+}
+
+
+static Html
+webgit_object_tree_content_action (struct webgit_repo_info* repo, unsigned char* sha1, struct tree *tree)
+{
+  (void) sha1;
+  query_in_flight = repo->query;
+  tree_in_flight = html_list ();
+
+  read_tree_recursive (tree, repo->query->path,
+                       repo->query->path ? strlen (repo->query->path) : 0, 0, NULL, webgit_html_tree);
+
+  return html (html_tag ("table"), tree_in_flight);
+}
+
+Html
+webgit_object_tree_action (struct webgit_repo_info* repo, unsigned char* sha1)
+{
+  struct tree *tree;
+
+  tree = parse_tree_indirect (sha1);
+  if (!tree)
+    die("not a tree object");
+
+  return html(
+              html(html_tag("div"), webgit_object_tree_menu_action (repo, sha1, tree)), html_nl (),
+              html(html_tag("div"), webgit_object_tree_content_action (repo, sha1, tree)), html_nl ()
+              );
+}
+
index b841847..107f527 100644 (file)
--- a/src/tag.c
+++ b/src/tag.c
 
 #include <time.h>
 
-time_t
-webgit_tag_date_parse (void* buffer, unsigned long size, struct tm* tm)
-{
-  struct tm tmp;
-  if (!tm)
-    tm = &tmp;
-
-  char* tagger = cwa_memmem (buffer, size, "tagger ", 7);
-  if (!tagger)
-    return (time_t)-1;
-
-  char* beg = strchr (tagger, '>');
-  if (!beg)
-    return (time_t)-1;
-
-  if (!strptime (beg + 2, "%s %Z", tm))
-    return (time_t)-1;
-
-  return mktime (tm);
-}
-
-
-int
-webgit_tag_type_parse (char* dest, void* buffer, unsigned long size)
-{
-  char* type = cwa_memmem (buffer, size, "type ", 5);
-  if (!type)
-    return -1;
-
-  char* end = strchr (type, '\n');
-  if (!end)
-    return -1;
-
-  return snprintf (dest, 16, "%.*s", end-type-5, type+5);
-}
-
-
-Html
-webgit_tag_name_parse (void* buffer, unsigned long size)
-{
-  char* tagger = cwa_memmem (buffer, size, "tagger ", 7);
-  if (!tagger)
-    return NULL;
-
-  char* end = strchr (tagger, '<');
-  if (!end)
-    return NULL;
-
-  return html_fmt ("%.*s", end-tagger-8, tagger+7);
-}
-
-Html
-webgit_tag_email_parse (void* buffer, unsigned long size)
-{
-  char* tagger = cwa_memmem (buffer, size, "tagger ", 7);
-  if (!tagger)
-    return NULL;
-
-  char* beg = strchr (tagger, '<');
-  if (!beg)
-    return NULL;
-
-  char* end = strchr (beg, '>');
-  if (!end)
-    return NULL;
-
-
-  return html_fmt ("%.*s", end-beg-1, beg+1);
-}
-
-
-Html
-webgit_tag_header_parse (void* buffer, unsigned long size)
-{
-  char* header = cwa_memmem (buffer, size, "\n\n", 2);
-  if (!header)
-    return NULL;
-
-  char* end = strchr (header+2, '\n');
-  if (!end)
-    end = header + strlen (header+2);
-  else
-    --end;
-
-  return html_fmt ("%.*s", end-header, header+2);
-}
-
-
-Html
-webgit_tag_message_parse (void* buffer, unsigned long size)
-{
-  char* header = cwa_memmem (buffer, size, "\n\n", 2);
-  if (!header)
-    return NULL;
-
-  char* beg = strchr (header+2, '\n');
-  if (!beg)
-    return html ();
-
-  return html_strndup (beg+1, size - (beg-header) - 1);
-}
-
-
 struct tag_context
 {
   struct webgit_repo_info* repo;
@@ -169,6 +66,7 @@ webgit_tag_link (struct webgit_repo_info* repo, const char* tag, int count, Html
 static int
 show_tag_ref (const char *refname, const unsigned char *sha1, int flags, void *data)
 {
+  (void) flags;
   struct tag_context* ctx = (struct tag_context*) data;
   struct webgit_repo_info* repo = ctx->repo;
 
@@ -204,7 +102,7 @@ show_tag_ref (const char *refname, const unsigned char *sha1, int flags, void *d
     parse_tag_buffer (tag, buffer, size);
 
   unsigned long date =
-    webgit_tag_date_parse (buffer, size, NULL);
+    webgit_object_tag_date_parse (buffer, size, NULL);
 
   char tagref[256];
   snprintf (tagref, 256, "refs/tags/%s", refname);
@@ -235,13 +133,13 @@ show_tag_ref (const char *refname, const unsigned char *sha1, int flags, void *d
                           html (
                                 html_tag ("td"),
                                 webgit_email_link (
-                                                   webgit_tag_name_parse (buffer, size),
-                                                   webgit_tag_email_parse (buffer, size)
+                                                   webgit_object_tag_name_parse (buffer, size),
+                                                   webgit_object_tag_email_parse (buffer, size)
                                                    )
                                 ),
                           html (
                                 html_tag ("td"),
-                                webgit_tag_header_parse (buffer, size)
+                                webgit_object_tag_header_parse (buffer, size)
                                 ),
                           html (
                                 html_tag ("td"),
index ee5592c..fb967f2 100644 (file)
--- a/src/tag.h
+++ b/src/tag.h
 
 #include <time.h>
 
-time_t
-webgit_tag_date_parse (void* buffer, unsigned long size, struct tm* tm);
-
-int
-webgit_tag_type_parse (char* dest, void* buffer, unsigned long size);
-
-Html
-webgit_tag_name_parse (void* buffer, unsigned long size);
-
-Html
-webgit_tag_email_parse (void* buffer, unsigned long size);
-
-Html
-webgit_tag_header_parse (void* buffer, unsigned long size);
-
-Html
-webgit_tag_message_parse (void* buffer, unsigned long size);
-
 Html
 webgit_tag_table (struct webgit_repo_info* repo, const char* tag, int count);