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,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)))