Partially sync files.el from XEmacs 21.5 for wildcard support.
[sxemacs] / src / dict.h
1 /*** dict.c -- generic dict (single valued mapping) service
2  *
3  * Copyright (C) 2007, 2008 Sebastian Freundt
4  *
5  * Author:  Sebastian Freundt <hroptatyr@sxemacs.org>
6  *
7  * This file is part of SXEmacs.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * 3. Neither the name of the author nor the names of any contributors
21  *    may be used to endorse or promote products derived from this
22  *    software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  * DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
31  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
34  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  * Commentary:
37  * See dict.c
38  *
39  ***/
40
41 #ifndef INCLUDED_dict_h_
42 #define INCLUDED_dict_h_
43
44 #include "lrecord.h"
45 #include "category.h"
46 #include <stdbool.h>
47
48 #ifdef ALL_DEBUG_FLAGS
49 #undef DICT_DEBUG_FLAG
50 #define DICT_DEBUG_FLAG
51 #endif
52
53 #define __DICT_DEBUG__(args...)         fprintf(stderr, "DICT " args)
54 #ifndef DICT_DEBUG_FLAG
55 #define DICT_DEBUG(args...)
56 #else
57 #define DICT_DEBUG(args...)             __DICT_DEBUG__(args)
58 #endif
59 #define DICT_CRITICAL(args...)          __DICT_DEBUG__("CRITICAL: " args)
60
61 typedef struct dict_s *dict_t;
62 typedef struct dict_iter_s *dict_iter_t;
63 typedef struct dict_impl_s *dict_impl_t;
64
65 typedef size_t(*dict_size_f)(dict_t);
66 typedef Lisp_Object(*dict_put_f)(dict_t, Lisp_Object, Lisp_Object);
67 typedef Lisp_Object(*dict_get_f)(dict_t, Lisp_Object, Lisp_Object);
68 typedef Lisp_Object(*dict_remove_f)(dict_t, Lisp_Object);
69 typedef void(*dict_iter_init_f)(dict_t, dict_iter_t);
70 typedef void(*dict_iter_next_f)(dict_iter_t, Lisp_Object*, Lisp_Object*);
71 typedef void(*dict_iter_fini_f)(dict_iter_t);
72
73 extern_inline dict_impl_t dict_impl(const void *obj);
74 extern_inline size_t dict_size(const dict_t);
75 extern_inline bool dict_empty_p(const dict_t);
76 extern_inline dict_t make_dict(void*);
77 extern_inline Lisp_Object put_dict(dict_t, Lisp_Object key, Lisp_Object val);
78 extern_inline Lisp_Object get_dict(dict_t, Lisp_Object key, Lisp_Object _default);
79 extern_inline Lisp_Object remove_dict(dict_t, Lisp_Object key);
80
81 extern_inline void dict_iter_init(dict_t, dict_iter_t);
82 extern_inline void dict_iter_next(dict_iter_t, Lisp_Object*, Lisp_Object*);
83 extern_inline void dict_iter_fini(dict_iter_t);
84
85 extern void dict_LTX_init(void);
86 extern void dict_LTX_reinit(void);
87 extern void dict_LTX_deinit(void);
88
89 \f
90 struct dict_impl_s {
91         dict_size_f size_f;
92         dict_put_f put_f;
93         dict_get_f get_f;
94         dict_remove_f remove_f;
95         dict_iter_init_f iter_init_f;
96         dict_iter_next_f iter_next_f;
97         dict_iter_fini_f iter_fini_f;
98 };
99
100 struct dict_s {
101         struct lcrecord_header lhreader;
102
103         /* just an anonymous one for the seq implementation */
104         void *seq_impl;
105         dict_impl_t impl;
106         /* the dual approach */
107         void *dict;
108 };
109
110 struct dict_iter_s {
111         dict_t dict;
112         void *data;
113 };
114
115 \f
116 /* inlines */
117 extern_inline dict_impl_t
118 dict_impl(const void *obj)
119 {
120         /* a dict is an association set (aset) in category speak */
121         if (INTP((Lisp_Object)obj) || CHARP((Lisp_Object)obj)) {
122                 return NULL;
123         }
124         return cat_morphism(obj, cat_mk_aset);
125 }
126
127 extern_inline size_t
128 dict_size(const dict_t d)
129 {
130         dict_impl_t di = dict_impl(d);
131
132         if (di != NULL) {
133                 return di->size_f(d);
134         } else {
135                 /* is this right here? */
136                 return wrong_type_argument(Qdictp, (Lisp_Object)d);
137         }
138 }
139
140 extern_inline bool
141 dict_empty_p(dict_t d)
142 {
143         return dict_size(d) == 0;
144 }
145
146 extern_inline dict_t
147 make_dict(void *foo)
148 {
149         return NULL;
150 }
151
152 extern_inline Lisp_Object
153 put_dict(dict_t d, Lisp_Object key, Lisp_Object val)
154 {
155         return dict_impl(d)->put_f(d, key, val);
156 }
157
158 extern_inline Lisp_Object
159 get_dict(dict_t d, Lisp_Object key, Lisp_Object _default)
160 {
161         return dict_impl(d)->get_f(d, key, _default);
162 }
163
164 extern_inline Lisp_Object
165 remove_dict(dict_t d, Lisp_Object key)
166 {
167         return dict_impl(d)->remove_f(d, key);
168 }
169
170 extern_inline void
171 dict_iter_init(dict_t d, dict_iter_t di)
172 {
173         dict_impl(d)->iter_init_f(d, di);
174         return;
175 }
176
177 extern_inline void
178 dict_iter_next(dict_iter_t di, Lisp_Object *key, Lisp_Object *val)
179 {
180         dict_impl(di->dict)->iter_next_f(di, key, val);
181         return;
182 }
183
184 extern_inline void
185 dict_iter_fini(dict_iter_t di)
186 {
187         dict_impl(di->dict)->iter_fini_f(di);
188         return;
189 }
190
191 #endif  /* INCLUDED_dict_h_ */