#ifndef GIT_H #define GIT_H /* * from git:git-compat-util.h */ #ifndef FLEX_ARRAY #if defined(__GNUC__) && (__GNUC__ < 3) #define FLEX_ARRAY 0 #else #define FLEX_ARRAY /* empty */ #endif #endif #include <unistd.h> #include <stdio.h> #include <sys/stat.h> #include <fcntl.h> #include <stddef.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <errno.h> #include <limits.h> #include <sys/param.h> #include <netinet/in.h> #include <sys/types.h> #include <dirent.h> #include <time.h> #include <regex.h> /* On most systems <limits.h> would have given us this, but * not on some systems (e.g. GNU/Hurd). */ #ifndef PATH_MAX #define PATH_MAX 4096 #endif #ifdef __GNUC__ #define NORETURN __attribute__((__noreturn__)) #else #define NORETURN #ifndef __attribute__ #define __attribute__(x) #endif #endif extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); static inline char* xstrdup(const char *str) { char *ret = strdup(str); if (!ret) die("Out of memory, strdup failed"); return ret; } static inline void *xmalloc(size_t size) { void *ret = malloc(size); if (!ret && !size) ret = malloc(1); if (!ret) die("Out of memory, malloc failed"); #ifdef XMALLOC_POISON memset(ret, 0xA5, size); #endif return ret; } static inline void *xrealloc(void *ptr, size_t size) { void *ret = realloc(ptr, size); if (!ret && !size) ret = realloc(ptr, 1); if (!ret) die("Out of memory, realloc failed"); return ret; } static inline void *xcalloc(size_t nmemb, size_t size) { void *ret = calloc(nmemb, size); if (!ret && (!nmemb || !size)) ret = calloc(1, 1); if (!ret) die("Out of memory, calloc failed"); return ret; } static inline ssize_t xread(int fd, void *buf, size_t len) { ssize_t nr; while (1) { nr = read(fd, buf, len); if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) continue; return nr; } } static inline ssize_t xwrite(int fd, const void *buf, size_t len) { ssize_t nr; while (1) { nr = write(fd, buf, len); if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) continue; return nr; } } /* * from git:cache.h */ enum object_type { OBJ_NONE = 0, OBJ_COMMIT = 1, OBJ_TREE = 2, OBJ_BLOB = 3, OBJ_TAG = 4, /* 5 for future expansion */ OBJ_OFS_DELTA = 6, OBJ_REF_DELTA = 7, OBJ_BAD, }; /* Convert to/from hex/sha1 representation */ #define MINIMUM_ABBREV 4 #define DEFAULT_ABBREV 7 extern const unsigned char null_sha1[20]; extern int sha1_object_info(const unsigned char *, char *, unsigned long *); extern void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size); extern int get_sha1(const char *str, unsigned char *sha1); extern int get_sha1_hex(const char *hex, unsigned char *sha1); extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */ static inline int is_null_sha1(const unsigned char *sha1) { return !memcmp(sha1, null_sha1, 20); } static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2) { return memcmp(sha1, sha2, 20); } static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src) { memcpy(sha_dst, sha_src, 20); } static inline void hashclr(unsigned char *hash) { memset(hash, 0, 20); } /* * from git:grep.h */ enum grep_pat_token { GREP_PATTERN, GREP_PATTERN_HEAD, GREP_PATTERN_BODY, GREP_AND, GREP_OPEN_PAREN, GREP_CLOSE_PAREN, GREP_NOT, GREP_OR, }; enum grep_context { GREP_CONTEXT_HEAD, GREP_CONTEXT_BODY, }; struct grep_pat { struct grep_pat *next; const char *origin; int no; enum grep_pat_token token; const char *pattern; regex_t regexp; }; enum grep_expr_node { GREP_NODE_ATOM, GREP_NODE_NOT, GREP_NODE_AND, GREP_NODE_OR, }; struct grep_opt { struct grep_pat *pattern_list; struct grep_pat **pattern_tail; struct grep_expr *pattern_expression; int prefix_length; regex_t regexp; unsigned linenum:1; unsigned invert:1; unsigned status_only:1; unsigned name_only:1; unsigned unmatch_name_only:1; unsigned count:1; unsigned word_regexp:1; unsigned fixed:1; unsigned all_match:1; #define GREP_BINARY_DEFAULT 0 #define GREP_BINARY_NOMATCH 1 #define GREP_BINARY_TEXT 2 unsigned binary:2; unsigned extended:1; unsigned relative:1; unsigned pathname:1; int regflags; unsigned pre_context; unsigned post_context; }; extern void compile_grep_patterns(struct grep_opt *opt); extern void free_grep_patterns(struct grep_opt *opt); /* * from git:object.h */ extern const char *type_names[9]; struct object_list { struct object *item; struct object_list *next; }; struct object_refs { unsigned count; struct object *base; struct object *ref[FLEX_ARRAY]; /* more */ }; struct object_array { unsigned int nr; unsigned int alloc; struct object_array_entry { struct object *item; const char *name; } *objects; }; #define TYPE_BITS 3 #define FLAG_BITS 27 /* * The object type is stored in 3 bits. */ struct object { unsigned parsed : 1; unsigned used : 1; unsigned type : TYPE_BITS; unsigned flags : FLAG_BITS; unsigned char sha1[20]; }; /* * from git:tree.h */ struct tree { struct object object; void *buffer; unsigned long size; }; struct tree *lookup_tree(const unsigned char *sha1); int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size); int parse_tree(struct tree *tree); struct tree *parse_tree_indirect(const unsigned char *sha1); typedef int (*read_tree_fn_t)(const unsigned char *, const char *, int, const char *, unsigned int, int); extern int read_tree_recursive(struct tree *tree, const char *base, int baselen, int stage, const char **match, read_tree_fn_t fn); extern int read_tree(struct<style>pre { line-height: 125%; } td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */</style><div class="highlight"><pre><span></span><span class="cm">/* ui-tag.c: display a tag</span> <span class="cm"> *</span> <span class="cm"> * Copyright (C) 2007 Lars Hjemli</span> <span class="cm"> *</span> <span class="cm"> * Licensed under GNU General Public License v2</span> <span class="cm"> * (see COPYING for full license text)</span> <span class="cm"> */</span> <span class="cp">#include</span><span class="w"> </span><span class="cpf">"cgit.h"</span> <span class="cp">#include</span><span class="w"> </span><span class="cpf">"html.h"</span> <span class="cp">#include</span><span class="w"> </span><span class="cpf">"ui-shared.h"</span> <span class="k">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">print_tag_content</span><span class="p">(</span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">buf</span><span class="p">)</span> <span class="p">{</span> <span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">p</span><span class="p">;</span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">buf</span><span class="p">)</span> <span class="w"> </span><span class="k">return</span><span class="p">;</span> <span class="w"> </span><span class="n">html</span><span class="p">(</span><span class="s">"<div class='commit-subject'>"</span><span class="p">);</span> <span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">strchr</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span><span class="w"> </span><span class="sc">'\n'</span><span class="p">);</span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="w"> </span><span class="o">*</span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sc">'\0'</span><span class="p">;</span> <span class="w"> </span><span class="n">html_txt</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span> <span class="w"> </span><span class="n">html</span><span class="p">(</span><span class="s">"</div>"</span><span class="p">);</span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">p</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="n">html</span><span class="p">(</span><span class="s">"<div class='commit-msg'>"</span><span class="p">);</span> <span class="w"> </span><span class="n">html_txt</span><span class="p">(</span><span class="o">++</span><span class="n">p</span><span class="p">);</span> <span class="w"> </span><span class="n">html</span><span class="p">(</span><span class="s">"</div>"</span><span class="p">);</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="kt">void</span><span class="w"> </span><span class="nf">print_download_links</span><span class="p">(</span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">revname</span><span class="p">)</spa