Fixed.
[riece] / lisp / riece-ruby.el
1 ;;; riece-ruby.el --- interact with ruby interpreter
2 ;; Copyright (C) 1998-2005 Daiki Ueno
3
4 ;; Author: Daiki Ueno <ueno@unixuser.org>
5 ;; Created: 1998-09-28
6 ;; Keywords: IRC, riece
7
8 ;; This file is part of Riece.
9
10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;; Code:
26
27 (defvar riece-ruby-command "ruby"
28   "Command name for Ruby interpreter.")
29
30 (defun riece-ruby-substitute-variables (program variable value)
31   (setq program (copy-sequence program))
32   (let ((pointer program))
33     (while pointer
34       (setq pointer (memq variable program))
35       (if pointer
36           (setcar pointer value)))
37     program))
38
39 (defun riece-ruby-escape-data (data)
40   (let ((index 0))
41     (while (string-match "[%\r\n]+" data index)
42       (setq data (replace-match
43                   (mapconcat (lambda (c) (format "%%%02X" c))
44                              (match-string 0 data) "")
45                   nil nil data)
46             index (+ (match-end 0)
47                      (* (- (match-end 0) (match-beginning 0)) 2))))
48     data))
49
50 (defun riece-ruby-unescape-data (data)
51   (let ((index 0))
52     (while (string-match "%\\([0-9A-F][0-9A-F]\\)" data index)
53       (setq data (replace-match
54                   (read (concat "\"\\x" (match-string 1 data) "\""))
55                   nil nil data)
56             index (- (match-end 0) 2)))
57     data))
58
59 (defun riece-ruby-start ()                      
60   (start-process "riece-ruby"
61                  (generate-new-buffer " *Ruby*")
62                  riece-ruby-command
63                  (expand-file-name "rubyserv.rb"
64                                    (file-name-directory
65                                     (symbol-file 'riece-ruby-start)))))
66
67 (defun riece-ruby-execute (process program &optional callback)
68   (set-process-filter process #'riece-ruby-filter)
69   (set-process-sentinel process #'riece-ruby-sentinel)
70   (with-current-buffer (process-buffer process)
71     (make-local-variable 'riece-ruby-callback)
72     (setq riece-ruby-callback callback)
73     (make-local-variable 'riece-ruby-data)
74     (setq riece-ruby-data nil))
75   (process-send-string process
76                        (concat "EVAL " (riece-ruby-escape-data program)
77                                "\n")))
78
79 (defun riece-ruby-filter (process input)
80   (save-excursion
81     (set-buffer (process-buffer process))
82     (goto-char (point-max))
83     (insert input)
84     (goto-char (process-mark process))
85     (beginning-of-line)
86     (while (looking-at ".*\r?\n")
87       (if (looking-at "OK\\( \\(.*\\)\\)?")
88           (progn
89             (funcall riece-ruby-callback
90                      (list 'OK
91                            (match-string 2)
92                            (riece-ruby-unescape-data
93                             (apply #'concat (nreverse riece-ruby-data)))))
94             (setq riece-ruby-data nil))
95         (if (looking-at "ERR \\([0-9]+\\)\\( \\(.*\\)\\)?")
96             (progn
97               (funcall riece-ruby-callback
98                        (list 'ERR
99                              (number-to-string (match-string 1))
100                              (match-string 3)
101                              (riece-ruby-unescape-data
102                               (apply #'concat (nreverse riece-ruby-data)))))
103               (setq riece-ruby-data nil))
104           (if (looking-at "D \\(.*\\)")
105               (setq riece-ruby-data (cons (match-string 1) riece-ruby-data)))))
106       (forward-line))))
107
108 (defun riece-ruby-sentinel (process status)
109   (kill-buffer (process-buffer process)))
110
111 (provide 'riece-ruby)
112
113 ;;; riece-ruby.el ends here