diff options
| author | 2007-05-13 21:21:19 (JST) | |
|---|---|---|
| committer | 2007-05-13 21:21:19 (JST) | |
| commit | c4ef667961ef4668c9449124f97d55b9ac46c059 (patch) | |
| tree | 3e1d3ed9dbf2bac55d0ffbcd2909c5d935fae48b | |
| parent | 48dc00342effe3ba530ff6cbb79e5d0d5fc740fd (diff) | |
| download | cgit-c4ef667961ef4668c9449124f97d55b9ac46c059.zip cgit-c4ef667961ef4668c9449124f97d55b9ac46c059.tar.gz | |
Add standard interface for file diff functions
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
| -rw-r--r-- | cgit.h | 7 | ||||
| -rw-r--r-- | shared.c | 79 |
2 files changed, 86 insertions, 0 deletions
| @@ -20,6 +20,7 @@ | |||
| 20 | 20 | ||
| 21 | typedef void (*configfn)(const char *name, const char *value); | 21 | typedef void (*configfn)(const char *name, const char *value); |
| 22 | typedef void (*filepair_fn)(struct diff_filepair *pair); | 22 | typedef void (*filepair_fn)(struct diff_filepair *pair); |
| 23 | typedef void (*linediff_fn)(char *line, int len); | ||
| 23 | 24 | ||
| 24 | struct cacheitem { | 25 | struct cacheitem { |
| 25 | char *name; | 26 | char *name; |
| @@ -117,9 +118,15 @@ extern int chk_positive(int result, char *msg); | |||
| 117 | extern int hextoint(char c); | 118 | extern int hextoint(char c); |
| 118 | 119 | ||
| 119 | extern void *cgit_free_commitinfo(struct commitinfo *info); | 120 | extern void *cgit_free_commitinfo(struct commitinfo *info); |
| 121 | |||
| 122 | extern int cgit_diff_files(const unsigned char *old_sha1, | ||
| 123 | const unsigned char *new_sha1, | ||
| 124 | linediff_fn fn); | ||
| 125 | |||
| 120 | extern void cgit_diff_tree(const unsigned char *old_sha1, | 126 | extern void cgit_diff_tree(const unsigned char *old_sha1, |
| 121 | const unsigned char *new_sha1, | 127 | const unsigned char *new_sha1, |
| 122 | filepair_fn fn); | 128 | filepair_fn fn); |
| 129 | |||
| 123 | extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); | 130 | extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); |
| 124 | 131 | ||
| 125 | extern char *fmt(const char *format,...); | 132 | extern char *fmt(const char *format,...); |
| @@ -207,6 +207,85 @@ void cgit_diff_tree_cb(struct diff_queue_struct *q, | |||
| 207 | } | 207 | } |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | static int load_mmfile(mmfile_t *file, const unsigned char *sha1) | ||
| 211 | { | ||
| 212 | enum object_type type; | ||
| 213 | |||
| 214 | if (is_null_sha1(sha1)) { | ||
| 215 | file->ptr = (char *)""; | ||
| 216 | file->size = 0; | ||
| 217 | } else { | ||
| 218 | file->ptr = read_sha1_file(sha1, &type, &file->size); | ||
| 219 | } | ||
| 220 | return 1; | ||
| 221 | } | ||
| 222 | |||
| 223 | /* | ||
| 224 | * Receive diff-buffers from xdiff and concatenate them as | ||
| 225 | * needed across multiple callbacks. | ||
| 226 | * | ||
| 227 | * This is basically a copy of xdiff-interface.c/xdiff_outf(), | ||
| 228 | * ripped from git and modified to use globals instead of | ||
| 229 | * a special callback-struct. | ||
| 230 | */ | ||
| 231 | char *diffbuf = NULL; | ||
| 232 | int buflen = 0; | ||
| 233 | |||
| 234 | int filediff_cb(void *priv, mmbuffer_t *mb, int nbuf) | ||
| 235 | { | ||
| 236 | int i; | ||
| 237 | |||
| 238 | for (i = 0; i < nbuf; i++) { | ||
| 239 | if (mb[i].ptr[mb[i].size-1] != '\n') { | ||
| 240 | /* Incomplete line */ | ||
| 241 | diffbuf = xrealloc(diffbuf, buflen + mb[i].size); | ||
| 242 | memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size); | ||
| 243 | buflen += mb[i].size; | ||
| 244 | continue; | ||
| 245 | } | ||
| 246 | |||
| 247 | /* we have a complete line */ | ||
| 248 | if (!diffbuf) { | ||
| 249 | ((linediff_fn)priv)(mb[i].ptr, mb[i].size); | ||
| 250 | continue; | ||
| 251 | } | ||
| 252 | diffbuf = xrealloc(diffbuf, buflen + mb[i].size); | ||
| 253 | memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size); | ||
| 254 | ((linediff_fn)priv)(diffbuf, buflen + mb[i].size); | ||
| 255 | free(diffbuf); | ||
| 256 | diffbuf = NULL; | ||
| 257 | buflen = 0; | ||
| 258 | } | ||
| 259 | if (diffbuf) { | ||
| 260 | ((linediff_fn)priv)(diffbuf, buflen); | ||
| 261 | free(diffbuf); | ||
| 262 | diffbuf = NULL; | ||
| 263 | buflen = 0; | ||
| 264 | } | ||
| 265 | return 0; | ||
| 266 | } | ||
| 267 | |||
| 268 | int cgit_diff_files(const unsigned char *old_sha1, | ||
| 269 | const unsigned char *new_sha1, | ||
| 270 | linediff_fn fn) | ||
| 271 | { | ||
| 272 | mmfile_t file1, file2; | ||
| 273 | xpparam_t diff_params; | ||
| 274 | xdemitconf_t emit_params; | ||
| 275 | xdemitcb_t emit_cb; | ||
| 276 | |||
| 277 | if (!load_mmfile(&file1, old_sha1) || !load_mmfile(&file2, new_sha1)) | ||
| 278 | return 1; | ||
| 279 | |||
| 280 | diff_params.flags = XDF_NEED_MINIMAL; | ||
| 281 | emit_params.ctxlen = 3; | ||
| 282 | emit_params.flags = XDL_EMIT_FUNCNAMES; | ||
| 283 | emit_cb.outf = filediff_cb; | ||
| 284 | emit_cb.priv = fn; | ||
| 285 | xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb); | ||
| 286 | return 0; | ||
| 287 | } | ||
| 288 | |||
| 210 | void cgit_diff_tree(const unsigned char *old_sha1, | 289 | void cgit_diff_tree(const unsigned char *old_sha1, |
| 211 | const unsigned char *new_sha1, | 290 | const unsigned char *new_sha1, |
| 212 | filepair_fn fn) | 291 | filepair_fn fn) |
