1 ;;; nnoo.el --- OO Gnus Backends
2 ;; Copyright (C) 1996,97 Free Software Foundation, Inc.
4 ;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
7 ;; This file is part of GNU Emacs.
9 ;; GNU Emacs is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING. If not, write to the
21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
31 (defvar nnoo-definition-alist nil
)
32 (defvar nnoo-state-alist nil
)
34 (defmacro defvoo
(var init
&optional doc
&rest map
)
35 "The same as `defvar', only takes list of variables to MAP to."
38 `(defvar ,var
,init
,doc
)
40 (nnoo-define ',var
',map
)))
41 (put 'defvoo
'lisp-indent-function
2)
42 (put 'defvoo
'edebug-form-spec
'(var init
&optional doc
&rest map
))
44 (defmacro deffoo
(func args
&rest forms
)
45 "The same as `defun', only register FUNC."
47 (defun ,func
,args
,@forms
)
48 (nnoo-register-function ',func
)))
49 (put 'deffoo
'lisp-indent-function
2)
50 (put 'deffoo
'edebug-form-spec
'(&define name lambda-list def-body
))
52 (defun nnoo-register-function (func)
53 (let ((funcs (nthcdr 3 (assoc (nnoo-backend func
)
54 nnoo-definition-alist
))))
56 (error "%s belongs to a backend that hasn't been declared" func
))
57 (setcar funcs
(cons func
(car funcs
)))))
59 (defmacro nnoo-declare
(backend &rest parents
)
62 (mapcar (lambda (p) (list p
)) ',parents
)
64 nnoo-definition-alist
)
65 (push (list ',backend
"*internal-non-initialized-backend*")
67 (put 'nnoo-declare
'lisp-indent-function
1)
69 (defun nnoo-parents (backend)
70 (nth 1 (assoc backend nnoo-definition-alist
)))
72 (defun nnoo-variables (backend)
73 (nth 2 (assoc backend nnoo-definition-alist
)))
75 (defun nnoo-functions (backend)
76 (nth 3 (assoc backend nnoo-definition-alist
)))
78 (defmacro nnoo-import
(backend &rest imports
)
79 `(nnoo-import-1 ',backend
',imports
))
80 (put 'nnoo-import
'lisp-indent-function
1)
82 (defun nnoo-import-1 (backend imports
)
84 (if (symbolp (car imports
)) (pop imports
) 'nnoo-parent-function
))
85 imp functions function
)
86 (while (setq imp
(pop imports
))
89 (nnoo-functions (car imp
))))
91 (unless (fboundp (setq function
92 (nnoo-symbol backend
(nnoo-rest-symbol
94 (eval `(deffoo ,function
(&rest args
)
95 (,call-function
',backend
',(car functions
) args
))))
98 (defun nnoo-parent-function (backend function args
)
99 (let* ((pbackend (nnoo-backend function
)))
100 (nnoo-change-server pbackend
(nnoo-current-server backend
)
101 (cdr (assq pbackend
(nnoo-parents backend
))))
102 (apply function args
)))
104 (defun nnoo-execute (backend function
&rest args
)
105 "Execute FUNCTION on behalf of BACKEND."
106 (let* ((pbackend (nnoo-backend function
)))
107 (nnoo-change-server pbackend
(nnoo-current-server backend
)
108 (cdr (assq pbackend
(nnoo-parents backend
))))
109 (apply function args
)))
111 (defmacro nnoo-map-functions
(backend &rest maps
)
112 `(nnoo-map-functions-1 ',backend
',maps
))
113 (put 'nnoo-map-functions
'lisp-indent-function
1)
115 (defun nnoo-map-functions-1 (backend maps
)
117 (while (setq m
(pop maps
))
120 (while (< i
(length (cdr m
)))
121 (if (numberp (nth i
(cdr m
)))
122 (push `(nth ,i args
) margs
)
123 (push (nth i
(cdr m
)) margs
))
125 (eval `(deffoo ,(nnoo-symbol backend
(nnoo-rest-symbol (car m
)))
127 (nnoo-parent-function ',backend
',(car m
)
128 ,(cons 'list
(nreverse margs
))))))))
130 (defun nnoo-backend (symbol)
131 (string-match "^[^-]+-" (symbol-name symbol
))
132 (intern (substring (symbol-name symbol
) 0 (1- (match-end 0)))))
134 (defun nnoo-rest-symbol (symbol)
135 (string-match "^[^-]+-" (symbol-name symbol
))
136 (intern (substring (symbol-name symbol
) (match-end 0))))
138 (defun nnoo-symbol (backend symbol
)
139 (intern (format "%s-%s" backend symbol
)))
141 (defun nnoo-define (var map
)
142 (let* ((backend (nnoo-backend var
))
143 (def (assq backend nnoo-definition-alist
))
144 (parents (nth 1 def
)))
146 (error "%s belongs to a backend that hasn't been declared." var
))
147 (setcar (nthcdr 2 def
)
148 (delq (assq var
(nth 2 def
)) (nth 2 def
)))
149 (setcar (nthcdr 2 def
)
150 (cons (cons var
(symbol-value var
))
153 (nconc (assq (nnoo-backend (car map
)) parents
)
154 (list (list (pop map
) var
))))))
156 (defun nnoo-change-server (backend server defs
)
157 (let* ((bstate (cdr (assq backend nnoo-state-alist
)))
158 (current (car bstate
))
159 (parents (nnoo-parents backend
))
160 (bvariables (nnoo-variables backend
))
163 (push (setq bstate
(list backend nil
))
166 (if (equal server current
)
168 (nnoo-push-server backend current
)
169 (setq state
(or (cdr (assoc server
(cddr bstate
)))
170 (nnoo-variables backend
)))
172 (set (caar state
) (cdar state
))
174 (setcar bstate server
)
175 (unless (cdr (assoc server
(cddr bstate
)))
176 (while (setq def
(pop defs
))
177 (unless (assq (car def
) bvariables
)
179 (list (cons (car def
) (and (boundp (car def
))
180 (symbol-value (car def
)))))))
181 (set (car def
) (cadr def
))))
184 (caar parents
) server
185 (mapcar (lambda (def) (list (car def
) (symbol-value (cadr def
))))
190 (defun nnoo-push-server (backend current
)
191 (let ((bstate (assq backend nnoo-state-alist
))
192 (defs (nnoo-variables backend
)))
193 ;; Remove the old definition.
194 (setcdr (cdr bstate
) (delq (assoc current
(cddr bstate
)) (cddr bstate
)))
195 ;; If this is the first time we push the server (i. e., this is
196 ;; the nil server), then we update the default values of
197 ;; all the variables to reflect the current values.
198 (when (equal current
"*internal-non-initialized-backend*")
199 (let ((defaults (nnoo-variables backend
))
201 (while (setq def
(pop defaults
))
202 (setcdr def
(symbol-value (car def
))))))
205 (push (cons (caar defs
) (symbol-value (caar defs
)))
208 (nconc bstate
(list (cons current state
))))))
210 (defsubst nnoo-current-server-p
(backend server
)
211 (equal (nnoo-current-server backend
) server
))
213 (defun nnoo-current-server (backend)
214 (nth 1 (assq backend nnoo-state-alist
)))
216 (defun nnoo-close-server (backend &optional server
)
218 (setq server
(nnoo-current-server backend
)))
220 (let* ((bstate (cdr (assq backend nnoo-state-alist
)))
221 (defs (assoc server
(cdr bstate
))))
224 (setcdr bstate
(delq defs
(cdr bstate
)))
227 (set (car (pop defs
)) nil
)))))
230 (defun nnoo-close (backend)
231 (setq nnoo-state-alist
232 (delq (assq backend nnoo-state-alist
)
236 (defun nnoo-status-message (backend server
)
237 (nnheader-get-report backend
))
239 (defun nnoo-server-opened (backend server
)
240 (and (nnoo-current-server-p backend server
)
242 (buffer-name nntp-server-buffer
)))
244 (defmacro nnoo-define-basics
(backend)
245 "Define `close-server', `server-opened' and `status-message'."
247 (nnoo-define-basics-1 ',backend
)))
249 (defun nnoo-define-basics-1 (backend)
250 (let ((functions '(close-server server-opened status-message
)))
252 (eval `(deffoo ,(nnoo-symbol backend
(car functions
))
254 (,(nnoo-symbol 'nnoo
(pop functions
)) ',backend server
)))))
255 (eval `(deffoo ,(nnoo-symbol backend
'open-server
)
256 (server &optional defs
)
257 (nnoo-change-server ',backend server defs
))))
259 (defmacro nnoo-define-skeleton
(backend)
260 "Define all required backend functions for BACKEND.
261 All functions will return nil and report an error."
263 (nnoo-define-skeleton-1 ',backend
)))
265 (defun nnoo-define-skeleton-1 (backend)
266 (let ((functions '(retrieve-headers
267 request-close request-article
268 request-group close-group
269 request-list request-post request-list-newsgroups
))
271 (while (setq function
(pop functions
))
272 (when (not (fboundp (setq fun
(nnoo-symbol backend function
))))
275 (nnheader-report ',backend
,(format "%s-%s not implemented"
276 backend function
))))))))
279 ;;; nnoo.el ends here.