(require (lib "plt-match.ss"))
(define header "// Autogenerated by autogen.ss")
(define sockopt.in "sockopt.in")
(define sockopt.export "sockopt.export")
(define sockopt.get "sockopt.get")
(define sockopt.set "sockopt.set")
(define (generate file gen)
(let ((outp (open-output-file file 'truncate)))
(parameterize ((current-output-port outp))
(display header)
(newline)
(gen)
(newline))
(close-output-port outp)))
(define (generate-exports in)
(define export "
#ifdef ~a
EXPORT_CONST( ~a );
#endif
")
(define (gen)
(define (genx sym) (printf export sym sym))
(for-each (match-lambda
(`(level ,sym . ,opts)
(for-each (match-lambda (`(,sym . ,_) (genx sym))) opts))
(`(const . ,syms) (for-each genx syms)))
in))
(generate sockopt.export gen))
(define (generate-sockopts in)
(define head "
case ~a:
switch (opt) {
")
(define tail "
default:
FAIL( \"socket-~asockopt: unknown option\" );
}
")
(define sockopt "
#ifdef ~a
case ~a: ~aSOCKOPT_~a(~a);
#endif
")
(define (gen op)
(define opname (string-upcase (symbol->string op)))
(define (genx)
(define (gen? optt) (or (eq? op optt) (eq? 'get/set optt)))
(match-lambda
(`(,sym (,type ,len) ,optt)
(when (gen? optt)
(printf sockopt sym sym opname type len)))
(`(,sym ,type ,optt)
(when (gen? optt)
(printf sockopt sym sym opname type "")))))
(lambda ()
(for-each (match-lambda
(`(level ,level . ,opts)
(printf head level)
(for-each (genx) opts)
(printf tail opname))
(`(const . ,_) (void)))
in)))
(generate sockopt.get (gen 'get))
(generate sockopt.set (gen 'set)))
(let ((in (read (open-input-file sockopt.in))))
(generate-exports in)
(generate-sockopts in))