clucumber 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,369 @@
1
+ ;; MCL backend for USOCKET 0.4.1
2
+ ;; Terje Norderhaug <terje@in-progress.com>, January 1, 2009
3
+
4
+ (in-package :ccl)
5
+
6
+ (eval-when (:compile-toplevel :load-toplevel :execute)
7
+ (require :opentransport))
8
+
9
+ ;; MCL Issue 28: Passive TCP streams should be able to listen to the loopback interface
10
+ ;; see http://code.google.com/p/mcl/issues/detail?id=28 for details
11
+
12
+ (defparameter *passive-interface-address* NIL
13
+ "Address to use for passive connections - optionally bind to loopback address while opening a tcp stream")
14
+
15
+ (advise local-interface-ip-address
16
+ (or *passive-interface-address* (:do-it))
17
+ :when :around :name 'override-local-interface-ip-address)
18
+
19
+ ;; MCL Issue 29: Passive TCP connections on OS assigned ports
20
+ ;; see http://code.google.com/p/mcl/issues/detail?id=29 for details
21
+ (advise ot-conn-tcp-passive-connect
22
+ (destructuring-bind (conn port &optional (allow-reuse t)) arglist
23
+ (declare (ignore allow-reuse))
24
+ (if (eql port #$kOTAnyInetAddress)
25
+ ;; Avoids registering a proxy for port 0 but instead registers one for the true port:
26
+ (multiple-value-bind (proxy result)
27
+ (let* ((*opentransport-class-proxies* NIL) ; makes ot-find-proxy return NIL
28
+ (result (:do-it)) ;; pushes onto *opentransport-class-proxies*
29
+ (proxy (prog1
30
+ (pop *opentransport-class-proxies*)
31
+ (assert (not *opentransport-class-proxies*))))
32
+ (context (cdr proxy))
33
+ (tmpconn (make-ot-conn :context context
34
+ :endpoint (pref context :ot-context.ref)))
35
+ (localaddress (ot-conn-tcp-get-addresses tmpconn)))
36
+ (declare (dynamic-extent tmpconn))
37
+ ;; replace original set in body of function
38
+ (setf (ot-conn-local-address conn) localaddress)
39
+ (values
40
+ (cons localaddress context)
41
+ result))
42
+ ;; need to be outside local binding of *opentransport-class-proxies*
43
+ (without-interrupts
44
+ (push proxy *opentransport-class-proxies*))
45
+ result)
46
+ (:do-it)))
47
+ :when :around :name 'ot-conn-tcp-passive-connect-any-address)
48
+
49
+ (in-package :usocket)
50
+
51
+ (defun handle-condition (condition &optional socket)
52
+ ; incomplete, needs to handle additional conditions
53
+ (flet ((raise-error (&optional socket-condition)
54
+ (if socket-condition
55
+ (error socket-condition :socket socket)
56
+ (error 'unknown-error :socket socket :real-error condition))))
57
+ (typecase condition
58
+ (ccl:host-stopped-responding
59
+ (raise-error 'host-down-error))
60
+ (ccl:host-not-responding
61
+ (raise-error 'host-unreachable-error))
62
+ (ccl:connection-reset
63
+ (raise-error 'connection-reset-error))
64
+ (ccl:connection-timed-out
65
+ (raise-error 'timeout-error))
66
+ (ccl:opentransport-protocol-error
67
+ (raise-error 'protocol-not-supported-error))
68
+ (otherwise
69
+ (raise-error)))))
70
+
71
+ (defun socket-connect (host port &key (element-type 'character) timeout deadline nodelay
72
+ local-host local-port)
73
+ (with-mapped-conditions ()
74
+ (let* ((socket
75
+ (make-instance 'active-socket
76
+ :remote-host (when host (host-to-hostname host))
77
+ :remote-port port
78
+ :local-host (when local-host (host-to-hostname local-host))
79
+ :local-port local-port
80
+ :deadline deadline
81
+ :nodelay nodelay
82
+ :connect-timeout (and timeout (round (* timeout 60)))
83
+ :element-type element-type))
84
+ (stream (socket-open-stream socket)))
85
+ (make-stream-socket :socket socket :stream stream))))
86
+
87
+ (defun socket-listen (host port
88
+ &key reuseaddress
89
+ (reuse-address nil reuse-address-supplied-p)
90
+ (backlog 5)
91
+ (element-type 'character))
92
+ (declare (ignore reuseaddress reuse-address-supplied-p))
93
+ (let ((socket (with-mapped-conditions ()
94
+ (make-instance 'passive-socket
95
+ :local-port port
96
+ :local-host host
97
+ :reuse-address reuse-address
98
+ :backlog backlog))))
99
+ (make-stream-server-socket socket :element-type element-type)))
100
+
101
+ (defmethod socket-accept ((usocket stream-server-usocket) &key element-type)
102
+ (let* ((socket (socket usocket))
103
+ (stream (with-mapped-conditions (usocket)
104
+ (socket-accept socket :element-type element-type))))
105
+ (make-stream-socket :socket socket :stream stream)))
106
+
107
+ (defmethod socket-close ((usocket usocket))
108
+ (with-mapped-conditions (usocket)
109
+ (socket-close (socket usocket))))
110
+
111
+ (defmethod ccl::stream-close ((usocket usocket))
112
+ (socket-close usocket))
113
+
114
+ (defun get-hosts-by-name (name)
115
+ (with-mapped-conditions ()
116
+ (list (hbo-to-vector-quad (ccl::get-host-address
117
+ (host-to-hostname name))))))
118
+
119
+ (defun get-host-by-address (address)
120
+ (with-mapped-conditions ()
121
+ (ccl::inet-host-name (host-to-hbo address))))
122
+
123
+ (defmethod get-local-name ((usocket usocket))
124
+ (values (get-local-address usocket)
125
+ (get-local-port usocket)))
126
+
127
+ (defmethod get-peer-name ((usocket stream-usocket))
128
+ (values (get-peer-address usocket)
129
+ (get-peer-port usocket)))
130
+
131
+ (defmethod get-local-address ((usocket usocket))
132
+ (hbo-to-vector-quad (ccl::get-host-address (or (local-host (socket usocket)) ""))))
133
+
134
+ (defmethod get-local-port ((usocket usocket))
135
+ (local-port (socket usocket)))
136
+
137
+ (defmethod get-peer-address ((usocket stream-usocket))
138
+ (hbo-to-vector-quad (ccl::get-host-address (remote-host (socket usocket)))))
139
+
140
+ (defmethod get-peer-port ((usocket stream-usocket))
141
+ (remote-port (socket usocket)))
142
+
143
+
144
+ (defun %setup-wait-list (wait-list)
145
+ (declare (ignore wait-list)))
146
+
147
+ (defun %add-waiter (wait-list waiter)
148
+ (declare (ignore wait-list waiter)))
149
+
150
+ (defun %remove-waiter (wait-list waiter)
151
+ (declare (ignore wait-list waiter)))
152
+
153
+
154
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
155
+ ;; BASIC MCL SOCKET IMPLEMENTATION
156
+
157
+ (defclass socket ()
158
+ ((local-port :reader local-port :initarg :local-port)
159
+ (local-host :reader local-host :initarg :local-host)
160
+ (element-type :reader element-type :initform 'ccl::base-character :initarg :element-type)))
161
+
162
+ (defclass active-socket (socket)
163
+ ((remote-host :reader remote-host :initarg :remote-host)
164
+ (remote-port :reader remote-port :initarg :remote-port)
165
+ (deadline :initarg :deadline)
166
+ (nodelay :initarg :nodelay)
167
+ (connect-timeout :reader connect-timeout :initform NIL :initarg :connect-timeout
168
+ :type (or null fixnum) :documentation "ticks (60th of a second)")))
169
+
170
+ (defmethod socket-open-stream ((socket active-socket))
171
+ (ccl::open-tcp-stream (or (remote-host socket)(ccl::local-interface-ip-address)) (remote-port socket)
172
+ :element-type (if (subtypep (element-type socket) 'character) 'ccl::base-character 'unsigned-byte)
173
+ :connect-timeout (connect-timeout socket)))
174
+
175
+ (defmethod socket-close ((socket active-socket))
176
+ NIL)
177
+
178
+ (defclass passive-socket (socket)
179
+ ((streams :accessor socket-streams :type list :initform NIL
180
+ :documentation "Circular list of streams with first element the next to open")
181
+ (reuse-address :reader reuse-address :initarg :reuse-address)
182
+ (lock :reader socket-lock :initform (ccl:make-lock "Socket"))))
183
+
184
+ (defmethod initialize-instance :after ((socket passive-socket) &key backlog)
185
+ (loop repeat backlog
186
+ collect (socket-open-listener socket) into streams
187
+ finally (setf (socket-streams socket)
188
+ (cdr (rplacd (last streams) streams))))
189
+ (when (zerop (local-port socket))
190
+ (setf (slot-value socket 'local-port)
191
+ (or (ccl::process-wait-with-timeout "binding port" (* 10 60)
192
+ #'ccl::stream-local-port (car (socket-streams socket)))
193
+ (error "timeout")))))
194
+
195
+ (defmethod socket-accept ((socket passive-socket) &key element-type &aux (lock (socket-lock socket)))
196
+ (flet ((connection-established-p (stream)
197
+ (ccl::with-io-buffer-locked ((ccl::stream-io-buffer stream nil))
198
+ (let ((state (ccl::opentransport-stream-connection-state stream)))
199
+ (not (eq :unbnd state))))))
200
+ (with-mapped-conditions ()
201
+ (ccl:with-lock-grabbed (lock nil "Socket Lock")
202
+ (let ((connection (shiftf (car (socket-streams socket))
203
+ (socket-open-listener socket element-type))))
204
+ (pop (socket-streams socket))
205
+ (ccl:process-wait "Accepting" #'connection-established-p connection)
206
+ connection)))))
207
+
208
+ (defmethod socket-close ((socket passive-socket))
209
+ (loop
210
+ with streams = (socket-streams socket)
211
+ for (stream tail) on streams
212
+ do (close stream :abort T)
213
+ until (eq tail streams)
214
+ finally (setf (socket-streams socket) NIL)))
215
+
216
+ (defmethod socket-open-listener (socket &optional element-type)
217
+ ; see http://code.google.com/p/mcl/issues/detail?id=28
218
+ (let* ((ccl::*passive-interface-address* (local-host socket))
219
+ (new (ccl::open-tcp-stream NIL (or (local-port socket) #$kOTAnyInetAddress)
220
+ :reuse-local-port-p (reuse-address socket)
221
+ :element-type (if (subtypep (or element-type (element-type socket))
222
+ 'character)
223
+ 'ccl::base-character
224
+ 'unsigned-byte))))
225
+ (declare (special ccl::*passive-interface-address*))
226
+ new))
227
+
228
+
229
+ (defun wait-for-input-internal (wait-list &key timeout &aux result)
230
+ (macrolet ((when-io-buffer-lock-grabbed ((lock &optional multiple-value-p) &body body)
231
+ "Evaluates the body if and only if the lock is successfully grabbed"
232
+ ;; like with-io-buffer-lock-grabbed but returns immediately instead of polling the lock
233
+ (let ((needs-unlocking-p (gensym))
234
+ (lock-var (gensym)))
235
+ `(let* ((,lock-var ,lock)
236
+ (ccl::*grabbed-io-buffer-locks* (cons ,lock-var ccl::*grabbed-io-buffer-locks*))
237
+ (,needs-unlocking-p (needs-unlocking-p ,lock-var)))
238
+ (declare (dynamic-extent ccl::*grabbed-io-buffer-locks*))
239
+ (when ,needs-unlocking-p
240
+ (,(if multiple-value-p 'multiple-value-prog1 'prog1)
241
+ (progn ,@body)
242
+ (ccl::%release-io-buffer-lock ,lock-var)))))))
243
+ (labels ((needs-unlocking-p (lock)
244
+ (declare (type ccl::lock lock))
245
+ ;; crucial - clears bogus lock.value as in grab-io-buffer-lock-out-of-line:
246
+ (ccl::%io-buffer-lock-really-grabbed-p lock)
247
+ (ccl:store-conditional lock nil ccl:*current-process*))
248
+ (input-available (stream)
249
+ "similar to stream-listen on buffered-input-stream-mixin but without waiting for lock"
250
+ (let ((io-buffer (ccl::stream-io-buffer stream)))
251
+ (or (not (eql 0 (ccl::io-buffer-incount io-buffer)))
252
+ (ccl::io-buffer-untyi-char io-buffer)
253
+ (locally (declare (optimize (speed 3) (safety 0)))
254
+ (when-io-buffer-lock-grabbed ((ccl::io-buffer-lock io-buffer))
255
+ (funcall (ccl::io-buffer-listen-function io-buffer) stream io-buffer))))))
256
+ (ready-sockets (sockets)
257
+ (dolist (sock sockets result)
258
+ (when (input-available (socket-stream sock))
259
+ (push sock result)))))
260
+ (with-mapped-conditions ()
261
+ (ccl:process-wait-with-timeout
262
+ "socket input"
263
+ (when timeout (truncate (* timeout 60)))
264
+ #'ready-sockets
265
+ (wait-list-waiters wait-list)))
266
+ (nreverse result))))
267
+
268
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
269
+ #| Test for wait-for-input
270
+ (let* ((sock1 (usocket:socket-connect "in-progress.com" 80))
271
+ (sock2 (usocket:socket-connect "common-lisp.net" 80))
272
+ (sockets (list sock1 sock2)))
273
+ (dolist (sock sockets)
274
+ (format (usocket:socket-stream sock)
275
+ "GET / HTTP/1.0~A~A~A~A"
276
+ #\Return #\Linefeed #\Return #\Linefeed)
277
+ (force-output (usocket:socket-stream sock)))
278
+ (wait-for-input sockets :timeout 5000))
279
+ |#
280
+
281
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
282
+ #| TEST (from test-usocket.lisp)
283
+
284
+
285
+ (defparameter +non-existing-host+ "192.168.1.1")
286
+ (defparameter +unused-local-port+ 15213)
287
+ (defparameter *soc1* (usocket::make-stream-socket :socket :my-socket
288
+ :stream :my-stream))
289
+ (defparameter +common-lisp-net+ #(208 72 159 207)) ;; common-lisp.net IP
290
+
291
+
292
+ (usocket:socket *soc1*)
293
+
294
+ (usocket:socket-connect "127.0.0.0" +unused-local-port+)
295
+
296
+ (usocket:socket-connect #(127 0 0 0) +unused-local-port+)
297
+
298
+ (usocket:socket-connect 2130706432 +unused-local-port+)
299
+
300
+ (let ((sock (usocket:socket-connect "common-lisp.net" 80)))
301
+ (unwind-protect
302
+ (typep sock 'usocket:usocket)
303
+ (usocket:socket-close sock)))
304
+
305
+ (let ((sock (usocket:socket-connect +common-lisp-net+ 80)))
306
+ (unwind-protect
307
+ (typep sock 'usocket:usocket)
308
+ (usocket:socket-close sock)))
309
+
310
+ (let ((sock (usocket:socket-connect (usocket::host-byte-order +common-lisp-net+) 80)))
311
+ (unwind-protect
312
+ (typep sock 'usocket:usocket)
313
+ (usocket:socket-close sock)))
314
+
315
+ (let ((sock (usocket:socket-connect "common-lisp.net" 80)))
316
+ (unwind-protect
317
+ (progn
318
+ (format (usocket:socket-stream sock)
319
+ "GET / HTTP/1.0~A~A~A~A"
320
+ #\Return #\Linefeed #\Return #\Linefeed)
321
+ (force-output (usocket:socket-stream sock))
322
+ (read-line (usocket:socket-stream sock)))
323
+ (usocket:socket-close sock)))
324
+
325
+ (let ((sock (usocket:socket-connect +common-lisp-net+ 80)))
326
+ (unwind-protect
327
+ (usocket::get-peer-address sock)
328
+ (usocket:socket-close sock)))
329
+
330
+ (let ((sock (usocket:socket-connect +common-lisp-net+ 80)))
331
+ (unwind-protect
332
+ (usocket::get-peer-port sock)
333
+ (usocket:socket-close sock)))
334
+
335
+ (let ((sock (usocket:socket-connect +common-lisp-net+ 80)))
336
+ (unwind-protect
337
+ (usocket::get-peer-name sock)
338
+ (usocket:socket-close sock)))
339
+
340
+ (let ((sock (usocket:socket-connect +common-lisp-net+ 80)))
341
+ (unwind-protect
342
+ (usocket::get-local-address sock)
343
+ (usocket:socket-close sock)))
344
+
345
+ |#
346
+
347
+
348
+ #|
349
+
350
+ (defun socket-server (host port)
351
+ (let ((socket (socket-listen host port)))
352
+ (unwind-protect
353
+ (loop
354
+ (with-open-stream (stream (socket-stream (socket-accept socket)))
355
+ (ccl::telnet-write-line stream "~A"
356
+ (reverse (ccl::telnet-read-line stream)))
357
+ (ccl::force-output stream)))
358
+ (close socket))))
359
+
360
+ (ccl::process-run-function "Socket Server" #'socket-server NIL 4088)
361
+
362
+ (let* ((sock (socket-connect nil 4088))
363
+ (stream (usocket:socket-stream sock)))
364
+ (assert (streamp stream))
365
+ (ccl::telnet-write-line stream "hello ~A" (random 10))
366
+ (ccl::force-output stream)
367
+ (ccl::telnet-read-line stream))
368
+
369
+ |#
@@ -0,0 +1,206 @@
1
+ ;;;; $Id: openmcl.lisp 522 2010-05-02 01:57:55Z ctian $
2
+ ;;;; $URL: svn://common-lisp.net/project/usocket/svn/usocket/trunk/backend/openmcl.lisp $
3
+
4
+ ;;;; See LICENSE for licensing information.
5
+
6
+ (in-package :usocket)
7
+
8
+ (defun get-host-name ()
9
+ (ccl::%stack-block ((resultbuf 256))
10
+ (when (zerop (#_gethostname resultbuf 256))
11
+ (ccl::%get-cstring resultbuf))))
12
+
13
+ (defparameter +openmcl-error-map+
14
+ '((:address-in-use . address-in-use-error)
15
+ (:connection-aborted . connection-aborted-error)
16
+ (:no-buffer-space . no-buffers-error)
17
+ (:connection-timed-out . timeout-error)
18
+ (:connection-refused . connection-refused-error)
19
+ (:host-unreachable . host-unreachable-error)
20
+ (:host-down . host-down-error)
21
+ (:network-down . network-down-error)
22
+ (:address-not-available . address-not-available-error)
23
+ (:network-reset . network-reset-error)
24
+ (:connection-reset . connection-reset-error)
25
+ (:shutdown . shutdown-error)
26
+ (:access-denied . operation-not-permitted-error)))
27
+
28
+ (defparameter +openmcl-nameserver-error-map+
29
+ '((:no-recovery . ns-no-recovery-error)
30
+ (:try-again . ns-try-again-condition)
31
+ (:host-not-found . ns-host-not-found-error)))
32
+
33
+ ;; we need something which the openmcl implementors 'forgot' to do:
34
+ ;; wait for more than one socket-or-fd
35
+
36
+ (defun input-available-p (sockets &optional ticks-to-wait)
37
+ (ccl::rletZ ((tv :timeval))
38
+ (ccl::ticks-to-timeval ticks-to-wait tv)
39
+ ;;### The trickery below can be moved to the wait-list now...
40
+ (ccl::%stack-block ((infds ccl::*fd-set-size*))
41
+ (ccl::fd-zero infds)
42
+ (let ((max-fd -1))
43
+ (dolist (sock sockets)
44
+ (let ((fd (openmcl-socket:socket-os-fd (socket sock))))
45
+ (setf max-fd (max max-fd fd))
46
+ (ccl::fd-set fd infds)))
47
+ (let* ((res (#_select (1+ max-fd)
48
+ infds (ccl::%null-ptr) (ccl::%null-ptr)
49
+ (if ticks-to-wait tv (ccl::%null-ptr)))))
50
+ (when (> res 0)
51
+ (dolist (x sockets)
52
+ (when (ccl::fd-is-set (openmcl-socket:socket-os-fd (socket x))
53
+ infds)
54
+ (setf (state x) :READ))))
55
+ sockets)))))
56
+
57
+ (defun raise-error-from-id (condition-id socket real-condition)
58
+ (let ((usock-err (cdr (assoc condition-id +openmcl-error-map+))))
59
+ (if usock-err
60
+ (error usock-err :socket socket)
61
+ (error 'unknown-error :socket socket :real-error real-condition))))
62
+
63
+ (defun handle-condition (condition &optional socket)
64
+ (typecase condition
65
+ (openmcl-socket:socket-error
66
+ (raise-error-from-id (openmcl-socket:socket-error-identifier condition)
67
+ socket condition))
68
+ (ccl:input-timeout
69
+ (error 'timeout-error :socket socket))
70
+ (ccl:communication-deadline-expired
71
+ (error 'deadline-timeout-error :socket socket))
72
+ (ccl::socket-creation-error #| ugh! |#
73
+ (let* ((condition-id (ccl::socket-creation-error-identifier condition))
74
+ (nameserver-error (cdr (assoc condition-id
75
+ +openmcl-nameserver-error-map+))))
76
+ (if nameserver-error
77
+ (error nameserver-error :host-or-ip nil)
78
+ (raise-error-from-id condition-id socket condition))))))
79
+
80
+ (defun to-format (element-type)
81
+ (if (subtypep element-type 'character)
82
+ :text
83
+ :binary))
84
+
85
+ (defun socket-connect (host port &key (protocol :stream) (element-type 'character)
86
+ timeout deadline nodelay
87
+ local-host local-port)
88
+ (with-mapped-conditions ()
89
+ (ecase protocol
90
+ (:stream
91
+ (let ((mcl-sock
92
+ (openmcl-socket:make-socket :remote-host (host-to-hostname host)
93
+ :remote-port port
94
+ :local-host (when local-host (host-to-hostname local-host))
95
+ :local-port local-port
96
+ :format (to-format element-type)
97
+ :deadline deadline
98
+ :nodelay nodelay
99
+ :connect-timeout timeout)))
100
+ (openmcl-socket:socket-connect mcl-sock)
101
+ (make-stream-socket :stream mcl-sock :socket mcl-sock)))
102
+ (:datagram
103
+ (let ((mcl-sock
104
+ (openmcl-socket:make-socket :address-family :internet
105
+ :type :datagram
106
+ :local-host (when local-host (host-to-hostname local-host))
107
+ :local-port local-port
108
+ :format :binary)))
109
+ (when (and host port)
110
+ (ccl::inet-connect (ccl::socket-device mcl-sock)
111
+ (ccl::host-as-inet-host host)
112
+ (ccl::port-as-inet-port port "udp")))
113
+ (make-datagram-socket mcl-sock))))))
114
+
115
+ (defun socket-listen (host port
116
+ &key reuseaddress
117
+ (reuse-address nil reuse-address-supplied-p)
118
+ (backlog 5)
119
+ (element-type 'character))
120
+ (let* ((reuseaddress (if reuse-address-supplied-p reuse-address reuseaddress))
121
+ (sock (with-mapped-conditions ()
122
+ (apply #'openmcl-socket:make-socket
123
+ (append (list :connect :passive
124
+ :reuse-address reuseaddress
125
+ :local-port port
126
+ :backlog backlog
127
+ :format (to-format element-type))
128
+ (when (ip/= host *wildcard-host*)
129
+ (list :local-host host)))))))
130
+ (make-stream-server-socket sock :element-type element-type)))
131
+
132
+ (defmethod socket-accept ((usocket stream-server-usocket) &key element-type)
133
+ (declare (ignore element-type)) ;; openmcl streams are bi/multivalent
134
+ (let ((sock (with-mapped-conditions (usocket)
135
+ (openmcl-socket:accept-connection (socket usocket)))))
136
+ (make-stream-socket :socket sock :stream sock)))
137
+
138
+ ;; One close method is sufficient because sockets
139
+ ;; and their associated objects are represented
140
+ ;; by the same object.
141
+ (defmethod socket-close ((usocket usocket))
142
+ (when (wait-list usocket)
143
+ (remove-waiter (wait-list usocket) usocket))
144
+ (with-mapped-conditions (usocket)
145
+ (close (socket usocket))))
146
+
147
+ (defmethod socket-send ((usocket datagram-usocket) buffer length &key host port)
148
+ (with-mapped-conditions (usocket)
149
+ (openmcl-socket:send-to (socket usocket) buffer length
150
+ :remote-host (if host (host-to-hbo host))
151
+ :remote-port port)))
152
+
153
+ (defmethod socket-receive ((usocket datagram-usocket) buffer length &key)
154
+ (with-mapped-conditions (usocket)
155
+ (openmcl-socket:receive-from (socket usocket) length :buffer buffer)))
156
+
157
+ (defmethod get-local-address ((usocket usocket))
158
+ (let ((address (openmcl-socket:local-host (socket usocket))))
159
+ (when address
160
+ (hbo-to-vector-quad address))))
161
+
162
+ (defmethod get-peer-address ((usocket stream-usocket))
163
+ (let ((address (openmcl-socket:remote-host (socket usocket))))
164
+ (when address
165
+ (hbo-to-vector-quad address))))
166
+
167
+ (defmethod get-local-port ((usocket usocket))
168
+ (openmcl-socket:local-port (socket usocket)))
169
+
170
+ (defmethod get-peer-port ((usocket stream-usocket))
171
+ (openmcl-socket:remote-port (socket usocket)))
172
+
173
+ (defmethod get-local-name ((usocket usocket))
174
+ (values (get-local-address usocket)
175
+ (get-local-port usocket)))
176
+
177
+ (defmethod get-peer-name ((usocket stream-usocket))
178
+ (values (get-peer-address usocket)
179
+ (get-peer-port usocket)))
180
+
181
+ (defun get-host-by-address (address)
182
+ (with-mapped-conditions ()
183
+ (openmcl-socket:ipaddr-to-hostname (host-to-hbo address))))
184
+
185
+ (defun get-hosts-by-name (name)
186
+ (with-mapped-conditions ()
187
+ (list (hbo-to-vector-quad (openmcl-socket:lookup-hostname
188
+ (host-to-hostname name))))))
189
+
190
+
191
+ (defun %setup-wait-list (wait-list)
192
+ (declare (ignore wait-list)))
193
+
194
+ (defun %add-waiter (wait-list waiter)
195
+ (declare (ignore wait-list waiter)))
196
+
197
+ (defun %remove-waiter (wait-list waiter)
198
+ (declare (ignore wait-list waiter)))
199
+
200
+ (defun wait-for-input-internal (wait-list &key timeout)
201
+ (with-mapped-conditions ()
202
+ (let* ((ticks-timeout (truncate (* (or timeout 1)
203
+ ccl::*ticks-per-second*))))
204
+ (input-available-p (wait-list-waiters wait-list)
205
+ (when timeout ticks-timeout))
206
+ wait-list)))