generate-ffi.rkt
#lang racket/base

(require (prefix-in make: (planet synx/maker:2))
         racket/runtime-path
         racket/system
         racket/file)

(define attrs
  '(dev ino mode nlink uid gid rdev size blksize blocks atime mtime ctime))

(define lookup
  (make-immutable-hash
   (map (λ (attr i) (cons attr i)) attrs (build-list (length attrs) values))))

(define-runtime-path info "compiled/generated-choose.i")

(define (make-info)
  (with-output-to-file
   info
   #:exists
   'replace
   (λ ()
     (define started? #f)
     (display "inline unsigned int choose(short index) {")
     (newline)
     (for
      ((index (in-naturals)) (attr attrs))
      (display "\t")
      (if started? (display "else ") (set! started? #t))
      (display "if (index==")
      (display index)
      (display ") return buf.st_")
      (display attr)
      (display ";\n"))
     (display "\tscheme_signal_error(\"Bad index %d\",index);\n")
     (display "}\n"))))

(define-runtime-path includer "lookup.ss")

(define (make-includer)
  (with-output-to-file
   includer
   #:exists
   'replace
   (λ ()
     (display "#lang racket/base

(provide (all-defined-out))

")
     (for-each
      (λ (attr i) (write `(define ,attr ,i)) (newline))
      attrs
      (build-list (length attrs) values)))))

(define-runtime-path source "ext.c")

(define-runtime-path location ".")

(when (not (file-exists? info)) (make-info))

(make:library location "ext" source info)

(define (attr->index i) (hash-ref lookup i))