-(defun c-for-structure (stream lisp-name c-struct)
- (destructuring-bind (c-name &rest elements) c-struct
- (format stream "printf(\"(sb-grovel::define-c-struct ~A %d)\\n\",sizeof (~A));~%" lisp-name c-name)
- (dolist (e elements)
- (destructuring-bind (lisp-type lisp-el-name c-type c-el-name) e
- ;; FIXME: this format string doesn't actually guarantee
- ;; non-multilined-string-constantness, it just makes it more
- ;; likely. Sort out the required behaviour (and maybe make
- ;; the generated C more readable, while we're at it...) --
- ;; CSR, 2003-05-27
- (format stream "printf(\"(sb-grovel::define-c-accessor ~A-~A\\n\\~% ~
- ~A ~A \");~%"
- lisp-name lisp-el-name lisp-name lisp-type)
- ;; offset
- (format stream "{ ~A t;printf(\"%d \",((unsigned long)&(t.~A)) - ((unsigned long)&(t)) ); }~%"
- c-name c-el-name)
- ;; length
- (format stream "{ ~A t;printf(\"%d\",(sizeof t.~A));}~%"
- c-name c-el-name)
- (format stream "printf(\")\\n\");~%")))))
+(defvar *default-c-stream* nil)
+
+(defun escape-for-string (string)
+ (c-escape string))
+
+(defun c-escape (string &optional (dangerous-chars '(#\")) (escape-char #\\))
+ "Escape DANGEROUS-CHARS in STRING, with ESCAPE-CHAR."
+ (coerce (loop for c across string
+ if (member c dangerous-chars) collect escape-char
+ collect c)
+ 'string))
+
+(defun as-c (&rest args)
+ "Pretty-print ARGS into the C source file, separated by #\Space"
+ (format *default-c-stream* "~A~{ ~A~}~%" (first args) (rest args)))
+
+(defun printf (formatter &rest args)
+ "Emit C code to printf the quoted code, via FORMAT.
+The first argument is the C string that should be passed to
+printf.
+
+The rest of the arguments are consumed by FORMAT clauses, until
+there are no more FORMAT clauses to fill. If there are more
+arguments, they are emitted as printf arguments.