clucumber 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +4 -9
  3. data/lib/clucumber/clucumber-bootstrap.lisp +32 -0
  4. data/lib/clucumber/vendor/cl-interpol/alias.lisp +55 -0
  5. data/lib/clucumber/vendor/cl-interpol/cl-interpol.asd +56 -0
  6. data/lib/clucumber/vendor/cl-interpol/load.lisp +53 -0
  7. data/lib/clucumber/vendor/cl-interpol/packages.lisp +40 -0
  8. data/lib/clucumber/vendor/cl-interpol/read.lisp +716 -0
  9. data/lib/clucumber/vendor/cl-interpol/specials.lisp +113 -0
  10. data/lib/clucumber/vendor/cl-interpol/test/packages.lisp +34 -0
  11. data/lib/clucumber/vendor/cl-interpol/test/tests.lisp +128 -0
  12. data/lib/clucumber/vendor/cl-interpol/test.lisp +177 -0
  13. data/lib/clucumber/vendor/cl-interpol/test2.lisp +6254 -0
  14. data/lib/clucumber/vendor/cl-interpol/unicode.lisp +13912 -0
  15. data/lib/clucumber/vendor/cl-interpol/util.lisp +122 -0
  16. data/lib/clucumber/vendor/cl-ppcre/api.lisp +1262 -0
  17. data/lib/clucumber/vendor/cl-ppcre/charmap.lisp +152 -0
  18. data/lib/clucumber/vendor/cl-ppcre/charset.lisp +242 -0
  19. data/lib/clucumber/vendor/cl-ppcre/chartest.lisp +98 -0
  20. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-test.asd +34 -0
  21. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode/packages.lisp +38 -0
  22. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode/resolver.lisp +61 -0
  23. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode.asd +58 -0
  24. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre.asd +79 -0
  25. data/lib/clucumber/vendor/cl-ppcre/closures.lisp +471 -0
  26. data/lib/clucumber/vendor/cl-ppcre/convert.lisp +875 -0
  27. data/lib/clucumber/vendor/cl-ppcre/errors.lisp +84 -0
  28. data/lib/clucumber/vendor/cl-ppcre/lexer.lisp +737 -0
  29. data/lib/clucumber/vendor/cl-ppcre/lispworks-defsystem.lisp +57 -0
  30. data/lib/clucumber/vendor/cl-ppcre/load.lisp +67 -0
  31. data/lib/clucumber/vendor/cl-ppcre/optimize.lisp +578 -0
  32. data/lib/clucumber/vendor/cl-ppcre/packages.lisp +68 -0
  33. data/lib/clucumber/vendor/cl-ppcre/parser.lisp +319 -0
  34. data/lib/clucumber/vendor/cl-ppcre/ppcre-tests.lisp +269 -0
  35. data/lib/clucumber/vendor/cl-ppcre/regex-class-util.lisp +555 -0
  36. data/lib/clucumber/vendor/cl-ppcre/regex-class.lisp +259 -0
  37. data/lib/clucumber/vendor/cl-ppcre/repetition-closures.lisp +833 -0
  38. data/lib/clucumber/vendor/cl-ppcre/scanner.lisp +506 -0
  39. data/lib/clucumber/vendor/cl-ppcre/specials.lisp +172 -0
  40. data/lib/clucumber/vendor/cl-ppcre/test/packages.lisp +37 -0
  41. data/lib/clucumber/vendor/cl-ppcre/test/perl-tests.lisp +150 -0
  42. data/lib/clucumber/vendor/cl-ppcre/test/tests.lisp +159 -0
  43. data/lib/clucumber/vendor/cl-ppcre/test/unicode-tests.lisp +80 -0
  44. data/lib/clucumber/vendor/cl-ppcre/util.lisp +201 -0
  45. data/lib/clucumber/vendor/cl-unicode/alias.lisp +135 -0
  46. data/lib/clucumber/vendor/cl-unicode/api.lisp +412 -0
  47. data/lib/clucumber/vendor/cl-unicode/build/char-info.lisp +133 -0
  48. data/lib/clucumber/vendor/cl-unicode/build/dump.lisp +239 -0
  49. data/lib/clucumber/vendor/cl-unicode/build/read.lisp +280 -0
  50. data/lib/clucumber/vendor/cl-unicode/build/util.lisp +182 -0
  51. data/lib/clucumber/vendor/cl-unicode/cl-unicode.asd +90 -0
  52. data/lib/clucumber/vendor/cl-unicode/conditions.lisp +54 -0
  53. data/lib/clucumber/vendor/cl-unicode/derived.lisp +120 -0
  54. data/lib/clucumber/vendor/cl-unicode/hash-tables.lisp +20 -0
  55. data/lib/clucumber/vendor/cl-unicode/lists.lisp +10 -0
  56. data/lib/clucumber/vendor/cl-unicode/methods.lisp +15 -0
  57. data/lib/clucumber/vendor/cl-unicode/packages.lisp +76 -0
  58. data/lib/clucumber/vendor/cl-unicode/specials.lisp +135 -0
  59. data/lib/clucumber/vendor/cl-unicode/test/packages.lisp +34 -0
  60. data/lib/clucumber/vendor/cl-unicode/test/tests.lisp +150 -0
  61. data/lib/clucumber/vendor/cl-unicode/test-functions.lisp +94 -0
  62. data/lib/clucumber/vendor/cl-unicode/util.lisp +274 -0
  63. data/lib/clucumber/vendor/lift/compare/fiveam-tests.lisp +14 -0
  64. data/lib/clucumber/vendor/lift/compare/lift-tests.lisp +13 -0
  65. data/lib/clucumber/vendor/lift/compare/rt-tests.lisp +16 -0
  66. data/lib/clucumber/vendor/lift/compare/xlunit-tests.lisp +15 -0
  67. data/lib/clucumber/vendor/lift/dev/changes.lisp +61 -0
  68. data/lib/clucumber/vendor/lift/dev/config.lisp +354 -0
  69. data/lib/clucumber/vendor/lift/dev/copy-file.lisp +117 -0
  70. data/lib/clucumber/vendor/lift/dev/introspection.lisp +232 -0
  71. data/lib/clucumber/vendor/lift/dev/lift-interface.lisp +56 -0
  72. data/lib/clucumber/vendor/lift/dev/lift-notes.lisp +202 -0
  73. data/lib/clucumber/vendor/lift/dev/lift-randomized.lisp +45 -0
  74. data/lib/clucumber/vendor/lift/dev/lift.lisp +2383 -0
  75. data/lib/clucumber/vendor/lift/dev/macros.lisp +229 -0
  76. data/lib/clucumber/vendor/lift/dev/measuring.lisp +156 -0
  77. data/lib/clucumber/vendor/lift/dev/packages.lisp +161 -0
  78. data/lib/clucumber/vendor/lift/dev/port.lisp +151 -0
  79. data/lib/clucumber/vendor/lift/dev/prototypes.lisp +282 -0
  80. data/lib/clucumber/vendor/lift/dev/random-testing.lisp +124 -0
  81. data/lib/clucumber/vendor/lift/dev/report-locations.lisp +13 -0
  82. data/lib/clucumber/vendor/lift/dev/reports.lisp +916 -0
  83. data/lib/clucumber/vendor/lift/dev/utilities.lisp +242 -0
  84. data/lib/clucumber/vendor/lift/docs/package.lisp +6 -0
  85. data/lib/clucumber/vendor/lift/docs/setup.lisp +17 -0
  86. data/lib/clucumber/vendor/lift/examples/basic-examples.lisp +289 -0
  87. data/lib/clucumber/vendor/lift/examples/random-testing.lisp +32 -0
  88. data/lib/clucumber/vendor/lift/lift-documentation.asd +28 -0
  89. data/lib/clucumber/vendor/lift/lift-test.asd +35 -0
  90. data/lib/clucumber/vendor/lift/lift.asd +77 -0
  91. data/lib/clucumber/vendor/lift/test/equality-tests.lisp +40 -0
  92. data/lib/clucumber/vendor/lift/test/finding-tests.lisp +32 -0
  93. data/lib/clucumber/vendor/lift/test/lift-test.lisp +783 -0
  94. data/lib/clucumber/vendor/lift/test/order-of-operations.lisp +54 -0
  95. data/lib/clucumber/vendor/lift/test/packages.lisp +17 -0
  96. data/lib/clucumber/vendor/lift/test/test-config-files.lisp +20 -0
  97. data/lib/clucumber/vendor/lift/test/test-dynamic-variables.lisp +57 -0
  98. data/lib/clucumber/vendor/lift/test/test-maximum-problems.lisp +74 -0
  99. data/lib/clucumber/vendor/lift/test/test-prototypes.lisp +278 -0
  100. data/lib/clucumber/vendor/lift/test/test-timeout.lisp +37 -0
  101. data/lib/clucumber/vendor/lift/test/tests-in-progress.lisp +62 -0
  102. data/lib/clucumber/vendor/lift/test/testsuite-expects.lisp +60 -0
  103. data/lib/clucumber/vendor/lift/timeout/package.lisp +13 -0
  104. data/lib/clucumber/vendor/lift/timeout/with-timeout.lisp +123 -0
  105. data/lib/clucumber/vendor/lift/website/stuff/Temp.lisp +34 -0
  106. data/lib/clucumber/vendor/st-json/st-json.asd +3 -0
  107. data/lib/clucumber/vendor/st-json/st-json.lisp +310 -0
  108. data/lib/clucumber/vendor/trivial-backtrace/dev/backtrace.lisp +127 -0
  109. data/lib/clucumber/vendor/trivial-backtrace/dev/fallback.lisp +10 -0
  110. data/lib/clucumber/vendor/trivial-backtrace/dev/map-backtrace.lisp +103 -0
  111. data/lib/clucumber/vendor/trivial-backtrace/dev/mucking.lisp +75 -0
  112. data/lib/clucumber/vendor/trivial-backtrace/dev/packages.lisp +13 -0
  113. data/lib/clucumber/vendor/trivial-backtrace/dev/utilities.lisp +104 -0
  114. data/lib/clucumber/vendor/trivial-backtrace/test/packages.lisp +5 -0
  115. data/lib/clucumber/vendor/trivial-backtrace/test/test-setup.lisp +4 -0
  116. data/lib/clucumber/vendor/trivial-backtrace/test/tests.lisp +16 -0
  117. data/lib/clucumber/vendor/trivial-backtrace/trivial-backtrace-test.asd +22 -0
  118. data/lib/clucumber/vendor/trivial-backtrace/trivial-backtrace.asd +35 -0
  119. data/lib/clucumber/vendor/usocket/backend/allegro.lisp +199 -0
  120. data/lib/clucumber/vendor/usocket/backend/armedbear.lisp +491 -0
  121. data/lib/clucumber/vendor/usocket/backend/clisp.lisp +260 -0
  122. data/lib/clucumber/vendor/usocket/backend/cmucl.lisp +266 -0
  123. data/lib/clucumber/vendor/usocket/backend/lispworks.lisp +741 -0
  124. data/lib/clucumber/vendor/usocket/backend/mcl.lisp +369 -0
  125. data/lib/clucumber/vendor/usocket/backend/openmcl.lisp +206 -0
  126. data/lib/clucumber/vendor/usocket/backend/sbcl.lisp +424 -0
  127. data/lib/clucumber/vendor/usocket/backend/scl.lisp +261 -0
  128. data/lib/clucumber/vendor/usocket/condition.lisp +227 -0
  129. data/lib/clucumber/vendor/usocket/package.lisp +82 -0
  130. data/lib/clucumber/vendor/usocket/server.lisp +45 -0
  131. data/lib/clucumber/vendor/usocket/test/package.lisp +13 -0
  132. data/lib/clucumber/vendor/usocket/test/test-usocket.lisp +166 -0
  133. data/lib/clucumber/vendor/usocket/usocket-test.asd +26 -0
  134. data/lib/clucumber/vendor/usocket/usocket.asd +37 -0
  135. data/lib/clucumber/vendor/usocket/usocket.lisp +542 -0
  136. data/lib/clucumber/vendor/usocket/vendor/kqueue.lisp +1 -0
  137. data/lib/clucumber/vendor/usocket/vendor/split-sequence.lisp +245 -0
  138. data/lib/clucumber.rb +29 -7
  139. metadata +151 -5
