summaryrefslogtreecommitdiffabout
path: root/shared.c
authorLars Hjemli <hjemli@gmail.com>2007-06-17 16:12:03 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2007-06-17 16:12:03 (UTC)
commit4a0be586662843382ecfa53af34a13b291312bc0 (patch) (unidiff)
tree01e0cd725fe249df3449bb089aad9f8d58081f89 /shared.c
parentfaaca447b071592c9a1e1f14b4d0d2a39b4c795a (diff)
downloadcgit-4a0be586662843382ecfa53af34a13b291312bc0.zip
cgit-4a0be586662843382ecfa53af34a13b291312bc0.tar.gz
cgit-4a0be586662843382ecfa53af34a13b291312bc0.tar.bz2
Add cgit_diff_link()
This adds a new function used to generate links to the diff page and uses it everywhere such links appear (expect for single files in the diffstat displayed on the commit page: this is now a link to the tree page). The updated diff-page now expects zero, one or two revision specifiers, in parameters head, id and id2. Id defaults to head unless otherwise specified, while head (as usual) defaults to repo.defbranch. If id2 isn't specified, it defaults to the first parent of id1. The most important change is of course that now all repo pages (summary, log, tree, commit and diff) has support for passing on the current branch and revision, i.e. the road is now open for a 'static' menu with links to all of these pages. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (limited to 'shared.c') (more/less context) (ignore whitespace changes)
-rw-r--r--shared.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/shared.c b/shared.c
index c7cd8a5..f20fb5c 100644
--- a/shared.c
+++ b/shared.c
@@ -235,144 +235,144 @@ void *cgit_free_commitinfo(struct commitinfo *info)
235{ 235{
236 free(info->author); 236 free(info->author);
237 free(info->author_email); 237 free(info->author_email);
238 free(info->committer); 238 free(info->committer);
239 free(info->committer_email); 239 free(info->committer_email);
240 free(info->subject); 240 free(info->subject);
241 free(info); 241 free(info);
242 return NULL; 242 return NULL;
243} 243}
244 244
245int hextoint(char c) 245int hextoint(char c)
246{ 246{
247 if (c >= 'a' && c <= 'f') 247 if (c >= 'a' && c <= 'f')
248 return 10 + c - 'a'; 248 return 10 + c - 'a';
249 else if (c >= 'A' && c <= 'F') 249 else if (c >= 'A' && c <= 'F')
250 return 10 + c - 'A'; 250 return 10 + c - 'A';
251 else if (c >= '0' && c <= '9') 251 else if (c >= '0' && c <= '9')
252 return c - '0'; 252 return c - '0';
253 else 253 else
254 return -1; 254 return -1;
255} 255}
256 256
257void cgit_diff_tree_cb(struct diff_queue_struct *q, 257void cgit_diff_tree_cb(struct diff_queue_struct *q,
258 struct diff_options *options, void *data) 258 struct diff_options *options, void *data)
259{ 259{
260 int i; 260 int i;
261 261
262 for (i = 0; i < q->nr; i++) { 262 for (i = 0; i < q->nr; i++) {
263 if (q->queue[i]->status == 'U') 263 if (q->queue[i]->status == 'U')
264 continue; 264 continue;
265 ((filepair_fn)data)(q->queue[i]); 265 ((filepair_fn)data)(q->queue[i]);
266 } 266 }
267} 267}
268 268
269static int load_mmfile(mmfile_t *file, const unsigned char *sha1) 269static int load_mmfile(mmfile_t *file, const unsigned char *sha1)
270{ 270{
271 enum object_type type; 271 enum object_type type;
272 272
273 if (is_null_sha1(sha1)) { 273 if (is_null_sha1(sha1)) {
274 file->ptr = (char *)""; 274 file->ptr = (char *)"";
275 file->size = 0; 275 file->size = 0;
276 } else { 276 } else {
277 file->ptr = read_sha1_file(sha1, &type, &file->size); 277 file->ptr = read_sha1_file(sha1, &type, &file->size);
278 } 278 }
279 return 1; 279 return 1;
280} 280}
281 281
282/* 282/*
283 * Receive diff-buffers from xdiff and concatenate them as 283 * Receive diff-buffers from xdiff and concatenate them as
284 * needed across multiple callbacks. 284 * needed across multiple callbacks.
285 * 285 *
286 * This is basically a copy of xdiff-interface.c/xdiff_outf(), 286 * This is basically a copy of xdiff-interface.c/xdiff_outf(),
287 * ripped from git and modified to use globals instead of 287 * ripped from git and modified to use globals instead of
288 * a special callback-struct. 288 * a special callback-struct.
289 */ 289 */
290char *diffbuf = NULL; 290char *diffbuf = NULL;
291int buflen = 0; 291int buflen = 0;
292 292
293int filediff_cb(void *priv, mmbuffer_t *mb, int nbuf) 293int filediff_cb(void *priv, mmbuffer_t *mb, int nbuf)
294{ 294{
295 int i; 295 int i;
296 296
297 for (i = 0; i < nbuf; i++) { 297 for (i = 0; i < nbuf; i++) {
298 if (mb[i].ptr[mb[i].size-1] != '\n') { 298 if (mb[i].ptr[mb[i].size-1] != '\n') {
299 /* Incomplete line */ 299 /* Incomplete line */
300 diffbuf = xrealloc(diffbuf, buflen + mb[i].size); 300 diffbuf = xrealloc(diffbuf, buflen + mb[i].size);
301 memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size); 301 memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size);
302 buflen += mb[i].size; 302 buflen += mb[i].size;
303 continue; 303 continue;
304 } 304 }
305 305
306 /* we have a complete line */ 306 /* we have a complete line */
307 if (!diffbuf) { 307 if (!diffbuf) {
308 ((linediff_fn)priv)(mb[i].ptr, mb[i].size); 308 ((linediff_fn)priv)(mb[i].ptr, mb[i].size);
309 continue; 309 continue;
310 } 310 }
311 diffbuf = xrealloc(diffbuf, buflen + mb[i].size); 311 diffbuf = xrealloc(diffbuf, buflen + mb[i].size);
312 memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size); 312 memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size);
313 ((linediff_fn)priv)(diffbuf, buflen + mb[i].size); 313 ((linediff_fn)priv)(diffbuf, buflen + mb[i].size);
314 free(diffbuf); 314 free(diffbuf);
315 diffbuf = NULL; 315 diffbuf = NULL;
316 buflen = 0; 316 buflen = 0;
317 } 317 }
318 if (diffbuf) { 318 if (diffbuf) {
319 ((linediff_fn)priv)(diffbuf, buflen); 319 ((linediff_fn)priv)(diffbuf, buflen);
320 free(diffbuf); 320 free(diffbuf);
321 diffbuf = NULL; 321 diffbuf = NULL;
322 buflen = 0; 322 buflen = 0;
323 } 323 }
324 return 0; 324 return 0;
325} 325}
326 326
327int cgit_diff_files(const unsigned char *old_sha1, 327int cgit_diff_files(const unsigned char *old_sha1,
328 const unsigned char *new_sha1, 328 const unsigned char *new_sha1,
329 linediff_fn fn) 329 linediff_fn fn)
330{ 330{
331 mmfile_t file1, file2; 331 mmfile_t file1, file2;
332 xpparam_t diff_params; 332 xpparam_t diff_params;
333 xdemitconf_t emit_params; 333 xdemitconf_t emit_params;
334 xdemitcb_t emit_cb; 334 xdemitcb_t emit_cb;
335 335
336 if (!load_mmfile(&file1, old_sha1) || !load_mmfile(&file2, new_sha1)) 336 if (!load_mmfile(&file1, old_sha1) || !load_mmfile(&file2, new_sha1))
337 return 1; 337 return 1;
338 338
339 diff_params.flags = XDF_NEED_MINIMAL; 339 diff_params.flags = XDF_NEED_MINIMAL;
340 emit_params.ctxlen = 3; 340 emit_params.ctxlen = 3;
341 emit_params.flags = XDL_EMIT_FUNCNAMES; 341 emit_params.flags = XDL_EMIT_FUNCNAMES;
342 emit_cb.outf = filediff_cb; 342 emit_cb.outf = filediff_cb;
343 emit_cb.priv = fn; 343 emit_cb.priv = fn;
344 xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb); 344 xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb);
345 return 0; 345 return 0;
346} 346}
347 347
348void cgit_diff_tree(const unsigned char *old_sha1, 348void cgit_diff_tree(const unsigned char *old_sha1,
349 const unsigned char *new_sha1, 349 const unsigned char *new_sha1,
350 filepair_fn fn) 350 filepair_fn fn)
351{ 351{
352 struct diff_options opt; 352 struct diff_options opt;
353 int ret; 353 int ret;
354 354
355 diff_setup(&opt); 355 diff_setup(&opt);
356 opt.output_format = DIFF_FORMAT_CALLBACK; 356 opt.output_format = DIFF_FORMAT_CALLBACK;
357 opt.detect_rename = 1; 357 opt.detect_rename = 1;
358 opt.recursive = 1; 358 opt.recursive = 1;
359 opt.format_callback = cgit_diff_tree_cb; 359 opt.format_callback = cgit_diff_tree_cb;
360 opt.format_callback_data = fn; 360 opt.format_callback_data = fn;
361 diff_setup_done(&opt); 361 diff_setup_done(&opt);
362 362
363 if (old_sha1) 363 if (old_sha1 && !is_null_sha1(old_sha1))
364 ret = diff_tree_sha1(old_sha1, new_sha1, "", &opt); 364 ret = diff_tree_sha1(old_sha1, new_sha1, "", &opt);
365 else 365 else
366 ret = diff_root_tree_sha1(new_sha1, "", &opt); 366 ret = diff_root_tree_sha1(new_sha1, "", &opt);
367 diffcore_std(&opt); 367 diffcore_std(&opt);
368 diff_flush(&opt); 368 diff_flush(&opt);
369} 369}
370 370
371void cgit_diff_commit(struct commit *commit, filepair_fn fn) 371void cgit_diff_commit(struct commit *commit, filepair_fn fn)
372{ 372{
373 unsigned char *old_sha1 = NULL; 373 unsigned char *old_sha1 = NULL;
374 374
375 if (commit->parents) 375 if (commit->parents)
376 old_sha1 = commit->parents->item->object.sha1; 376 old_sha1 = commit->parents->item->object.sha1;
377 cgit_diff_tree(old_sha1, commit->object.sha1, fn); 377 cgit_diff_tree(old_sha1, commit->object.sha1, fn);
378} 378}