Skip to content

Commit 23e1240

Browse files
committed
[diff] add callbacks
1 parent 8a59286 commit 23e1240

File tree

7 files changed

+307
-68
lines changed

7 files changed

+307
-68
lines changed

diff.c

+159-58
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,79 @@
22
#include "php_git2_priv.h"
33
#include "diff.h"
44

5+
static int php_git2_git_diff_file_cb(
6+
const git_diff_delta *delta,
7+
float progress,
8+
void *payload)
9+
{
10+
php_git2_t *result;
11+
zval *param_delta = NULL, *param_progress = NULL, *retval_ptr = NULL;
12+
php_git2_multi_cb_t *p = (php_git2_multi_cb_t*)payload;
13+
int i = 0, retval = 0;
14+
GIT2_TSRMLS_SET(p->tsrm_ls)
15+
16+
Z_ADDREF_P(p->payload);
17+
MAKE_STD_ZVAL(param_progress);
18+
ZVAL_DOUBLE(param_progress, progress);
19+
php_git2_diff_delta_to_array(delta, &param_delta TSRMLS_CC);
20+
if (php_git2_call_function_v(&p->callbacks[0].fci, &p->callbacks[0].fcc TSRMLS_CC, &retval_ptr, 3, &param_delta, &param_progress, &p->payload)) {
21+
return GIT_EUSER;
22+
}
23+
retval = Z_LVAL_P(retval_ptr);
24+
zval_ptr_dtor(&retval_ptr);
25+
26+
return retval;
27+
}
28+
29+
static int php_git2_git_diff_hunk_cb(
30+
const git_diff_delta *delta,
31+
const git_diff_hunk *hunk,
32+
void *payload)
33+
{
34+
php_git2_t *result;
35+
zval *param_delta = NULL, *param_hunk = NULL, *retval_ptr = NULL;
36+
php_git2_multi_cb_t *p = (php_git2_multi_cb_t*)payload;
37+
int i = 0, retval = 0;
38+
GIT2_TSRMLS_SET(p->tsrm_ls)
39+
40+
Z_ADDREF_P(p->payload);
41+
php_git2_diff_delta_to_array(delta, &param_delta TSRMLS_CC);
42+
php_git2_diff_hunk_to_array(hunk, &param_hunk TSRMLS_CC);
43+
44+
if (php_git2_call_function_v(&p->callbacks[1].fci, &p->callbacks[1].fcc TSRMLS_CC, &retval_ptr, 3, &param_delta, &param_hunk, &p->payload)) {
45+
return GIT_EUSER;
46+
}
47+
48+
retval = Z_LVAL_P(retval_ptr);
49+
zval_ptr_dtor(&retval_ptr);
50+
return retval;
51+
}
52+
53+
static int php_git2_git_diff_line_cb(
54+
const git_diff_delta *delta,
55+
const git_diff_hunk *hunk,
56+
const git_diff_line *line,
57+
void *payload) {
58+
php_git2_t *result;
59+
zval *param_delta = NULL, *param_hunk = NULL, *param_line = NULL, *retval_ptr = NULL;
60+
php_git2_multi_cb_t *p = (php_git2_multi_cb_t*)payload;
61+
int i = 0, retval = 0;
62+
GIT2_TSRMLS_SET(p->tsrm_ls)
63+
64+
Z_ADDREF_P(p->payload);
65+
php_git2_diff_delta_to_array(delta, &param_delta TSRMLS_CC);
66+
php_git2_diff_hunk_to_array(hunk, &param_hunk TSRMLS_CC);
67+
php_git2_diff_line_to_array(line, &param_line TSRMLS_CC);
68+
69+
if (php_git2_call_function_v(&p->callbacks[2].fci, &p->callbacks[2].fcc TSRMLS_CC, &retval_ptr, 4, &param_delta, &param_hunk, &param_line, &p->payload)) {
70+
return GIT_EUSER;
71+
}
72+
73+
retval = Z_LVAL_P(retval_ptr);
74+
zval_ptr_dtor(&retval_ptr);
75+
return retval;
76+
}
77+
578
/* {{{ proto void git_diff_free(resource $diff)
679
*/
780
PHP_FUNCTION(git_diff_free)
@@ -101,7 +174,6 @@ PHP_FUNCTION(git_diff_index_to_workdir)
101174
RETURN_FALSE;
102175
}
103176
ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_diff));
104-
105177
}
106178
/* }}} */
107179

