(mail-undo-backslash-quoting): Renamed from undo-...
[bpt/emacs.git] / lisp / emacs-lisp / tq.el
CommitLineData
abeffda9
ER
1;;; tq.el --- utility to maintain a transaction queue
2
58142744
ER
3;; Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
4
83023647
ER
5;; Author: Scott Draves <spot@cs.cmu.edu>
6;; Adapted-By: ESR
d7b4d18f 7;; Keywords: extensions
83023647 8
58142744
ER
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option)
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
22;; along with GNU Emacs; see the file COPYING. If not, write to
23;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24
25;;; Commentary:
83023647 26
abeffda9
ER
27;;; manages receiving a stream asynchronously,
28;;; parsing it into transactions, and then calling
29;;; handler functions
30
abeffda9
ER
31;;; Our basic structure is the queue/process/buffer triple. Each entry
32;;; of the queue is a regexp/closure/function triple. We buffer
33;;; bytes from the process until we see the regexp at the head of the
34;;; queue. Then we call the function with the closure and the
35;;; collected bytes.
36
83023647 37;;; Code:
abeffda9 38
abeffda9
ER
39(defun tq-create (process)
40 "Create and return a transaction queue. PROCESS should be capable
41of sending and receiving streams of bytes. It may be a local process,
42or it may be connected to a tcp server on another machine."
43 (let ((tq (cons nil (cons process
44 (generate-new-buffer
45 (concat " tq-temp-"
46 (process-name process)))))))
47 (set-process-filter process
48 (`(lambda (proc string)
49 (tq-filter '(, tq) string))))
50 tq))
51
52;;; accessors
53(defun tq-queue (tq) (car tq))
54(defun tq-process (tq) (car (cdr tq)))
55(defun tq-buffer (tq) (cdr (cdr tq)))
56
57(defun tq-queue-add (tq re closure fn)
58 (setcar tq (nconc (tq-queue tq)
59 (cons (cons re (cons closure fn)) nil)))
60 'ok)
61
62(defun tq-queue-head-regexp (tq) (car (car (tq-queue tq))))
63(defun tq-queue-head-fn (tq) (cdr (cdr (car (tq-queue tq)))))
64(defun tq-queue-head-closure (tq) (car (cdr (car (tq-queue tq)))))
65(defun tq-queue-empty (tq) (not (tq-queue tq)))
66(defun tq-queue-pop (tq) (setcar tq (cdr (car tq))) (null (car tq)))
67
68
69;;; must add to queue before sending!
70(defun tq-enqueue (tq question regexp closure fn)
71 "Add a transaction to TQ. Send question to the process, and call FN
72with CLOSURE and and the answer, when it appears. The end of the
73answer is identified by REGEXP."
74 (tq-queue-add tq regexp closure fn)
75 (process-send-string (tq-process tq) question))
76
77(defun tq-close (tq)
78 "Shut down the process, and destroy the evidence."
79 (delete-process (tq-process tq))
80 (kill-buffer (tq-buffer tq)))
81
82(defun tq-filter (tq string)
83 "Append STRING to the TQ's buffer; then process the new data."
84 (set-buffer (tq-buffer tq))
85 (goto-char (point-max))
86 (insert string)
87 (tq-process-buffer tq))
88
89(defun tq-process-buffer (tq)
90 "Check TQ's buffer for the regexp at the head of the queue."
91 (set-buffer (tq-buffer tq))
92 (if (= 0 (buffer-size)) ()
93 (if (tq-queue-empty tq)
94 (let ((buf (generate-new-buffer "*spurious*")))
95 (copy-to-buffer buf (point-min) (point-max))
96 (delete-region (point-min) (point))
97 (pop-to-buffer buf nil)
98 (error (concat "Spurious communication from process "
99 (process-name (tq-process tq))
100 ", see buffer *spurious*.")))
101 (goto-char (point-min))
102 (if (re-search-forward (tq-queue-head-regexp tq) nil t)
103 (let ((answer (buffer-substring (point-min) (point))))
104 (delete-region (point-min) (point))
105 (funcall (tq-queue-head-fn tq)
106 (tq-queue-head-closure tq)
107 answer)
108 (tq-queue-pop tq)
109 (tq-process-buffer tq))))))
110
58142744
ER
111(provide 'tq)
112
abeffda9 113;;; tq.el ends here