1744
|
1 ;; -*- Mode: Emacs-Lisp -*-
|
|
2 ;; sc-alist.el -- Version 1.0 (used to be baw-alist.el)
|
|
3
|
|
4 ;; association list utilities providing insertion, deletion, sorting
|
|
5 ;; fetching off key-value pairs in association lists.
|
|
6
|
|
7 ;; ========== Disclaimer ==========
|
|
8 ;; This software is distributed in the hope that it will be useful,
|
|
9 ;; but WITHOUT ANY WARRANTY. No author or distributor accepts
|
|
10 ;; responsibility to anyone for the consequences of using it or for
|
|
11 ;; whether it serves any particular purpose or works at all, unless he
|
|
12 ;; says so in writing.
|
|
13
|
|
14 ;; This software was written as part of the supercite author's
|
|
15 ;; official duty as an employee of the United States Government and is
|
|
16 ;; thus in the public domain. You are free to use that particular
|
|
17 ;; software as you wish, but WITHOUT ANY WARRANTY WHATSOEVER. It
|
|
18 ;; would be nice, though if when you use any of this code, you give
|
|
19 ;; due credit to the author.
|
|
20
|
|
21 ;; ========== Author (unless otherwise stated) ========================
|
|
22 ;; NAME: Barry A. Warsaw USMAIL: Century Computing, Inc.
|
|
23 ;; TELE: (301) 593-3330 1014 West Street
|
|
24 ;; INET: bwarsaw@cen.com Laurel, Md 20707
|
|
25 ;; UUCP: uunet!cen.com!bwarsaw
|
|
26 ;;
|
|
27 (provide 'sc-alist)
|
|
28
|
|
29
|
|
30 (defun asort (alist-symbol key)
|
|
31 "Move a specified key-value pair to the head of an alist.
|
|
32 The alist is referenced by ALIST-SYMBOL. Key-value pair to move to
|
|
33 head is one matching KEY. Returns the sorted list and doesn't affect
|
|
34 the order of any other key-value pair. Side effect sets alist to new
|
|
35 sorted list."
|
|
36 (set alist-symbol
|
|
37 (sort (copy-alist (eval alist-symbol))
|
|
38 (function (lambda (a b) (equal (car a) key))))))
|
|
39
|
|
40
|
|
41 (defun aelement (key value)
|
|
42 "Makes a list of a cons cell containing car of KEY and cdr of VALUE.
|
|
43 The returned list is suitable as an element of an alist."
|
|
44 (list (cons key value)))
|
|
45
|
|
46
|
|
47 (defun aheadsym (alist)
|
|
48 "Return the key symbol at the head of ALIST."
|
|
49 (car (car alist)))
|
|
50
|
|
51
|
|
52 (defun anot-head-p (alist key)
|
|
53 "Find out if a specified key-value pair is not at the head of an alist.
|
|
54 The alist to check is specified by ALIST and the key-value pair is the
|
|
55 one matching the supplied KEY. Returns nil if ALIST is nil, or if
|
|
56 key-value pair is at the head of the alist. Returns t if key-value
|
|
57 pair is not at the head of alist. ALIST is not altered."
|
|
58 (not (equal (aheadsym alist) key)))
|
|
59
|
|
60
|
|
61 (defun aput (alist-symbol key &optional value)
|
|
62 "Inserts a key-value pair into an alist.
|
|
63 The alist is referenced by ALIST-SYMBOL. The key-value pair is made
|
|
64 from KEY and optionally, VALUE. Returns the altered alist or nil if
|
|
65 ALIST is nil.
|
|
66
|
|
67 If the key-value pair referenced by KEY can be found in the alist, and
|
|
68 VALUE is supplied non-nil, then the value of KEY will be set to VALUE.
|
|
69 If VALUE is not supplied, or is nil, the key-value pair will not be
|
|
70 modified, but will be moved to the head of the alist. If the key-value
|
|
71 pair cannot be found in the alist, it will be inserted into the head
|
|
72 of the alist (with value nil if VALUE is nil or not supplied)."
|
|
73 (let ((elem (aelement key value))
|
|
74 alist)
|
|
75 (asort alist-symbol key)
|
|
76 (setq alist (eval alist-symbol))
|
|
77 (cond ((null alist) (set alist-symbol elem))
|
|
78 ((anot-head-p alist key) (set alist-symbol (nconc elem alist)))
|
|
79 (value (setcar alist (car elem)))
|
|
80 (t alist))))
|
|
81
|
|
82
|
|
83 (defun adelete (alist-symbol key)
|
|
84 "Delete a key-value pair from the alist.
|
|
85 Alist is referenced by ALIST-SYMBOL and the key-value pair to remove
|
|
86 is pair matching KEY. Returns the altered alist."
|
|
87 (asort alist-symbol key)
|
|
88 (let ((alist (eval alist-symbol)))
|
|
89 (cond ((null alist) nil)
|
|
90 ((anot-head-p alist key) alist)
|
|
91 (t (set alist-symbol (cdr alist))))))
|
|
92
|
|
93
|
|
94 (defun aget (alist key &optional keynil-p)
|
|
95 "Returns the value in ALIST that is associated with KEY.
|
|
96 Optional KEYNIL-P describes what to do if the value associated with
|
|
97 KEY is nil. If KEYNIL-P is not supplied or is nil, and the value is
|
|
98 nil, then KEY is returned. If KEYNIL-P is non-nil, then nil would be
|
|
99 returned.
|
|
100
|
|
101 If no key-value pair matching KEY could be found in ALIST, or ALIST is
|
|
102 nil then nil is returned. ALIST is not altered."
|
|
103 (let ((copy (copy-alist alist)))
|
|
104 (cond ((null alist) nil)
|
|
105 ((progn (asort 'copy key)
|
|
106 (anot-head-p copy key)) nil)
|
|
107 ((cdr (car copy)))
|
|
108 (keynil-p nil)
|
|
109 ((car (car copy)))
|
|
110 (t nil))))
|
|
111
|
|
112
|
|
113 (defun amake (alist-symbol keylist &optional valuelist)
|
|
114 "Make an association list.
|
|
115 The association list is attached to the alist referenced by
|
|
116 ALIST-SYMBOL. Each element in the KEYLIST becomes a key and is
|
|
117 associated with the value in VALUELIST with the same index. If
|
|
118 VALUELIST is not supplied or is nil, then each key in KEYLIST is
|
|
119 associated with nil.
|
|
120
|
|
121 KEYLIST and VALUELIST should have the same number of elements, but
|
|
122 this isn't enforced. If VALUELIST is smaller than KEYLIST, remaining
|
|
123 keys are associated with nil. If VALUELIST is larger than KEYLIST,
|
|
124 extra values are ignored. Returns the created alist."
|
|
125 (let ((keycar (car keylist))
|
|
126 (keycdr (cdr keylist))
|
|
127 (valcar (car valuelist))
|
|
128 (valcdr (cdr valuelist)))
|
|
129 (cond ((null keycdr)
|
|
130 (aput alist-symbol keycar valcar))
|
|
131 (t
|
|
132 (amake alist-symbol keycdr valcdr)
|
|
133 (aput alist-symbol keycar valcar))))
|
|
134 (eval alist-symbol))
|