@@ -112,17 +184,21 @@ PHP_FUNCTION(git_diff_tree_to_workdir)
112184
int result = 0, error = 0;
113185
git_diff *diff = NULL;
114186
zval *repo = NULL, *old_tree = NULL, *opts = NULL;
115-
php_git2_t *_repo = NULL, *_old_tree = NULL;
187+
php_git2_t *_repo = NULL, *_old_tree = NULL, *_result;
116188

117189
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
118-
"rr<git_diff_options>", &repo, &old_tree, &opts) == FAILURE) {
190+
"rra", &repo, &old_tree, &opts) == FAILURE) {
119191
return;
120192
}
121193

122194
ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
123195
ZEND_FETCH_RESOURCE(_old_tree, php_git2_t*, &old_tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
124-
result = git_diff_tree_to_workdir(&diff, PHP_GIT2_V(_repo, repository), PHP_GIT2_V(_old_tree, tree), opts);
125-
RETURN_LONG(result);
196+
result = git_diff_tree_to_workdir(&diff, PHP_GIT2_V(_repo, repository), PHP_GIT2_V(_old_tree, tree), NULL);
197+
198+
if (php_git2_make_resource(&_result, PHP_GIT2_TYPE_DIFF, diff, 0 TSRMLS_CC)) {
199+
RETURN_FALSE;
200+
}
201+
ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_result));
126202
}
127203
/* }}} */
128204

@@ -192,7 +268,6 @@ PHP_FUNCTION(git_diff_find_similar)
192268
}
193269
/* }}} */
194270

195-
196271
/* {{{ proto long git_diff_options_init( $options, long $version)
197272
*/
198273
PHP_FUNCTION(git_diff_options_init)
@@ -213,7 +288,6 @@ PHP_FUNCTION(git_diff_options_init)
213288
}
214289
/* }}} */
215290

216-
217291
/* {{{ proto long git_diff_num_deltas(resource $diff)
218292
*/
219293
PHP_FUNCTION(git_diff_num_deltas)
@@ -233,7 +307,6 @@ PHP_FUNCTION(git_diff_num_deltas)
233307
}
234308
/* }}} */
235309

236-
237310
/* {{{ proto long git_diff_num_deltas_of_type(resource $diff, $type)
238311
*/
239312
PHP_FUNCTION(git_diff_num_deltas_of_type)
@@ -254,13 +327,12 @@ PHP_FUNCTION(git_diff_num_deltas_of_type)
254327
}
255328
/* }}} */
256329

257-
258330
/* {{{ proto resource git_diff_get_delta(resource $diff, long $idx)
259331
*/
260332
PHP_FUNCTION(git_diff_get_delta)
261333
{
262334
const git_diff_delta *result = NULL;
263-
zval *diff = NULL;
335+
zval *diff = NULL, *_result;
264336
php_git2_t *_diff = NULL;
265337
long idx = 0;
266338

@@ -271,11 +343,11 @@ PHP_FUNCTION(git_diff_get_delta)
271343

272344
ZEND_FETCH_RESOURCE(_diff, php_git2_t*, &diff, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
273345
result = git_diff_get_delta(PHP_GIT2_V(_diff, diff), idx);
274-
/* TODO(chobie): implement this */
346+
php_git2_git_diff_delta_to_array(result, &_result TSRMLS_CC);
347+
RETURN_ZVAL(_result, 0, 1);
275348
}
276349
/* }}} */
277350

278-
279351
/* {{{ proto long git_diff_is_sorted_icase(resource $diff)
280352
*/
281353
PHP_FUNCTION(git_diff_is_sorted_icase)
@@ -304,21 +376,28 @@ PHP_FUNCTION(git_diff_foreach)
304376
int result = 0, error = 0;
305377
zval *diff = NULL, *file_cb = NULL, *hunk_cb = NULL, *line_cb = NULL, *payload = NULL;
306378
php_git2_t *_diff = NULL;
307-
zend_fcall_info fci = empty_fcall_info;
308-
zend_fcall_info_cache fcc = empty_fcall_info_cache;
309-
php_git2_cb_t *cb = NULL;
379+
zend_fcall_info file_fci = empty_fcall_info;
380+
zend_fcall_info_cache file_fcc = empty_fcall_info_cache;
381+
zend_fcall_info hunk_fci = empty_fcall_info;
382+
zend_fcall_info_cache hunk_fcc = empty_fcall_info_cache;
383+
zend_fcall_info line_fci = empty_fcall_info;
384+
zend_fcall_info_cache line_fcc = empty_fcall_info_cache;
385+
php_git2_multi_cb_t *cb = NULL;
310386

311387
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
312-
"rfffz", &diff, &fci, &fcc, &fci, &fcc, &fci, &fcc, &payload) == FAILURE) {
388+
"rfffz", &diff, &file_fci, &file_fcc, &hunk_fci, &hunk_fcc, &line_fci, &line_fcc, &payload) == FAILURE) {
313389
return;
314390
}
315391

