]> code.delx.au - gnu-emacs/commitdiff
Revision: emacs@sv.gnu.org/emacs--devo--0--patch-220
authorMiles Bader <miles@gnu.org>
Sun, 16 Apr 2006 02:17:00 +0000 (02:17 +0000)
committerMiles Bader <miles@gnu.org>
Sun, 16 Apr 2006 02:17:00 +0000 (02:17 +0000)
Creator:  Michael Olson <mwolson@gnu.org>

Improve tq.el.

* lispref/processes.texi (Transaction Queues): Mention the new optional
  `delay-question' argument for `tq-enqueue'.

* lisp/emacs-lisp/tq.el: Improve comments.
  (tq-queue-head-question): New accessor function.
  (tq-queue-head-regexp, tq-queue-head-closure, tq-queue-head-fn):
  Update for modified queue structure.
  (tq-queue-add): Accept `question' argument.
  (tq-queue-pop): If a question is pending, send it.
  (tq-enqueue): Accept new optional argument `delay-question'.  If
  this is non-nil, and at least one other question is pending a
  response, queue the question rather than sending it immediately.

lisp/ChangeLog
lisp/emacs-lisp/tq.el
lispref/ChangeLog
lispref/processes.texi

index 547e4663d51a7c6ba7fb6c9a8d5110d75ad7c8d1..dfc0c79b1f5b5a5d562d8f0ccf742f75cbc7e285 100644 (file)
@@ -1,3 +1,15 @@
+2006-04-15  Michael Olson  <mwolson@gnu.org>
+
+       * emacs-lisp/tq.el: Improve comments.
+       (tq-queue-head-question): New accessor function.
+       (tq-queue-head-regexp, tq-queue-head-closure, tq-queue-head-fn):
+       Update for modified queue structure.
+       (tq-queue-add): Accept `question' argument.
+       (tq-queue-pop): If a question is pending, send it.
+       (tq-enqueue): Accept new optional argument `delay-question'.  If
+       this is non-nil, and at least one other question is pending a
+       response, queue the question rather than sending it immediately.
+
 2006-04-15  Roland Winkler  <Roland.Winkler@physik.uni-erlangen.de>
 
        * calendar/appt.el (appt-add): Check whether an appointment is
index a4a22806d09333782ebb3713585aec603754e769..2126d7663fce2d058d0fdc96af8a82496e60e308 100644 (file)
 
 ;;; Commentary:
 
-;; manages receiving a stream asynchronously,
-;; parsing it into transactions, and then calling
-;; handler functions
+;; This file manages receiving a stream asynchronously, parsing it
+;; into transactions, and then calling the associated handler function
+;; upon the completion of each transaction.
 
 ;; Our basic structure is the queue/process/buffer triple.  Each entry
-;; of the queue is a regexp/closure/function triple.  We buffer
-;; bytes from the process until we see the regexp at the head of the
-;; queue.  Then we call the function with the closure and the
-;; collected bytes.
+;; of the queue part is a list of question, regexp, closure, and
+;; function that is consed to the last element.
+
+;; A transaction queue may be created by calling `tq-create'.
+
+;; A request may be added to the queue by calling `tq-enqueue'.  If
+;; the `delay-question' argument is non-nil, we will wait to send the
+;; question to the process until it has finished sending other input.
+;; Otherwise, once a request is enqueued, we send the given question
+;; immediately to the process.
+
+;; We then buffer bytes from the process until we see the regexp that
+;; was provided in the call to `tq-enqueue'.  Then we call the
+;; provided function with the closure and the collected bytes.  If we
+;; have indicated that the question from the next transaction was not
+;; sent immediately, send it at this point, awaiting the response.
 
 ;;; Code:
 
