@@ -84,6 +84,16 @@ public function isSavior()
8484 }
8585 }
8686
87+ public function isCallbacker ()
88+ {
89+ foreach ($ this ->args as $ arg ) {
90+ if (preg_match ("/_cb$/ " , $ arg ->getType ())) {
91+ return true ;
92+ }
93+ }
94+ return false ;
95+ }
96+
8797 public function getArguments ()
8898 {
8999 return $ this ->args ;
@@ -137,6 +147,11 @@ public function getType()
137147 return $ this ->type ;
138148 }
139149
150+ public function isCallback ()
151+ {
152+ return preg_match ("/_cb$/ " , $ this ->type );
153+ }
154+
140155 public function getPtr ()
141156 {
142157 return str_repeat ("* " , $ this ->ptr - 1 );
@@ -164,6 +179,8 @@ public function getZendType()
164179 return "char " ;
165180 } else if (preg_match ("/^git_/ " , $ this ->type )) {
166181 return "zval " ;
182+ } else if (preg_match ("/payload/ " , $ this ->name )) {
183+ return "zval " ;
167184 } else {
168185 error_log (sprintf ("%s (zendtype) " , $ this ->type ));
169186 }
@@ -360,6 +377,7 @@ public function shouldResource(Arg $arg)
360377 "git_filter_source " ,
361378 "git_diff_line " ,
362379 "git_reference_iterator " ,
380+ "git_config_iterator " ,
363381 );
364382 }
365383
@@ -425,6 +443,8 @@ public function generateProto(Printer $printer, Func $f)
425443 $ printer ->put ("array " );
426444 } else if (preg_match ("/(git_strarray)/ " , $ arg ->getType ())) {
427445 $ printer ->put ("array " );
446+ } else if (preg_match ("/_cb$/ " , $ arg ->getType ())) {
447+ $ printer ->put ("Callable " );
428448 } else {
429449 error_log (sprintf ("# unknown type (%s) " , $ arg ->getType ()));
430450 }
@@ -551,6 +571,20 @@ public function generateDeclarations(Printer $printer, Func $f)
551571 "value " => "NULL " ,
552572 );
553573 }
574+ if ($ f ->isCallbacker ()) {
575+ $ tables ["zend_fcall_info " ][] = array (
576+ "name " => "fci " ,
577+ "value " => "empty_fcall_info " ,
578+ );
579+ $ tables ["zend_fcall_info_cache " ][] = array (
580+ "name " => "fcc " ,
581+ "value " => "empty_fcall_info_cache " ,
582+ );
583+ $ tables ["php_git2_cb_t " ][] = array (
584+ "name " => "*cb " ,
585+ "value " => "NULL " ,
586+ );
587+ }
554588
555589
556590 foreach ($ tables as $ type => $ values ) {
@@ -594,6 +628,10 @@ public function generateParse(Printer $printer, Func $f)
594628 $ printer ->put ("a " );
595629 } else if ($ this ->shouldResource ($ arg )) {
596630 $ printer ->put ("r " );
631+ } else if ($ arg ->isCallback ()) {
632+ $ printer ->put ("f " );
633+ } else if ($ f ->isCallbacker () && preg_match ("/payload/ " , $ arg ->getName ())) {
634+ $ printer ->put ("z " );
597635 } else {
598636 $ printer ->put ("< {$ arg ->getType ()}> " );
599637 }
@@ -612,7 +650,12 @@ public function generateParse(Printer $printer, Func $f)
612650 continue ;
613651 }
614652
615- $ printer ->put ("&`name` " , "name " , $ arg ->getName ());
653+ if ($ arg ->isCallback ()) {
654+ $ printer ->put ("&fci, " );
655+ $ printer ->put ("&fcc " );
656+ } else {
657+ $ printer ->put ("&`name` " , "name " , $ arg ->getName ());
658+ }
616659 if (preg_match ("/char/ " , $ arg ->getZendType ())) {
617660 $ printer ->put (", " );
618661 $ printer ->put ("&`name`_len " , "name " , $ arg ->getName ());
@@ -648,26 +691,45 @@ public function generateFetchResourceIfNeeded(Printer $printer, Func $f)
648691 }
649692 }
650693
651- public function generateOidTranslation (Printer $ printer , Func $ f )
652- {
653- foreach ($ f ->getArguments () as $ arg ) {
654- /** @var Arg $arg */
655- if ($ arg ->getType () == "git_oid " ) {
656- $ printer ->put ("if (git_oid_fromstrn(&__`name`, `name`, `name`_len)) { \n" ,
657- "name " , $ arg ->getName ()
658- );
659- $ printer ->block (function (Printer $ printer ) use ($ arg ) {
660- $ printer ->put ("RETURN_FALSE; \n" );
661- });
662- $ printer ->put ("} \n" );
663- $ arg ->setName ("__ " . $ arg ->getName ());
664- }
694+ public function generateOidTranslation (Printer $ printer , Func $ f )
695+ {
696+ foreach ($ f ->getArguments () as $ arg ) {
697+ /** @var Arg $arg */
698+ if ($ arg ->getType () == "git_oid " ) {
699+ $ printer ->put ("if (git_oid_fromstrn(&__`name`, `name`, `name`_len)) { \n" ,
700+ "name " , $ arg ->getName ()
701+ );
702+ $ printer ->block (function (Printer $ printer ) use ($ arg ) {
703+ $ printer ->put ("RETURN_FALSE; \n" );
704+ });
705+ $ printer ->put ("} \n" );
706+ $ arg ->setName ("__ " . $ arg ->getName ());
665707 }
666708 }
709+ }
710+
711+ public function generateCallbackInit (Printer $ printer , Func $ f )
712+ {
713+ if ($ f ->isCallbacker ()) {
714+ $ printer ->put ("if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { \n" );
715+ $ printer ->block (function (Printer $ printer ) {
716+ $ printer ->put ("RETURN_FALSE; \n" );
717+ });
718+ $ printer ->put ("} \n" );
719+ }
720+ }
721+
722+ public function generateCallbackFree (Printer $ printer , Func $ f )
723+ {
724+ if ($ f ->isCallbacker ()) {
725+ $ printer ->put ("php_git2_cb_free(cb); \n" );
726+ }
727+ }
667728
668729 public function generateFunctionCall (Printer $ printer , Func $ f )
669730 {
670731 $ this ->generateOidTranslation ($ printer , $ f );
732+ $ this ->generateCallbackInit ($ printer , $ f );
671733 if ($ f ->getReturnType () == "int " && $ f ->isResourceCreator ()) {
672734 $ printer ->put ("error = `function` " ,
673735 "function " , $ f ->getName ()
@@ -801,6 +863,10 @@ public function generateFunctionCall(Printer $printer, Func $f)
801863 );
802864 } else if ($ arg ->shouldWrite ()) {
803865 $ printer ->put ("&`name` " , "name " , $ arg ->getName ());
866+ } else if ($ arg ->isCallback ()) {
867+ $ printer ->put ("<CHANGEME> " );
868+ } else if (preg_match ("/payload/ " , $ arg ->getName ())) {
869+ $ printer ->put ("cb " );
804870 } else {
805871 $ printer ->put ("`name` " , "name " , $ arg ->getName ());
806872 }
@@ -812,6 +878,7 @@ public function generateFunctionCall(Printer $printer, Func $f)
812878 }
813879 $ printer ->put ("); \n" );
814880
881+ $ this ->generateCallbackFree ($ printer , $ f );
815882 if (preg_match ("/_is_/ " , $ f ->getName ())) {
816883 $ printer ->put ("RETURN_BOOL(`name`); \n" , "name " , "result " );
817884 } else {
0 commit comments