#endif
+/* Void! */
+struct _hb_void_t {};
+typedef const _hb_void_t &hb_void_t;
+#define HB_VOID (* (const _hb_void_t *) NULL)
+
+
/* Basics */
#undef ARRAY_LENGTH
template <typename Type, unsigned int n>
-static inline unsigned int ARRAY_LENGTH (const Type (&a)[n]) { return n; }
+static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
+/* A const version, but does not detect erratically being called on pointers. */
+#define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
#define HB_STMT_START do
#define HB_STMT_END while (0)
#define hb_be_uint32_get(v) (uint32_t) ((v[0] << 24) + (v[1] << 16) + (v[2] << 8) + v[3])
#define hb_be_uint32_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3])
+#define hb_be_uint24_put(v,V) HB_STMT_START { v[0] = (V>>16); v[1] = (V>>8); v[2] (V); } HB_STMT_END
+#define hb_be_uint24_get(v) (uint32_t) ((v[0] << 16) + (v[1] << 8) + v[2])
+#define hb_be_uint24_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2])
+
/* ASCII tag/character handling */
#define DEBUG_LEVEL(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT))
#define DEBUG(WHAT) (DEBUG_LEVEL (WHAT, 0))
-template <int max_level> inline void
+template <int max_level> static inline void
_hb_debug_msg_va (const char *what,
const void *obj,
const char *func,
} else
fprintf (stderr, " " VRBAR LBAR);
- if (func) {
- /* If there's a class name, just write that. */
- const char *dotdot = strstr (func, "::");
+ if (func)
+ {
+ /* Skip "typename" */
+ if (0 == strncmp (func, "typename ", 9))
+ func += 9;
+ /* Skip return type */
const char *space = strchr (func, ' ');
- if (space && dotdot && space < dotdot)
+ if (space)
func = space + 1;
- unsigned int func_len = dotdot ? dotdot - func : strlen (func);
+ /* Skip parameter list */
+ const char *paren = strchr (func, '(');
+ unsigned int func_len = paren ? paren - func : strlen (func);
fprintf (stderr, "%.*s: ", func_len, func);
}
const char *message HB_UNUSED,
va_list ap HB_UNUSED) {}
-template <int max_level> inline void
+template <int max_level> static inline void
_hb_debug_msg (const char *what,
const void *obj,
const char *func,
int level_dir,
const char *message,
...) HB_PRINTF_FUNC(7, 8);
-template <int max_level> inline void
+template <int max_level> static inline void
_hb_debug_msg (const char *what,
const void *obj,
const char *func,
/*
+ * Printer
+ */
+
+template <typename T>
+struct hb_printer_t {};
+
+template <>
+struct hb_printer_t<bool> {
+ const char *print (bool v) { return v ? "true" : "false"; }
+};
+
+template <>
+struct hb_printer_t<hb_void_t> {
+ const char *print (hb_void_t) { return ""; }
+};
+
+
+/*
* Trace
*/
-template <int max_level>
+template <typename T>
+static inline void _hb_warn_no_return (bool returned)
+{
+ if (unlikely (!returned)) {
+ fprintf (stderr, "OUCH, returned with no call to TRACE_RETURN. This is a bug, please report.\n");
+ }
+}
+template <>
+inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
+{}
+
+template <int max_level, typename ret_t>
struct hb_auto_trace_t {
explicit inline hb_auto_trace_t (unsigned int *plevel_,
const char *what_,
}
inline ~hb_auto_trace_t (void)
{
- if (unlikely (!returned)) {
- fprintf (stderr, "OUCH, returned with no call to TRACE_RETURN. This is a bug, please report. Level was %d.\n", plevel ? *plevel : -1);
+ _hb_warn_no_return<ret_t> (returned);
+ if (!returned) {
_hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, " ");
- return;
}
-
if (plevel) --*plevel;
}
- inline bool ret (bool v, unsigned int line = 0)
+ inline ret_t ret (ret_t v, unsigned int line = 0)
{
if (unlikely (returned)) {
fprintf (stderr, "OUCH, double calls to TRACE_RETURN. This is a bug, please report.\n");
return v;
}
- _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, "return %s (line %d)", v ? "true" : "false", line);
+ _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1,
+ "return %s (line %d)",
+ hb_printer_t<ret_t>().print (v), line);
if (plevel) --*plevel;
plevel = NULL;
returned = true;
private:
unsigned int *plevel;
- bool returned;
const char *what;
const void *obj;
+ bool returned;
};
-template <> /* Optimize when tracing is disabled */
-struct hb_auto_trace_t<0> {
+template <typename ret_t> /* Optimize when tracing is disabled */
+struct hb_auto_trace_t<0, ret_t> {
explicit inline hb_auto_trace_t (unsigned int *plevel_ HB_UNUSED,
const char *what HB_UNUSED,
const void *obj HB_UNUSED,
const char *message HB_UNUSED,
...) {}
- template <typename T>
- inline T ret (T v, unsigned int line = 0) { return v; }
+ inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; }
};
#define TRACE_RETURN(RET) trace.ret (RET, __LINE__)