(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 #:exists '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 " #ifdef ~a case ~a: switch (opt) { ") (define tail " default: ERROR( \"socket-~asockopt: unknown option\" ); } #endif ") (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 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))