root/trunk/bknr/datastore/src/utils/reader.lisp

Revision 1827, 3.3 kB (checked in by hhubner, 3 years ago)

Tchadvar Roussanov:

This is a small patch for init.lisp and some fixes to make sbcl compiler
happy with 'defconstant'.

  • Property svn:eol-style set to native
  • Property svn:keywords set to author date id revision
Line 
1 (in-package :bknr.utils)
2
3 (define-constant +whitespace-chars+
4   '(#\Space #\Newline #\Tab #\Linefeed))
5
6 (defun whitespace-char-p (c)
7   (member c +whitespace-chars+))
8
9 (defun whitespace-p (c-or-s)
10   (cond ((stringp c-or-s)
11          (every #'whitespace-char-p c-or-s))
12         ((characterp c-or-s)
13          (whitespace-char-p c-or-s))
14         (t nil)))
15
16 (defun bknr-read-string-until (s endchar &key (start nil)
17                                (test #'eql) test-not (unread-endchar nil))
18   (do ((c (peek-char nil s nil 'eof)
19           (peek-char nil s nil 'eof))
20        (ret (copy-list start))
21        (escaped nil (and (not escaped) (eql c #\\))))
22       ((or (eq c 'eof)
23            (and (not escaped)
24                 (if test-not
25                     (not (funcall test-not c endchar))
26                     (funcall test c endchar))))
27        (unless (or unread-endchar
28                    (eq c 'eof))
29          (push (read-char s) ret))
30        (coerce (nreverse ret) 'string))
31     (push (read-char s) ret)))
32
33 (defun bknr-read-string (s)
34   (bknr-read-string-until s #\" :start '(#\")))
35
36 (defun bknr-read-comment (s)
37   (bknr-read-string-until s '(#\Newline #\Linefeed) :test #'member :unread-endchar t))
38
39 (defun bknr-read-whitespace (s)
40   (bknr-read-string-until s +whitespace-chars+ :test-not #'member :unread-endchar t))
41
42 (defun bknr-read-something (s)
43   (bknr-read-string-until s (append +whitespace-chars+ '(#\( #\" #\))) :test #'member
44                         :unread-endchar t))
45
46 (defun bknr-read-delimited-list (s endchar &optional eof-error-p eof-value collect-whitespace)
47   (do ((c (peek-char nil s nil 'eof)
48           (peek-char nil s nil 'eof))
49        ret)
50       ((or (eq c 'eof)
51            (eq c endchar))
52        (when (eq c endchar)
53          (read-char s))
54        (nreverse ret))
55     (push (bknr-read s eof-error-p eof-value collect-whitespace) ret)))
56
57 (defun bknr-read (s &optional (eof-error-p t) eof-value (collect-whitespace t))
58   (prog ()
59    again
60    (let ((c (peek-char nil s eof-error-p eof-value)))
61      (cond ((and eof-value
62                  (eq c eof-value))
63             (return eof-value))
64            ((eq c #\()
65             (read-char s)
66             (return
67               (if collect-whitespace
68                   (collect-whitespace (bknr-read-delimited-list
69                                        s #\) eof-error-p eof-value collect-whitespace))
70                   (bknr-read-delimited-list
71                    s #\) eof-error-p eof-value collect-whitespace))))
72            ((eq c #\")
73               (read-char s)
74             (return (bknr-read-string s)))
75            ((eq c #\;)
76             (return (bknr-read-comment s)))
77            ((eq c #\))
78             (read-char s)
79             (return ")"))
80            ((whitespace-char-p c)
81             (let ((whitespace (bknr-read-whitespace s)))
82                 (if collect-whitespace
83                     (return whitespace)
84                     (go again))))
85            (t (return (bknr-read-something s)))))))
86
87 (defun collect-whitespace (list)
88   (do ((l list (cdr l))
89        whitespace)
90       ((or (null l)
91            (not (whitespace-p (car l))))
92        (cond ((and (null whitespace)
93                    (null l))
94               nil)
95              (t (cons (apply #'concatenate 'string (nreverse whitespace))
96                       (unless (null l)
97                         (cons (car l) (collect-whitespace (cdr l))))))))
98     (when (> (length (car l)) 0)
99       (push (car l) whitespace))))
100
101 (defun string-beginning-with-p (string beginning)
102   (let ((beginlen (length beginning)))
103     (and (stringp string)
104          (and (>= (length string) beginlen)
105               (string-equal (subseq string 0 beginlen) beginning)))))
106
107 (defun string-delimited-by-p (string char)
108   (and (stringp string)
109        (let ((len (length string)))
110          (and (> len 2)
111               (eql (char string 0) char)
112               (eql (char string (1- len)) char)))))
113
Note: See TracBrowser for help on using the browser.