* auto-load.c (_initialize_auto_load): Update.
[external/binutils.git] / gdb / registry.h
1 /* Macros for general registry objects.
2
3    Copyright (C) 2011, 2012
4    Free Software Foundation, Inc.
5
6    This file is part of GDB.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
21 #ifndef REGISTRY_H
22 #define REGISTRY_H
23
24 /* The macros here implement a template type and functions for
25    associating some user data with a container object.
26
27    The API user requests a key from a registry during gdb
28    initialization.  Later this key can be used to associate some
29    module-specific data with a specific container object.
30
31    A registry is associated with a struct tag name.
32
33    The exported API is best used via the wrapper macros:
34    
35    - register_TAG_data(TAG)
36    Get a new key for the container type TAG.
37    
38    - register_TAG_data_with_cleanup(TAG, SAVE, FREE)
39    Get a new key for the container type TAG.
40    SAVE and FREE are defined as void (*) (struct TAG *, void *)
41    When the container is destroyed, first all registered SAVE
42    functions are called.
43    Then all FREE functions are called.
44    Either or both may be NULL.
45    
46    - clear_TAG_data(TAG, OBJECT)
47    Clear all the data associated with OBJECT.  Should be called by the
48    container implementation when a container object is destroyed.
49    
50    - set_TAG_data(TAG, OBJECT, KEY, DATA)
51    Set the data on an object.
52    
53    - TAG_data(TAG, OBJECT, KEY)
54    Fetch the data for an object; returns NULL if it has not been set.
55 */
56
57 /* This macro is used in a container struct definition to define the
58    fields used by the registry code.  */
59
60 #define REGISTRY_FIELDS                         \
61   void **data;                                  \
62   unsigned num_data
63
64 /* Define a new registry implementation.  */
65
66 #define DEFINE_REGISTRY(TAG)                                            \
67 struct TAG ## _data                                                     \
68 {                                                                       \
69   unsigned index;                                                       \
70   void (*save) (struct TAG *, void *);                                  \
71   void (*free) (struct TAG *, void *);                                  \
72 };                                                                      \
73                                                                         \
74 struct TAG ## _data_registration                                        \
75 {                                                                       \
76   struct TAG ## _data *data;                                            \
77   struct TAG ## _data_registration *next;                               \
78 };                                                                      \
79                                                                         \
80 struct TAG ## _data_registry                                            \
81 {                                                                       \
82   struct TAG ## _data_registration *registrations;                      \
83   unsigned num_registrations;                                           \
84 };                                                                      \
85                                                                         \
86 struct TAG ## _data_registry TAG ## _data_registry = { NULL, 0 };       \
87                                                                         \
88 const struct TAG ## _data *                                             \
89 register_ ## TAG ## _data_with_cleanup (void (*save) (struct TAG *, void *), \
90                                     void (*free) (struct TAG *, void *)) \
91 {                                                                       \
92   struct TAG ## _data_registration **curr;                              \
93                                                                         \
94   /* Append new registration.  */                                       \
95   for (curr = &TAG ## _data_registry.registrations;                     \
96        *curr != NULL; curr = &(*curr)->next);                           \
97                                                                         \
98   *curr = XMALLOC (struct TAG ## _data_registration);                   \
99   (*curr)->next = NULL;                                                 \
100   (*curr)->data = XMALLOC (struct TAG ## _data);                        \
101   (*curr)->data->index = TAG ## _data_registry.num_registrations++;     \
102   (*curr)->data->save = save;                                           \
103   (*curr)->data->free = free;                                           \
104                                                                         \
105   return (*curr)->data;                                                 \
106 }                                                                       \
107                                                                         \
108 const struct TAG ## _data *                                             \
109 register_ ## TAG ## _data (void)                                        \
110 {                                                                       \
111   return register_ ## TAG ## _data_with_cleanup (NULL, NULL);           \
112 }                                                                       \
113                                                                         \
114 static void                                                             \
115 TAG ## _alloc_data (struct TAG *container)                              \
116 {                                                                       \
117   gdb_assert (container->data == NULL);                                 \
118   container->num_data = TAG ## _data_registry.num_registrations;        \
119   container->data = XCALLOC (container->num_data, void *);              \
120 }                                                                       \
121                                                                         \
122 void                                                                    \
123 clear_ ## TAG ## _data (struct TAG *container)                          \
124 {                                                                       \
125   struct TAG ## _data_registration *registration;                       \
126   int i;                                                                \
127                                                                         \
128   gdb_assert (container->data != NULL);                                 \
129                                                                         \
130   /* Process all the save handlers.  */                                 \
131                                                                         \
132   for (registration = TAG ## _data_registry.registrations, i = 0;       \
133        i < container->num_data;                                         \
134        registration = registration->next, i++)                          \
135     if (container->data[i] != NULL && registration->data->save != NULL) \
136       registration->data->save (container, container->data[i]);         \
137                                                                         \
138   /* Now process all the free handlers.  */                             \
139                                                                         \
140   for (registration = TAG ## _data_registry.registrations, i = 0;       \
141        i < container->num_data;                                         \
142        registration = registration->next, i++)                          \
143     if (container->data[i] != NULL && registration->data->free != NULL) \
144       registration->data->free (container, container->data[i]);         \
145                                                                         \
146   memset (container->data, 0, container->num_data * sizeof (void *));   \
147 }                                                                       \
148                                                                         \
149 static void                                                             \
150 TAG ## _free_data (struct TAG *container)                               \
151 {                                                                       \
152   void ***rdata = &container->data;                                     \
153   gdb_assert (*rdata != NULL);                                          \
154   clear_ ## TAG ## _data (container);                                   \
155   xfree (*rdata);                                                       \
156   *rdata = NULL;                                                        \
157 }                                                                       \
158                                                                         \
159 void                                                                    \
160 set_ ## TAG ## _data (struct TAG *container, const struct TAG ## _data *data, \
161                   void *value)                                          \
162 {                                                                       \
163   gdb_assert (data->index < container->num_data);                       \
164   container->data[data->index] = value;                                 \
165 }                                                                       \
166                                                                         \
167 void *                                                                  \
168 TAG ## _data (struct TAG *container, const struct TAG ## _data *data)   \
169 {                                                                       \
170   gdb_assert (data->index < container->num_data);                       \
171   return container->data[data->index];                                  \
172 }
173
174
175 /* External declarations for the registry functions.  */
176
177 #define DECLARE_REGISTRY(TAG)                                           \
178 extern const struct TAG ## _data *register_ ## TAG ## _data (void);     \
179 extern const struct TAG ## _data *register_ ## TAG ## _data_with_cleanup \
180  (void (*save) (struct TAG *, void *), void (*free) (struct TAG *, void *)); \
181 extern void clear_ ## TAG ## _data (struct TAG *);              \
182 extern void set_ ## TAG ## _data (struct TAG *,                 \
183                                const struct TAG ## _data *data, void *value); \
184 extern void *TAG ## _data (struct TAG *,                        \
185                            const struct TAG ## _data *data);
186
187 #endif /* REGISTRY_H */