ini-sections, ini-keys, ini-for-each added.
This commit is contained in:
@@ -1,16 +1,21 @@
|
||||
#lang racket/base
|
||||
|
||||
(require racket/string)
|
||||
(require racket/file)
|
||||
(require racket/port)
|
||||
(require racket/serialize)
|
||||
(require racket/string
|
||||
racket/file
|
||||
racket/port
|
||||
racket/serialize
|
||||
racket/contract)
|
||||
|
||||
(provide file->ini
|
||||
ini->file
|
||||
ini-get
|
||||
ini-set!
|
||||
make-ini
|
||||
get-ini-file
|
||||
get-ini-file
|
||||
ini-sections
|
||||
ini-keys
|
||||
ini-for-each
|
||||
is-ini?
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -18,7 +23,7 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-struct ini-cfg
|
||||
(contents #:mutable #t)
|
||||
((contents #:mutable))
|
||||
)
|
||||
|
||||
(define (output-value v out)
|
||||
@@ -89,8 +94,12 @@
|
||||
(build-path pref-dir (string-append (symbol->string f) ".ini")))
|
||||
(build-path f)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Writes an ini file to the given file
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define (ini->file ini file #:private? [private? #f])
|
||||
(define/contract (ini->file ini file #:private? [private? #f])
|
||||
(->* (ini-cfg? path-string?) (#:private? boolean?) void?)
|
||||
(let* ((file (get-ini-file file))
|
||||
(_ (make-parent-directory* file))
|
||||
(out (if (and private?
|
||||
@@ -132,11 +141,24 @@
|
||||
(newline out))
|
||||
(error "Unknown line format")))))
|
||||
lines))))
|
||||
(mcdr ini)))
|
||||
(close-output-port out)))
|
||||
(ini-cfg-contents ini)))
|
||||
(close-output-port out))
|
||||
(void)
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Creates an empty ini structure
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define (make-ini)
|
||||
(mcons 'ini (list)))
|
||||
(make-ini-cfg '()))
|
||||
|
||||
(define (is-ini? i)
|
||||
(ini-cfg? i))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Reads an ini file to an internal ini structure
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define (file->ini file*)
|
||||
(let* ((file (get-ini-file file*))
|
||||
@@ -168,7 +190,14 @@
|
||||
(if m-section
|
||||
(f (append sections (list section)) (list (string->symbol (string-trim (cadr m-section)))) (cdr lines))
|
||||
(error (format "Unknown INI line\n~a: ~a\n" line-nr line)))))))))))
|
||||
(mcons 'ini (f '() (list 'nil) lines)))))
|
||||
(make-ini-cfg (f '() (list 'nil) lines))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Gets a value from the ini structure
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define (ini-get ini section key def-val)
|
||||
(letrec ((g (lambda (ini)
|
||||
@@ -186,10 +215,17 @@
|
||||
(f (cdr l))))))))
|
||||
(f (cdar ini)))
|
||||
(g (cdr ini)))))))
|
||||
(g (mcdr ini))))
|
||||
(g (ini-cfg-contents ini))))
|
||||
|
||||
(define (ini-set! ini section key val)
|
||||
(let ((found #f))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Sets a value in the ini structure
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define (ini-set! ini section key* val)
|
||||
(let ((found #f)
|
||||
(key (string->symbol (format "~a" key*)))
|
||||
)
|
||||
(letrec ((for-sect (lambda (sect)
|
||||
(if (null? sect)
|
||||
(if found
|
||||
@@ -215,8 +251,73 @@
|
||||
(if (section=? section-key section)
|
||||
(cons (cons section (for-sect (cdr ini-section))) (for-ini (cdr ini)))
|
||||
(cons ini-section (for-ini (cdr ini)))))))))
|
||||
(let ((new-ini (for-ini (mcdr ini))))
|
||||
(set-mcdr! ini new-ini)
|
||||
ini)))))
|
||||
(let ((new-ini (for-ini (ini-cfg-contents ini))))
|
||||
(set-ini-cfg-contents! ini new-ini))
|
||||
ini))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Gets all sections of the ini file
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define/contract (ini-sections cfg)
|
||||
(-> ini-cfg? (listof symbol?))
|
||||
(map (λ (sect) (car sect))
|
||||
(filter (λ (sect) (not (eq? (car sect) 'nil)))
|
||||
(ini-cfg-contents cfg))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Gets all keys for a given section
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define/contract (ini-keys cfg section)
|
||||
(-> ini-cfg? symbol? (listof symbol?))
|
||||
(let ((s (filter (λ (sect) (eq? (car sect) section)) (ini-cfg-contents cfg))))
|
||||
(if (null? s)
|
||||
'()
|
||||
(map cadr
|
||||
(filter (λ (kv)
|
||||
(not (eq? (car kv) 'empty))) (cdar s)))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; iterates over all sections and keys of an ini structure
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define (any? a) #t)
|
||||
|
||||
(define/contract (ini-for-each f cfg)
|
||||
(-> procedure? ini-cfg? any?)
|
||||
(for-each (λ (s)
|
||||
(for-each (λ (kv)
|
||||
(when (eq? (car kv) 'keyval)
|
||||
(f (car s) (cadr kv) (caddr kv))))
|
||||
(cdr s)))
|
||||
(ini-cfg-contents cfg)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Tests for module library.rkt
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(module+ test
|
||||
(require rackunit)
|
||||
|
||||
(define (run-ini-tests)
|
||||
(define test-ini (make-ini))
|
||||
(ini-set! test-ini 'section1 'key1 "Value 1")
|
||||
(ini-set! test-ini 'section1 'key2 42)
|
||||
(ini-set! test-ini 'section1 77 7777)
|
||||
|
||||
(ini-set! test-ini 'section2 'key1 (list "Value 1"))
|
||||
(ini-set! test-ini 'section2 "my-key" (make-hash '((a . 42) (b . "Hi There"))))
|
||||
|
||||
(check-equal?
|
||||
(list 'section1 'section2) (ini-sections test-ini))
|
||||
|
||||
test-ini
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user