X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Futil.h;h=e5339875494842cc1a6638c6cc6b5f6ccb5b8196;hb=e7009c364026d69381cdda23941f99ff040d4948;hp=e741067abd0a0ac9f6e2c5c78005c5082f656822;hpb=71d7c22f54ae32d15133571e09ddf7ab435e8afa;p=openvswitch diff --git a/lib/util.h b/lib/util.h index e741067a..e5339875 100644 --- a/lib/util.h +++ b/lib/util.h @@ -85,6 +85,22 @@ extern const char *program_name; #define OVS_TYPEOF(OBJECT) void * #endif +/* Given OBJECT of type pointer-to-structure, expands to the offset of MEMBER + * within an instance of the structure. + * + * The GCC-specific version avoids the technicality of undefined behavior if + * OBJECT is null, invalid, or not yet initialized. This makes some static + * checkers (like Coverity) happier. But the non-GCC version does not actually + * dereference any pointer, so it would be surprising for it to cause any + * problems in practice. + */ +#ifdef __GNUC__ +#define OBJECT_OFFSETOF(OBJECT, MEMBER) offsetof(typeof(*(OBJECT)), MEMBER) +#else +#define OBJECT_OFFSETOF(OBJECT, MEMBER) \ + ((char *) &(OBJECT)->MEMBER - (char *) (OBJECT)) +#endif + /* Given POINTER, the address of the given MEMBER in a STRUCT object, returns the STRUCT object. */ #define CONTAINER_OF(POINTER, STRUCT, MEMBER) \ @@ -99,7 +115,7 @@ extern const char *program_name; * from the type of '*OBJECT'. */ #define OBJECT_CONTAINING(POINTER, OBJECT, MEMBER) \ ((OVS_TYPEOF(OBJECT)) (void *) \ - ((char *) (POINTER) - ((char *) &(OBJECT)->MEMBER - (char *) (OBJECT)))) + ((char *) (POINTER) - OBJECT_OFFSETOF(OBJECT, MEMBER))) /* Given POINTER, the address of the given MEMBER within an object of the type * that that OBJECT points to, assigns the address of the outer object to @@ -135,9 +151,13 @@ void *x2nrealloc(void *p, size_t *n, size_t s); void ovs_strlcpy(char *dst, const char *src, size_t size); void ovs_strzcpy(char *dst, const char *src, size_t size); +void ovs_abort(int err_no, const char *format, ...) + PRINTF_FORMAT(2, 3) NO_RETURN; void ovs_fatal(int err_no, const char *format, ...) PRINTF_FORMAT(2, 3) NO_RETURN; void ovs_error(int err_no, const char *format, ...) PRINTF_FORMAT(2, 3); +void ovs_error_valist(int err_no, const char *format, va_list) + PRINTF_FORMAT(2, 0); const char *ovs_retval_to_string(int); void ovs_hex_dump(FILE *, const void *, size_t, uintptr_t offset, bool ascii);