;; ;; member2-record.scm ;; ;; Procedures working with complete member record (as loaded by the ;; members-base). ;; ;; ISC License ;; ;; Copyright 2023 Brmlab, z.s. ;; Dominik Pantůček ;; ;; Permission to use, copy, modify, and/or distribute this software ;; for any purpose with or without fee is hereby granted, provided ;; that the above copyright notice and this permission notice appear ;; in all copies. ;; ;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL ;; WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED ;; WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE ;; AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR ;; CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS ;; OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, ;; NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ;; CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ;; (declare (unit member2-record)) (module member2-record ( make-member-record member-record-input-file member-record-set member-record-add-highlight member-record-tests! ) (import scheme (chicken base) (chicken keyword) dictionary testing) ;; Creates new member record based on the file and symlinks ;; information received from the members directory. Any keyword ;; arguments are converted to respective symbols in the dictionary. (define (make-member-record file-name file-path symlinks . args) (let loop ((args args) (pairs `((file-name . ,file-name) (file-path . ,file-path) (symlinks . ,symlinks)))) (if (null? args) (make-dict pairs) (if (not (keyword? (car args))) (error 'make-member-record "Optional arguments must be keywords" (car args)) (if (null? (cdr args)) (error 'make-member-record "Each optional keyword argument must have a value" (car args)) (loop (cddr args) (cons (cons (string->symbol (keyword->string (car args))) (cadr args)) pairs))))))) ;; Returns opened input file for this record (used by parser). (define (member-record-input-file mr) (open-input-file (dict-ref mr 'file-path))) ;; Sets pairs of keys/values for given member record. (define (member-record-set mr . args) (let loop ((args args) (mr mr)) (if (null? args) mr (if (not (keyword? (car args))) (error 'member-record-set "Needs argument keyword" (car args)) (if (null? (cdr args)) (error 'member-record-set "Argument needs value" (car args)) (loop (cddr args) (dict-set mr (string->symbol (keyword->string (car args))) (cadr args)))))))) ;; Adds highlight identified by line number, message, pass number and ;; type (error, warning, info). (define (member-record-add-highlight mr line-number message pass type) (dict-set mr 'highlights (cons (list line-number message pass type) (dict-ref mr 'highlights '())))) ;; Self-tests (define (member-record-tests!) (run-tests member-record (test-equal? make-member-record (make-member-record "1234" "members/1234" '("member")) '((file-name . "1234") (file-path . "members/1234") (symlinks "member"))) (test-equal? make-member-record (make-member-record "1234" "members/1234" '("member") #:id 1234) '((id . 1234) (file-name . "1234") (file-path . "members/1234") (symlinks "member"))) (test-equal? member-record-set (member-record-set '() #:id 1234) '((id . 1234))) (test-equal? member-record-add-highlight (member-record-add-highlight '() 123 "Interesting..." 0 'info) '((highlights . ((123 "Interesting..." 0 info))))) )) ) (import member2-record) (member-record-tests!)