diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce Kwon <bryce@brycekwon.com> | |
| commit | ||
| parent | ||
| tree | ||
| download | ||
Pass callbacks to git by address
ISO C has no conversion between a function pointer and void *, so the
callbacks handed through git's data pointers and the write found by
dlsym stopped the pedantic half of a DEVELOPER=1 build.
| -rw-r--r-- | source/cgit.mk | 2 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | source/filter.c | 9 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | source/shared.c | 8 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | source/shared.h | 5 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | source/ui-log.c | 4 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
5 files changed, 20 insertions, 8 deletions
diff --git a/source/cgit.mk b/source/cgit.mk index 4109930..6e17737 100644 --- a/source/cgit.mk +++ b/source/cgit.mk @@ -34,7 +34,7 @@ $(CGIT_BUILD)/VERSION: force-version # Pinned so a compiler moving its default, as GCC 15 did to gnu23, cannot # change what the sources mean. The GNU dialect because git's headers use GNU -# extensions and dlsym needs a non-conforming cast. Git keeps its own choice. +# extensions. Git keeps its own choice. CGIT_STD ?= gnu17 # CGIT_CFLAGS is tracked separately so that changing it does not force a rebuild diff --git a/source/filter.c b/source/filter.c index 3ffd077..5f96cc0 100644 --- a/source/filter.c +++ b/source/filter.c @@ -150,9 +150,14 @@ static struct cgit_filter *current_write_filter = NULL; void cgit_init_filters(void) { - libc_write = dlsym(RTLD_NEXT, "write"); - if (!libc_write) + void *symbol = dlsym(RTLD_NEXT, "write"); + + if (!symbol) die("Unable to find libc's write function"); + // ISO C cannot convert an object pointer to a function pointer, while + // POSIX guarantees the two share a representation, so the bytes are + // copied across instead. + memcpy(&libc_write, &symbol, sizeof(libc_write)); } /* diff --git a/source/shared.c b/source/shared.c index a6a5106..af848f6 100644 --- a/source/shared.c +++ b/source/shared.c @@ -123,7 +123,7 @@ static void release_mmfile(mmfile_t *file, const struct object_id *oid) */ static int emit_line(void *priv, mmbuffer_t *mb, int nbuf) { - linediff_fn emit = (linediff_fn)priv; + linediff_fn emit = *(linediff_fn *)priv; int i; for (i = 0; i < nbuf; i++) { @@ -372,7 +372,7 @@ int cgit_refs_cb(const struct reference *ref, void *cb_data) void cgit_diff_tree_cb(struct diff_queue_struct *q, struct diff_options *options, void *data) { - filepair_fn fn = (filepair_fn)data; + filepair_fn fn = *(filepair_fn *)data; int i; for (i = 0; i < q->nr; i++) { @@ -443,7 +443,7 @@ int cgit_diff_files(const struct object_id *old_oid, const struct object_id *new emit_params.ctxlen = context > 0 ? context : DEFAULT_DIFF_CONTEXT; emit_params.flags = XDL_EMIT_FUNCNAMES; emit_cb.out_line = emit_line; - emit_cb.priv = fn; + emit_cb.priv = &fn; xdl_diff(&old_file, &new_file, &diff_params, &emit_params, &emit_cb); release_mmfile(&old_file, old_oid); release_mmfile(&new_file, new_oid); @@ -477,7 +477,7 @@ void cgit_diff_tree(const struct object_id *old_oid, const struct object_id *new if (ignorews) DIFF_XDL_SET(&opt, IGNORE_WHITESPACE); opt.format_callback = cgit_diff_tree_cb; - opt.format_callback_data = fn; + opt.format_callback_data = &fn; if (prefix) cgit_diff_limit_path(&opt, prefix); diff_setup_done(&opt); diff --git a/source/shared.h b/source/shared.h index 129cfb7..46324a1 100644 --- a/source/shared.h +++ b/source/shared.h @@ -48,6 +48,11 @@ extern int cgit_refs_cb(const struct reference *ref, void *cb_data); extern void cgit_free_commitinfo(struct commitinfo *info); extern void cgit_free_taginfo(struct taginfo *info); +/* + * A diff format callback that hands each filepair to the filepair_fn data + * points at. ISO C has no conversion between a function pointer and void *, + * so the function travels by address. + */ extern void cgit_diff_tree_cb(struct diff_queue_struct *q, struct diff_options *options, void *data); /* diff --git a/source/ui-log.c b/source/ui-log.c index 9f21114..d23fcd4 100644 --- a/source/ui-log.c +++ b/source/ui-log.c @@ -93,6 +93,8 @@ static void follow_path(struct diff_filepair *pair) */ static int should_show(struct commit *commit, struct rev_info *revs) { + // Static, because the walk keeps the address in its diff options. + static filepair_fn follow = follow_path; struct commit_list *parents = commit->parents; struct commit *parent; int found = 0, saved_fmt; @@ -128,7 +130,7 @@ static int should_show(struct commit *commit, struct rev_info *revs) saved_fmt = revs->diffopt.output_format; revs->diffopt.output_format = DIFF_FORMAT_CALLBACK; revs->diffopt.format_callback = cgit_diff_tree_cb; - revs->diffopt.format_callback_data = follow_path; + revs->diffopt.format_callback_data = &follow; revs->diffopt.no_free = 1; diff_flush(&revs->diffopt); revs->diffopt.output_format = saved_fmt; |
