From: ueno Date: Wed, 10 Aug 2005 11:17:10 +0000 (+0000) Subject: * riece-ruby.el: New file. X-Git-Tag: channel-coding-branchpoint~179 X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=7a56fa0c94b45cffa5f00a610e9193146851d9c0;p=elisp%2Friece.git * riece-ruby.el: New file. --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index a518f52..7914d27 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,6 @@ 2005-08-10 Daiki Ueno + * riece-ruby.el: New file. * rubyserv.rb: Rewrite. 2005-08-09 Daiki Ueno diff --git a/lisp/riece-ruby.el b/lisp/riece-ruby.el index a0006e4..5acdc3f 100644 --- a/lisp/riece-ruby.el +++ b/lisp/riece-ruby.el @@ -27,6 +27,17 @@ (defvar riece-ruby-command "ruby" "Command name for Ruby interpreter.") +(defvar riece-ruby-process nil) + +(defvar riece-ruby-lock nil) +(defvar riece-ruby-response nil) +(defvar riece-ruby-data nil) +(defvar riece-ruby-input nil) +(defvar riece-ruby-status nil) + +(defvar riece-ruby-output-handler-alist nil) +(defvar riece-ruby-exit-handler-alist nil) + (defun riece-ruby-substitute-variables (program variable value) (setq program (copy-sequence program)) (let ((pointer program)) @@ -56,25 +67,51 @@ index (- (match-end 0) 2))) data)) -(defun riece-ruby-start () - (start-process "riece-ruby" - (generate-new-buffer " *Ruby*") - riece-ruby-command - (expand-file-name "rubyserv.rb" - (file-name-directory - (symbol-file 'riece-ruby-start))))) - -(defun riece-ruby-execute (process program &optional callback) - (set-process-filter process #'riece-ruby-filter) - (set-process-sentinel process #'riece-ruby-sentinel) - (with-current-buffer (process-buffer process) - (make-local-variable 'riece-ruby-callback) - (setq riece-ruby-callback callback) +(defun riece-ruby-send-eval (name program) + (let* ((string (riece-ruby-escape-data program)) + (length (- (length string) 998)) + (index 0) + data) + (while (< index length) + (setq data (cons (substring string index (setq index (+ index 998))) + data))) + (setq data (cons (substring string index) data) + data (nreverse data)) + (save-excursion + (set-buffer (process-buffer riece-ruby-process)) + (make-local-variable 'riece-ruby-lock) + (setq riece-ruby-lock nil) + (make-local-variable 'riece-ruby-response) + (setq riece-ruby-response nil) + (make-local-variable 'riece-ruby-data) + (setq riece-ruby-data nil) + (make-local-variable 'riece-ruby-input) + (setq riece-ruby-input nil) + (make-local-variable 'riece-ruby-status) + (setq riece-ruby-status nil)) + (process-send-string riece-ruby-process + (concat "EVAL " name "\r\n")) + (while data + (process-send-string riece-ruby-process + (concat "D " (car data) "\r\n")) + (setq data (cdr data))) + (process-send-string riece-ruby-process "END\r\n"))) + +(defun riece-ruby-send-poll (name) + (save-excursion + (set-buffer (process-buffer riece-ruby-process)) + (make-local-variable 'riece-ruby-lock) + (setq riece-ruby-lock nil) + (make-local-variable 'riece-ruby-response) + (setq riece-ruby-response nil) (make-local-variable 'riece-ruby-data) - (setq riece-ruby-data nil)) - (process-send-string process - (concat "EVAL " (riece-ruby-escape-data program) - "\n"))) + (setq riece-ruby-data nil) + (make-local-variable 'riece-ruby-input) + (setq riece-ruby-input nil) + (make-local-variable 'riece-ruby-status) + (setq riece-ruby-status nil)) + (process-send-string riece-ruby-process + (concat "POLL " name "\r\n"))) (defun riece-ruby-filter (process input) (save-excursion @@ -84,30 +121,71 @@ (goto-char (process-mark process)) (beginning-of-line) (while (looking-at ".*\r?\n") - (if (looking-at "OK\\( \\(.*\\)\\)?") + (if (looking-at "OK\\( \\(.*\\)\\)?\r") (progn - (funcall riece-ruby-callback - (list 'OK - (match-string 2) - (riece-ruby-unescape-data - (apply #'concat (nreverse riece-ruby-data))))) - (setq riece-ruby-data nil)) - (if (looking-at "ERR \\([0-9]+\\)\\( \\(.*\\)\\)?") + (if riece-ruby-input + (setq riece-ruby-data (mapconcat #'riece-ruby-unescape-data + riece-ruby-input ""))) + (setq riece-ruby-input nil + riece-ruby-response (list 'OK (match-string 2)) + riece-ruby-lock nil)) + (if (looking-at "ERR \\([0-9]+\\)\\( \\(.*\\)\\)?\r") (progn - (funcall riece-ruby-callback - (list 'ERR - (number-to-string (match-string 1)) - (match-string 3) - (riece-ruby-unescape-data - (apply #'concat (nreverse riece-ruby-data))))) - (setq riece-ruby-data nil)) - (if (looking-at "D \\(.*\\)") - (setq riece-ruby-data (cons (match-string 1) riece-ruby-data))))) - (forward-line)))) + (setq riece-ruby-input nil + riece-ruby-response + (list 'ERR (string-to-number (match-string 2)) + (match-string 3)) + riece-ruby-lock nil)) + (if (looking-at "D \\(.*\\)\r") + (setq riece-ruby-input (cons (match-string 1) riece-ruby-input)) + (if (looking-at "S program \\(.*\\)\r") + (setq riece-ruby-status (match-string 1)) + (if (looking-at "# output \\(.*\\) \\(.*\\)\r") + (let ((entry (assoc (match-string 1) + riece-ruby-output-handler-alist))) + (if entry + (funcall (cdr entry) (match-string 2)))) + (if (looking-at "# exit \\(.*\\)\r") + (let ((entry (assoc (match-string 1) + riece-ruby-exit-handler-alist))) + (if entry + (funcall (cdr entry)))))))))) + (forward-line)) + (set-marker (process-mark process) (point-marker)))) (defun riece-ruby-sentinel (process status) (kill-buffer (process-buffer process))) +(defun riece-ruby-execute (name program) + (unless (and riece-ruby-process + (eq (process-status riece-ruby-process) 'run)) + (setq riece-ruby-process + (start-process "riece-ruby" (generate-new-buffer " *Ruby*") + riece-ruby-command + (expand-file-name + "rubyserv.rb" + (file-name-directory + (symbol-file 'riece-ruby-execute))))) + (set-process-filter riece-ruby-process #'riece-ruby-filter) + (set-process-sentinel riece-ruby-process #'riece-ruby-sentinel)) + (save-excursion + (set-buffer (process-buffer riece-ruby-process)) + (setq riece-ruby-lock t) + (riece-ruby-send-eval name program) + (while riece-ruby-lock + (accept-process-output riece-ruby-process)))) + +(defun riece-ruby-inspect (name) + (save-excursion + (set-buffer (process-buffer riece-ruby-process)) + (setq riece-ruby-lock t) + (riece-ruby-send-poll name) + (while (null riece-ruby-response) + (accept-process-output riece-ruby-process)) + (list riece-ruby-response + riece-ruby-data + riece-ruby-status))) + (provide 'riece-ruby) ;;; riece-ruby.el ends here diff --git a/lisp/rubyserv.rb b/lisp/rubyserv.rb index 97247c2..7083834 100644 --- a/lisp/rubyserv.rb +++ b/lisp/rubyserv.rb @@ -1,11 +1,10 @@ # A simple IPC server executing Ruby programs. require 'thread' -require 'stringio' class RubyServ def initialize - @buf = StringIO.new + @buf = '' @que = Queue.new @thr = Hash.new end @@ -13,7 +12,7 @@ class RubyServ def dispatch(line) case line.chomp when /\AD / - @buf << unescape($') + @buf << $' when /\A(\S+)\s*/ c = $1 r = $' @@ -63,6 +62,7 @@ class RubyServ return end code = deq_data unless code + p code puts("OK\r\n") @thr[name] = Thread.current Thread.current[:rubyserv_name] = name @@ -73,7 +73,7 @@ class RubyServ Thread.current[:rubyserv_error] = true Thread.current[:rubyserv_response] = e end - puts("# exited #{name}\r\n") + puts("# exit #{name}\r\n") end def dispatch_poll(c, r) @@ -81,14 +81,14 @@ class RubyServ if !thr puts("ERR 105 Parameter error: no such name \"#{r}\"\r\n") elsif thr.alive? - puts("S running\r\n") + puts("S program running\r\n") puts("OK\r\n") else @thr.delete(r) if thr[:rubyserv_error] - puts("S exited\r\n") + puts("S program exited\r\n") else - puts("S finished\r\n") + puts("S program finished\r\n") end if d = thr[:rubyserv_response] send_data(d.to_s) @@ -119,7 +119,9 @@ class RubyServ end def enq_data - @que.enq(@buf.string) + d = unescape(@buf) + @buf = '' + @que.enq(d) end def deq_data