summaryrefslogtreecommitdiff
path: root/include/libHX
diff options
context:
space:
mode:
Diffstat (limited to 'include/libHX')
-rw-r--r--include/libHX/cast.h129
-rw-r--r--include/libHX/defs.h115
-rw-r--r--include/libHX/misc.h3
-rw-r--r--include/libHX/option.h10
4 files changed, 141 insertions, 116 deletions
diff --git a/include/libHX/cast.h b/include/libHX/cast.h
new file mode 100644
index 0000000..cb2cba5
--- /dev/null
+++ b/include/libHX/cast.h
@@ -0,0 +1,129 @@
+#ifndef _LIBHX_CAST_H
+#define _LIBHX_CAST_H 1
+
+#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..31c818f 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 *, \
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 *);