-
Notifications
You must be signed in to change notification settings - Fork 1
/
stream.lisp
90 lines (74 loc) · 3.47 KB
/
stream.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
;;;; SPDX-FileCopyrightText: Atlas Engineer LLC
;;;; SPDX-License-Identifier: BSD-3-Clause
(in-package #:ndebug)
(defclass debugger-input-stream (trivial-gray-streams:fundamental-character-input-stream)
((input-fn :initarg :input-fn
:accessor input-fn
:documentation "The one-shot function returning string.
This string is then used for all the input operations.")
(input :initarg :input
:accessor input
:documentation "The string to use as input buffer.")
(index :initform 0
:initarg :index
:accessor index
:documentation "The index in the string.")))
(defmethod slot-unbound (class (stream debugger-input-stream) (slot-name (eql 'input)))
(setf (input stream) (funcall (input-fn stream))))
(defmethod trivial-gray-streams:stream-read-char ((stream debugger-input-stream))
(when (= (index stream) (length (input stream)))
(setf (input stream) (funcall (input-fn stream))
(index stream) 0)
(when (uiop:emptyp (input stream))
(return-from trivial-gray-streams:stream-read-char :eof)))
(prog1
(char (input stream) (index stream))
(incf (index stream))))
(defmethod trivial-gray-streams:stream-listen ((stream debugger-input-stream))
(< (index stream) (length (input stream))))
(defmethod trivial-gray-streams:stream-unread-char ((stream debugger-input-stream) char)
(decf (index stream))
nil)
(defmethod trivial-gray-streams:stream-clear-input ((stream debugger-input-stream))
(setf (input stream) ""
(index stream) 0)
nil)
(defmethod trivial-gray-streams:stream-line-column ((stream debugger-input-stream))
nil)
(defclass debugger-output-stream (trivial-gray-streams:fundamental-character-output-stream)
((output-fn :initarg :output-fn
:accessor output-fn
:documentation "The one-shot function accepting string and printing it.")
(output :initform (make-array 0 :adjustable t :fill-pointer 0 :element-type 'character)
:initarg :output
:accessor output
:documentation "The vector to use as the output buffer.")
(column :initform 0
:initarg :column
:accessor column)))
(defmethod trivial-gray-streams:stream-write-char ((stream debugger-output-stream) char)
(vector-push-extend char (output stream))
(if (char= #\newline char)
(setf (column stream) 0)
(incf (column stream)))
char)
(defmethod trivial-gray-streams:stream-line-column ((stream debugger-output-stream))
(column stream))
(defmethod trivial-gray-streams:stream-finish-output ((stream debugger-output-stream))
(funcall (output-fn stream) (coerce (output stream) 'string))
(loop until (zerop (length (output stream)))
do (vector-pop (output stream)))
nil)
(defmethod trivial-gray-streams:stream-force-output ((stream debugger-output-stream))
(trivial-gray-streams:stream-finish-output stream))
(defmethod trivial-gray-streams:stream-fresh-line ((stream debugger-output-stream))
(cond ((zerop (column stream)) nil)
(t (terpri stream) t)))
(declaim (ftype (function ((function () string) (function (string))) two-way-stream)
make-debugger-stream))
(defun make-debugger-stream (input-fn output-fn)
"Construct a `*query-io*'-compatible stream out of INPUT-FN and OUTPUT-FN."
(make-two-way-stream
;; FIXME: Understand/reproduce how Swank makes those streams.
(make-instance 'debugger-input-stream :input-fn input-fn)
(make-instance 'debugger-output-stream :output-fn output-fn)))