+There is no error checking done, unless you pass too few FORMAT
+clause args. I recommend using this formatting convention in
+code:
+
+ (printf \"string ~A ~S %d %d\" format-arg-1 format-arg-2
+ printf-arg-1 printf-arg-2)"
+ (let ((*print-pretty* nil))
+ (apply #'format *default-c-stream*
+ " printf (\"~@?\\n\"~@{, ~A~});~%"
+ (c-escape formatter)
+ args)))
+
+(defun c-for-structure (lispname cstruct)
+ (destructuring-bind (cname &rest elements) cstruct
+ (printf "(cl:eval-when (:compile-toplevel :load-toplevel :execute) (sb-grovel::define-c-struct ~A %d" lispname
+ (format nil "sizeof(~A)" cname))
+ (dolist (e elements)
+ (destructuring-bind (lisp-type lisp-el-name c-type c-el-name &key distrust-length) e
+ (printf " (~A ~A \"~A\"" lisp-el-name lisp-type c-type)
+ ;; offset
+ (as-c "{" cname "t;")
+ (printf " %d"
+ (format nil "((unsigned long)&(t.~A)) - ((unsigned long)&(t))" c-el-name))
+ (as-c "}")
+ ;; length
+ (if distrust-length
+ (printf " 0)")
+ (progn
+ (as-c "{" cname "t;")
+ (printf " %d)"
+ (format nil "sizeof(t.~A)" c-el-name))
+ (as-c "}")))))
+ (printf "))")))