@@ -235,3 +235,231 @@ void php_git2_strarray_free(git_strarray *out)
235235 }
236236 efree (out -> strings );
237237}
238+
239+ void php_git2_git_checkout_opts_to_array (git_checkout_opts * opts , zval * * out TSRMLS_DC )
240+ {
241+ zval * result ;
242+ git_checkout_opts tmp = GIT_CHECKOUT_OPTS_INIT ;
243+ opts = & tmp ;
244+
245+ MAKE_STD_ZVAL (result );
246+ array_init (result );
247+
248+ add_assoc_long_ex (result , ZEND_STRS ("version" ), opts -> version );
249+ add_assoc_long_ex (result , ZEND_STRS ("checkout_strategy" ), opts -> checkout_strategy );
250+ add_assoc_long_ex (result , ZEND_STRS ("disable_filters" ), opts -> disable_filters );
251+ add_assoc_long_ex (result , ZEND_STRS ("dir_mode" ), opts -> dir_mode );
252+ add_assoc_long_ex (result , ZEND_STRS ("file_mode" ), opts -> file_mode );
253+ add_assoc_long_ex (result , ZEND_STRS ("file_open_flags" ), opts -> file_open_flags );
254+ add_assoc_long_ex (result , ZEND_STRS ("notify_flags" ), opts -> notify_flags );
255+
256+ if (opts -> notify_payload != NULL ) {
257+
258+ } else {
259+ add_assoc_null_ex (result , ZEND_STRS ("notify_cb" ));
260+ }
261+
262+ if (opts -> notify_payload != NULL ) {
263+
264+ } else {
265+ add_assoc_null_ex (result , ZEND_STRS ("notify_payload" ));
266+ }
267+
268+ if (opts -> progress_cb != NULL ) {
269+
270+ } else {
271+ add_assoc_null_ex (result , ZEND_STRS ("progress_cb" ));
272+ }
273+
274+ if (opts -> progress_payload != NULL ) {
275+
276+ } else {
277+ add_assoc_null_ex (result , ZEND_STRS ("progress_payload" ));
278+ }
279+
280+ if (opts -> paths .count > 0 ) {
281+ zval * paths ;
282+ php_git2_strarray_to_array (& opts -> paths , & paths TSRMLS_CC );
283+ add_assoc_zval_ex (result , ZEND_STRS ("paths" ), paths );
284+ } else {
285+ zval * paths ;
286+ MAKE_STD_ZVAL (paths );
287+ array_init (paths );
288+ add_assoc_zval_ex (result , ZEND_STRS ("paths" ), paths );
289+ }
290+
291+ if (opts -> baseline != NULL ) {
292+ // git_tree
293+
294+ } else {
295+ add_assoc_null_ex (result , ZEND_STRS ("baseline" ));
296+ }
297+ add_assoc_string_ex (result , ZEND_STRS ("target_directory" ), (opts -> target_directory ) ? opts -> target_directory : "" , 1 );
298+ add_assoc_string_ex (result , ZEND_STRS ("our_label" ), (opts -> our_label ) ? opts -> our_label : "" , 1 );
299+ add_assoc_string_ex (result , ZEND_STRS ("their_label" ), (opts -> their_label ) ? opts -> their_label : "" , 1 );
300+
301+ * out = result ;
302+ }
303+
304+ void php_git_git_checkout_opts_free (git_checkout_opts * target TSRMLS_DC )
305+ {
306+ php_git2_cb_t * tmp ;
307+
308+ if (target -> notify_payload ) {
309+ tmp = (php_git2_cb_t * )target -> notify_payload ;
310+ if (tmp -> fci ) {
311+ efree (tmp -> fci );
312+ }
313+ if (tmp -> fcc ) {
314+ efree (tmp -> fcc );
315+ }
316+ efree (target -> notify_payload );
317+ }
318+ if (target -> progress_payload ) {
319+ tmp = (php_git2_cb_t * )target -> progress_payload ;
320+ if (tmp -> fci ) {
321+ efree (tmp -> fci );
322+ }
323+ if (tmp -> fcc ) {
324+ efree (tmp -> fcc );
325+ }
326+ efree (target -> progress_payload );
327+ }
328+
329+ php_git2_strarray_free (& target -> paths );
330+ efree (target );
331+ }
332+
333+
334+ static int php_git2_git_checkout_notify_cb (git_checkout_notify_t why ,
335+ const char * path ,
336+ const git_diff_file * baseline ,
337+ const git_diff_file * target ,
338+ const git_diff_file * workdir ,
339+ void * payload )
340+ {
341+ /* TODO(chobie): implement callback */
342+ }
343+
344+ void php_git2_git_checkout_progress_cb (const char * path ,
345+ size_t completed_steps ,
346+ size_t total_steps ,
347+ void * payload )
348+ {
349+ php_git2_t * result ;
350+ zval * param_path , * param_completed_steps , * param_total_steps , * retval_ptr = NULL ;
351+ php_git2_cb_t * p = (php_git2_cb_t * )payload ;
352+ GIT2_TSRMLS_SET (p -> tsrm_ls );
353+
354+ MAKE_STD_ZVAL (param_path );
355+ MAKE_STD_ZVAL (param_completed_steps );
356+ MAKE_STD_ZVAL (param_total_steps );
357+ ZVAL_NULL (param_path );
358+ if (path != NULL ) {
359+ ZVAL_STRING (param_path , path , 1 );
360+ }
361+ ZVAL_LONG (param_completed_steps , completed_steps );
362+ ZVAL_LONG (param_total_steps , total_steps );
363+
364+ if (php_git2_call_function_v (p -> fci , p -> fcc TSRMLS_CC , & retval_ptr , 4 , & param_path , & param_completed_steps , & param_total_steps , & p -> payload )) {
365+ return ;
366+ }
367+
368+ zval_ptr_dtor (& retval_ptr );
369+ }
370+
371+
372+ static void php_git2_fcall_info_wrapper (zval * target , zend_fcall_info * * out_fci , zend_fcall_info_cache * * out_fcc TSRMLS_DC )
373+ {
374+ char * is_callable_error = NULL ;
375+ zend_fcall_info * fci = NULL ;
376+ zend_fcall_info_cache * fcc = NULL ;
377+
378+ fci = (zend_fcall_info * )emalloc (sizeof (zend_fcall_info ));
379+ fcc = (zend_fcall_info_cache * )emalloc (sizeof (zend_fcall_info_cache ));
380+ memcpy (fci , & empty_fcall_info , sizeof (zend_fcall_info ));
381+ memcpy (fcc , & empty_fcall_info_cache , sizeof (zend_fcall_info_cache ));
382+
383+ if (zend_fcall_info_init (target , 0 , fci , fcc , NULL , & is_callable_error TSRMLS_CC ) == SUCCESS ) {
384+ if (is_callable_error ) {
385+ efree (is_callable_error );
386+ }
387+ } else {
388+ fprintf (stderr , "FAILED" );
389+ efree (fci );
390+ efree (fcc );
391+ return ;
392+ }
393+
394+ * out_fci = fci ;
395+ * out_fcc = fcc ;
396+ }
397+
398+ int php_git2_array_to_git_checkout_opts (git_checkout_opts * * out , zval * array TSRMLS_DC )
399+ {
400+ const char * target_directory , * our_label , * their_label ;
401+ git_checkout_opts * opts = NULL , def = GIT_CHECKOUT_OPTS_INIT ;
402+ php_git2_cb_t * notify_payload = NULL , * progress_payload = NULL ;
403+ zval * notify_cb = NULL , * progress_cb = NULL ;
404+ char * tmp ;
405+
406+ opts = (git_checkout_opts * )emalloc (sizeof (struct git_checkout_opts ));
407+ memcpy (opts , & def , sizeof (git_checkout_opts ));
408+
409+ notify_cb = php_git2_read_arrval (array , ZEND_STRS ("notify_cb" ) TSRMLS_CC );
410+ progress_cb = php_git2_read_arrval (array , ZEND_STRS ("progress_cb" ) TSRMLS_CC );
411+
412+
413+ opts -> notify_cb = php_git2_git_checkout_notify_cb ;
414+ opts -> progress_cb = php_git2_git_checkout_progress_cb ;
415+ opts -> version = php_git2_read_arrval_long (array , ZEND_STRS ("version" ) TSRMLS_CC );
416+ opts -> checkout_strategy = php_git2_read_arrval_long (array , ZEND_STRS ("checkout_strategy" ) TSRMLS_CC );
417+ opts -> disable_filters = php_git2_read_arrval_long (array , ZEND_STRS ("disable_filters" ) TSRMLS_CC );
418+ opts -> dir_mode = php_git2_read_arrval_long (array , ZEND_STRS ("dir_mode" ) TSRMLS_CC );
419+ opts -> file_mode = php_git2_read_arrval_long (array , ZEND_STRS ("file_mode" ) TSRMLS_CC );
420+ opts -> file_open_flags = php_git2_read_arrval_long (array , ZEND_STRS ("file_open_flags" ) TSRMLS_CC );
421+ opts -> notify_flags = php_git2_read_arrval_long (array , ZEND_STRS ("notify_flags" ) TSRMLS_CC );
422+
423+ //notify_cb
424+ if (Z_TYPE_P (notify_cb ) != IS_NULL ) {
425+ zend_fcall_info * fci ;
426+ zend_fcall_info_cache * fcc ;
427+
428+ php_git2_fcall_info_wrapper (notify_cb , & fci , & fcc TSRMLS_CC );
429+ if (php_git2_cb_init (& notify_payload , fci , fcc ,
430+ php_git2_read_arrval (array , ZEND_STRS ("notify_payload" ) TSRMLS_CC ) TSRMLS_CC )) {
431+ }
432+ opts -> notify_payload = notify_payload ;
433+ } else {
434+ opts -> notify_cb = NULL ;
435+ }
436+
437+ //progress_cb
438+ if (Z_TYPE_P (progress_cb ) != IS_NULL ) {
439+ zend_fcall_info * fci ;
440+ zend_fcall_info_cache * fcc ;
441+
442+ php_git2_fcall_info_wrapper (progress_cb , & fci , & fcc TSRMLS_CC );
443+ if (php_git2_cb_init (& progress_payload , fci , fcc ,
444+ php_git2_read_arrval (array , ZEND_STRS ("progress_payload" ) TSRMLS_CC ) TSRMLS_CC )) {
445+ }
446+ opts -> progress_payload = progress_payload ;
447+ } else {
448+ opts -> progress_cb = NULL ;
449+ }
450+
451+
452+ php_git2_array_to_strarray (& opts -> paths , php_git2_read_arrval (array , ZEND_STRS ("paths" ) TSRMLS_CC ) TSRMLS_CC );
453+
454+ // TODO: assign baseline(git_tree)
455+
456+ target_directory = php_git2_read_arrval_string (array , ZEND_STRS ("target_directory" ) TSRMLS_CC );
457+ our_label = php_git2_read_arrval_string (array , ZEND_STRS ("our_label" ) TSRMLS_CC );
458+ their_label = php_git2_read_arrval_string (array , ZEND_STRS ("their_label" ) TSRMLS_CC );
459+ opts -> target_directory = target_directory ;
460+ opts -> our_label = our_label ;
461+ opts -> their_label = their_label ;
462+
463+ * out = opts ;
464+ return 0 ;
465+ }
0 commit comments