Welcome to the CHICKEN Scheme pasting service

C=>Scheme w/callback added by alynpost on Wed Jan 16 17:20:32 2013

;;
;; callback to allocate a string in Scheme from C.
;;
(define-external
  (c0re_make_string (size_t n)) scheme-object
    (make-string n))

;; clist is a list with constant time insertion
;;
; XXX: destructively modifies |x|
(define (make-clist #!optional (x '()))
  (let ((head (cons #f x)))
    (cons head (last-pair head))))

(define-syntax clist-head
  (syntax-rules ()
    ((_ d) (car d))))

(define-syntax clist-tail
  (syntax-rules ()
    ((_ d) (cdr d))))

(define (clist-append! d v)
  (let ((l (list v)))
    (set-cdr! (clist-tail d) l)
    ; advance the tail pointer.
    (set-cdr! d l)))

(define (clist->list d)
  (cdr (clist-head d)))

(declare (foreign-declare #<<EOF
#include <sys/types.h>
#include <string.h>
#include <pwd.h>
EOF
))

(define (getpwent)
  (define-external
    (c0re_getpwent_cb (scheme-object clist)
                      (scheme-object user)
                      (scheme-object passwd)
                      (scheme-object uid)
                      (scheme-object gid)
                      (scheme-object home)
                      (scheme-object shell)) void
      (let ((pwent `((user   . ,user)
                     (passwd . ,passwd)
                     (uid    . ,uid)
                     (gid    . ,gid)
                     (home   . ,home)
                     (shell  . ,shell))))
        (clist-append! clist pwent)))

  (define c0re_getpwent
    (foreign-safe-lambda* bool ((scheme-object clist)) #<<EOF
    struct passwd *pw;
    C_word shell, dir, passwd, name;
    size_t n;

    pw = getpwent();

    if(!pw) {
      endpwent();
      C_return(0);
    }

    n = strlen(pw->pw_name);
    name = c0re_make_string(n);
    C_memcpy(C_c_string(name), pw->pw_name, n);

    n = strlen(pw->pw_passwd);
    passwd = c0re_make_string(n);
    C_memcpy(C_c_string(passwd), pw->pw_passwd, n);

    n = strlen(pw->pw_dir);
    dir = c0re_make_string(n);
    C_memcpy(C_c_string(dir), pw->pw_dir, n);

    n = strlen(pw->pw_shell);
    shell = c0re_make_string(n);
    C_memcpy(C_c_string(shell), pw->pw_shell, n);

    c0re_getpwent_cb(clist,
                     name,
                     passwd,
                     C_fix(pw->pw_uid),
                     C_fix(pw->pw_gid),
                     dir,
                     shell);
    C_return(1);
EOF
))

  (let loop ((clist (make-clist)))
    (if (c0re_getpwent clist)
        (loop clist)
        (clist->list clist))))

Your annotation:

Enter a new annotation:

Your nick:
The title of your paste:
Your paste (mandatory) :
What does `(string? "foo")' produce?
Visually impaired? Let me spell it for you (wav file) download WAV