autogen.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 #: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))