3 (defun nice-name (string)
4 (string-trim "
" string
))
6 (defun nice-keyword (string)
7 (s-sql:from-sql-name
(nice-name string
)))
9 (defun read-from-string-maybe (string)
11 (let ((token (read-from-string string
)))
12 (if (numberp token
) token string
))
15 (defun groupname (line)
16 "Return group name if any, or nil."
17 (let* ((groupname-start (position #\
[ line
))
18 (groupname-end (and groupname-start
(position #\
] line
:start groupname-start
))))
19 (when groupname-end
(nice-keyword (subseq line
(1+ groupname-start
) groupname-end
)))))
21 (defun key-value-pair (line)
22 "Return a key/value pair if any, or nil."
23 (let ((equal-sign-position (position #\
= line
)))
24 (when equal-sign-position
25 (list (nice-keyword (subseq line
0 equal-sign-position
))
26 (read-from-string-maybe (nice-name (subseq line
(1+ equal-sign-position
))))))))
28 (defun discard-comment (line)
29 (let ((half-cleaned (subseq line
0 (position #\
# line
))))
30 (subseq half-cleaned
0 (position #\
; half-cleaned))))
34 "Read the ini file from path. Return an alist of plists."
35 (with-open-file (stream path
)
36 (let ((ini (list (cons nil nil
)))) ;group of the groupless
38 for line
= (discard-comment (read-line stream nil
))
40 (let ((groupname (groupname line
)))
42 (setf ini
(append ini
(list (cons groupname nil
))))
43 (let ((key-value-pair (key-value-pair line
)))
44 (when key-value-pair
(setf (cdar (last ini
)) (append (cdar (last ini
)) key-value-pair
)))))))