-rw-r--r-- | cgit.c | 7 | ||||
-rw-r--r-- | cgit.h | 2 | ||||
-rw-r--r-- | git.h | 68 | ||||
-rw-r--r-- | ui-log.c | 13 |
4 files changed, 83 insertions, 7 deletions
@@ -15,30 +15,33 @@ static void cgit_print_repo_page(struct cacheitem *item) if (chdir(fmt("%s/%s", cgit_root, cgit_query_repo)) || cgit_read_config("info/cgit", cgit_repo_config_cb)) { char *title = fmt("%s - %s", cgit_root_title, "Bad request"); cgit_print_docstart(title, item); cgit_print_pageheader(title, 0); cgit_print_error(fmt("Unable to scan repository: %s", strerror(errno))); cgit_print_docend(); return; } setenv("GIT_DIR", fmt("%s/%s", cgit_root, cgit_query_repo), 1); char *title = fmt("%s - %s", cgit_repo_name, cgit_repo_desc); + int show_search = 0; + if (cgit_query_page && !strcmp(cgit_query_page, "log")) + show_search = 1; cgit_print_docstart(title, item); - cgit_print_pageheader(title, 0); + cgit_print_pageheader(title, show_search); if (!cgit_query_page) { cgit_print_summary(); } else if (!strcmp(cgit_query_page, "log")) { - cgit_print_log(cgit_query_head, cgit_query_ofs, 100); + cgit_print_log(cgit_query_head, cgit_query_ofs, 100, cgit_query_search); } else if (!strcmp(cgit_query_page, "tree")) { cgit_print_tree(cgit_query_sha1); } else if (!strcmp(cgit_query_page, "commit")) { cgit_print_commit(cgit_query_sha1); } else if (!strcmp(cgit_query_page, "view")) { cgit_print_view(cgit_query_sha1); } else if (!strcmp(cgit_query_page, "diff")) { cgit_print_diff(cgit_query_sha1, cgit_query_sha2); } cgit_print_docend(); } @@ -95,19 +95,19 @@ extern int cache_expired(struct cacheitem *item); extern char *cgit_repourl(const char *reponame); extern char *cgit_pageurl(const char *reponame, const char *pagename, const char *query); extern void cgit_print_error(char *msg); extern void cgit_print_date(unsigned long secs); extern void cgit_print_docstart(char *title, struct cacheitem *item); extern void cgit_print_docend(); extern void cgit_print_pageheader(char *title, int show_search); extern void cgit_print_repolist(struct cacheitem *item); extern void cgit_print_summary(); -extern void cgit_print_log(const char *tip, int ofs, int cnt); +extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep); extern void cgit_print_view(const char *hex); extern void cgit_print_tree(const char *hex); extern void cgit_print_commit(const char *hex); extern void cgit_print_diff(const char *old_hex, const char *new_hex); #endif /* CGIT_H */ @@ -22,25 +22,25 @@ #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 @@ -147,24 +147,90 @@ 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 */ struct object_list { struct object *item; struct object_list *next; }; struct object_refs { @@ -23,37 +23,44 @@ void print_commit(struct commit *commit) char *qry = fmt("id=%s", sha1_to_hex(commit->object.sha1)); char *url = cgit_pageurl(cgit_query_repo, "commit", qry); html_link_open(url, NULL, NULL); html_ntxt(80, info->subject); html_link_close(); html("</td><td>"); html_txt(info->author); html("</td></tr>\n"); cgit_free_commitinfo(info); } -void cgit_print_log(const char *tip, int ofs, int cnt) +void cgit_print_log(const char *tip, int ofs, int cnt, char *grep) { struct rev_info rev; struct commit *commit; - const char *argv[2] = {NULL, tip}; + const char *argv[3] = {NULL, tip, NULL}; + int argc = 2; int i; + if (grep) + argv[argc++] = fmt("--grep=%s", grep); init_revisions(&rev, NULL); rev.abbrev = DEFAULT_ABBREV; rev.commit_format = CMIT_FMT_DEFAULT; rev.verbose_header = 1; rev.show_root_diff = 0; - setup_revisions(2, argv, &rev, NULL); + setup_revisions(argc, argv, &rev, NULL); + if (rev.grep_filter) { + rev.grep_filter->regflags |= REG_ICASE; + compile_grep_patterns(rev.grep_filter); + } prepare_revision_walk(&rev); html("<h2>Log</h2>"); html("<table class='list nowrap'>"); html("<tr><th class='left'>Date</th>" "<th class='left'>Message</th>" "<th class='left'>Author</th></tr>\n"); if (ofs<0) ofs = 0; for (i = 0; i < ofs && (commit = get_revision(&rev)) != NULL; i++) { |