module-context.h revision a813184174d2ef1692e93ac13db99608b010f811
#ifndef MODULE_CONTEXT_H
#define MODULE_CONTEXT_H
#include "array.h"
/*
This is a bit complex to use, but it prevents using wrong module IDs
in module_contexts arrays.
---------
The main structure is implemented like this:
struct STRUCT_NAME_module_register {
unsigned int id;
};
union STRUCT_NAME_module_context {
struct STRUCT_NAME_module_register *reg;
// it's allowed to have some structure here so it won't waste space.
// for example: struct STRUCT_NAME_vfuncs super;
};
struct STRUCT_NAME {
ARRAY(union STRUCT_NAME_module_context *) module_contexts;
};
extern struct STRUCT_NAME_module_register STRUCT_NAME_module_register;
---------
The usage in modules goes like:
static MODULE_CONTEXT_DEFINE(mymodule_STRUCT_NAME_module,
&STRUCT_NAME_module_register);
struct mymodule_STRUCT_NAME {
union STRUCT_NAME_module_context module_ctx;
// module-specific data
};
struct mymodule_STRUCT_NAME *ctx = i_new(...);
MODULE_CONTEXT_SET(obj, mymodule_STRUCT_NAME_module, ctx);
struct mymodule_STRUCT_NAME *ctx =
MODULE_CONTEXT(obj, mymodule_STRUCT_NAME_module);
*/
#define OBJ_REGISTER(obj) \
/* Will crash if context is missing. This is mainly used to simplify code and
keep static analyzers happy. This syntax discards result of i_panic and
returns NULL instead to keep compilers happy. */
#ifdef HAVE_TYPEOF
struct _name { \
struct module_context_id id; \
} _name
# define MODULE_CONTEXT_INIT(_reg) \
#else
struct _name { \
struct module_context_id id; \
} _name
# define MODULE_CONTEXT_INIT(_reg) \
#endif
struct module_context_id {
unsigned int *module_id_register;
unsigned int module_id;
bool module_id_set;
};
{
if (!id->module_id_set) {
}
}
void *_module_tmp = ctx + \
(**(obj)->module_contexts.v)) + \
} STMT_END
#endif