xref: /dflybsd-src/contrib/gdb-7/gdb/registry.h (revision de8e141f24382815c10a4012d209bbbf7abf1112)
1*ef5ccd6cSJohn Marino /* Macros for general registry objects.
2*ef5ccd6cSJohn Marino 
3*ef5ccd6cSJohn Marino    Copyright (C) 2011-2013 Free Software Foundation, Inc.
4*ef5ccd6cSJohn Marino 
5*ef5ccd6cSJohn Marino    This file is part of GDB.
6*ef5ccd6cSJohn Marino 
7*ef5ccd6cSJohn Marino    This program is free software; you can redistribute it and/or modify
8*ef5ccd6cSJohn Marino    it under the terms of the GNU General Public License as published by
9*ef5ccd6cSJohn Marino    the Free Software Foundation; either version 3 of the License, or
10*ef5ccd6cSJohn Marino    (at your option) any later version.
11*ef5ccd6cSJohn Marino 
12*ef5ccd6cSJohn Marino    This program is distributed in the hope that it will be useful,
13*ef5ccd6cSJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
14*ef5ccd6cSJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*ef5ccd6cSJohn Marino    GNU General Public License for more details.
16*ef5ccd6cSJohn Marino 
17*ef5ccd6cSJohn Marino    You should have received a copy of the GNU General Public License
18*ef5ccd6cSJohn Marino    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19*ef5ccd6cSJohn Marino 
20*ef5ccd6cSJohn Marino #ifndef REGISTRY_H
21*ef5ccd6cSJohn Marino #define REGISTRY_H
22*ef5ccd6cSJohn Marino 
23*ef5ccd6cSJohn Marino /* The macros here implement a template type and functions for
24*ef5ccd6cSJohn Marino    associating some user data with a container object.
25*ef5ccd6cSJohn Marino 
26*ef5ccd6cSJohn Marino    A registry is associated with a struct tag name.  To attach a
27*ef5ccd6cSJohn Marino    registry to a structure, use DEFINE_REGISTRY.  This takes the
28*ef5ccd6cSJohn Marino    structure tag and an access method as arguments.  In the usual
29*ef5ccd6cSJohn Marino    case, where the registry fields appear directly in the struct, you
30*ef5ccd6cSJohn Marino    can use the 'REGISTRY_FIELDS' macro to declare the fields in the
31*ef5ccd6cSJohn Marino    struct definition, and you can pass 'REGISTRY_ACCESS_FIELD' as the
32*ef5ccd6cSJohn Marino    access argument to DEFINE_REGISTRY.  In other cases, use
33*ef5ccd6cSJohn Marino    REGISTRY_FIELDS to define the fields in the appropriate spot, and
34*ef5ccd6cSJohn Marino    then define your own accessor to find the registry field structure
35*ef5ccd6cSJohn Marino    given an instance of your type.
36*ef5ccd6cSJohn Marino 
37*ef5ccd6cSJohn Marino    The API user requests a key from a registry during gdb
38*ef5ccd6cSJohn Marino    initialization.  Later this key can be used to associate some
39*ef5ccd6cSJohn Marino    module-specific data with a specific container object.
40*ef5ccd6cSJohn Marino 
41*ef5ccd6cSJohn Marino    The exported API is best used via the wrapper macros:
42*ef5ccd6cSJohn Marino 
43*ef5ccd6cSJohn Marino    - register_TAG_data(TAG)
44*ef5ccd6cSJohn Marino    Get a new key for the container type TAG.
45*ef5ccd6cSJohn Marino 
46*ef5ccd6cSJohn Marino    - register_TAG_data_with_cleanup(TAG, SAVE, FREE)
47*ef5ccd6cSJohn Marino    Get a new key for the container type TAG.
48*ef5ccd6cSJohn Marino    SAVE and FREE are defined as void (*) (struct TAG *, void *)
49*ef5ccd6cSJohn Marino    When the container is destroyed, first all registered SAVE
50*ef5ccd6cSJohn Marino    functions are called.
51*ef5ccd6cSJohn Marino    Then all FREE functions are called.
52*ef5ccd6cSJohn Marino    Either or both may be NULL.
53*ef5ccd6cSJohn Marino 
54*ef5ccd6cSJohn Marino    - clear_TAG_data(TAG, OBJECT)
55*ef5ccd6cSJohn Marino    Clear all the data associated with OBJECT.  Should be called by the
56*ef5ccd6cSJohn Marino    container implementation when a container object is destroyed.
57*ef5ccd6cSJohn Marino 
58*ef5ccd6cSJohn Marino    - set_TAG_data(TAG, OBJECT, KEY, DATA)
59*ef5ccd6cSJohn Marino    Set the data on an object.
60*ef5ccd6cSJohn Marino 
61*ef5ccd6cSJohn Marino    - TAG_data(TAG, OBJECT, KEY)
62*ef5ccd6cSJohn Marino    Fetch the data for an object; returns NULL if it has not been set.
63*ef5ccd6cSJohn Marino */
64*ef5ccd6cSJohn Marino 
65*ef5ccd6cSJohn Marino /* This structure is used in a container to hold the data that the
66*ef5ccd6cSJohn Marino    registry uses.  */
67*ef5ccd6cSJohn Marino 
68*ef5ccd6cSJohn Marino struct registry_fields
69*ef5ccd6cSJohn Marino {
70*ef5ccd6cSJohn Marino   void **data;
71*ef5ccd6cSJohn Marino   unsigned num_data;
72*ef5ccd6cSJohn Marino };
73*ef5ccd6cSJohn Marino 
74*ef5ccd6cSJohn Marino /* This macro is used in a container struct definition to define the
75*ef5ccd6cSJohn Marino    fields used by the registry code.  */
76*ef5ccd6cSJohn Marino 
77*ef5ccd6cSJohn Marino #define REGISTRY_FIELDS				\
78*ef5ccd6cSJohn Marino   struct registry_fields registry_data
79*ef5ccd6cSJohn Marino 
80*ef5ccd6cSJohn Marino /* A convenience macro for the typical case where the registry data is
81*ef5ccd6cSJohn Marino    kept as fields of the object.  This can be passed as the ACCESS
82*ef5ccd6cSJohn Marino    method to DEFINE_REGISTRY.  */
83*ef5ccd6cSJohn Marino 
84*ef5ccd6cSJohn Marino #define REGISTRY_ACCESS_FIELD(CONTAINER) \
85*ef5ccd6cSJohn Marino   (CONTAINER)
86*ef5ccd6cSJohn Marino 
87*ef5ccd6cSJohn Marino /* Opaque type representing a container type with a registry.  This
88*ef5ccd6cSJohn Marino    type is never defined.  This is used to factor out common
89*ef5ccd6cSJohn Marino    functionality of all struct tag names into common code.  IOW,
90*ef5ccd6cSJohn Marino    "struct tag name" pointers are cast to and from "struct
91*ef5ccd6cSJohn Marino    registry_container" pointers when calling the common registry
92*ef5ccd6cSJohn Marino    "backend" functions.  */
93*ef5ccd6cSJohn Marino struct registry_container;
94*ef5ccd6cSJohn Marino 
95*ef5ccd6cSJohn Marino /* Registry callbacks have this type.  */
96*ef5ccd6cSJohn Marino typedef void (*registry_data_callback) (struct registry_container *, void *);
97*ef5ccd6cSJohn Marino 
98*ef5ccd6cSJohn Marino struct registry_data
99*ef5ccd6cSJohn Marino {
100*ef5ccd6cSJohn Marino   unsigned index;
101*ef5ccd6cSJohn Marino   registry_data_callback save;
102*ef5ccd6cSJohn Marino   registry_data_callback free;
103*ef5ccd6cSJohn Marino };
104*ef5ccd6cSJohn Marino 
105*ef5ccd6cSJohn Marino struct registry_data_registration
106*ef5ccd6cSJohn Marino {
107*ef5ccd6cSJohn Marino   struct registry_data *data;
108*ef5ccd6cSJohn Marino   struct registry_data_registration *next;
109*ef5ccd6cSJohn Marino };
110*ef5ccd6cSJohn Marino 
111*ef5ccd6cSJohn Marino struct registry_data_registry
112*ef5ccd6cSJohn Marino {
113*ef5ccd6cSJohn Marino   struct registry_data_registration *registrations;
114*ef5ccd6cSJohn Marino   unsigned num_registrations;
115*ef5ccd6cSJohn Marino };
116*ef5ccd6cSJohn Marino 
117*ef5ccd6cSJohn Marino /* Registry backend functions.  Client code uses the frontend
118*ef5ccd6cSJohn Marino    functions defined by DEFINE_REGISTRY below instead.  */
119*ef5ccd6cSJohn Marino 
120*ef5ccd6cSJohn Marino const struct registry_data *register_data_with_cleanup
121*ef5ccd6cSJohn Marino   (struct registry_data_registry *registry,
122*ef5ccd6cSJohn Marino    registry_data_callback save,
123*ef5ccd6cSJohn Marino    registry_data_callback free);
124*ef5ccd6cSJohn Marino 
125*ef5ccd6cSJohn Marino void registry_alloc_data (struct registry_data_registry *registry,
126*ef5ccd6cSJohn Marino 			  struct registry_fields *registry_fields);
127*ef5ccd6cSJohn Marino 
128*ef5ccd6cSJohn Marino /* Cast FUNC and CONTAINER to the real types, and call FUNC, also
129*ef5ccd6cSJohn Marino    passing DATA.  */
130*ef5ccd6cSJohn Marino typedef void (*registry_callback_adaptor) (registry_data_callback func,
131*ef5ccd6cSJohn Marino 					   struct registry_container *container,
132*ef5ccd6cSJohn Marino 					   void *data);
133*ef5ccd6cSJohn Marino 
134*ef5ccd6cSJohn Marino void registry_clear_data (struct registry_data_registry *data_registry,
135*ef5ccd6cSJohn Marino 			  registry_callback_adaptor adaptor,
136*ef5ccd6cSJohn Marino 			  struct registry_container *container,
137*ef5ccd6cSJohn Marino 			  struct registry_fields *fields);
138*ef5ccd6cSJohn Marino 
139*ef5ccd6cSJohn Marino void registry_container_free_data (struct registry_data_registry *data_registry,
140*ef5ccd6cSJohn Marino 				   registry_callback_adaptor adaptor,
141*ef5ccd6cSJohn Marino 				   struct registry_container *container,
142*ef5ccd6cSJohn Marino 				   struct registry_fields *fields);
143*ef5ccd6cSJohn Marino 
144*ef5ccd6cSJohn Marino void registry_set_data (struct registry_fields *fields,
145*ef5ccd6cSJohn Marino 			const struct registry_data *data,
146*ef5ccd6cSJohn Marino 			void *value);
147*ef5ccd6cSJohn Marino 
148*ef5ccd6cSJohn Marino void *registry_data (struct registry_fields *fields,
149*ef5ccd6cSJohn Marino 		     const struct registry_data *data);
150*ef5ccd6cSJohn Marino 
151*ef5ccd6cSJohn Marino /* Define a new registry implementation.  */
152*ef5ccd6cSJohn Marino 
153*ef5ccd6cSJohn Marino #define DEFINE_REGISTRY(TAG, ACCESS)					\
154*ef5ccd6cSJohn Marino struct registry_data_registry TAG ## _data_registry = { NULL, 0 };	\
155*ef5ccd6cSJohn Marino 									\
156*ef5ccd6cSJohn Marino const struct TAG ## _data *						\
157*ef5ccd6cSJohn Marino register_ ## TAG ## _data_with_cleanup (void (*save) (struct TAG *, void *), \
158*ef5ccd6cSJohn Marino 					void (*free) (struct TAG *, void *)) \
159*ef5ccd6cSJohn Marino {									\
160*ef5ccd6cSJohn Marino   struct registry_data_registration **curr;				\
161*ef5ccd6cSJohn Marino 									\
162*ef5ccd6cSJohn Marino   return (struct TAG ## _data *)					\
163*ef5ccd6cSJohn Marino     register_data_with_cleanup (&TAG ## _data_registry,			\
164*ef5ccd6cSJohn Marino 				(registry_data_callback) save,		\
165*ef5ccd6cSJohn Marino 				(registry_data_callback) free);		\
166*ef5ccd6cSJohn Marino }									\
167*ef5ccd6cSJohn Marino 									\
168*ef5ccd6cSJohn Marino const struct TAG ## _data *						\
169*ef5ccd6cSJohn Marino register_ ## TAG ## _data (void)					\
170*ef5ccd6cSJohn Marino {									\
171*ef5ccd6cSJohn Marino   return register_ ## TAG ## _data_with_cleanup (NULL, NULL);		\
172*ef5ccd6cSJohn Marino }									\
173*ef5ccd6cSJohn Marino 									\
174*ef5ccd6cSJohn Marino static void								\
175*ef5ccd6cSJohn Marino TAG ## _alloc_data (struct TAG *container)				\
176*ef5ccd6cSJohn Marino {									\
177*ef5ccd6cSJohn Marino   struct registry_fields *rdata = &ACCESS (container)->registry_data;	\
178*ef5ccd6cSJohn Marino 									\
179*ef5ccd6cSJohn Marino   registry_alloc_data (&TAG ## _data_registry, rdata);			\
180*ef5ccd6cSJohn Marino }									\
181*ef5ccd6cSJohn Marino 									\
182*ef5ccd6cSJohn Marino static void								\
183*ef5ccd6cSJohn Marino TAG ## registry_callback_adaptor (registry_data_callback func,		\
184*ef5ccd6cSJohn Marino 				  struct registry_container *container, \
185*ef5ccd6cSJohn Marino 				  void *data)				\
186*ef5ccd6cSJohn Marino {									\
187*ef5ccd6cSJohn Marino   struct TAG *tagged_container = (struct TAG *) container;		\
188*ef5ccd6cSJohn Marino   struct registry_fields *rdata						\
189*ef5ccd6cSJohn Marino     = &ACCESS (tagged_container)->registry_data;			\
190*ef5ccd6cSJohn Marino 									\
191*ef5ccd6cSJohn Marino   registry_ ## TAG ## _callback tagged_func				\
192*ef5ccd6cSJohn Marino     = (registry_ ## TAG ## _callback) func;				\
193*ef5ccd6cSJohn Marino 									\
194*ef5ccd6cSJohn Marino   tagged_func (tagged_container, data);					\
195*ef5ccd6cSJohn Marino }									\
196*ef5ccd6cSJohn Marino 									\
197*ef5ccd6cSJohn Marino void									\
198*ef5ccd6cSJohn Marino clear_ ## TAG ## _data (struct TAG *container)				\
199*ef5ccd6cSJohn Marino {									\
200*ef5ccd6cSJohn Marino   struct registry_fields *rdata = &ACCESS (container)->registry_data;	\
201*ef5ccd6cSJohn Marino 									\
202*ef5ccd6cSJohn Marino   registry_clear_data (&TAG ## _data_registry,				\
203*ef5ccd6cSJohn Marino 		       TAG ## registry_callback_adaptor,		\
204*ef5ccd6cSJohn Marino 		       (struct registry_container *) container,		\
205*ef5ccd6cSJohn Marino 		       rdata);						\
206*ef5ccd6cSJohn Marino }									\
207*ef5ccd6cSJohn Marino 									\
208*ef5ccd6cSJohn Marino static void								\
209*ef5ccd6cSJohn Marino TAG ## _free_data (struct TAG *container)				\
210*ef5ccd6cSJohn Marino {									\
211*ef5ccd6cSJohn Marino   struct registry_fields *rdata = &ACCESS (container)->registry_data;	\
212*ef5ccd6cSJohn Marino 									\
213*ef5ccd6cSJohn Marino   registry_container_free_data (&TAG ## _data_registry,			\
214*ef5ccd6cSJohn Marino 				TAG ## registry_callback_adaptor,	\
215*ef5ccd6cSJohn Marino 				(struct registry_container *) container, \
216*ef5ccd6cSJohn Marino 				rdata);					\
217*ef5ccd6cSJohn Marino }									\
218*ef5ccd6cSJohn Marino 									\
219*ef5ccd6cSJohn Marino void									\
220*ef5ccd6cSJohn Marino set_ ## TAG ## _data (struct TAG *container,				\
221*ef5ccd6cSJohn Marino 		      const struct TAG ## _data *data,			\
222*ef5ccd6cSJohn Marino 		      void *value)					\
223*ef5ccd6cSJohn Marino {									\
224*ef5ccd6cSJohn Marino   struct registry_fields *rdata = &ACCESS (container)->registry_data;	\
225*ef5ccd6cSJohn Marino 									\
226*ef5ccd6cSJohn Marino   registry_set_data (rdata,						\
227*ef5ccd6cSJohn Marino 		     (struct registry_data *) data,			\
228*ef5ccd6cSJohn Marino 		     value);						\
229*ef5ccd6cSJohn Marino }									\
230*ef5ccd6cSJohn Marino 									\
231*ef5ccd6cSJohn Marino void *									\
232*ef5ccd6cSJohn Marino TAG ## _data (struct TAG *container, const struct TAG ## _data *data)	\
233*ef5ccd6cSJohn Marino {									\
234*ef5ccd6cSJohn Marino   struct registry_fields *rdata = &ACCESS (container)->registry_data;	\
235*ef5ccd6cSJohn Marino 									\
236*ef5ccd6cSJohn Marino   return registry_data (rdata,						\
237*ef5ccd6cSJohn Marino 			(struct registry_data *) data);			\
238*ef5ccd6cSJohn Marino }
239*ef5ccd6cSJohn Marino 
240*ef5ccd6cSJohn Marino 
241*ef5ccd6cSJohn Marino /* External declarations for the registry functions.  */
242*ef5ccd6cSJohn Marino 
243*ef5ccd6cSJohn Marino #define DECLARE_REGISTRY(TAG)						\
244*ef5ccd6cSJohn Marino struct TAG ## _data;							\
245*ef5ccd6cSJohn Marino typedef void (*registry_ ## TAG ## _callback) (struct TAG *, void *);	\
246*ef5ccd6cSJohn Marino extern const struct TAG ## _data *register_ ## TAG ## _data (void);	\
247*ef5ccd6cSJohn Marino extern const struct TAG ## _data *register_ ## TAG ## _data_with_cleanup \
248*ef5ccd6cSJohn Marino  (registry_ ## TAG ## _callback save, registry_ ## TAG ## _callback free); \
249*ef5ccd6cSJohn Marino extern void clear_ ## TAG ## _data (struct TAG *);		\
250*ef5ccd6cSJohn Marino extern void set_ ## TAG ## _data (struct TAG *,			\
251*ef5ccd6cSJohn Marino 				  const struct TAG ## _data *data, \
252*ef5ccd6cSJohn Marino 				  void *value);			\
253*ef5ccd6cSJohn Marino extern void *TAG ## _data (struct TAG *,			\
254*ef5ccd6cSJohn Marino 			   const struct TAG ## _data *data);
255*ef5ccd6cSJohn Marino 
256*ef5ccd6cSJohn Marino #endif /* REGISTRY_H */
257