@@ -0,0 +1,578 @@
1
+ ;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-PPCRE; Base: 10 -*-
2
+ ;;; $Header: /usr/local/cvsrep/cl-ppcre/optimize.lisp,v 1.36 2009/09/17 19:17:31 edi Exp $
3
+
4
+ ;;; This file contains optimizations which can be applied to converted
5
+ ;;; parse trees.
6
+
7
+ ;;; Copyright (c) 2002-2009, Dr. Edmund Weitz. All rights reserved.
8
+
9
+ ;;; Redistribution and use in source and binary forms, with or without
10
+ ;;; modification, are permitted provided that the following conditions
11
+ ;;; are met:
12
+
13
+ ;;; * Redistributions of source code must retain the above copyright
14
+ ;;; notice, this list of conditions and the following disclaimer.
15
+
16
+ ;;; * Redistributions in binary form must reproduce the above
17
+ ;;; copyright notice, this list of conditions and the following
18
+ ;;; disclaimer in the documentation and/or other materials
19
+ ;;; provided with the distribution.
20
+
21
+ ;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
22
+ ;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23
+ ;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
+ ;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
25
+ ;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ ;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27
+ ;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
+ ;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29
+ ;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30
+ ;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
+ ;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+
33
+ (in-package :cl-ppcre)
34
+
35
+ (defgeneric flatten (regex)
36
+ (declare #.*standard-optimize-settings*)
37
+ (:documentation "Merges adjacent sequences and alternations, i.e. it
38
+ transforms #<SEQ #<STR \"a\"> #<SEQ #<STR \"b\"> #<STR \"c\">>> to
39
+ #<SEQ #<STR \"a\"> #<STR \"b\"> #<STR \"c\">>. This is a destructive
40
+ operation on REGEX."))
41
+
42
+ (defmethod flatten ((seq seq))
43
+ (declare #.*standard-optimize-settings*)
44
+ ;; this looks more complicated than it is because we modify SEQ in
45
+ ;; place to avoid unnecessary consing
46
+ (let ((elements-rest (elements seq)))
47
+ (loop
48
+ (unless elements-rest
49
+ (return))
50
+ (let ((flattened-element (flatten (car elements-rest)))
51
+ (next-elements-rest (cdr elements-rest)))
52
+ (cond ((typep flattened-element 'seq)
53
+ ;; FLATTENED-ELEMENT is a SEQ object, so we "splice"
54
+ ;; it into out list of elements
55
+ (let ((flattened-element-elements
56
+ (elements flattened-element)))
57
+ (setf (car elements-rest)
58
+ (car flattened-element-elements)
59
+ (cdr elements-rest)
60
+ (nconc (cdr flattened-element-elements)
61
+ (cdr elements-rest)))))
62
+ (t
63
+ ;; otherwise we just replace the current element with
64
+ ;; its flattened counterpart
65
+ (setf (car elements-rest) flattened-element)))
66
+ (setq elements-rest next-elements-rest))))
67
+ (let ((elements (elements seq)))
68
+ (cond ((cadr elements)
69
+ seq)
70
+ ((cdr elements)
71
+ (first elements))
72
+ (t (make-instance 'void)))))
73
+
74
+ (defmethod flatten ((alternation alternation))
75
+ (declare #.*standard-optimize-settings*)
76
+ ;; same algorithm as above
77
+ (let ((choices-rest (choices alternation)))
78
+ (loop
79
+ (unless choices-rest
80
+ (return))
81
+ (let ((flattened-choice (flatten (car choices-rest)))
82
+ (next-choices-rest (cdr choices-rest)))
83
+ (cond ((typep flattened-choice 'alternation)
84
+ (let ((flattened-choice-choices
85
+ (choices flattened-choice)))
86
+ (setf (car choices-rest)
87
+ (car flattened-choice-choices)
88
+ (cdr choices-rest)
89
+ (nconc (cdr flattened-choice-choices)
90
+ (cdr choices-rest)))))
91
+ (t
92
+ (setf (car choices-rest) flattened-choice)))
93
+ (setq choices-rest next-choices-rest))))
94
+ (let ((choices (choices alternation)))
95
+ (cond ((cadr choices)
96
+ alternation)
97
+ ((cdr choices)
98
+ (first choices))
99
+ (t (signal-syntax-error "Encountered alternation without choices.")))))
100
+
101
+ (defmethod flatten ((branch branch))
102
+ (declare #.*standard-optimize-settings*)
103
+ (with-slots (test then-regex else-regex)
104
+ branch
105
+ (setq test
106
+ (if (numberp test)
107
+ test
108
+ (flatten test))
109
+ then-regex (flatten then-regex)
110
+ else-regex (flatten else-regex))
111
+ branch))
112
+
113
+ (defmethod flatten ((regex regex))
114
+ (declare #.*standard-optimize-settings*)
115
+ (typecase regex
116
+ ((or repetition register lookahead lookbehind standalone)
117
+ ;; if REGEX contains exactly one inner REGEX object flatten it
118
+ (setf (regex regex)
119
+ (flatten (regex regex)))
120
+ regex)
121
+ (t
122
+ ;; otherwise (ANCHOR, BACK-REFERENCE, CHAR-CLASS, EVERYTHING,
123
+ ;; LOOKAHEAD, LOOKBEHIND, STR, VOID, FILTER, and WORD-BOUNDARY)
124
+ ;; do nothing
125
+ regex)))
126
+
127
+ (defgeneric gather-strings (regex)
128
+ (declare #.*standard-optimize-settings*)
129
+ (:documentation "Collects adjacent strings or characters into one
130
+ string provided they have the same case mode. This is a destructive
131
+ operation on REGEX."))
132
+
133
+ (defmethod gather-strings ((seq seq))
134
+ (declare #.*standard-optimize-settings*)
135
+ ;; note that GATHER-STRINGS is to be applied after FLATTEN, i.e. it
136
+ ;; expects SEQ to be flattened already; in particular, SEQ cannot be
137
+ ;; empty and cannot contain embedded SEQ objects
138
+ (let* ((start-point (cons nil (elements seq)))
139
+ (curr-point start-point)
140
+ old-case-mode
141
+ collector
142
+ collector-start
143
+ (collector-length 0)
144
+ skip)
145
+ (declare (fixnum collector-length))
146
+ (loop
147
+ (let ((elements-rest (cdr curr-point)))
148
+ (unless elements-rest
149
+ (return))
150
+ (let* ((element (car elements-rest))
151
+ (case-mode (case-mode element old-case-mode)))
152
+ (cond ((and case-mode
153
+ (eq case-mode old-case-mode))
154
+ ;; if ELEMENT is a STR and we have collected a STR of
155
+ ;; the same case mode in the last iteration we
156
+ ;; concatenate ELEMENT onto COLLECTOR and remember the
157
+ ;; value of its SKIP slot
158
+ (let ((old-collector-length collector-length))
159
+ (unless (and (adjustable-array-p collector)
160
+ (array-has-fill-pointer-p collector))
161
+ (setq collector
162
+ (make-array collector-length
163
+ :initial-contents collector
164
+ :element-type 'character
165
+ :fill-pointer t
166
+ :adjustable t)
167
+ collector-start nil))
168
+ (adjust-array collector
169
+ (incf collector-length (len element))
170
+ :fill-pointer t)
171
+ (setf (subseq collector
172
+ old-collector-length)
173
+ (str element)
174
+ ;; it suffices to remember the last SKIP slot
175
+ ;; because due to the way MAYBE-ACCUMULATE
176
+ ;; works adjacent STR objects have the same
177
+ ;; SKIP value
178
+ skip (skip element)))
179
+ (setf (cdr curr-point) (cdr elements-rest)))
180
+ (t
181
+ (let ((collected-string
182
+ (cond (collector-start
183
+ collector-start)
184
+ (collector
185
+ ;; if we have collected something already
186
+ ;; we convert it into a STR
187
+ (make-instance 'str
188
+ :skip skip
189
+ :str collector
190
+ :case-insensitive-p
191
+ (eq old-case-mode
192
+ :case-insensitive)))
193
+ (t nil))))
194
+ (cond (case-mode
195
+ ;; if ELEMENT is a string with a different case
196
+ ;; mode than the last one we have either just
197
+ ;; converted COLLECTOR into a STR or COLLECTOR
198
+ ;; is still empty; in both cases we can now
199
+ ;; begin to fill it anew
200
+ (setq collector (str element)
201
+ collector-start element
202
+ ;; and we remember the SKIP value as above
203
+ skip (skip element)
204
+ collector-length (len element))
205
+ (cond (collected-string
206
+ (setf (car elements-rest)
207
+ collected-string
208
+ curr-point
209
+ (cdr curr-point)))
210
+ (t
211
+ (setf (cdr curr-point)
212
+ (cdr elements-rest)))))
213
+ (t
214
+ ;; otherwise this is not a STR so we apply
215
+ ;; GATHER-STRINGS to it and collect it directly
216
+ ;; into RESULT
217
+ (cond (collected-string
218
+ (setf (car elements-rest)
219
+ collected-string
220
+ curr-point
221
+ (cdr curr-point)
222
+ (cdr curr-point)
223
+ (cons (gather-strings element)
224
+ (cdr curr-point))
225
+ curr-point
226
+ (cdr curr-point)))
227
+ (t
228
+ (setf (car elements-rest)
229
+ (gather-strings element)
230
+ curr-point
231
+ (cdr curr-point))))
232
+ ;; we also have to empty COLLECTOR here in case
233
+ ;; it was still filled from the last iteration
234
+ (setq collector nil
235
+ collector-start nil))))))
236
+ (setq old-case-mode case-mode))))
237
+ (when collector
238
+ (setf (cdr curr-point)
239
+ (cons
240
+ (make-instance 'str
241
+ :skip skip
242
+ :str collector
243
+ :case-insensitive-p
244
+ (eq old-case-mode
245
+ :case-insensitive))
246
+ nil)))
247
+ (setf (elements seq) (cdr start-point))
248
+ seq))
249
+
250
+ (defmethod gather-strings ((alternation alternation))
251
+ (declare #.*standard-optimize-settings*)
252
+ ;; loop ON the choices of ALTERNATION so we can modify them directly
253
+ (loop for choices-rest on (choices alternation)
254
+ while choices-rest
255
+ do (setf (car choices-rest)
256
+ (gather-strings (car choices-rest))))
257
+ alternation)
258
+
259
+ (defmethod gather-strings ((branch branch))
260
+ (declare #.*standard-optimize-settings*)
261
+ (with-slots (test then-regex else-regex)
262
+ branch
263
+ (setq test
264
+ (if (numberp test)
265
+ test
266
+ (gather-strings test))
267
+ then-regex (gather-strings then-regex)
268
+ else-regex (gather-strings else-regex))
269
+ branch))
270
+
271
+ (defmethod gather-strings ((regex regex))
272
+ (declare #.*standard-optimize-settings*)
273
+ (typecase regex
274
+ ((or repetition register lookahead lookbehind standalone)
275
+ ;; if REGEX contains exactly one inner REGEX object apply
276
+ ;; GATHER-STRINGS to it
277
+ (setf (regex regex)
278
+ (gather-strings (regex regex)))
279
+ regex)
280
+ (t
281
+ ;; otherwise (ANCHOR, BACK-REFERENCE, CHAR-CLASS, EVERYTHING,
282
+ ;; LOOKAHEAD, LOOKBEHIND, STR, VOID, FILTER, and WORD-BOUNDARY)
283
+ ;; do nothing
284
+ regex)))
285
+
286
+ ;; Note that START-ANCHORED-P will be called after FLATTEN and GATHER-STRINGS.
287
+
288
+ (defgeneric start-anchored-p (regex &optional in-seq-p)
289
+ (declare #.*standard-optimize-settings*)
290
+ (:documentation "Returns T if REGEX starts with a \"real\" start
291
+ anchor, i.e. one that's not in multi-line mode, NIL otherwise. If
292
+ IN-SEQ-P is true the function will return :ZERO-LENGTH if REGEX is a
293
+ zero-length assertion."))
294
+
295
+ (defmethod start-anchored-p ((seq seq) &optional in-seq-p)
296
+ (declare (ignore in-seq-p))
297
+ ;; note that START-ANCHORED-P is to be applied after FLATTEN and
298
+ ;; GATHER-STRINGS, i.e. SEQ cannot be empty and cannot contain
299
+ ;; embedded SEQ objects
300
+ (loop for element in (elements seq)
301
+ for anchored-p = (start-anchored-p element t)
302
+ ;; skip zero-length elements because they won't affect the
303
+ ;; "anchoredness" of the sequence
304
+ while (eq anchored-p :zero-length)
305
+ finally (return (and anchored-p (not (eq anchored-p :zero-length))))))
306
+
307
+ (defmethod start-anchored-p ((alternation alternation) &optional in-seq-p)
308
+ (declare #.*standard-optimize-settings*)
309
+ (declare (ignore in-seq-p))
310
+ ;; clearly an alternation can only be start-anchored if all of its
311
+ ;; choices are start-anchored
312
+ (loop for choice in (choices alternation)
313
+ always (start-anchored-p choice)))
314
+
315
+ (defmethod start-anchored-p ((branch branch) &optional in-seq-p)
316
+ (declare #.*standard-optimize-settings*)
317
+ (declare (ignore in-seq-p))
318
+ (and (start-anchored-p (then-regex branch))
319
+ (start-anchored-p (else-regex branch))))
320
+
321
+ (defmethod start-anchored-p ((repetition repetition) &optional in-seq-p)
322
+ (declare #.*standard-optimize-settings*)
323
+ (declare (ignore in-seq-p))
324
+ ;; well, this wouldn't make much sense, but anyway...
325
+ (and (plusp (minimum repetition))
326
+ (start-anchored-p (regex repetition))))
327
+
328
+ (defmethod start-anchored-p ((register register) &optional in-seq-p)
329
+ (declare #.*standard-optimize-settings*)
330
+ (declare (ignore in-seq-p))
331
+ (start-anchored-p (regex register)))
332
+
333
+ (defmethod start-anchored-p ((standalone standalone) &optional in-seq-p)
334
+ (declare #.*standard-optimize-settings*)
335
+ (declare (ignore in-seq-p))
336
+ (start-anchored-p (regex standalone)))
337
+
338
+ (defmethod start-anchored-p ((anchor anchor) &optional in-seq-p)
339
+ (declare #.*standard-optimize-settings*)
340
+ (declare (ignore in-seq-p))
341
+ (and (startp anchor)
342
+ (not (multi-line-p anchor))))
343
+
344
+ (defmethod start-anchored-p ((regex regex) &optional in-seq-p)
345
+ (declare #.*standard-optimize-settings*)
346
+ (typecase regex
347
+ ((or lookahead lookbehind word-boundary void)
348
+ ;; zero-length assertions
349
+ (if in-seq-p
350
+ :zero-length
351
+ nil))
352
+ (filter
353
+ (if (and in-seq-p
354
+ (len regex)
355
+ (zerop (len regex)))
356
+ :zero-length
357
+ nil))
358
+ (t
359
+ ;; BACK-REFERENCE, CHAR-CLASS, EVERYTHING, and STR
360
+ nil)))
361
+
362
+ ;; Note that END-STRING-AUX will be called after FLATTEN and GATHER-STRINGS.
363
+
364
+ (defgeneric end-string-aux (regex &optional old-case-insensitive-p)
365
+ (declare #.*standard-optimize-settings*)
366
+ (:documentation "Returns the constant string (if it exists) REGEX
367
+ ends with wrapped into a STR object, otherwise NIL.
368
+ OLD-CASE-INSENSITIVE-P is the CASE-INSENSITIVE-P slot of the last STR
369
+ collected or :VOID if no STR has been collected yet. (This is a helper
370
+ function called by END-STRIN.)"))
371
+
372
+ (defmethod end-string-aux ((str str)
373
+ &optional (old-case-insensitive-p :void))
374
+ (declare #.*standard-optimize-settings*)
375
+ (declare (special last-str))
376
+ (cond ((and (not (skip str)) ; avoid constituents of STARTS-WITH
377
+ ;; only use STR if nothing has been collected yet or if
378
+ ;; the collected string has the same value for
379
+ ;; CASE-INSENSITIVE-P
380
+ (or (eq old-case-insensitive-p :void)
381
+ (eq (case-insensitive-p str) old-case-insensitive-p)))
382
+ (setf last-str str
383
+ ;; set the SKIP property of this STR
384
+ (skip str) t)
385
+ str)
386
+ (t nil)))
387
+
388
+ (defmethod end-string-aux ((seq seq)
389
+ &optional (old-case-insensitive-p :void))
390
+ (declare #.*standard-optimize-settings*)
391
+ (declare (special continuep))
392
+ (let (case-insensitive-p
393
+ concatenated-string
394
+ concatenated-start
395
+ (concatenated-length 0))
396
+ (declare (fixnum concatenated-length))
397
+ (loop for element in (reverse (elements seq))
398
+ ;; remember the case-(in)sensitivity of the last relevant
399
+ ;; STR object
400
+ for loop-old-case-insensitive-p = old-case-insensitive-p
401
+ then (if skip
402
+ loop-old-case-insensitive-p
403
+ (case-insensitive-p element-end))
404
+ ;; the end-string of the current element
405
+ for element-end = (end-string-aux element
406
+ loop-old-case-insensitive-p)
407
+ ;; whether we encountered a zero-length element
408
+ for skip = (if element-end
409
+ (zerop (len element-end))
410
+ nil)
411
+ ;; set CONTINUEP to NIL if we have to stop collecting to
412
+ ;; alert END-STRING-AUX methods on enclosing SEQ objects
413
+ unless element-end
414
+ do (setq continuep nil)
415
+ ;; end loop if we neither got a STR nor a zero-length
416
+ ;; element
417
+ while element-end
418
+ ;; only collect if not zero-length
419
+ unless skip
420
+ do (cond (concatenated-string
421
+ (when concatenated-start
422
+ (setf concatenated-string
423
+ (make-array concatenated-length
424
+ :initial-contents (reverse (str concatenated-start))
425
+ :element-type 'character
426
+ :fill-pointer t
427
+ :adjustable t)
428
+ concatenated-start nil))
429
+ (let ((len (len element-end))
430
+ (str (str element-end)))
431
+ (declare (fixnum len))
432
+ (incf concatenated-length len)
433
+ (loop for i of-type fixnum downfrom (1- len) to 0
434
+ do (vector-push-extend (char str i)
435
+ concatenated-string))))
436
+ (t
437
+ (setf concatenated-string
438
+ t
439
+ concatenated-start
440
+ element-end
441
+ concatenated-length
442
+ (len element-end)
443
+ case-insensitive-p
444
+ (case-insensitive-p element-end))))
445
+ ;; stop collecting if END-STRING-AUX on inner SEQ has said so
446
+ while continuep)
447
+ (cond ((zerop concatenated-length)
448
+ ;; don't bother to return zero-length strings
449
+ nil)
450
+ (concatenated-start
451
+ concatenated-start)
452
+ (t
453
+ (make-instance 'str
454
+ :str (nreverse concatenated-string)
455
+ :case-insensitive-p case-insensitive-p)))))
456
+
457
+ (defmethod end-string-aux ((register register)
458
+ &optional (old-case-insensitive-p :void))
459
+ (declare #.*standard-optimize-settings*)
460
+ (end-string-aux (regex register) old-case-insensitive-p))
461
+
462
+ (defmethod end-string-aux ((standalone standalone)
463
+ &optional (old-case-insensitive-p :void))
464
+ (declare #.*standard-optimize-settings*)
465
+ (end-string-aux (regex standalone) old-case-insensitive-p))
466
+
467
+ (defmethod end-string-aux ((regex regex)
468
+ &optional (old-case-insensitive-p :void))
469
+ (declare #.*standard-optimize-settings*)
470
+ (declare (special last-str end-anchored-p continuep))
471
+ (typecase regex
472
+ ((or anchor lookahead lookbehind word-boundary void)
473
+ ;; a zero-length REGEX object - for the sake of END-STRING-AUX
474
+ ;; this is a zero-length string
475
+ (when (and (typep regex 'anchor)
476
+ (not (startp regex))
477
+ (or (no-newline-p regex)
478
+ (not (multi-line-p regex)))
479
+ (eq old-case-insensitive-p :void))
480
+ ;; if this is a "real" end-anchor and we haven't collected
481
+ ;; anything so far we can set END-ANCHORED-P (where 1 or 0
482
+ ;; indicate whether we accept a #\Newline at the end or not)
483
+ (setq end-anchored-p (if (no-newline-p regex) 0 1)))
484
+ (make-instance 'str
485
+ :str ""
486
+ :case-insensitive-p :void))
487
+ (t
488
+ ;; (ALTERNATION, BACK-REFERENCE, BRANCH, CHAR-CLASS, EVERYTHING,
489
+ ;; REPETITION, FILTER)
490
+ nil)))
491
+
492
+ (defun end-string (regex)
493
+ (declare (special end-string-offset))
494
+ (declare #.*standard-optimize-settings*)
495
+ "Returns the constant string (if it exists) REGEX ends with wrapped
496
+ into a STR object, otherwise NIL."
497
+ ;; LAST-STR points to the last STR object (seen from the end) that's
498
+ ;; part of END-STRING; CONTINUEP is set to T if we stop collecting
499
+ ;; in the middle of a SEQ
500
+ (let ((continuep t)
501
+ last-str)
502
+ (declare (special continuep last-str))
503
+ (prog1
504
+ (end-string-aux regex)
505
+ (when last-str
506
+ ;; if we've found something set the START-OF-END-STRING-P of
507
+ ;; the leftmost STR collected accordingly and remember the
508
+ ;; OFFSET of this STR (in a special variable provided by the
509
+ ;; caller of this function)
510
+ (setf (start-of-end-string-p last-str) t
511
+ end-string-offset (offset last-str))))))
512
+
513
+ (defgeneric compute-min-rest (regex current-min-rest)
514
+ (declare #.*standard-optimize-settings*)
515
+ (:documentation "Returns the minimal length of REGEX plus
516
+ CURRENT-MIN-REST. This is similar to REGEX-MIN-LENGTH except that it
517
+ recurses down into REGEX and sets the MIN-REST slots of REPETITION
518
+ objects."))
519
+
520
+ (defmethod compute-min-rest ((seq seq) current-min-rest)
521
+ (declare #.*standard-optimize-settings*)
522
+ (loop for element in (reverse (elements seq))
523
+ for last-min-rest = current-min-rest then this-min-rest
524
+ for this-min-rest = (compute-min-rest element last-min-rest)
525
+ finally (return this-min-rest)))
526
+
527
+ (defmethod compute-min-rest ((alternation alternation) current-min-rest)
528
+ (declare #.*standard-optimize-settings*)
529
+ (loop for choice in (choices alternation)
530
+ minimize (compute-min-rest choice current-min-rest)))
531
+
532
+ (defmethod compute-min-rest ((branch branch) current-min-rest)
533
+ (declare #.*standard-optimize-settings*)
534
+ (min (compute-min-rest (then-regex branch) current-min-rest)
535
+ (compute-min-rest (else-regex branch) current-min-rest)))
536
+
537
+ (defmethod compute-min-rest ((str str) current-min-rest)
538
+ (declare #.*standard-optimize-settings*)
539
+ (+ current-min-rest (len str)))
540
+
541
+ (defmethod compute-min-rest ((filter filter) current-min-rest)
542
+ (declare #.*standard-optimize-settings*)
543
+ (+ current-min-rest (or (len filter) 0)))
544
+
545
+ (defmethod compute-min-rest ((repetition repetition) current-min-rest)
546
+ (declare #.*standard-optimize-settings*)
547
+ (setf (min-rest repetition) current-min-rest)
548
+ (compute-min-rest (regex repetition) current-min-rest)
549
+ (+ current-min-rest (* (minimum repetition) (min-len repetition))))
550
+
551
+ (defmethod compute-min-rest ((register register) current-min-rest)
552
+ (declare #.*standard-optimize-settings*)
553
+ (compute-min-rest (regex register) current-min-rest))
554
+
555
+ (defmethod compute-min-rest ((standalone standalone) current-min-rest)
556
+ (declare #.*standard-optimize-settings*)
557
+ (declare (ignore current-min-rest))
558
+ (compute-min-rest (regex standalone) 0))
559
+
560
+ (defmethod compute-min-rest ((lookahead lookahead) current-min-rest)
561
+ (declare #.*standard-optimize-settings*)
562
+ (compute-min-rest (regex lookahead) 0)
563
+ current-min-rest)
564
+
565
+ (defmethod compute-min-rest ((lookbehind lookbehind) current-min-rest)
566
+ (declare #.*standard-optimize-settings*)
567
+ (compute-min-rest (regex lookbehind) (+ current-min-rest (len lookbehind)))
568
+ current-min-rest)
569
+
570
+ (defmethod compute-min-rest ((regex regex) current-min-rest)
571
+ (declare #.*standard-optimize-settings*)
572
+ (typecase regex
573
+ ((or char-class everything)
574
+ (1+ current-min-rest))
575
+ (t
576
+ ;; zero min-len and no embedded regexes (ANCHOR,
577
+ ;; BACK-REFERENCE, VOID, and WORD-BOUNDARY)
578
+ current-min-rest)))
@@ -0,0 +1,68 @@
1
+ ;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
2
+ ;;; $Header: /usr/local/cvsrep/cl-ppcre/packages.lisp,v 1.39 2009/09/17 19:17:31 edi Exp $
3
+
4
+ ;;; Copyright (c) 2002-2009, Dr. Edmund Weitz. All rights reserved.
5
+
6
+ ;;; Redistribution and use in source and binary forms, with or without
7
+ ;;; modification, are permitted provided that the following conditions
8
+ ;;; are met:
9
+
10
+ ;;; * Redistributions of source code must retain the above copyright
11
+ ;;; notice, this list of conditions and the following disclaimer.
12
+
13
+ ;;; * Redistributions in binary form must reproduce the above
14
+ ;;; copyright notice, this list of conditions and the following
15
+ ;;; disclaimer in the documentation and/or other materials
16
+ ;;; provided with the distribution.
17
+
18
+ ;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
19
+ ;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ ;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
+ ;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22
+ ;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ ;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24
+ ;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
+ ;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
+ ;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27
+ ;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
+ ;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ (in-package :cl-user)
31
+
32
+ (defpackage :cl-ppcre
33
+ (:nicknames :ppcre)
34
+ #+:genera
35
+ (:shadowing-import-from :common-lisp :lambda :simple-string :string)
36
+ (:use #-:genera :cl #+:genera :future-common-lisp)
37
+ (:shadow :digit-char-p :defconstant)
38
+ (:export :parse-string
39
+ :create-scanner
40
+ :create-optimized-test-function
41
+ :parse-tree-synonym
42
+ :define-parse-tree-synonym
43
+ :scan
44
+ :scan-to-strings
45
+ :do-scans
46
+ :do-matches
47
+ :do-matches-as-strings
48
+ :all-matches
49
+ :all-matches-as-strings
50
+ :split
51
+ :regex-replace
52
+ :regex-replace-all
53
+ :regex-apropos
54
+ :regex-apropos-list
55
+ :quote-meta-chars
56
+ :*regex-char-code-limit*
57
+ :*use-bmh-matchers*
58
+ :*allow-quoting*
59
+ :*allow-named-registers*
60
+ :*optimize-char-classes*
61
+ :*property-resolver*
62
+ :ppcre-error
63
+ :ppcre-invocation-error
64
+ :ppcre-syntax-error
65
+ :ppcre-syntax-error-string
66
+ :ppcre-syntax-error-pos
67
+ :register-groups-bind
68
+ :do-register-groups))