Diff options
Diffstat (limited to '')
-rw-r--r--source/shared.c264
-rw-r--r--source/shared.h27
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);