From 18602745de52e5869f3865245c3c72986831dae2 Mon Sep 17 00:00:00 2001 From: Geoff Thorpe Date: Tue, 9 Jan 2001 00:02:09 +0000 Subject: [PATCH] This adds macros to implement (and/or declare) type-safe wrapper functions around the callbacks required in the LHASH code for the "doall" functions. Also - fix the evil function pointer casting in the two lh_doall functions by deferring to a static utility function. Previously lh_doall() was invoking lh_doall_arg() by casting the callback to the 2-parameter prototype and passing in a NULL argument. This appears to have been working thus far but it's not a hot idea. If the extra level of indirection becomes a performance hit, we can just provide two virtually identical implementations for each variant later on. --- crypto/lhash/lhash.c | 30 ++++++++++++++++-------------- crypto/lhash/lhash.h | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/crypto/lhash/lhash.c b/crypto/lhash/lhash.c index 874647af6b..9d815f0ca0 100644 --- a/crypto/lhash/lhash.c +++ b/crypto/lhash/lhash.c @@ -267,19 +267,8 @@ void *lh_retrieve(LHASH *lh, const void *data) return((void *)ret); } -void lh_doall(LHASH *lh, LHASH_DOALL_FN_TYPE func) - { - /* Yikes that's bad - we're accepting a function that accepts 2 - * parameters (albeit we have to waive type-safety here) and then - * forcibly calling that callback with *3* parameters leaving the 3rd - * NULL. Obviously this "works" otherwise it wouldn't have survived so - * long, but is it "good"?? - * FIXME: Use an internal function from this and the "_arg" version that - * doesn't assume the ability to mutate function prototypes so badly. */ - lh_doall_arg(lh, (LHASH_DOALL_ARG_FN_TYPE)func, NULL); - } - -void lh_doall_arg(LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, const void *arg) +static void doall_util_fn(LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, + LHASH_DOALL_ARG_FN_TYPE func_arg, const void *arg) { int i; LHASH_NODE *a,*n; @@ -294,12 +283,25 @@ void lh_doall_arg(LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, const void *arg) /* 28/05/91 - eay - n added so items can be deleted * via lh_doall */ n=a->next; - func(a->data,arg); + if(use_arg) + func_arg(a->data,arg); + else + func(a->data); a=n; } } } +void lh_doall(LHASH *lh, LHASH_DOALL_FN_TYPE func) + { + doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)NULL, NULL); + } + +void lh_doall_arg(LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, const void *arg) + { + doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)NULL, func, arg); + } + static void expand(LHASH *lh) { LHASH_NODE **n,**n1,**n2,*np; diff --git a/crypto/lhash/lhash.h b/crypto/lhash/lhash.h index 3c5355885f..a6048a4b7d 100644 --- a/crypto/lhash/lhash.h +++ b/crypto/lhash/lhash.h @@ -115,6 +115,25 @@ typedef void (*LHASH_DOALL_ARG_FN_TYPE)(const void *, const void *); return f_name(a,b); } #define LHASH_COMP_FN(f_name) f_name##_LHASH_COMP +/* Third: "doall" functions */ +#define DECLARE_LHASH_DOALL_FN(f_name,o_type) \ + void f_name##_LHASH_DOALL(const void *); +#define IMPLEMENT_LHASH_DOALL_FN(f_name,o_type) \ + void f_name##_LHASH_DOALL(const void *arg) { \ + o_type a = (o_type)arg; \ + return f_name(a); } +#define LHASH_DOALL_FN(f_name) f_name##_LHASH_DOALL + +/* Fourth: "doall_arg" functions */ +#define DECLARE_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \ + void f_name##_LHASH_DOALL_ARG(const void *, const void *); +#define IMPLEMENT_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \ + void f_name##_LHASH_DOALL_ARG(const void *arg1, const void *arg2) { \ + o_type a = (o_type)arg1; \ + a_type b = (a_type)arg2; \ + return f_name(a,b); } +#define LHASH_DOALL_ARG_FN(f_name) f_name##_LHASH_DOALL_ARG + typedef struct lhash_st { LHASH_NODE **b; -- 2.25.1