22#include "git2_exception.h"
33#include "git2_repository.h"
44#include "git2_tree.h"
5+ #include "git2_tree_entry.h"
56
67static zend_class_entry * php_git2_tree_ce ;
78static zend_object_handlers php_git2_tree_handler ;
@@ -79,6 +80,78 @@ static PHP_METHOD(Tree, lookup_oid) {
7980GIT2_TREE_GET_OID (id )
8081GIT2_TREE_GET_LONG (entrycount )
8182
83+ struct git2_treewalk_payload {
84+ zval * this ;
85+ zval * * callback_data ;
86+ zend_fcall_info callback_i ;
87+ zend_fcall_info_cache callback_ic ;
88+ };
89+
90+ static int git2_treewalk_cb (const char * root , const git_tree_entry * entry , void * payload ) {
91+ int error ;
92+ zval argv [3 ]; // root, entry, callback_data
93+ zval retval ;
94+ struct git2_treewalk_payload * p = payload ;
95+
96+ ZVAL_STRING (& argv [0 ], root );
97+ git2_tree_entry_spawn (& argv [1 ], entry );
98+ ZVAL_COPY_VALUE (& argv [2 ], * p -> callback_data );
99+
100+ p -> callback_i .retval = & retval ;
101+ p -> callback_i .param_count = 3 ;
102+ p -> callback_i .params = argv ;
103+
104+ // TODO HERE
105+ error = zend_call_function (& p -> callback_i , & p -> callback_ic );
106+ if (error == FAILURE ) {
107+ return -1 ; // causes end of walk
108+ } else if (!Z_ISUNDEF (retval )) {
109+ convert_to_long (& retval );
110+ error = Z_LVAL (retval );
111+ zval_ptr_dtor (& retval );
112+ }
113+
114+ zval_ptr_dtor (& argv [0 ]);
115+ zval_ptr_dtor (& argv [1 ]);
116+ zval_ptr_dtor (& argv [2 ]); // ?
117+ }
118+
119+ ZEND_BEGIN_ARG_INFO_EX (arginfo_tree_walk , 0 , 0 , 2 )
120+ ZEND_ARG_INFO (0 , mode )
121+ ZEND_ARG_INFO (0 , callback )
122+ ZEND_ARG_INFO (1 , callback_data )
123+ ZEND_END_ARG_INFO ()
124+
125+ static PHP_METHOD (Tree , walk ) {
126+ long mode ;
127+ zval * * callback_data ;
128+ struct git2_treewalk_payload p ;
129+ p .this = getThis ();
130+
131+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "lfZ" , & mode , & p .callback_i , & p .callback_ic , & callback_data ) != SUCCESS ) {
132+ return ;
133+ }
134+
135+ GIT2_TREE_FETCH ();
136+
137+ switch (mode ) {
138+ case GIT_TREEWALK_PRE : case GIT_TREEWALK_POST :
139+ break ;
140+ default :
141+ git2_throw_exception (0 TSRMLS_CC , "Invalid mode provided, should be Git2::TREEWALK_PRE or Git2::TREEWALK_POST" );
142+ return ;
143+ }
144+
145+ int res = git_tree_walk (intern -> tree , mode , git2_treewalk_cb , & p );
146+
147+ if (res != 0 ) {
148+ git2_throw_last_error ();
149+ return ;
150+ }
151+
152+ RETURN_TRUE ;
153+ }
154+
82155void git2_tree_spawn (zval * * return_value , git_tree * tree TSRMLS_DC ) {
83156 git2_tree_object_t * intern ;
84157
@@ -118,6 +191,7 @@ static zend_function_entry git2_tree_methods[] = {
118191 PHP_ME (Tree , lookup_oid , arginfo_tree_id , ZEND_ACC_PUBLIC |ZEND_ACC_STATIC )
119192 PHP_ME (Tree , id , arginfo_tree_id , ZEND_ACC_PUBLIC )
120193 PHP_ME (Tree , entrycount , arginfo_tree_entrycount , ZEND_ACC_PUBLIC )
194+ PHP_ME (Tree , walk , arginfo_tree_walk , ZEND_ACC_PUBLIC )
121195/* PHP_ME(Tree, __construct, arginfo___construct, ZEND_ACC_PUBLIC) */
122196 { NULL , NULL , NULL }
123197};
@@ -134,10 +208,9 @@ void git2_tree_init(TSRMLS_DC) {
134208 php_git2_tree_handler .free_obj = php_git2_tree_free_object ;
135209
136210 // normalize
137- #define GIT2_REF_CONST (_x ) zend_declare_class_constant_long(php_git2_tree_ce, ZEND_STRL(#_x), GIT_REF_ ## _x TSRMLS_CC)
138- GIT2_REF_CONST (FORMAT_NORMAL );
139- GIT2_REF_CONST (FORMAT_ALLOW_ONELEVEL );
140- GIT2_REF_CONST (FORMAT_REFSPEC_PATTERN );
141- GIT2_REF_CONST (FORMAT_REFSPEC_SHORTHAND );
211+ #define GIT2_TREE_CONST (_x , _y ) zend_declare_class_constant_long(php_git2_tree_ce, ZEND_STRL(#_x), _y TSRMLS_CC)
212+
213+ GIT2_TREE_CONST (WALK_PRE , GIT_TREEWALK_PRE );
214+ GIT2_TREE_CONST (WALK_POST , GIT_TREEWALK_POST );
142215}
143216
0 commit comments