Diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce Kwon <bryce@brycekwon.com> | |
| commit | ||
| parent | ||
| tree | ||
| download | ||
Order shared.c the way shared.h declares it
The header's blob and pathspec checks move after the diff wrappers so
each group reads as one, and each static helper now sits directly above
its only user.
| -rw-r--r-- | source/shared.c | 264 | |
| -rw-r--r-- | source/shared.h | 27 |
2 files changed, 144 insertions, 147 deletions
diff --git a/source/shared.c b/source/shared.c index 7538c85..1e1bb26 100644 --- a/source/shared.c +++ b/source/shared.c @@ -1,15 +1,13 @@ /* - * The helpers that no single page owns, along with the process wide state - * every page reads. Repositories are registered here as cgitrc is parsed, the - * reference and commit records that the renderers list are built and freed - * here, and git's diff machinery is wrapped so a caller is handed whole - * filepairs or whole lines instead of xdiff buffers. + * The helpers that no single page owns, along with the process-wide state + * every page reads. Repositories are registered here as cgitrc is parsed, and + * git's diff machinery is wrapped so a caller is handed whole filepairs or + * whole lines instead of xdiff buffers. */ #define USE_THE_REPOSITORY_VARIABLE #include "cgit.h" -#include "parsing.h" #include "shared.h" #define MACRO_EXPANSION_BUFSIZE (1024 * 8) @@ -20,103 +18,6 @@ struct cgit_repolist cgit_repolist; struct cgit_context ctx; char cgit_default_repo_desc[] = "[no description]"; -/* - * Git's wider syntax is refused, since :/pattern and rev^{/pattern} walk the - * whole history for a match, and a leading dash reads as an option further - * down. - */ -int cgit_valid_rev(const char *rev) -{ - const char *p = rev; - - if (!rev || !*rev || *rev == '-') - return 0; - while (isxdigit((unsigned char)*p)) - p++; - if (!*p) - return 1; - return !check_refname_format(rev, REFNAME_ALLOW_ONELEVEL); -} - -static int load_mmfile(mmfile_t *file, const struct object_id *oid) -{ - enum object_type type; - size_t size; - - // A null oid is the absent side of an add or a delete, and diffs as an - // empty file rather than as a failure. - if (is_null_oid(oid)) { - file->ptr = (char *)""; - file->size = 0; - return 1; - } - - file->ptr = odb_read_object(the_repository->objects, oid, &type, &size); - if (!file->ptr) - return 0; - file->size = size; - return 1; -} - -/* - * The test is on the oid rather than the size, because load_mmfile uses a - * literal only for a null oid, while a real but empty blob owns its buffer. - */ -static void release_mmfile(mmfile_t *file, const struct object_id *oid) -{ - if (!is_null_oid(oid)) - free(file->ptr); -} - -/* - * Xdiff hands over one line per call, in pieces that are the prefix, the - * record and, for a record with no newline, the marker saying so. They are - * joined here before the line reaches fn. - */ -static int emit_line(void *priv, mmbuffer_t *mb, int nbuf) -{ - linediff_fn emit = *(linediff_fn *)priv; - struct strbuf line = STRBUF_INIT; - int i; - - for (i = 0; i < nbuf; i++) - strbuf_add(&line, mb[i].ptr, mb[i].size); - emit(line.buf, line.len); - strbuf_release(&line); - return 0; -} - -/* - * Takes an unsigned char because a byte over 0x7f is negative where char is - * signed, which the ctype tests are not defined for. - */ -static int is_token_char(unsigned char c) -{ - return isalnum(c) || c == '_'; -} - -/* - * Replace the variable name held at name with its value from the environment, - * writing at most room bytes including the terminator, and return where the - * text now ends. - */ -static char *expand_macro(char *name, size_t room) -{ - char *value; - size_t len; - - len = 0; - value = getenv(name); - if (value) { - len = strlen(value) + 1; - if (len > room) - len = room; - strlcpy(name, value, len); - --len; - } - return name + len; -} - struct cgit_repo *cgit_add_repo(const char *url) { struct cgit_repo *repo; @@ -179,20 +80,6 @@ struct cgit_repo *cgit_get_repoinfo(const char *url) return NULL; } -char *cgit_trim_end(const char *str, char c) -{ - size_t len; - - if (!str) - return NULL; - len = strlen(str); - while (len > 0 && str[len - 1] == c) - len--; - if (len == 0) - return NULL; - return xstrndup(str, len); -} - void cgit_diff_tree_cb(struct diff_queue_struct *q, struct diff_options *options UNUSED, void *data) { filepair_fn fn = *(filepair_fn *)data; @@ -206,6 +93,54 @@ void cgit_diff_tree_cb(struct diff_queue_struct *q, struct diff_options *options } } +static int load_mmfile(mmfile_t *file, const struct object_id *oid) +{ + enum object_type type; + size_t size; + + // A null oid is the absent side of an add or a delete, and diffs as an + // empty file rather than as a failure. + if (is_null_oid(oid)) { + file->ptr = (char *)""; + file->size = 0; + return 1; + } + + file->ptr = odb_read_object(the_repository->objects, oid, &type, &size); + if (!file->ptr) + return 0; + file->size = size; + return 1; +} + +/* + * The test is on the oid rather than the size, because load_mmfile uses a + * literal only for a null oid, while a real but empty blob owns its buffer. + */ +static void release_mmfile(mmfile_t *file, const struct object_id *oid) +{ + if (!is_null_oid(oid)) + free(file->ptr); +} + +/* + * Xdiff hands over one line per call, in pieces that are the prefix, the + * record and, for a record with no newline, the marker saying so. They are + * joined here before the line reaches fn. + */ +static int emit_line(void *priv, mmbuffer_t *mb, int nbuf) +{ + linediff_fn emit = *(linediff_fn *)priv; + struct strbuf line = STRBUF_INIT; + int i; + + for (i = 0; i < nbuf; i++) + strbuf_add(&line, mb[i].ptr, mb[i].size); + emit(line.buf, line.len); + strbuf_release(&line); + return 0; +} + int cgit_diff_files(const struct object_id *old_oid, const struct object_id *new_oid, size_t *old_size, size_t *new_size, int *binary, int context, int ignorews, linediff_fn fn) @@ -273,22 +208,6 @@ int cgit_diff_files(const struct object_id *old_oid, const struct object_id *new return 0; } -int cgit_blob_too_large(size_t size) -{ - return ctx.cfg.max_blob_size && size / 1024 > (size_t)ctx.cfg.max_blob_size; -} - -void cgit_literal_pathspec(struct pathspec *ps, struct pathspec_item *item, const char *path) -{ - int len = path ? strlen(path) : 0; - - // nowildcard_len matching len makes git treat the path as literal - // rather than as a glob. - *item = (struct pathspec_item){ .match = path, .len = len, .nowildcard_len = len }; - ps->nr = path ? 1 : 0; - ps->items = item; -} - void cgit_diff_limit_path(struct diff_options *opt, const char *prefix) { cgit_literal_pathspec(&opt->pathspec, xmalloc(sizeof(struct pathspec_item)), xstrdup(prefix)); @@ -329,6 +248,36 @@ void cgit_diff_commit(struct commit *commit, filepair_fn fn, const char *prefix) cgit_diff_tree(old_oid, &commit->object.oid, fn, prefix, ctx.qry.ignorews); } +int cgit_blob_too_large(size_t size) +{ + return ctx.cfg.max_blob_size && size / 1024 > (size_t)ctx.cfg.max_blob_size; +} + +void cgit_literal_pathspec(struct pathspec *ps, struct pathspec_item *item, const char *path) +{ + int len = path ? strlen(path) : 0; + + // nowildcard_len matching len makes git treat the path as literal + // rather than as a glob. + *item = (struct pathspec_item){ .match = path, .len = len, .nowildcard_len = len }; + ps->nr = path ? 1 : 0; + ps->items = item; +} + +char *cgit_trim_end(const char *str, char c) +{ + size_t len; + + if (!str) + return NULL; + len = strlen(str); + while (len > 0 && str[len - 1] == c) + len--; + if (len == 0) + return NULL; + return xstrndup(str, len); +} + int cgit_read_first_line(const char *path, char **buf) { int fd, err; @@ -423,6 +372,37 @@ void cgit_utf8_sanitize(char *text) } } +/* + * Takes an unsigned char because a byte over 0x7f is negative where char is + * signed, which the ctype tests are not defined for. + */ +static int is_token_char(unsigned char c) +{ + return isalnum(c) || c == '_'; +} + +/* + * Replace the variable name held at name with its value from the environment, + * writing at most room bytes including the terminator, and return where the + * text now ends. + */ +static char *expand_macro(char *name, size_t room) +{ + char *value; + size_t len; + + len = 0; + value = getenv(name); + if (value) { + len = strlen(value) + 1; + if (len > room) + len = room; + strlcpy(name, value, len); + --len; + } + return name + len; +} + char *cgit_expand_macros(const char *text) { static char result[MACRO_EXPANSION_BUFSIZE]; @@ -473,6 +453,24 @@ int cgit_readme_is_tracked(const char *readme) return colon && colon[1]; } +/* + * Git's wider syntax is refused, since :/pattern and rev^{/pattern} walk the + * whole history for a match, and a leading dash reads as an option further + * down. + */ +int cgit_valid_rev(const char *rev) +{ + const char *p = rev; + + if (!rev || !*rev || *rev == '-') + return 0; + while (isxdigit((unsigned char)*p)) + p++; + if (!*p) + return 1; + return !check_refname_format(rev, REFNAME_ALLOW_ONELEVEL); +} + int cgit_notes_ref_usable(const char *notes_ref) { struct object_id oid; diff --git a/source/shared.h b/source/shared.h index 4359bef..302b752 100644 --- a/source/shared.h +++ b/source/shared.h @@ -1,9 +1,8 @@ /* - * The helpers that belong to no single page. Repository registration, the - * lifetimes of the reference and commit records the renderers build, thin - * wrappers over git's diff machinery, and a handful of string, date and - * mimetype utilities all live here because several renderers need them. The - * two process-wide globals, ctx and cgit_repolist, are defined here as well. + * The helpers that more than one file needs. Repository registration and thin + * wrappers over git's diff machinery make up most of it, beside a few string + * and request checks. The two process-wide globals, ctx and cgit_repolist, + * are defined here as well. */ #ifndef CGIT_SHARED_H @@ -42,6 +41,15 @@ extern int cgit_diff_files(const struct object_id *old_oid, const struct object_ linediff_fn fn); /* + * Limit a diff to the paths below prefix, which is taken literally. + */ +extern void cgit_diff_limit_path(struct diff_options *opt, const char *prefix); + +extern void cgit_diff_tree(const struct object_id *old_oid, const struct object_id *new_oid, + filepair_fn fn, const char *prefix, int ignorews); +extern void cgit_diff_commit(struct commit *commit, filepair_fn fn, const char *prefix); + +/* * Whether a blob of size bytes is past max-blob-size. Callers ask before * reading the object, so a huge blob stays out of memory rather than being * noticed once it is already there. @@ -55,15 +63,6 @@ extern int cgit_blob_too_large(size_t size); extern void cgit_literal_pathspec(struct pathspec *ps, struct pathspec_item *item, const char *path); /* - * Limit a diff to the paths below prefix, which is taken literally. - */ -extern void cgit_diff_limit_path(struct diff_options *opt, const char *prefix); - -extern void cgit_diff_tree(const struct object_id *old_oid, const struct object_id *new_oid, - filepair_fn fn, const char *prefix, int ignorews); -extern void cgit_diff_commit(struct commit *commit, filepair_fn fn, const char *prefix); - -/* * Copy str without its trailing runs of c, returning NULL if nothing is left. */ extern char *cgit_trim_end(const char *str, char c); |
