ref: 60eafd49a8e2a67d82ad1e9f5d0618003c6c4cec
dir: /lib/zuo/config.zuo/
#lang zuo/base (provide config-file->hash) (define (config-file->hash path [vars (hash)]) (unless (path-string? path) (arg-error 'config->hash "path string" path)) (unless (hash? vars) (arg-error 'config->hash "hash table" vars)) (define content (file->string path)) (define no-cr-content (string-join (string-split content "\r") "")) (define lines (string-split (string-join (string-split no-cr-content "\\\n") "") "\n")) (define config (foldl (lambda (line accum) (define positions ; (list var-start var-end =-pos) or #f (let loop ([i 0] [start #f] [end #f]) (cond [(= i (string-length line)) #f] [else (let ([c (string-ref line i)]) (cond [(= (char "=") c) (and start (list start (or end i) i))] [(or (= (char "_") c) (and (<= (char "a") c) (<= c (char "z"))) (and (<= (char "A") c) (<= c (char "Z"))) (and (<= (char "0") c) (<= c (char "9")))) (and (not end) (loop (+ i 1) (or start i) #f))] [(= (char " ") c) (if start (loop (+ i 1) start (or end i)) (loop (+ i 1) #f #f))] [else #f]))]))) (cond [positions (define var (string->symbol (substring line (car positions) (cadr positions)))) (define rhs (substring line (+ (list-ref positions 2) 1) (string-length line))) (hash-set accum var (string-trim (remove-makefile-comment rhs)))] [else accum])) (hash) lines)) (foldl (lambda (key config) (hash-set config key (hash-ref vars key) )) config (hash-keys vars))) (define (remove-makefile-comment s) (define l (string-split s "#")) (cond [(= (length l) 1) s] [else ;; A `\` just before `#` escapes the `#` (let loop ([l l]) (cond [(null? l) ""] [else (let* ([s (car l)] [len (string-length s)]) (cond [(= len 0) ""] [(= (char "\\") (string-ref s (- len 1))) (~a (substring s 0 (- len 1)) "#" (loop (cdr l)))] [else s]))]))]))