Marko Tapio Manninen mmstud@gmail.com writes:
void (*cb)(struct evbuffer *, size_t, size_t, void *);
This is explained in tutorial format in §3.9 `Calling Lisp from C' in the official manual, and reference documentation is in §11 `Callbacks'. The official manual may be found on the website, but I strongly recommend that you use the one you should have received with CFFI.
(defconstant HTTP_OK 200) (defconstant HTTP_NOCONTENT 204) (defconstant HTTP_MOVEPERM 301) ...
`defcenum' would be good for this.
(defcstruct evbuffer (*buffer :unsigned-char) (*orig_buffer :unsigned-char) (misalign size-t) (totallen size-t) (off size-t) (*cb :pointer) ; struct? (*cbarg :pointer))
Interestingly, this arg is called "closure" in libraries that know what it hacks around. You may wish to call it that to make its nature clear to Lisp-readers.
(defcfun ("evbuffer_add_printf" %evbuffer-add-printf) :void (buf evbuffer) (msg :string) (uri :string))
I believe this was mentioned on #lisp, but those should not be indented a full tab-stop. The communities of Lisp indenters are not nearly as divergent as with some languages, and I don't think you'll find one that would encourage that.
(defcfun ("evhttp_send_reply" %evhttp-send-reply) :void (req evhttp-request) (flag :int) (msg :string) (buf evbuffer))
;;; unwind-protect to create evbuffer-new?
Yes, but it's for freeing, not allocating. See §3.8 `Memory management' for some tips.
(defun generic-handler (req &optional (arg nil)) (let ((buf (%evbuffer-new))) (if (null buf) (error "Failed to create response buffer")
Unfortunately, you can't signal ERROR here after you convert it to a real callback; see the aforementioned §3.9 for why. For generalized conditions, think of this as a game of volleyball, where the call to whatever C function calls GENERIC-HANDLER is the net.