PageRenderTime 26ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/emacs/emacs.d.symlink/elpa/slime-20140221.336/swank-rpc.lisp

https://gitlab.com/joncanady/outdated-dotfiles
Lisp | 161 lines | 113 code | 19 blank | 29 comment | 5 complexity | 8ef08cbaaaf294da73f55c8154618431 MD5 | raw file
  1. ;;; -*- indent-tabs-mode: nil; coding: latin-1-unix -*-
  2. ;;;
  3. ;;; swank-rpc.lisp -- Pass remote calls and responses between lisp systems.
  4. ;;;
  5. ;;; Created 2010, Terje Norderhaug <terje@in-progress.com>
  6. ;;;
  7. ;;; This code has been placed in the Public Domain. All warranties
  8. ;;; are disclaimed.
  9. ;;;
  10. (defpackage #:swank-rpc
  11. (:use :cl)
  12. (:export
  13. #:read-message
  14. #:swank-reader-error
  15. #:swank-reader-error.packet
  16. #:swank-reader-error.cause
  17. #:write-message))
  18. (in-package :swank-rpc)
  19. ;;;;; Input
  20. (define-condition swank-reader-error (reader-error)
  21. ((packet :type string :initarg :packet
  22. :reader swank-reader-error.packet)
  23. (cause :type reader-error :initarg :cause
  24. :reader swank-reader-error.cause)))
  25. (defun read-message (stream package)
  26. (let ((packet (read-packet stream)))
  27. (handler-case (values (read-form packet package))
  28. (reader-error (c)
  29. (error 'swank-reader-error
  30. :packet packet :cause c)))))
  31. (defun read-packet (stream)
  32. (let* ((length (parse-header stream))
  33. (octets (read-chunk stream length)))
  34. (handler-case (swank-backend:utf8-to-string octets)
  35. (error (c)
  36. (error 'swank-reader-error
  37. :packet (asciify octets)
  38. :cause c)))))
  39. (defun asciify (packet)
  40. (with-output-to-string (*standard-output*)
  41. (loop for code across (etypecase packet
  42. (string (map 'vector #'char-code packet))
  43. (vector packet))
  44. do (cond ((<= code #x7f) (write-char (code-char code)))
  45. (t (format t "\\x~x" code))))))
  46. (defun parse-header (stream)
  47. (parse-integer (map 'string #'code-char (read-chunk stream 6))
  48. :radix 16))
  49. (defun read-chunk (stream length)
  50. (let* ((buffer (make-array length :element-type '(unsigned-byte 8)))
  51. (count (read-sequence buffer stream)))
  52. (cond ((= count length)
  53. buffer)
  54. ((zerop count)
  55. (error 'end-of-file :stream stream))
  56. (t
  57. (error "Short read: length=~D count=~D" length count)))))
  58. ;; FIXME: no one ever tested this and will probably not work.
  59. (defparameter *validate-input* nil
  60. "Set to true to require input that strictly conforms to the protocol")
  61. (defun read-form (string package)
  62. (with-standard-io-syntax
  63. (let ((*package* package))
  64. (if *validate-input*
  65. (validating-read string)
  66. (read-from-string string)))))
  67. (defun validating-read (string)
  68. (with-input-from-string (*standard-input* string)
  69. (simple-read)))
  70. (defun simple-read ()
  71. "Read a form that conforms to the protocol, otherwise signal an error."
  72. (let ((c (read-char)))
  73. (case c
  74. (#\" (with-output-to-string (*standard-output*)
  75. (loop for c = (read-char) do
  76. (case c
  77. (#\" (return))
  78. (#\\ (write-char (read-char)))
  79. (t (write-char c))))))
  80. (#\( (loop collect (simple-read)
  81. while (ecase (read-char)
  82. (#\) nil)
  83. (#\space t))))
  84. (#\' `(quote ,(simple-read)))
  85. (t (let ((string (with-output-to-string (*standard-output*)
  86. (loop for ch = c then (read-char nil nil) do
  87. (case ch
  88. ((nil) (return))
  89. (#\\ (write-char (read-char)))
  90. ((#\space #\)) (unread-char ch)(return))
  91. (t (write-char ch)))))))
  92. (cond ((digit-char-p c) (parse-integer string))
  93. ((intern string))))))))
  94. ;;;;; Output
  95. (defun write-message (message package stream)
  96. (let* ((string (prin1-to-string-for-emacs message package))
  97. (octets (handler-case (swank-backend:string-to-utf8 string)
  98. (error (c) (encoding-error c string))))
  99. (length (length octets)))
  100. (write-header stream length)
  101. (write-sequence octets stream)
  102. (finish-output stream)))
  103. ;; FIXME: for now just tell emacs that we and an encoding problem.
  104. (defun encoding-error (condition string)
  105. (swank-backend:string-to-utf8
  106. (prin1-to-string-for-emacs
  107. `(:reader-error
  108. ,(asciify string)
  109. ,(format nil "Error during string-to-utf8: ~a"
  110. (or (ignore-errors (asciify (princ-to-string condition)))
  111. (asciify (princ-to-string (type-of condition))))))
  112. (find-package :cl))))
  113. (defun write-header (stream length)
  114. (declare (type (unsigned-byte 24) length))
  115. ;;(format *trace-output* "length: ~d (#x~x)~%" length length)
  116. (loop for c across (format nil "~6,'0x" length)
  117. do (write-byte (char-code c) stream)))
  118. (defun prin1-to-string-for-emacs (object package)
  119. (with-standard-io-syntax
  120. (let ((*print-case* :downcase)
  121. (*print-readably* nil)
  122. (*print-pretty* nil)
  123. (*package* package))
  124. (prin1-to-string object))))
  125. #| TEST/DEMO:
  126. (defparameter *transport*
  127. (with-output-to-string (out)
  128. (write-message '(:message (hello "world")) *package* out)
  129. (write-message '(:return 5) *package* out)
  130. (write-message '(:emacs-rex NIL) *package* out)))
  131. *transport*
  132. (with-input-from-string (in *transport*)
  133. (loop while (peek-char T in NIL)
  134. collect (read-message in *package*)))
  135. |#