Next step in tidying up the LHASH code. This commit defines DECLARE and
authorGeoff Thorpe <geoff@openssl.org>
Sat, 2 Dec 2000 23:08:59 +0000 (23:08 +0000)
committerGeoff Thorpe <geoff@openssl.org>
Sat, 2 Dec 2000 23:08:59 +0000 (23:08 +0000)
IMPLEMENT macros for defining wrapper functions for "hash" and "cmp" callbacks
that are specific to the underlying item type in a hash-table. This prevents
function pointer casting altogether, and also provides some type-safety
because the macro does per-variable casting from the (void *) type used in
LHASH itself to the type declared in the macro - and if that doesn't match the
prototype expected by the "hash" or "cmp" function then a compiler error will
result.

NB: IMPLEMENT macros are not required unless predeclared forms are required
(either in a header file, or further up in a C file than the implementation
needs to be). The DECLARE macros must occur after the type-specific hash/cmp
callbacks are declared. Also, the IMPLEMENT and DECLARE macros are such that
they can be prefixed with "static" if desired and a trailing semi-colon should
be appended (making it look more like a regular declaration and easier on
auto-formatting text-editors too).

Now that these macros are defined, I will next be commiting changes to a
number of places in the library where the casting was doing bad things. After
that, the final step will be to make the analogous changes for the lh_doall
and lh_doall_arg functions (more specifically, their callback parameters).

crypto/lhash/lhash.h

index 0c1e2d2..5e3fde5 100644 (file)
@@ -89,6 +89,35 @@ typedef unsigned long (*LHASH_HASH_FN_TYPE)(void *);
 typedef void (*LHASH_DOALL_FN_TYPE)(void *);
 typedef void (*LHASH_DOALL_ARG_FN_TYPE)(void *, void *);
 
+/* Macros for declaring and implementing type-safe wrappers for LHASH callbacks.
+ * This way, callbacks can be provided to LHASH structures without function
+ * pointer casting and the macro-defined callbacks provide per-variable casting
+ * before deferring to the underlying type-specific callbacks. NB: It is
+ * possible to place a "static" in front of both the DECLARE and IMPLEMENT
+ * macros if the functions are strictly internal. To keep text-editors happy,
+ * the macro deliberately doesn't define a trailing semi-colon - so the macro
+ * can be placed just like a regular function declaration, with an optional
+ * "static" prefix and trailing simi-colon. */
+
+/* First: "hash" functions */
+#define DECLARE_LHASH_HASH_FN(f_name,o_type) \
+       unsigned long f_name##_LHASH_HASH(void *)
+#define IMPLEMENT_LHASH_HASH_FN(f_name,o_type) \
+       unsigned long f_name##_LHASH_HASH(void *arg) { \
+               o_type a = (o_type)arg; \
+               return f_name(a); }
+#define LHASH_HASH_FN(f_name) f_name##_LHASH_HASH
+
+/* Second: "compare" functions */
+#define DECLARE_LHASH_COMP_FN(f_name,o_type) \
+       int f_name##_LHASH_COMP(void *, void *)
+#define IMPLEMENT_LHASH_COMP_FN(f_name,o_type) \
+       int f_name##_LHASH_COMP(void *arg1, void *arg2) { \
+               o_type a = (o_type)arg1; \
+               o_type b = (o_type)arg2; \
+               return f_name(a,b); }
+#define LHASH_COMP_FN(f_name) f_name##_LHASH_COMP
+
 typedef struct lhash_st
        {
        LHASH_NODE **b;