From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ian Jackson Subject: [PATCH 12/10] libxl: New convenience macro CONTAINING_STRUCT Date: Mon, 9 Jan 2012 17:34:35 +0000 Message-ID: <1326130477-18085-3-git-send-email-ian.jackson@eu.citrix.com> References: <1325882107-5794-1-git-send-email-ian.jackson@eu.citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1325882107-5794-1-git-send-email-ian.jackson@eu.citrix.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com Cc: Ian Jackson List-Id: xen-devel@lists.xenproject.org Provide a convenient and type-safe wrapper which does the correct dance to subtract offsetof. Signed-off-by: Ian Jackson --- tools/libxl/libxl_internal.h | 35 +++++++++++++++++++++++++++++++++++ 1 files changed, 35 insertions(+), 0 deletions(-) diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index e0ff15c..e0c2ad6 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1224,6 +1224,41 @@ _hidden void libxl__ao__destroy(libxl_ctx*, libxl__ao *ao); * Convenience macros. */ +/* + * [GET_]CONTAINING_STRUCT work like this. Given: + * typedef struct { + * ... + * member_type member_name; + * ... + * } outer_type; + * Then: + * void GET_CONTAINING_STRUCT(outer_type *outer_var [NB:UPDATED], + * some_type *inner_ptr, + * member_name); + * outer_type *CONTAINING_STRUCT(outer_type, + * some_type *inner_ptr, + * member_name); + * The semantics are that after: + * outer_type outer, *outer_var; + * member_type *inner_ptr = &outer->member_name; + * GET_CONTAINING_STRUCT(outer_var, &outer_ptr->member_name, member_name) + * The following hold: + * CONTAINING_STRUCT(inner_ptr, outer_type, member_name) == outer_ptr + * outer_var == &outer + */ +#define GET_CONTAINING_STRUCT(outer_var, inner_ptr, member_name) \ + ((outer_var) = (void*)((char*)(inner_ptr) - \ + offsetof(typeof(*(outer_var)), member_name)), \ + (void)(&(outer_var)->member_name == \ + (typeof(inner_ptr))0) /* type check */, \ + (void)0) +#define CONTAINING_STRUCT(outer_type, inner_ptr, member_name) \ + ({ \ + typeof(outer_type) *containing_struct; \ + GET_CONTAINING_STRUCT(containing_struct, inner_ptr, member_name); \ + containing_struct; \ + }) + /* * All of these assume (or define) -- 1.7.2.5