X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=calist.el;h=22cb3ece3d621c8b6293fc01a79eaeb889e86af8;hb=4426be092c80a2e8c8113ccb1e696743d6210263;hp=38f4889117032c5c06580cbad79e279689aa4387;hpb=5d7a54352bf7c47b3a266dc4b296d1b822fc8f2e;p=elisp%2Fapel.git diff --git a/calist.el b/calist.el index 38f4889..22cb3ec 100644 --- a/calist.el +++ b/calist.el @@ -1,8 +1,10 @@ ;;; calist.el --- Condition functions -;; Copyright (C) 1998 MORIOKA Tomohiko. +;; Copyright (C) 1998 Free Software Foundation, Inc. +;; Copyright (C) 1999 Electrotechnical Laboratory, JAPAN. +;; Licensed to the Free Software Foundation. -;; Author: MORIOKA Tomohiko +;; Author: MORIOKA Tomohiko ;; Keywords: condition, alist, tree ;; This file is part of APEL (A Portable Emacs Library). @@ -19,20 +21,56 @@ ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. ;;; Code: (eval-when-compile (require 'cl)) -(defvar calist-field-match-method-obarray [nil]) +(require 'alist) + +(defvar calist-package-alist nil) +(defvar calist-field-match-method-obarray nil) + +(defun find-calist-package (name) + "Return a calist-package by NAME." + (cdr (assq name calist-package-alist))) (defun define-calist-field-match-method (field-type function) "Set field-match-method for FIELD-TYPE to FUNCTION." (fset (intern (symbol-name field-type) calist-field-match-method-obarray) function)) +(defun use-calist-package (name) + "Make the symbols of package NAME accessible in the current package." + (mapatoms (lambda (sym) + (if (intern-soft (symbol-name sym) + calist-field-match-method-obarray) + (signal 'conflict-of-calist-symbol + (list (format "Conflict of symbol %s" sym))) + (if (fboundp sym) + (define-calist-field-match-method + sym (symbol-function sym)) + ))) + (find-calist-package name))) + +(defun make-calist-package (name &optional use) + "Create a new calist-package." + (let ((calist-field-match-method-obarray (make-vector 7 0))) + (set-alist 'calist-package-alist name + calist-field-match-method-obarray) + (use-calist-package (or use 'standard)) + calist-field-match-method-obarray)) + +(defun in-calist-package (name) + "Set the current calist-package to a new or existing calist-package." + (setq calist-field-match-method-obarray + (or (find-calist-package name) + (make-calist-package name)))) + +(in-calist-package 'standard) + (defun calist-default-field-match-method (calist field-type field-value) (let ((s-field (assoc field-type calist))) (cond ((null s-field) @@ -43,13 +81,15 @@ ((equal (cdr s-field) field-value) calist)))) +(define-calist-field-match-method t (function calist-default-field-match-method)) + (defsubst calist-field-match-method (field-type) - (condition-case nil - (symbol-function - (intern-soft - (symbol-name field-type) calist-field-match-method-obarray)) - (error (symbol-function 'calist-default-field-match-method)) - )) + (symbol-function + (or (intern-soft (if (symbolp field-type) + (symbol-name field-type) + field-type) + calist-field-match-method-obarray) + (intern-soft "t" calist-field-match-method-obarray)))) (defsubst calist-field-match (calist field-type field-value) (funcall (calist-field-match-method field-type) @@ -84,8 +124,41 @@ ret-alist)))) )))) -(defun ctree-find-calist (rule-tree alist) - "Return list of condition-alist which matches ALIST in RULE-TREE." +(defun ctree-match-calist-partially (rule-tree alist) + "Return matched condition-alist if ALIST matches RULE-TREE." + (if (null rule-tree) + alist + (let ((type (car rule-tree)) + (choices (cdr rule-tree)) + default) + (catch 'tag + (while choices + (let* ((choice (car choices)) + (choice-value (car choice))) + (if (eq choice-value t) + (setq default choice) + (let ((ret-alist (calist-field-match alist type (car choice)))) + (if ret-alist + (throw 'tag + (if (cdr choice) + (ctree-match-calist-partially + (cdr choice) ret-alist) + ret-alist)) + )))) + (setq choices (cdr choices))) + (if default + (let ((ret-alist (calist-field-match alist type t))) + (if ret-alist + (if (cdr default) + (ctree-match-calist-partially (cdr default) ret-alist) + ret-alist))) + (calist-field-match alist type t)) + )))) + +(defun ctree-find-calist (rule-tree alist &optional all) + "Return list of condition-alist which matches ALIST in RULE-TREE. +If optional argument ALL is specified, default rules are not ignored +even if other rules are matched for ALIST." (if (null rule-tree) (list alist) (let ((type (car rule-tree)) @@ -99,21 +172,38 @@ (let ((ret-alist (calist-field-match alist type (car choice)))) (if ret-alist (if (cdr choice) - (setq dest - (append - (ctree-find-calist (cdr choice) ret-alist) - dest)) - (setq dest (cons ret-alist dest)) + (let ((ret (ctree-find-calist + (cdr choice) ret-alist all))) + (while ret + (let ((elt (car ret))) + (or (member elt dest) + (setq dest (cons elt dest)) + )) + (setq ret (cdr ret)) + )) + (or (member ret-alist dest) + (setq dest (cons ret-alist dest))) ))))) (setq choices (cdr choices))) - (or dest + (or (and (not all) dest) (if default (let ((ret-alist (calist-field-match alist type t))) (if ret-alist (if (cdr default) - (ctree-find-calist (cdr default) ret-alist) - (list ret-alist) - )))))))) + (let ((ret (ctree-find-calist + (cdr default) ret-alist all))) + (while ret + (let ((elt (car ret))) + (or (member elt dest) + (setq dest (cons elt dest)) + )) + (setq ret (cdr ret)) + )) + (or (member ret-alist dest) + (setq dest (cons ret-alist dest))) + )))) + ) + dest))) (defun calist-to-ctree (calist) "Convert condition-alist CALIST to condition-tree." @@ -169,7 +259,7 @@ (type (car cell)) (value (cdr cell))) (cons type - (list '(t) + (list (list t) (cons value (calist-to-ctree (cdr calist))))) )) (t @@ -188,12 +278,19 @@ (delete ret (copy-alist calist))) )))) (setq values (cdr values))) - (setcdr ctree (list* '(t) - (cons (cdr ret) - (calist-to-ctree - (delete ret (copy-alist calist)))) - (cdr ctree))) - ) + (if (assq t (cdr ctree)) + (setcdr ctree + (cons (cons (cdr ret) + (calist-to-ctree + (delete ret (copy-alist calist)))) + (cdr ctree))) + (setcdr ctree + (list* (list t) + (cons (cdr ret) + (calist-to-ctree + (delete ret (copy-alist calist)))) + (cdr ctree))) + )) (catch 'tag (while values (let ((cell (car values))) @@ -201,10 +298,16 @@ (ctree-add-calist-with-default (cdr cell) calist)) ) (setq values (cdr values))) - (let ((elt (cons t (calist-to-ctree calist)))) - (or (member elt (cdr ctree)) - (setcdr ctree (cons elt (cdr ctree))) - ))) + (let ((cell (assq t (cdr ctree)))) + (if cell + (setcdr cell + (ctree-add-calist-with-default (cdr cell) + calist)) + (let ((elt (cons t (calist-to-ctree calist)))) + (or (member elt (cdr ctree)) + (setcdr ctree (cons elt (cdr ctree))) + )) + ))) ) ctree)))) @@ -222,6 +325,7 @@ ;;; @ end ;;; -(provide 'calist) +(require 'product) +(product-provide (provide 'calist) (require 'apel-ver)) ;;; calist.el ends here