316392
ZEND_FETCH_RESOURCE(_diff, php_git2_t*, &diff, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
317-
if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) {
318-
RETURN_FALSE;
319-
}
320-
//result = git_diff_foreach(PHP_GIT2_V(_diff, diff), <CHANGEME>, <CHANGEME>, <CHANGEME>, cb);
321-
php_git2_cb_free(cb);
393+
php_git2_multi_cb_init(&cb, payload TSRMLS_CC, 3,
394+
&file_fci, &file_fcc,
395+
&hunk_fci, &hunk_fcc,
396+
&line_fci, &line_fcc
397+
);
398+
399+
result = git_diff_foreach(PHP_GIT2_V(_diff, diff), php_git2_git_diff_file_cb, php_git2_git_diff_hunk_cb, php_git2_git_diff_line_cb, cb);
400+
php_git2_multi_cb_free(cb);
322401
RETURN_LONG(result);
323402
}
324403
/* }}} */
@@ -327,7 +406,7 @@ PHP_FUNCTION(git_diff_foreach)
327406
*/
328407
PHP_FUNCTION(git_diff_status_char)
329408
{
330-
char *result = NULL;
409+
char result;
331410
long status = 0;
332411

333412
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
@@ -336,7 +415,7 @@ PHP_FUNCTION(git_diff_status_char)
336415
}
337416

338417
result = git_diff_status_char(status);
339-
RETURN_STRING(result, 1);
418+
RETURN_STRINGL(&result, 1, 1);
340419
}
341420
/* }}} */
342421

@@ -349,7 +428,7 @@ PHP_FUNCTION(git_diff_print)
349428
php_git2_t *_diff = NULL;
350429
zend_fcall_info fci = empty_fcall_info;
351430
zend_fcall_info_cache fcc = empty_fcall_info_cache;
352-
php_git2_cb_t *cb = NULL;
431+
php_git2_multi_cb_t *cb = NULL;
353432
long format = 0;
354433

355434
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
@@ -358,11 +437,11 @@ PHP_FUNCTION(git_diff_print)
358437
}
359438

