[slime-cvs] CVS update: slime/swank.lisp

Helmut Eller heller at common-lisp.net
Tue Dec 27 15:12:26 UTC 2005


Update of /project/slime/cvsroot/slime
In directory common-lisp.net:/tmp/cvs-serv14303

Modified Files:
	swank.lisp 
Log Message:
(log-event): Record the event in the history buffer.
(*event-history*, *event-history-index*, *enable-event-history*): Ring
buffer for events.
(dump-event-history, dump-event, escape-non-ascii, ascii-string-p)
(ascii-char-p): New functions.

(close-connection): Escape non-ascii strings and include the event
history in the error message.

Date: Tue Dec 27 16:12:23 2005
Author: heller

Index: slime/swank.lisp
diff -u slime/swank.lisp:1.355 slime/swank.lisp:1.356
--- slime/swank.lisp:1.355	Tue Dec 20 01:26:25 2005
+++ slime/swank.lisp	Tue Dec 27 16:12:22 2005
@@ -323,14 +323,54 @@
 
 (defvar *log-events* nil)
 (defvar *log-output* *error-output*)
+(defvar *event-history* (make-array 40 :initial-element nil)
+  "A ring buffer to record events for better error messages.")
+(defvar *event-history-index* 0)
+(defvar *enable-event-history* t)
 
 (defun log-event (format-string &rest args)
   "Write a message to *terminal-io* when *log-events* is non-nil.
 Useful for low level debugging."
+  (when *enable-event-history*
+    (setf (aref *event-history* *event-history-index*) 
+          (apply #'format nil format-string args))
+    (setf *event-history-index* 
+          (mod (1+ *event-history-index*) (length *event-history*))))
   (when *log-events*
     (apply #'format *log-output* format-string args)
     (force-output *log-output*)))
 
+(defun event-history-to-list ()
+  "Return the list of events (older events first)."
+  (let ((arr *event-history*)
+        (idx *event-history-index*))
+    (concatenate 'list (subseq arr idx) (subseq arr 0 idx))))
+
+(defun dump-event-history (stream)
+  (dolist (e (event-history-to-list))
+    (dump-event e stream)))
+
+(defun dump-event (event stream)
+  (cond ((stringp event)
+         (write-string (escape-non-ascii event) stream))
+        ((null event))
+        (t (format stream "Unexpected event: ~A~%" event))))
+
+(defun escape-non-ascii (string)
+  "Return a string like STRING but with non-ascii chars escaped."
+  (cond ((ascii-string-p string) string)
+        (t (with-output-to-string (out)
+             (loop for c across string do
+               (cond ((ascii-char-p c) (write-char c out))
+                     (t (format out "\\x~4,'0X" (char-code c)))))))))
+
+(defun ascii-string-p (o)
+  (and (stringp o)
+       (every #'ascii-char-p o)))
+
+(defun ascii-char-p (c) 
+  (<= (char-code c) 127))
+
 
 ;;;; TCP Server
 
@@ -510,7 +550,19 @@
   (setf *connections* (remove c *connections*))
   (run-hook *connection-closed-hook* c)
   (when condition
-    (format *debug-io* "~&;; Connection to Emacs lost.~%;; [~A]~%" condition)
+    (finish-output *debug-io*)
+    (format *debug-io* "~&;; Event history start:~%")
+    (dump-event-history *debug-io*)
+    (format *debug-io* ";; Event history end.~%~
+                        ;; Connection to Emacs lost. [~%~
+                        ;;  condition: ~A~%~
+                        ;;  type: ~S~%~
+                        ;;  encoding: ~S style: ~S dedicated: ~S]~%"
+            (escape-non-ascii (safe-condition-message condition) )
+            (type-of condition)
+            (connection.external-format c) 
+            (connection.communication-style c)
+            *use-dedicated-output-stream*)
     (finish-output *debug-io*)))
 
 (defmacro with-reader-error-handler ((connection) &body body)
@@ -962,9 +1014,8 @@
                (pos (read-sequence string stream)))
           (assert (= pos length) ()
                   "Short read: length=~D  pos=~D" length pos)
-          (let ((form (read-form string)))
-            (log-event "READ: ~A~%" string)
-            form))
+          (log-event "READ: ~S~%" string)
+          (read-form string))
       (serious-condition (c)
         (error (make-condition 'slime-protocol-error :condition c))))))
 




More information about the slime-cvs mailing list