ruby-changes:35497
From: normal <ko1@a...>
Date: Sun, 14 Sep 2014 08:49:44 +0900 (JST)
Subject: [ruby-changes:35497] normal:r47579 (trunk): ccan/container_of: add container_of_or_null
normal 2014-09-14 08:49:28 +0900 (Sun, 14 Sep 2014) New Revision: 47579 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47579 Log: ccan/container_of: add container_of_or_null * ccan/container_of/container_of.h (container_of_or_null): added [ccan 7ec5b8e06b2fd5fa98b1fcde1158c286d2d429d8] (David Gibson) It's quite common to have a pointer which could be either a pointer to a structure member, or NULL. This needs special casing with container_of(), or it will convert NULL into something strange. This patch adds container_of_or_null(), which will return NULL if passed (an appropriately typed) NULL, or the containining structure as container_of() otherwise. Modified files: trunk/ChangeLog trunk/ccan/container_of/container_of.h Index: ChangeLog =================================================================== --- ChangeLog (revision 47578) +++ ChangeLog (revision 47579) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sun Sep 14 08:43:37 2014 Eric Wong <e@8...> + + * ccan/container_of/container_of.h (container_of_or_null): added + [ccan 7ec5b8e06b2fd5fa98b1fcde1158c286d2d429d8] (David Gibson) + Sun Sep 14 08:41:44 2014 Eric Wong <e@8...> * ccan/list/list.h (list_del_init, list_node_init): new functions Index: ccan/container_of/container_of.h =================================================================== --- ccan/container_of/container_of.h (revision 47578) +++ ccan/container_of/container_of.h (revision 47579) @@ -33,6 +33,42 @@ https://github.com/ruby/ruby/blob/trunk/ccan/container_of/container_of.h#L33 - container_off(containing_type, member)) \ + check_types_match(*(member_ptr), ((containing_type *)0)->member)) + +/** + * container_of_or_null - get pointer to enclosing structure, or NULL + * @member_ptr: pointer to the structure member + * @containing_type: the type this member is within + * @member: the name of this member within the structure. + * + * Given a pointer to a member of a structure, this macro does pointer + * subtraction to return the pointer to the enclosing type, unless it + * is given NULL, in which case it also returns NULL. + * + * Example: + * struct foo { + * int fielda, fieldb; + * // ... + * }; + * struct info { + * int some_other_field; + * struct foo my_foo; + * }; + * + * static struct info *foo_to_info_allowing_null(struct foo *foo) + * { + * return container_of_or_null(foo, struct info, my_foo); + * } + */ +static inline char *container_of_or_null_(void *member_ptr, size_t offset) +{ + return member_ptr ? (char *)member_ptr - offset : NULL; +} +#define container_of_or_null(member_ptr, containing_type, member) \ + ((containing_type *) \ + container_of_or_null_(member_ptr, \ + container_off(containing_type, member)) \ + + check_types_match(*(member_ptr), ((containing_type *)0)->member)) + /** * container_off - get offset to enclosing structure * @containing_type: the type this member is within -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/