blob: 747bf682afbbc2cb4608b0e72f28871994101363 (
plain) (
tree)
|
|
;;; rudel-debug.el --- Debugging functions for Rudel
;;
;; Copyright (C) 2009 Jan Moringen
;;
;; Author: Jan Moringen <scymtym@users.sourceforge.net>
;; Keywords: Rudel, debugging
;; X-RCS: $Id:$
;;
;; This file is part of Rudel.
;;
;; Rudel is free software: you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; Rudel is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with rudel. If not, see <http://www.gnu.org/licenses>.
;;; Commentary:
;;
;; Debugging functions for Rudel.
;;; History:
;;
;; 0.1 - Initial revision.
;;; Code:
;;
(require 'data-debug)
(require 'eieio-datadebug)
(require 'rudel-util)
;;; Customization
;;
(defgroup rudel-debug nil
"Customization options related to Rudel's debugging functions."
:group 'rudel)
(defface rudel-debug-sent-data-face
'((default (:background "orange")))
"Face used for sent data."
:group 'rudel-debug)
(defface rudel-debug-received-data-face
'((default (:background "light sky blue")))
"Face used for received (but not yet processed) data."
:group 'rudel-debug)
(defface rudel-debug-received-processed-data-face
'((default (:background "DeepSkyBlue1")))
"Face used for received data after processing."
:group 'rudel-debug)
(defface rudel-debug-state-face
'((default (:background "light gray")))
"Face used when indicating state changes."
:group 'rudel-debug)
(defface rudel-debug-special-face
'((default (:background "light sea green")))
"Face used for additional information."
:group 'rudel-debug)
(defvar rudel-debug-tag-faces
'((:sent . (rudel-debug-sent-data-face "< "))
(:received . (rudel-debug-received-data-face "> "))
(:received-processed . (rudel-debug-received-processed-data-face ">> "))
(:state . (rudel-debug-state-face "| "))
(:special . (rudel-debug-special-face "; ")))
"Associate tag to faces and prefixes.")
;;; Data debug functions
;;
(defun rudel-adebug-session ()
"Analyze current session in data debug buffer."
(interactive)
;; Make sure we have a session.
(unless rudel-current-session
(error "No active Rudel session"))
(with-current-buffer (data-debug-new-buffer "RUDEL-SESSION")
(data-debug-insert-thing rudel-current-session "# " "")))
(defun rudel-adebug-server (server)
"Analyze server in data debug buffer."
(interactive)
(with-current-buffer (data-debug-new-buffer "RUDEL-SERVER")
(data-debug-insert-thing server "# " "")))
;;; Advice stuff
;;
(defadvice rudel-join-session (after rudel-debug last activate)
"Run data-debug inspection on newly created session objects."
(require 'rudel-debug)
(rudel-adebug-session))
(defadvice rudel-host-session (after rudel-debug last activate)
"Run data-debug inspection on newly created server objects."
(require 'rudel-debug)
(rudel-adebug-server ad-return-value))
;;; Network functions
;;
(defun rudel-suspend-session-socket ()
"Suspend the socket associated to the current session."
(interactive)
;; Make sure we have a session.
(unless rudel-current-session
(error "No active Rudel session"))
(with-slots (connection) rudel-current-session
(with-slots (socket) connection
(stop-process socket))))
(defun rudel-resume-session-socket ()
"Resume the socket associated to the current session."
(interactive)
;; Make sure we have a session.
(unless rudel-current-session
(error "No active Rudel session"))
(with-slots (connection) rudel-current-session
(with-slots (socket) connection
(continue-process socket))))
;;; Reset functions
;;
(defun rudel-kill-processes ()
"TODO"
(interactive)
(mapc #'delete-process (process-list)))
(defun rudel-reset ()
"TODO"
(interactive)
(dolist (buffer (buffer-list))
(with-current-buffer buffer
(when rudel-buffer-document
(setq rudel-buffer-document nil))))
(rudel-kill-processes)
(setq rudel-current-session nil))
;;; Socket debugging
;;
(defmethod rudel-state-change :before ((this rudel-socket-owner)
state message)
"Print STATE and MESSAGE to debug stream."
(with-slots (socket) this
(rudel-debug-stream-insert
(rudel-debug-stream-name socket)
:state
(format "connection state changed to %s: \"%s\""
(upcase (symbol-name state))
;; MESSAGE ends with a newline; remove it
(substring message 0 -1))))
)
;;; Utility functions
;;
(defun rudel-debug-stream-name (socket)
"Return debug stream name for SOCKET."
(process-name socket))
(defun rudel-debug-stream-insert (stream tag data &optional object)
"Insert DATA and possibly OBJECT into stream using TAG as style."
(let* ((buffer-name (format "*%s stream*" stream))
(buffer (or (get-buffer buffer-name)
(data-debug-new-buffer buffer-name)))
(appearance (cdr (assoc tag rudel-debug-tag-faces)))
(face (when appearance
(or (nth 0 appearance)
'default)))
(prefix (or (nth 1 appearance)
"")))
(save-excursion
(set-buffer buffer)
(goto-char 0)
(insert prefix
(propertize data 'face face)
(if (string= (substring data -1) "\n")
"" "\n"))
(when object
(data-debug-insert-thing object prefix ""))))
)
(provide 'rudel-debug)
;;; rudel-debug.el ends here
|