360439
ZEND_FETCH_RESOURCE(_diff, php_git2_t*, &diff, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
361-
if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) {
440+
if (php_git2_multi_cb_init(&cb, payload TSRMLS_CC, 3, &empty_fcall_info, &empty_fcall_info_cache, &empty_fcall_info, &empty_fcall_info_cache, &fci, &fcc)) {
362441
RETURN_FALSE;
363442
}
364-
//result = git_diff_print(PHP_GIT2_V(_diff, diff), format, <CHANGEME>, cb);
365-
php_git2_cb_free(cb);
443+
result = git_diff_print(PHP_GIT2_V(_diff, diff), format, php_git2_git_diff_line_cb, cb);
444+
php_git2_multi_cb_free(cb);
366445
RETURN_LONG(result);
367446
}
368447
/* }}} */
@@ -375,23 +454,33 @@ PHP_FUNCTION(git_diff_blobs)
375454
zval *old_blob = NULL, *new_blob = NULL, *options = NULL, *file_cb = NULL, *hunk_cb = NULL, *line_cb = NULL, *payload = NULL;
376455
php_git2_t *_old_blob = NULL, *_new_blob = NULL;
377456
char *old_as_path = NULL, *new_as_path = NULL;
378-
zend_fcall_info fci = empty_fcall_info;
379-
zend_fcall_info_cache fcc = empty_fcall_info_cache;
457+
zend_fcall_info file_fci = empty_fcall_info;
458+
zend_fcall_info_cache file_fcc = empty_fcall_info_cache;
459+
zend_fcall_info hunk_fci = empty_fcall_info;
460+
zend_fcall_info_cache hunk_fcc = empty_fcall_info_cache;
461+
zend_fcall_info line_fci = empty_fcall_info;
462+
zend_fcall_info_cache line_fcc = empty_fcall_info_cache;
380463
php_git2_cb_t *cb = NULL;
381464

382-
// if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
383-
// "rsrs<git_diff_options>fffz", &old_blob, &old_as_path, &old_as_path_len, &new_blob, &new_as_path, &new_as_path_len, &options, &fci, &fcc, &fci, &fcc, &fci, &fcc, &payload) == FAILURE) {
384-
// return;
385-
// }
386-
//
387-
// ZEND_FETCH_RESOURCE(_old_blob, php_git2_t*, &old_blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
388-
// ZEND_FETCH_RESOURCE(_new_blob, php_git2_t*, &new_blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
389-
// if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) {
390-
// RETURN_FALSE;
391-
// }
392-
// result = git_diff_blobs(PHP_GIT2_V(_old_blob, blob), old_as_path, PHP_GIT2_V(_new_blob, blob), new_as_path, options, <CHANGEME>, <CHANGEME>, <CHANGEME>, cb);
393-
// php_git2_cb_free(cb);
394-
// RETURN_LONG(result);
465+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
466+
"rsrsafffz", &old_blob, &old_as_path, &old_as_path_len, &new_blob, &new_as_path, &new_as_path_len, &options,
467+
&file_fci, &file_fcc, &hunk_fci, &hunk_fcc, &line_fci, &line_fcc, &payload) == FAILURE) {
468+
return;
469+
}
470+
471+
ZEND_FETCH_RESOURCE(_old_blob, php_git2_t*, &old_blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
472+
ZEND_FETCH_RESOURCE(_new_blob, php_git2_t*, &new_blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
473+
php_git2_multi_cb_init(&cb, payload TSRMLS_CC, 3,
474+
&file_fci, &file_fcc,
475+
&hunk_fci, &hunk_fcc,
476+
&line_fci, &line_fcc
477+
);
478+
result = git_diff_blobs(
479+
PHP_GIT2_V(_old_blob, blob), old_as_path,
480+
PHP_GIT2_V(_new_blob, blob), new_as_path, NULL,
481+
php_git2_git_diff_file_cb, php_git2_git_diff_hunk_cb, php_git2_git_diff_line_cb, cb);
482+
php_git2_multi_cb_free(cb);
483+
RETURN_LONG(result);
395484
}
396485
/* }}} */
397486

@@ -403,22 +492,34 @@ PHP_FUNCTION(git_diff_blob_to_buffer)
403492
zval *old_blob = NULL, *options = NULL, *file_cb = NULL, *hunk_cb = NULL, *line_cb = NULL, *payload = NULL;
404493
php_git2_t *_old_blob = NULL;
405494
char *old_as_path = NULL, *buffer = NULL, *buffer_as_path = NULL;
406-
// long buffer_len = 0;
407-
zend_fcall_info fci = empty_fcall_info;
408-
zend_fcall_info_cache fcc = empty_fcall_info_cache;
409-
php_git2_cb_t *cb = NULL;
495+
zend_fcall_info file_fci = empty_fcall_info;
496+
zend_fcall_info_cache file_fcc = empty_fcall_info_cache;
497+
zend_fcall_info hunk_fci = empty_fcall_info;
498+
zend_fcall_info_cache hunk_fcc = empty_fcall_info_cache;
499+
zend_fcall_info line_fci = empty_fcall_info;
500+
zend_fcall_info_cache line_fcc = empty_fcall_info_cache;
501+
php_git2_multi_cb_t *cb = NULL;
502+
git_diff_options opts = {0};
410503

411-
// if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
412-
// "rssls<git_diff_options>fffz", &old_blob, &old_as_path, &old_as_path_len, &buffer, &buffer_len, &buffer_len, &buffer_as_path, &buffer_as_path_len, &options, &fci, &fcc, &fci, &fcc, &fci, &fcc, &payload) == FAILURE) {
413-
// return;
414-
// }
415-
//
416-
// ZEND_FETCH_RESOURCE(_old_blob, php_git2_t*, &old_blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
417-
// if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) {
418-
// RETURN_FALSE;
419-
// }
420-
// result = git_diff_blob_to_buffer(PHP_GIT2_V(_old_blob, blob), old_as_path, buffer, buffer_len, buffer_as_path, options, <CHANGEME>, <CHANGEME>, <CHANGEME>, cb);
421-
// php_git2_cb_free(cb);
422-
// RETURN_LONG(result);
504+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
505+
"rsslsafffz", &old_blob, &old_as_path, &old_as_path_len,
506+
&buffer, &buffer_len, &buffer_len, &buffer_as_path, &buffer_as_path_len, &options,
507+
&file_fci, &file_fcc, &hunk_fci, &hunk_fcc, &line_fci, &line_fcc, &payload) == FAILURE) {
508+
return;
509+
}
510+
511+
ZEND_FETCH_RESOURCE(_old_blob, php_git2_t*, &old_blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
512+
php_git2_multi_cb_init(&cb, payload TSRMLS_CC, 3,
513+
&file_fci, &file_fcc,
514+
&hunk_fci, &hunk_fcc,
515+
&line_fci, &line_fcc
516+
);
517+
result = git_diff_blob_to_buffer(
518+
PHP_GIT2_V(_old_blob, blob), old_as_path,
519+
buffer, buffer_len, buffer_as_path,
520+
&opts,
521+
php_git2_git_diff_file_cb, php_git2_git_diff_hunk_cb, php_git2_git_diff_line_cb, cb);
522+
php_git2_multi_cb_free(cb);
523+
RETURN_LONG(result);
423524
}
424525
/* }}} */

