diff --git a/libmacro/libmacro.c b/libmacro/libmacro.c index 7e26cc4b..96b298e5 100644 --- a/libmacro/libmacro.c +++ b/libmacro/libmacro.c @@ -27,14 +27,16 @@ #if defined (__linux__) || defined (__CYGWIN__) #include #endif + +#include #include #include void *memdup(void *src, size_t len) { void *dst = calloc(1, len); - if (dst) { - memcpy(dst, src, len); + if (LIKELY(dst != NULL)) { + (void) memcpy(dst, src, len); } return dst; } @@ -42,26 +44,33 @@ void *memdup(void *src, size_t len) struct iovec *iovec_create(size_t len) { struct iovec *vec = CALLOC(1, struct iovec); - vec->iov_len = len; - vec->iov_base = calloc(1, len); + if (LIKELY(vec != NULL)) { + vec->iov_len = len; + vec->iov_base = calloc(1, len); + if (UNLIKELY(vec->iov_base == NULL)) { + free(vec); + vec = NULL; + } + } return vec; } void iovec_destroy(struct iovec *vec) { - if (!vec || !vec->iov_base) - return; - free(vec->iov_base); - free(vec); + if (LIKELY(vec != NULL)) { + /* free(NULL) do nop */ + free(vec->iov_base); + free(vec); + } } +/** + * Fast little endian check + * NOTE: not applicable for PDP endian + */ bool is_little_endian(void) { - unsigned int probe = 0xff; - size_t sz = sizeof(unsigned int); - unsigned char * probe_byte = (unsigned char *)&probe; - if (!(probe_byte[0] == 0xff || probe_byte[sz - 1] == 0xff)) { - printf("%s: something wrong!\n", __func__); - } - return probe_byte[0] == 0xff; + static uint16_t x = 0x01; + return *((uint8_t *) &x); } + diff --git a/libmacro/libmacro.h b/libmacro/libmacro.h index ef6a3679..1914558a 100644 --- a/libmacro/libmacro.h +++ b/libmacro/libmacro.h @@ -25,7 +25,7 @@ #include #include -#if defined (__linux__) || defined (__CYGWIN__) +#if defined (__linux__) || defined (__CYGWIN__) || defined (__APPLE__) #include #include #elif defined (__WIN32__) || defined (WIN32) || defined (_MSC_VER) @@ -41,9 +41,14 @@ extern "C" { * MACRO DEFINES ARE UPPERCASE */ +/** + * Variable-argument unused annotation + */ +#define UNUSED(e, ...) (void) ((void) (e), ##__VA_ARGS__) + #ifdef __GNUC__ -#define LIKELY(x) (__builtin_expect(!!(x), 1)) -#define UNLIKELY(x) (__builtin_expect(!!(x), 0)) +#define LIKELY(x) (__builtin_expect(!(x), 0)) +#define UNLIKELY(x) (__builtin_expect(!(x), 1)) #else #define LIKELY(x) (x) #define UNLIKELY(x) (x) @@ -52,16 +57,17 @@ extern "C" { #define SWAP(a, b) \ do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) -#define MIN2(a, b) ((a) > (b) ? (b) : (a)) -#define MAX2(a, b) ((a) > (b) ? (a) : (b)) +#define MIN2(a, b) ((a) > (b) ? (b) : (a)) +#define MAX2(a, b) ((a) > (b) ? (a) : (b)) +#define ABS(x) ((x) >= 0 ? (x) : -(x)) -#define CALLOC(size, type) (type *)calloc(size, sizeof(type)) -#define SIZEOF(array) (sizeof(array)/sizeof(array[0])) +#define CALLOC(size, type) (type *) calloc(size, sizeof(type)) +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) -#define VERBOSE() \ - do {\ - printf("%s:%s:%d xxxxxx\n", __FILE__, __func__, __LINE__);\ - } while (0); +#define VERBOSE() \ + do { \ + printf("%s:%s:%d xxxxxx\n", __FILE__, __func__, __LINE__); \ + } while (0) #define DUMP_BUFFER(buf, len) \ do { \ @@ -77,19 +83,39 @@ extern "C" { printf("\n"); \ } while (0) -#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) +#define ALIGN2(x, a) (((x) + (a) - 1) & ~((a) - 1)) + +#define is_alpha(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z')) + +/** + * Compile-time strlen(3) + * XXX: Should only used for `char[]' NOT `char *' + * Assume string ends with null byte('\0') + */ +#define STRLEN(s) (sizeof(s) - 1) + +/** + * Compile-time assurance see: linux/arch/x86/boot/boot.h + * Will fail build if condition yield true + */ +#ifndef BUILD_BUG_ON +#if defined (__WIN32__) || defined (_WIN32) || defined (_MSC_VER) +/* + * MSVC compiler allows negative array size(treat as unsigned value) + * yet them don't allow zero-size array + */ +#define BUILD_BUG_ON(cond) ((void) sizeof(char[!(cond)])) +#else +#define BUILD_BUG_ON(cond) ((void) sizeof(char[1 - 2 * !!(cond)])) +#endif +#endif void *memdup(void *src, size_t len); struct iovec *iovec_create(size_t len); void iovec_destroy(struct iovec *); -#define UNUSED(arg) (arg = arg) - - bool is_little_endian(void); -#define is_character(c) (((c)<='z'&&(c)>='a') || ((c)<='Z'&&(c)>='A')) - #ifdef __cplusplus } #endif diff --git a/libmacro/test_libmacro.c b/libmacro/test_libmacro.c index 7c7606ea..53e119b6 100644 --- a/libmacro/test_libmacro.c +++ b/libmacro/test_libmacro.c @@ -20,6 +20,7 @@ * SOFTWARE. ******************************************************************************/ #include "libmacro.h" +#include #include #include @@ -38,10 +39,35 @@ void foo() UNUSED(p); } +void unused_macro_tests(void) +{ + int i; + UNUSED(i); + + char c = '@'; + UNUSED(c, i); + + int a, b; + UNUSED(a, b); + + UNUSED(sizeof(char) == 1); + UNUSED(sizeof(char) == 1, i); + UNUSED(a, sizeof(char) == 1, b); + + UNUSED(0, i, "Yummy!", a, b, 'a', NULL, 3.141592654); + + const char *duh = "Suck less!"; + UNUSED(duh); +} int main(int argc, char **argv) { + UNUSED(argc, argv); + foo(); printf("hello world\n"); + unused_macro_tests(); + printf("Little endian: %d\n", is_little_endian()); return 0; } +