Commits

evhan committed 6ef561a

use new branch iterator API for branches-fold

Comments (0)

Files changed (3)

git-lolevel-exports.scm

  blob-rawsize
  branch-create
  branch-delete
- branch-foreach
  branch-is-head
+ branch-iterator-new
+ branch-iterator-free
  branch-lookup
  branch-move
  branch-name
+ branch-next
  checkout-head
  checkout-index
  checkout-tree
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; branch.h
 
+(define-foreign-type branch-iterator (c-pointer "git_branch_iterator"))
+
 (define-external GIT_BRANCH_ALL int
   (foreign-value "GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE" int))
 
 (define branch-delete       (foreign-lambda/retval git_branch_delete reference))
 (define branch-is-head      (foreign-lambda bool git_branch_is_head reference))
 
-(define-foreign-type branch-foreach-cb (function int ((const c-string) branch-type c-pointer)))
-(define-external (branch_foreach_cb (c-string name) (branch-type type) (c-pointer fn)) int
-  ((callback-lookup fn) name type) 0)
-
-(define (branch-foreach repo flags fn)
-  (call-with-callback fn
-   (lambda (callback)
-     (guard-errors git_branch_foreach
-      ((foreign-safe-lambda int git_branch_foreach
-        repository branch-type branch-foreach-cb            c-pointer)
-        repo       flags       (location branch_foreach_cb) callback)))))
+;; Branch iterators.
+(define branch-iterator-new  (foreign-lambda/allocate branch-iterator git_branch_iterator_new repository branch-type))
+(define branch-iterator-free (foreign-lambda void git_branch_iterator_free branch-iterator))
+(define branch-next
+  (let ((next (foreign-lambda/allocate reference git_branch_next (c-pointer branch-type) branch-iterator)))
+    (lambda (iter)
+      (let-location ((t branch-type))
+        (let ((b (next (location t) iter)))
+          (values b t))))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; checkout.h
 (define branch-head?    (compose git-branch-is-head reference->pointer))
 
 (define (branches-fold kons knil repo #!optional (type 'all))
-  (let ((state knil))
-    (git-branch-foreach
-     (repository->pointer repo)
-     type
-     (lambda (name type)
-       (set! state
-         (kons (pointer->reference
-                repo
-                (git-branch-lookup
-                 (repository->pointer repo)
-                 name
-                 type))
-               state))))
-    state))
+  (let* ((repo* (repository->pointer repo))
+         (iter  (set-finalizer! (git-branch-iterator-new repo* type) git-branch-iterator-free)))
+     (let loop ((state knil))
+       (let ((b (condition-case
+                  (git-branch-next iter)
+                  ((git) #f))))
+         (if (not b)
+             state
+             (loop (kons (pointer->reference repo b) state)))))))
 
 (define (branches repo #!optional (type 'all))
   (branches-fold cons '() repo type))