diff.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_foreach, 0, 0, 5)
100100
ZEND_ARG_INFO(0, file_cb)
101101
ZEND_ARG_INFO(0, hunk_cb)
102102
ZEND_ARG_INFO(0, line_cb)
103-
ZEND_ARG_INFO(0, payload)
103+
ZEND_ARG_INFO(1, payload)
104104
ZEND_END_ARG_INFO()
105105

106106
ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_status_char, 0, 0, 1)
@@ -111,7 +111,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_print, 0, 0, 4)
111111
ZEND_ARG_INFO(0, diff)
112112
ZEND_ARG_INFO(0, format)
113113
ZEND_ARG_INFO(0, print_cb)
114-
ZEND_ARG_INFO(0, payload)
114+
ZEND_ARG_INFO(1, payload)
115115
ZEND_END_ARG_INFO()
116116

117117
ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_blobs, 0, 0, 9)

example/diff.php

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
$repo = git_repository_open(".");
3+
$tree = git_tree_lookup($repo, "e14ccb8e18d632d78ce2f0aeb06597a03f42b237");
4+
$diff = git_diff_tree_to_workdir($repo, $tree, array());
5+
6+
$p = array();
7+
git_diff_print($diff, GIT_DIFF_FORMAT_PATCH, function($diff_delta, $diff_hunk, $diff_line, $payload){
8+
if ($diff_line['origin'] == "-" || $diff_line['origin'] == "+") {
9+
echo $diff_line['origin'];
10+
}
11+
echo $diff_line['content'];
12+
}, $p);

0 commit comments

Comments
 (0)