aboutsummaryrefslogtreecommitdiff
path: root/module/calp/util/config.scm
diff options
context:
space:
mode:
Diffstat (limited to 'module/calp/util/config.scm')
-rw-r--r--module/calp/util/config.scm173
1 files changed, 44 insertions, 129 deletions
diff --git a/module/calp/util/config.scm b/module/calp/util/config.scm
index 3bc55d92..b2a46ea7 100644
--- a/module/calp/util/config.scm
+++ b/module/calp/util/config.scm
@@ -7,143 +7,58 @@
(define-module (calp util config)
:use-module (hnh util)
:use-module (srfi srfi-1)
- :use-module (ice-9 format) ; for format-procedure
:use-module (ice-9 curried-definitions) ; for ensure
:use-module (calp translation)
:export (define-config)
)
-(define-once config-values (make-hash-table))
-
-;; properties declared before being bound into hash-map
-;; to allow nicer scripting in this file.
-
-(define-once config-properties (make-hash-table))
-(define description (make-object-property))
-(define source-module (make-object-property))
-(define pre (make-object-property))
-(define post (make-object-property))
-(hashq-set! config-properties #:description description)
-(hashq-set! config-properties #:source-module source-module)
-(hashq-set! config-properties #:pre pre)
-(hashq-set! config-properties #:post post)
-
-
-;; Config cells "are" immutable. @var{set-property!} is
-;; therefore intentionally unwritten.
-
-(define-public (get-property config-name property-key)
- ((hashq-ref config-properties property-key) config-name))
-
-
-(define (define-config% name default-value kwargs)
- (for (key value) in (group kwargs 2)
- (aif (hashq-ref config-properties key)
- (set! (it name) value)
- (scm-error 'configuration-error
- "define-config"
- (_ "No configuration slot named ~s, when defining ~s")
- (list key name)
- #f)))
- (set-config! name (get-config name default-value)))
-
-(define-syntax define-config
- (syntax-rules ()
- ((_ name default kwargs ...)
- (define-config% (quote name) default
- (list source-module: (current-module)
- kwargs ...)))))
-
-(define-public (set-config! name value)
- (hashq-set! config-values name
- (aif (pre name)
- (or (it value)
- (scm-error 'configuration-error
- "set-config!"
- ;; first slot is property name, second is new
- ;; property value.
- (_ "Pre-property failed when setting ~s to ~s")
- (list name value)
- #f))
- value))
-
- (awhen (post name) (it value)))
-
-;; unique symbol here since #f is a valid configuration value.
-(define %uniq (gensym))
-(define*-public (get-config key optional: (default %uniq))
- (if (eq? default %uniq)
- (let ((v (hashq-ref config-values key %uniq)))
- (when (eq? v %uniq)
- (scm-error 'configuration-error
- "get-config"
- (_ "No configuration item named ~s")
- (list key) #f))
- v)
- (hashq-ref config-values key default)))
+(define (fix-keywords args)
+ (map (lambda (arg)
+ (if (keyword? (syntax->datum arg))
+ (syntax->datum arg)
+ arg))
+ args))
+
+(define %configuration-error
+ (_ "Pre-property failed when setting ~s to ~s"))
+
+(define-syntax (define-config stx)
+ (syntax-case stx ()
+ ((_ name default kw ...)
+ (let ((pre (cond ((memv pre: (fix-keywords #'(kw ...))) => cadr) (else #f)))
+ (post (cond ((memv post: (fix-keywords #'(kw ...))) => cadr) (else #f))))
+ #`(begin
+ (define-once name
+ (make-parameter
+ default
+ #,@(cond ((and pre post)
+ #`((lambda (new-value)
+ (cond ((#,pre new-value)
+ => (lambda (translated)
+ (#,post translated)
+ translated))
+ (else
+ (scm-error 'configuration-error
+ "set-config!"
+ %configuration-error
+ (list (quote name) new-value)))))))
+ (pre
+ #`((lambda (new-value)
+ (or (#,pre new-value)
+ (scm-error 'configuration-error
+ "set-config!"
+ %configuration-error
+ (list (quote name) new-value))))))
+ (post
+ #`((lambda (new-value)
+ (#,post new-value)
+ new-value))
+ )
+ (else #'()))))
+ (export name))))))
(define-public ((ensure predicate) value)
(if (predicate value)
value #f))
-
-
-
-;; (format-procedure (lambda (x y) ...)) => λx, y
-;; (define (f x) ...)
-;; (format-procedure f) => f(x)
-(define (format-procedure proc)
- ((aif (procedure-name proc)
- (lambda (s) (string-append (symbol->string it) "(" s ")"))
- (lambda (s) (string-append "λ" s)))
- (let ((args ((@ (ice-9 session) procedure-arguments)
- proc)))
- (string-join
- (remove null?
- (list
- (awhen ((ensure (negate null?))
- (assoc-ref args 'required))
- (format #f "~{~a~^, ~}" it))
- (awhen ((ensure (negate null?))
- (assoc-ref args 'optional))
- (format #f "[~{~a~^, ~}]" it))
- (awhen ((ensure (negate null?))
- (assoc-ref args 'keyword))
- (format #f "key: ~{~a~^, ~}"
- (map keyword->symbol
- (map car it))))
- (awhen ((ensure (negate null?))
- (assoc-ref args 'rest))
- (format #f "~a ..." it))))
- ", "))))
-
-(export format-procedure)
-
-;; TODO break this up into separate `get-all-configuration-items' and
-;; `format-configuration-items' procedures
-(define-public (get-configuration-documentation)
- (define groups
- (group-by (compose source-module car)
- (hash-map->list list config-values)))
-
- `(*TOP*
- (header ,(_ "Configuration variables"))
- (dl
- ,@(concatenate
- (for (module values) in groups
- `((dt "") (dd (header ,(aif module
- (->str (module-name it))
- #f)))
- ,@(concatenate
- (for (key value) in values
- `((dt ,key)
- (dd (p (@ (inline))
- ,(or (description key) "")))
- ;; Configuration variable value indicator
- (dt ,(_ "V:"))
- (dd ,(if (procedure? value)
- (format-procedure value)
- `(scheme ,value))
- (br)))))))))))
-