From 65892e28812cc06cceba26c22caca6e6b83960e0 Mon Sep 17 00:00:00 2001 From: Carl Worth <cworth@cworth.org> Date: Mon, 10 Jun 2013 14:40:43 -0700 Subject: [PATCH] Add a new GLWRAP_DEFER_WITH_RETURN macro. This allows for the elimination of some code duplication from our implementation of glXGetPrcAddressARB. The previous implementation duplicated code from glwrap_lookup simply because the GLWRAP_DEFER macro did not provide access to the return value of the wrapped function. With the new macro, (very much like GLWRAP_DEFER but accepting a parameter for a variable to accept the return value), we can eliminate this code duplication. Of course, our symbol-extraction script is now a bit more complicated since it has to find occurrences of DEFER_WITH_RETURN in addition to occurrences of DEFER, and pull out the function name as the second argument rather than the first. --- extract-wrapped-symbols | 11 ++++++++--- glwrap.h | 8 ++++++++ glxwrap.c | 23 +++++++---------------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/extract-wrapped-symbols b/extract-wrapped-symbols index 2b9f76a..8cdd035 100755 --- a/extract-wrapped-symbols +++ b/extract-wrapped-symbols @@ -8,12 +8,16 @@ # libfips, while all other symbols are private. # We have two different patterns for identifying wrapped -# functions. The first is a call to a macro ending in "DEFER" (such as -# DEFER or TIMED_DEFER). In this case, the first argument to the macro -# is the name of the wrapped function. +# functions. The first is a call to one of the DEFER macros +# (GLWRAP_DEFER, TIMED_DEFER, WGLWRAP_DEFER_WITH_RETURN, etc.). In +# this case, the name of the wrapped function appears as the first or +# second argument to the macro, (second for the case of of +# _WITH_RETURN macro). deferred=`grep 'DEFER[ (]*e*gl' $@ | sed -s 's/.*DEFER *(\([^,)]*\).*/\1/'` +deferred_return=`grep 'DEFER_WITH_RETURN *([^,]*, *e*gl' $@ | sed -s 's/.*DEFER_WITH_RETURN *([^,]*, *\([^,)]*\).*/\1/'` + # The second-case is functions for which we either implement or call # the underlying "real" function. In these cases, the code uses the # convention of having a function or a function-pointer with a name of @@ -32,6 +36,7 @@ global: EOF echo "$deferred +$deferred_return $wrapped" | sort | uniq | sed -e 's/\(.*\)/ \1;/' cat <<EOF diff --git a/glwrap.h b/glwrap.h index 9195007..bd2e265 100644 --- a/glwrap.h +++ b/glwrap.h @@ -37,4 +37,12 @@ glwrap_lookup (char *name); real_ ## function(__VA_ARGS__); \ } while (0); +/* As GLWRAP_DEFER, but also set 'ret' to the return value */ +#define GLWRAP_DEFER_WITH_RETURN(ret, function,...) do { \ + static typeof(&function) real_ ## function; \ + if (! real_ ## function) \ + real_ ## function = glwrap_lookup (#function); \ + (ret) = real_ ## function(__VA_ARGS__); \ +} while (0); + #endif diff --git a/glxwrap.c b/glxwrap.c index 6da42e6..84bf485 100644 --- a/glxwrap.c +++ b/glxwrap.c @@ -45,24 +45,15 @@ glXSwapBuffers (Display *dpy, GLXDrawable drawable) */ void (*glXGetProcAddressARB (const GLubyte *func))(void) { - void *ptr; - static typeof(&glXGetProcAddressARB) glxwrap_real_glXGetProcAddressARB = NULL; - char *name = "glXGetProcAddressARB"; - - if (! glxwrap_real_glXGetProcAddressARB) { - glxwrap_real_glXGetProcAddressARB = glwrap_lookup (name); - if (! glxwrap_real_glXGetProcAddressARB) { - fprintf (stderr, "Error: Failed to find function %s.\n", - name); - return NULL; - } - } + void *ret; /* If our library has this symbol, that's what we want to give. */ - ptr = dlwrap_real_dlsym (NULL, (const char *) func); - if (ptr) - return ptr; + ret = dlwrap_real_dlsym (NULL, (const char *) func); + if (ret) + return ret; /* Otherwise, just defer to the real glXGetProcAddressARB. */ - return glxwrap_real_glXGetProcAddressARB (func); + GLWRAP_DEFER_WITH_RETURN (ret, glXGetProcAddressARB, func); + + return ret; } -- 2.45.2