9eed0a550aa4827dd969099c86ded580be2e4cf4
[riece] / lisp / riece-addon.el
1 ;;; riece-addon.el --- add-on management
2 ;; Copyright (C) 1998-2004 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 (defun riece-load-and-build-addon-dependencies (addons)
28   (let ((load-path (cons riece-addon-directory load-path))
29         dependencies)
30     (while addons
31       (require (car addons))            ;error will be reported here
32       (let* ((requires
33               (funcall (or (intern-soft
34                             (concat (symbol-name (car addons)) "-requires"))
35                            #'ignore)))
36              (pointer requires)
37              entry)
38         ;; Increment succs' pred count.
39         (if (setq entry (assq (car addons) dependencies))
40             (setcar (cdr entry) (+ (length requires) (nth 1 entry)))
41           (setq dependencies (cons (list (car addons) (length requires))
42                                    dependencies)))
43         ;; Merge pred's succs.
44         (while pointer
45           (if (setq entry (assq (car pointer) dependencies))
46               (setcdr (cdr entry)
47                       (cons (car addons) (nthcdr 2 entry)))
48             (setq dependencies (cons (list (car pointer) 0 (car addons))
49                                      dependencies)))
50           (setq pointer (cdr pointer))))
51       (setq addons (cdr addons)))
52     dependencies))
53
54 (defun riece-resolve-addons (addons)
55   (let ((pointer addons)
56         dependencies queue)
57     ;; Uniquify, first.
58     (while pointer
59       (if (memq (car pointer) (cdr pointer))
60           (setcar pointer nil))
61       (setq pointer (cdr pointer)))
62     (setq dependencies (riece-load-and-build-addon-dependencies
63                         (delq nil addons))
64           pointer dependencies)
65     ;; Sort them.
66     (while pointer
67       (if (zerop (nth 1 (car pointer)))
68           (setq dependencies (delq (car pointer) dependencies)
69                 queue (cons (car pointer) queue)))
70       (setq pointer (cdr pointer)))
71     (setq addons nil)
72     (while queue
73       (setq addons (cons (car (car queue)) addons)
74             pointer (nthcdr 2 (car queue)))
75       (while pointer
76         (let* ((entry (assq (car pointer) dependencies))
77                (count (1- (nth 1 entry))))
78           (if (zerop count)
79               (progn
80                 (setq dependencies (delq entry dependencies)
81                       queue (nconc queue (list entry))))
82             (setcar (cdr entry) count)))
83         (setq pointer (cdr pointer)))
84       (setq queue (cdr queue)))
85     (if dependencies
86         (error "Circular add-on dependency found"))
87     (nreverse addons)))
88
89 (defun riece-insinuate-addon (addon)
90   (require addon)               ;implicit dependency
91   (funcall (intern (concat (symbol-name addon) "-insinuate")))
92   (if riece-debug
93       (message "Add-on %S is insinuated" addon)))
94
95 (defun riece-enable-addon (addon)
96   (let ((enabled (intern-soft (concat (symbol-name addon) "-enabled"))))
97     (if (null enabled)
98         (if riece-debug
99             (message "Add-on %S doesn't support enable/disable" addon))
100       (if (symbol-value enabled)
101           (if riece-debug
102               (message "Can't enable add-on %S" addon))
103         (funcall (or (intern-soft (concat (symbol-name addon) "-enable"))
104                      #'ignore))
105         (if riece-debug
106             (message "Add-on %S enabled" addon))))))
107
108 (defun riece-disable-addon (addon)
109   (let ((enabled (intern-soft (concat (symbol-name addon) "-enabled"))))
110     (if (null enabled)
111         (if riece-debug
112             (message "Add-on %S doesn't support enable/disable" addon))
113       (if (symbol-value enabled)
114           (progn
115             (funcall (or (intern-soft (concat (symbol-name (car addons))
116                                               "-disable"))
117                          #'ignore))
118             (if riece-debug
119                 (message "Add-on %S disabled" (car addons))))
120         (if riece-debug
121             (message "Can't disable add-on %S" addon))))))
122
123 (provide 'riece-addon)
124
125 ;;; riece-addon.el ends here