* registry.h (struct registry_fields): New.

(REGISTRY_FIELDS): Redefine.
	(REGISTRY_ACCESS_FIELD): New macro.
	(DEFINE_REGISTRY): Add ACCESS argument.  Update defined
	functions.
This commit is contained in:
Tom Tromey 2012-08-22 15:31:12 +00:00
parent 8e260fc026
commit 6b81941e35
5 changed files with 63 additions and 27 deletions

View File

@ -1,3 +1,11 @@
2012-08-22 Tom Tromey <tromey@redhat.com>
* registry.h (struct registry_fields): New.
(REGISTRY_FIELDS): Redefine.
(REGISTRY_ACCESS_FIELD): New macro.
(DEFINE_REGISTRY): Add ACCESS argument. Update defined
functions.
2012-08-22 Tom Tromey <tromey@redhat.com>
* auto-load.c (_initialize_auto_load): Update.

View File

@ -39,7 +39,7 @@ void _initialize_inferiors (void);
/* Keep a registry of per-inferior data-pointers required by other GDB
modules. */
DEFINE_REGISTRY (inferior)
DEFINE_REGISTRY (inferior, REGISTRY_ACCESS_FIELD)
struct inferior *inferior_list = NULL;
static int highest_inferior_num;

View File

@ -58,7 +58,7 @@
/* Keep a registry of per-objfile data-pointers required by other GDB
modules. */
DEFINE_REGISTRY (objfile)
DEFINE_REGISTRY (objfile, REGISTRY_ACCESS_FIELD)
/* Externally visible variables that are owned by this module.
See declarations in objfile.h for more info. */

View File

@ -42,7 +42,7 @@ static int highest_address_space_num;
/* Keep a registry of per-program_space data-pointers required by other GDB
modules. */
DEFINE_REGISTRY (program_space)
DEFINE_REGISTRY (program_space, REGISTRY_ACCESS_FIELD)

View File

@ -24,12 +24,21 @@
/* The macros here implement a template type and functions for
associating some user data with a container object.
A registry is associated with a struct tag name. To attach a
registry to a structure, use DEFINE_REGISTRY. This takes the
structure tag and an access method as arguments. In the usual
case, where the registry fields appear directly in the struct, you
can use the 'REGISTRY_FIELDS' macro to declare the fields in the
struct definition, and you can pass 'REGISTRY_ACCESS_FIELD' as the
access argument to DEFINE_REGISTRY. In other cases, use
REGISTRY_FIELDS to define the fields in the appropriate spot, and
then define your own accessor to find the registry field structure
given an instance of your type.
The API user requests a key from a registry during gdb
initialization. Later this key can be used to associate some
module-specific data with a specific container object.
A registry is associated with a struct tag name.
The exported API is best used via the wrapper macros:
- register_TAG_data(TAG)
@ -54,16 +63,31 @@
Fetch the data for an object; returns NULL if it has not been set.
*/
/* This structure is used in a container to hold the data that the
registry uses. */
struct registry_fields
{
void **data;
unsigned num_data;
};
/* This macro is used in a container struct definition to define the
fields used by the registry code. */
#define REGISTRY_FIELDS \
void **data; \
unsigned num_data
struct registry_fields registry_data
/* A convenience macro for the typical case where the registry data is
kept as fields of the object. This can be passed as the ACCESS
method to DEFINE_REGISTRY. */
#define REGISTRY_ACCESS_FIELD(CONTAINER) \
(CONTAINER)
/* Define a new registry implementation. */
#define DEFINE_REGISTRY(TAG) \
#define DEFINE_REGISTRY(TAG, ACCESS) \
struct TAG ## _data \
{ \
unsigned index; \
@ -114,61 +138,65 @@ register_ ## TAG ## _data (void) \
static void \
TAG ## _alloc_data (struct TAG *container) \
{ \
gdb_assert (container->data == NULL); \
container->num_data = TAG ## _data_registry.num_registrations; \
container->data = XCALLOC (container->num_data, void *); \
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
gdb_assert (rdata->data == NULL); \
rdata->num_data = TAG ## _data_registry.num_registrations; \
rdata->data = XCALLOC (rdata->num_data, void *); \
} \
\
void \
clear_ ## TAG ## _data (struct TAG *container) \
{ \
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
struct TAG ## _data_registration *registration; \
int i; \
\
gdb_assert (container->data != NULL); \
gdb_assert (rdata->data != NULL); \
\
/* Process all the save handlers. */ \
\
for (registration = TAG ## _data_registry.registrations, i = 0; \
i < container->num_data; \
i < rdata->num_data; \
registration = registration->next, i++) \
if (container->data[i] != NULL && registration->data->save != NULL) \
registration->data->save (container, container->data[i]); \
if (rdata->data[i] != NULL && registration->data->save != NULL) \
registration->data->save (container, rdata->data[i]); \
\
/* Now process all the free handlers. */ \
\
for (registration = TAG ## _data_registry.registrations, i = 0; \
i < container->num_data; \
i < rdata->num_data; \
registration = registration->next, i++) \
if (container->data[i] != NULL && registration->data->free != NULL) \
registration->data->free (container, container->data[i]); \
if (rdata->data[i] != NULL && registration->data->free != NULL) \
registration->data->free (container, rdata->data[i]); \
\
memset (container->data, 0, container->num_data * sizeof (void *)); \
memset (rdata->data, 0, rdata->num_data * sizeof (void *)); \
} \
\
static void \
TAG ## _free_data (struct TAG *container) \
{ \
void ***rdata = &container->data; \
gdb_assert (*rdata != NULL); \
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
gdb_assert (rdata->data != NULL); \
clear_ ## TAG ## _data (container); \
xfree (*rdata); \
*rdata = NULL; \
xfree (rdata->data); \
rdata->data = NULL; \
} \
\
void \
set_ ## TAG ## _data (struct TAG *container, const struct TAG ## _data *data, \
void *value) \
{ \
gdb_assert (data->index < container->num_data); \
container->data[data->index] = value; \
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
gdb_assert (data->index < rdata->num_data); \
rdata->data[data->index] = value; \
} \
\
void * \
TAG ## _data (struct TAG *container, const struct TAG ## _data *data) \
{ \
gdb_assert (data->index < container->num_data); \
return container->data[data->index]; \
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
gdb_assert (data->index < rdata->num_data); \
return rdata->data[data->index]; \
}