+;;; Accessors
+
+;; This part looks like (queue . (process . buffer))
+(defun tq-queue               (tq) (car tq))
+(defun tq-process             (tq) (car (cdr tq)))
+(defun tq-buffer              (tq) (cdr (cdr tq)))
+
+;; The structure of `queue' is as follows
+;; ((question regexp closure . fn)
+;;  <other queue entries>)
+;; question: string to send to the process
+(defun tq-queue-head-question (tq) (car (car (tq-queue tq))))
+;; regexp: regular expression that matches the end of a response from
+;; the process
+(defun tq-queue-head-regexp   (tq) (car (cdr (car (tq-queue tq)))))
+;; closure: additional data to pass to function
+(defun tq-queue-head-closure  (tq) (car (cdr (cdr (car (tq-queue tq))))))
+;; fn: function to call upon receiving a complete response from the
+;; process
+(defun tq-queue-head-fn       (tq) (cdr (cdr (cdr (car (tq-queue tq))))))
+
+;; Determine whether queue is empty
+(defun tq-queue-empty         (tq) (not (tq-queue tq)))
+
+;;; Core functionality
+
 ;;;###autoload
 (defun tq-create (process)
   "Create and return a transaction queue communicating with PROCESS.
@@ -54,33 +92,37 @@ to a tcp server on another machine."
                           (tq-filter ',tq string)))
     tq))
 
-;;; accessors
-(defun tq-queue   (tq) (car tq))
-(defun tq-process (tq) (car (cdr tq)))
-(defun tq-buffer  (tq) (cdr (cdr tq)))
-
-(defun tq-queue-add (tq re closure fn)
+(defun tq-queue-add (tq question re closure fn)
   (setcar tq (nconc (tq-queue tq)
-                   (cons (cons re (cons closure fn)) nil)))
+                   (cons (cons question (cons re (cons closure fn))) nil)))
   'ok)
 
-(defun tq-queue-head-regexp  (tq) (car (car (tq-queue tq))))
-(defun tq-queue-head-fn      (tq) (cdr (cdr (car (tq-queue tq)))))
-(defun tq-queue-head-closure (tq) (car (cdr (car (tq-queue tq)))))
-(defun tq-queue-empty        (tq) (not (tq-queue tq)))
-(defun tq-queue-pop          (tq) (setcar tq (cdr (car tq))) (null (car tq)))
+(defun tq-queue-pop (tq)
+  (setcar tq (cdr (car tq)))
+  (let ((question (tq-queue-head-question tq)))
+    (when question
+      (process-send-string (tq-process tq) question)))
+  (null (car tq)))
 
-
-;;; must add to queue before sending!
-(defun tq-enqueue (tq question regexp closure fn)
+(defun tq-enqueue (tq question regexp closure fn &optional delay-question)
   "Add a transaction to transaction queue TQ.
 This sends the string QUESTION to the process that TQ communicates with.
-When the corresponding answer comes back, we call FN
-with two arguments: CLOSURE, and the answer to the question.
+
+When the corresponding answer comes back, we call FN with two
+arguments: CLOSURE, which may contain additional data that FN
+needs, and the answer to the question.
+
 REGEXP is a regular expression to match the entire answer;
-that's how we tell where the answer ends."
-  (tq-queue-add tq regexp closure fn)
-  (process-send-string (tq-process tq) question))
+that's how we tell where the answer ends.
+
+If DELAY-QUESTION is non-nil, delay sending this question until
+the process has finished replying to any previous questions.
+This produces more reliable results with some processes."
+  (let ((sendp (or (not delay-question)
+                  (not (tq-queue-head-question tq)))))
+    (tq-queue-add tq (unless sendp question) regexp closure fn)
+    (when sendp
+      (process-send-string (tq-process tq) question))))
 
 (defun tq-close (tq)
   "Shut down transaction queue TQ, terminating the process."
index f16982eb414fed69592c300920d7b5aaff6aea66..c3591cbb64a3d96cc42ce93808e70f1348ee8a90 100644 (file)
@@ -1,3 +1,8 @@
+2006-04-15  Michael Olson  <mwolson@gnu.org>
+
+       * processes.texi (Transaction Queues): Mention the new optional
+       `delay-question' argument for `tq-enqueue'.
+
 2006-04-13  Bill Wohler  <wohler@newt.com>
 
        * customize.texi (Common Keywords): Use dotted notation for
index 5f0cfb0edf03a801ea1cd57ef44356cf88c7ecd6..44da398770dfc39779dc336ffb95064129f267c8 100644 (file)
@@ -1508,7 +1508,7 @@ process, or it may be a TCP connection to a server, possibly on another
 machine.
 @end defun
 
-@defun tq-enqueue queue question regexp closure fn
+@defun tq-enqueue queue question regexp closure fn &optional delay-question
 This function sends a transaction to queue @var{queue}.  Specifying the
 queue has the effect of specifying the subprocess to talk to.
 
@@ -1521,6 +1521,10 @@ The argument @var{regexp} is a regular expression that should match
 text at the end of the entire answer, but nothing before; that's how
 @code{tq-enqueue} determines where the answer ends.
 
+If the argument @var{delay-question} is non-nil, delay sending this
+question until the process has finished replying to any previous
+questions.  This produces more reliable results with some processes."
+
 The return value of @code{tq-enqueue} itself is not meaningful.
 @end defun