git.fiddlerwoaroof.com
Browse code

Have split handle empty strings appropriately.

fiddlerwoaroof authored on 27/08/2017 20:57:00
Showing 2 changed files
... ...
@@ -49,7 +49,8 @@
49 49
 
50 50
 ;; TODO: implement test
51 51
 (defun %split-on-char (divider string &key count (test nil))
52
-  (declare (optimize #+dev (debug 3) (speed 3) (space 2))
52
+  (declare (optimize #+dev (debug 3) #+dev (speed 0) #+dev (space 0)
53
+                     #-dev (speed 3) #-dev(space 2))
53 54
            (type (or null array-length) count)
54 55
            (type (or null function symbol) test)
55 56
            (type character divider)
... ...
@@ -60,21 +61,25 @@
60 61
   (check-type string simple-string)
61 62
 
62 63
   (flet ((count-splits (string)
63
-           (declare (optimize (speed 3))
64
+           (declare (optimize #+dev (debug 3) #+dev (speed 0) #+dev (space 0)
65
+                              #-dev (speed 3) #-dev(space 2))
64 66
                     (type simple-string string))
65
-           (do* ((x (the array-length 0) (1+ x))
66
-                 (cur-char #1=(aref string x) #1#)
67
-                 (result (the array-length
68
-                              (if (char= cur-char divider)
69
-                                  1
70
-                                  0))
71
-                         (if (char= cur-char divider)
72
-                             (1+ result)
73
-                             result)))
74
-                ((= x (1- (length string))) (1+ result))
75
-             (declare (type array-length result))))
67
+           (if (/= 0 (length string))
68
+               (do* ((x (the array-length 0) (1+ x))
69
+                     (cur-char #1=(aref string x) #1#)
70
+                     (result (the array-length
71
+                                  (if (char= cur-char divider)
72
+                                      1
73
+                                      0))
74
+                             (if (char= cur-char divider)
75
+                                 (1+ result)
76
+                                 result)))
77
+                    ((= x (1- (length string))) (1+ result))
78
+                 (declare (type array-length result)))
79
+               0))
76 80
          (find-pos (start-pos)
77
-           (declare (optimize (speed 3))
81
+           (declare (optimize #+dev (debug 3) #+dev (speed 0) #+dev (space 0)
82
+                     #-dev (speed 3) #-dev(space 2))
78 83
                     (type array-index start-pos))
79 84
            (etypecase test
80 85
              (function (position divider string :start start-pos :test test))
... ...
@@ -85,7 +90,7 @@
85 90
       (setf count (count-splits string)))
86 91
 
87 92
     (check-type count array-length)
88
-    (let ((parts (make-array count :fill-pointer 0))
93
+    (let ((parts (make-array (max count 1) :fill-pointer 0))
89 94
           (start-pos (the fixnum 0)))
90 95
       (declare (dynamic-extent start-pos))
91 96
       (prog1 parts
... ...
@@ -97,10 +102,11 @@
97 102
              (setf start-pos (1+ end-pos))
98 103
            while (< (length parts) (1- count))
99 104
            finally
100
-             (when (and end-pos count)
101
-               (vector-push (subseq string start-pos)
102
-                            parts))
103
-             )))))
105
+             (cond ((and end-pos count)
106
+                    (vector-push (subseq string start-pos)
107
+                                 parts))
108
+                   ((not end-pos)
109
+                    (vector-push "" parts))))))))
104 110
 
105 111
 (defun %split-on-string (divider string &key count (test nil))
106 112
   (declare (optimize #+dev (debug 3) (speed 3))
... ...
@@ -1,7 +1,9 @@
1 1
 (in-package :fwoar.string-utils)
2 2
 
3 3
 (defun vos-equal (a b)
4
-  (every 'equal a b))
4
+  (and (= (length a)
5
+          (length b))
6
+       (every 'equal a b)))
5 7
 
6 8
 (progn
7 9
   (st:deftest string-split-as-expected-with-test ()
... ...
@@ -36,6 +38,10 @@
36 38
     (st:should be vos-equal
37 39
                #("a" "b" "c" "d")
38 40
                (%split-on-string " " "a b c d")))
41
+  (st:deftest string-split-empty-string-as-expected ()
42
+    (st:should be vos-equal
43
+               #("")
44
+               (%split-on-string "/" "")))
39 45
 
40 46
   (st:deftest char-split-as-expected-with-test ()
41 47
     (st:should be vos-equal
... ...
@@ -65,4 +71,9 @@
65 71
     (st:should be vos-equal
66 72
                #("a" "b" "c" "d")
67 73
                (%split-on-char #\space "a b c d")))
74
+
75
+  (st:deftest char-split-empty-string-as-expected ()
76
+    (st:should be vos-equal
77
+               #("")
78
+               (%split-on-char #\/ "")))
68 79
   )