diff options
Diffstat (limited to 'include/libHX')
| -rw-r--r-- | include/libHX/cast.h | 135 | ||||
| -rw-r--r-- | include/libHX/defs.h | 121 | ||||
| -rw-r--r-- | include/libHX/misc.h | 3 | ||||
| -rw-r--r-- | include/libHX/option.h | 10 | 
4 files changed, 147 insertions, 122 deletions
| diff --git a/include/libHX/cast.h b/include/libHX/cast.h new file mode 100644 index 0000000..c8fe0ba --- /dev/null +++ b/include/libHX/cast.h @@ -0,0 +1,135 @@ +#ifndef _LIBHX_CAST_H +#define _LIBHX_CAST_H 1 + +#ifndef BUILD_BUG_ON_EXPR +#	define BUILD_BUG_ON_EXPR(condition) (sizeof(char[1 - 2 * !!(condition)]) - 1) +#endif +#ifndef BUILD_BUG_ON +#	define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_EXPR(condition)) +#endif +#ifdef __cplusplus +#	ifndef const_cast +#		define const_cast(T, x) const_cast<T>(x) +#	endif +#	ifndef static_cast +#		define static_cast(T, x) static_cast<T>(x) +#	endif +#	define const_cast1(type, expr)      const_cast<type>(expr) +#	define const_cast2(type, expr)      const_cast<type>(expr) +#	define const_cast3(type, expr)      const_cast<type>(expr) + +template<typename new_type> +static __inline__ new_type signed_cast(const char *expr) +{ +	return reinterpret_cast<new_type>(expr); +} + +template<typename new_type> +static __inline__ new_type signed_cast(const signed char *expr) +{ +	return reinterpret_cast<new_type>(expr); +} + +template<typename new_type> +static __inline__ new_type signed_cast(const unsigned char *expr) +{ +	return reinterpret_cast<new_type>(expr); +} + +template<typename new_type> +static __inline__ new_type signed_cast(char *expr) +{ +	return reinterpret_cast<new_type>(expr); +} + +template<typename new_type> +static __inline__ new_type signed_cast(signed char *expr) +{ +	return reinterpret_cast<new_type>(expr); +} + +template<typename new_type> +static __inline__ new_type signed_cast(unsigned char *expr) +{ +	return reinterpret_cast<new_type>(expr); +} + +#else +	/* N.B. signed_cast<> does not exist in C++. */ +#	define __signed_cast_compatible(a, b) \ +		__builtin_choose_expr( \ +			__builtin_types_compatible_p(b, const char *) || \ +			__builtin_types_compatible_p(b, const signed char *) || \ +			__builtin_types_compatible_p(b, const unsigned char *), \ +			/* if src has a const qualifier */ \ +			__builtin_types_compatible_p(a, const char *) || \ +			__builtin_types_compatible_p(a, const signed char *) || \ +			__builtin_types_compatible_p(a, const unsigned char *), \ +			/* and if it has none... */ \ +			__builtin_types_compatible_p(a, const char *) || \ +			__builtin_types_compatible_p(a, const signed char *) || \ +			__builtin_types_compatible_p(a, const unsigned char *) || \ +			__builtin_types_compatible_p(a, char *) || \ +			__builtin_types_compatible_p(a, signed char *) || \ +			__builtin_types_compatible_p(a, unsigned char *) \ +		) + +#	if defined(__GNUC__) && !defined(__clang__) && !defined(signed_cast) +#		define signed_cast(type, expr) ({ \ +			BUILD_BUG_ON(!__signed_cast_compatible(__typeof__(type), __typeof__(expr))); \ +			(type)(expr); \ +		}) +#	endif +#	if defined(__GNUC__) && !defined(__clang__) && !defined(static_cast) +#		define static_cast(type, expr) \ +			((struct { type x; }){(expr)}.x) +#	endif +#	if defined(__GNUC__) && !defined(__clang__) && !defined(const_cast1) +		/* +		 * The idea starts with (in abstract notation) +		 * 	typeof deref typeof expr +		 * To deref something, we need an object, which we can get by +		 * creating a temporary aggregate, such as a union, of which +		 * the member is accessed and dereferenced. +		 * 	*(union { __typeof__(expr) x; }){init}.x +		 * union has two nice properties: +		 * - with an additional dummy member, we do not have to +		 *   initialize x according to its type, which, if expr is +		 *   an array type, may want extra braces. +		 * - and with that dummy member, we also avoid the ugly +		 *   "literal 0 is implicitly convertible to a pointer". +		 * Unfortunately, this all requires C99 compound initializers. +		 * That's ok - gcc and clang only treat it as a warning even +		 * under strict C89 - and if you still force strict C89 on +		 * yourself, you have a lot to answer for either way. +		 */ +#		define __const_cast_strip(ptrs, expr) \ +			__typeof__(ptrs(union { int z; __typeof__(expr) x; }){0}.x) +#		define __const_cast_p(ptrs, new_type, expr) ((new_type)( \ +			(expr) + \ +			BUILD_BUG_ON_EXPR(!__builtin_types_compatible_p(__const_cast_strip(ptrs, expr), __const_cast_strip(ptrs, new_type))) \ +		)) +#		define const_cast1(new_type, expr) __const_cast_p(*, new_type, expr) +#		define const_cast2(new_type, expr) __const_cast_p(**, new_type, expr) +#		define const_cast3(new_type, expr) __const_cast_p(***, new_type, expr) +#	endif +#	ifndef signed_cast +#		define signed_cast(type, expr)      ((type)(expr)) +#	endif +#	ifndef static_cast +#		define static_cast(type, expr)      ((type)(expr)) +#	endif +#	ifndef const_cast +#		define const_cast(type, expr)       ((type)(expr)) +#	endif +#	ifndef const_cast1 +#		define const_cast1(type, expr)      ((type)(expr)) +#		define const_cast2(type, expr)      ((type)(expr)) +#		define const_cast3(type, expr)      ((type)(expr)) +#	endif +#	ifndef reinterpret_cast +#		define reinterpret_cast(type, expr) ((type)(expr)) +#	endif +#endif + +#endif /* _LIBHX_CAST_H */ diff --git a/include/libHX/defs.h b/include/libHX/defs.h index 9d17019..ba84b37 100644 --- a/include/libHX/defs.h +++ b/include/libHX/defs.h @@ -1,6 +1,7 @@  #ifndef _LIBHX_DEFS_H  #define _LIBHX_DEFS_H 1 +#include <libHX/cast.h>  #ifdef __cplusplus  #	define HXsizeof_member(type, member) sizeof(type::member)  #	if __cplusplus >= 201100L @@ -13,123 +14,9 @@  #		include <type_traits>  #		define containerof(var, T, member) reinterpret_cast<std::conditional<std::is_const<std::remove_pointer<decltype(var)>::type>::value, std::add_const<T>::type, T>::type *>(reinterpret_cast<std::conditional<std::is_const<std::remove_pointer<decltype(var)>::type>::value, const char, char>::type *>(var) - offsetof(T, member))  #	endif -#	ifndef static_cast -#		define static_cast(T, x) static_cast<T>(x) -#	endif - -template<typename new_type> -static __inline__ new_type signed_cast(const char *expr) -{ -	return reinterpret_cast<new_type>(expr); -} - -template<typename new_type> -static __inline__ new_type signed_cast(const signed char *expr) -{ -	return reinterpret_cast<new_type>(expr); -} - -template<typename new_type> -static __inline__ new_type signed_cast(const unsigned char *expr) -{ -	return reinterpret_cast<new_type>(expr); -} - -template<typename new_type> -static __inline__ new_type signed_cast(char *expr) -{ -	return reinterpret_cast<new_type>(expr); -} - -template<typename new_type> -static __inline__ new_type signed_cast(signed char *expr) -{ -	return reinterpret_cast<new_type>(expr); -} - -template<typename new_type> -static __inline__ new_type signed_cast(unsigned char *expr) -{ -	return reinterpret_cast<new_type>(expr); -}  #else  #	define HXsizeof_member(type, member) sizeof(((type *)NULL)->member)  #	define HXtypeof_member(type, member) __typeof__(((type *)NULL)->member) -	/* N.B. signed_cast<> does not exist in C++. */ -#	define __signed_cast_compatible(a, b) \ -		__builtin_choose_expr( \ -			__builtin_types_compatible_p(b, const char *) || \ -			__builtin_types_compatible_p(b, const signed char *) || \ -			__builtin_types_compatible_p(b, const unsigned char *), \ -			/* if src has a const qualifier */ \ -			__builtin_types_compatible_p(a, const char *) || \ -			__builtin_types_compatible_p(a, const signed char *) || \ -			__builtin_types_compatible_p(a, const unsigned char *), \ -			/* and if it has none... */ \ -			__builtin_types_compatible_p(a, const char *) || \ -			__builtin_types_compatible_p(a, const signed char *) || \ -			__builtin_types_compatible_p(a, const unsigned char *) || \ -			__builtin_types_compatible_p(a, char *) || \ -			__builtin_types_compatible_p(a, signed char *) || \ -			__builtin_types_compatible_p(a, unsigned char *) \ -		) - -#	if defined(__GNUC__) && !defined(__clang__) && !defined(signed_cast) -#		define signed_cast(type, expr) ({ \ -			BUILD_BUG_ON(!__signed_cast_compatible(__typeof__(type), __typeof__(expr))); \ -			(type)(expr); \ -		}) -#	endif -#	if defined(__GNUC__) && !defined(__clang__) && !defined(static_cast) -#		define static_cast(type, expr) \ -			((struct { type x; }){(expr)}.x) -#	endif -#	if defined(__GNUC__) && !defined(__clang__) && !defined(const_cast1) -		/* -		 * The idea starts with (in abstract notation) -		 * 	typeof deref typeof expr -		 * To deref something, we need an object, which we can get by -		 * creating a temporary aggregate, such as a union, of which -		 * the member is accessed and dereferenced. -		 * 	*(union { __typeof__(expr) x; }){init}.x -		 * union has two nice properties: -		 * - with an additional dummy member, we do not have to -		 *   initialize x according to its type, which, if expr is -		 *   an array type, may want extra braces. -		 * - and with that dummy member, we also avoid the ugly -		 *   "literal 0 is implicitly convertible to a pointer". -		 * Unfortunately, this all requires C99 compound initializers. -		 * That's ok - gcc and clang only treat it as a warning even -		 * under strict C89 - and if you still force strict C89 on -		 * yourself, you have a lot to answer for either way. -		 */ -#		define __const_cast_strip(ptrs, expr) \ -			__typeof__(ptrs(union { int z; __typeof__(expr) x; }){0}.x) -#		define __const_cast_p(ptrs, new_type, expr) ((new_type)( \ -			(expr) + \ -			BUILD_BUG_ON_EXPR(!__builtin_types_compatible_p(__const_cast_strip(ptrs, expr), __const_cast_strip(ptrs, new_type))) \ -		)) -#		define const_cast1(new_type, expr) __const_cast_p(*, new_type, expr) -#		define const_cast2(new_type, expr) __const_cast_p(**, new_type, expr) -#		define const_cast3(new_type, expr) __const_cast_p(***, new_type, expr) -#	endif -#	ifndef signed_cast -#		define signed_cast(type, expr)      ((type)(expr)) -#	endif -#	ifndef static_cast -#		define static_cast(type, expr)      ((type)(expr)) -#	endif -#	ifndef const_cast -#		define const_cast(type, expr)       ((type)(expr)) -#	endif -#	ifndef const_cast1 -#		define const_cast1(type, expr)      ((type)(expr)) -#		define const_cast2(type, expr)      ((type)(expr)) -#		define const_cast3(type, expr)      ((type)(expr)) -#	endif -#	ifndef reinterpret_cast -#		define reinterpret_cast(type, expr) ((type)(expr)) -#	endif  #	ifndef containerof  #		include <stddef.h>  #		define containerof(var, type, member) reinterpret_cast(type *, \ @@ -151,12 +38,6 @@ static __inline__ new_type signed_cast(unsigned char *expr)  #ifndef ARRAY_SIZE  #	define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)) + __array_size_check(x))  #endif -#ifndef BUILD_BUG_ON_EXPR -#	define BUILD_BUG_ON_EXPR(condition) (sizeof(char[1 - 2 * !!(condition)]) - 1) -#endif -#ifndef BUILD_BUG_ON -#	define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_EXPR(condition)) -#endif  #ifndef DEMOTE_TO_PTR  	/*  	 * An alternative approach is also (p+0), but that does not ensure that diff --git a/include/libHX/misc.h b/include/libHX/misc.h index 1d49c7f..ac381dc 100644 --- a/include/libHX/misc.h +++ b/include/libHX/misc.h @@ -79,7 +79,10 @@ extern struct timespec *HX_timespec_mulf(struct timespec *,  extern struct timeval *HX_timeval_sub(struct timeval *,  	const struct timeval *, const struct timeval *);  extern long HX_time_compare(const struct stat *, const struct stat *, char); +#ifndef LIBHX_ZVECFREE_DECLARATION +#define LIBHX_ZVECFREE_DECLARATION  extern void HX_zvecfree(char **); +#endif  /*   *	RAND.C diff --git a/include/libHX/option.h b/include/libHX/option.h index 40cc6e7..ef9c626 100644 --- a/include/libHX/option.h +++ b/include/libHX/option.h @@ -8,6 +8,7 @@  #	include <stddef.h>  #	include <stdio.h>  #endif +#include <libHX/cast.h>  #ifdef __cplusplus  extern "C" { @@ -228,8 +229,13 @@ struct HXoption {  	const char *help, *htyp;  }; -extern int HX_getopt(const struct HXoption *, int *, const char ***, -	unsigned int); +#ifndef LIBHX_ZVECFREE_DECLARATION +#define LIBHX_ZVECFREE_DECLARATION +extern void HX_zvecfree(char **); +#endif +extern int HX_getopt(const struct HXoption *, int *, char ***, unsigned int); +extern int HX_getopt5(const struct HXoption *, char **argv, int *nargc, char ***nargv, unsigned int flags); +#define HX_getopt(a, b, c, d) HX_getopt((a), (b), const_cast3(char ***, (c)), (d))  extern void HX_getopt_help(const struct HXoptcb *, FILE *);  extern void HX_getopt_help_cb(const struct HXoptcb *);  extern void HX_getopt_usage(const struct HXoptcb *, FILE *); | 
