aboutsummaryrefslogtreecommitdiffstats
path: root/csc/strings.csc
blob: 0259697787f239bd9881e0b6ce111651a7d8cd9b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
(define-library (csc strings)
  (export
    contains
    find
    join
    not-found-error?
    prefix?
    split
    str-quote)
  (import (scheme base)
          (only (scheme case-lambda) case-lambda)
          (only (scheme write) write)
          (only (csc list) intercalate)
          (only (csc loop) loop))
  (begin


    (define prefix?
      (case-lambda
        ((prefix str) (prefix? prefix str 0))
        ((prefix str start)
         (and (<= (string-length prefix) (- (string-length str) start))
              (string=? prefix (substring str start (+ start (string-length prefix))))))))


    (define (str-quote s)
      (let ((out (open-output-string)))
        (write s out)
        (get-output-string out)))


    (define-record-type <not-found-error>
      (make-not-found-error)
      not-found-error?)


    (define find
      (case-lambda
        ((match str) (find match str 0 (string-length str)))
        ((match str start) (find match str start (string-length str)))
        ((match str start end)
         (let loop ((i start))
           (cond ((>= i end) (raise (make-not-found-error)))
                 ((prefix? match str i) i)
                 (else (loop (+ 1 i))))))))


    (define (contains s substr)
      (if (string=? "" substr)
        #t
        (guard (e ((not-found-error? e) #f))
          (find substr s)
          #t)))


    (define (join sep . strings)
      (apply string-append (intercalate sep strings)))


    (define (split s sep)
      (loop for s* = s then (string-copy s* (+ i (string-length sep)))
            for i = (guard (e ((not-found-error? e) (string-length s*)))
                      (find sep s*))
            collect (substring s* 0 i)
            while (< i (string-length s*))))))