[Libguestfs] [PATCH] lib: Add COMPILE_REGEXP macro to hide regexp constructors/destructors.
Pino Toscano
ptoscano at redhat.com
Fri Nov 28 17:15:02 UTC 2014
On Friday 28 November 2014 14:44:30 Richard W.M. Jones wrote:
> [NOTE: this is not the complete patch. Once ACKed, I will make the
> same mechanical change to all the other places in the library that use
> this pattern.]
> ---
> src/guestfs-internal.h | 24 ++++++++
> src/inspect-fs-unix.c | 164 +++++++++++--------------------------------------
> 2 files changed, 59 insertions(+), 129 deletions(-)
>
> diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
> index fd0c4a1..33d28f5 100644
> --- a/src/guestfs-internal.h
> +++ b/src/guestfs-internal.h
> @@ -667,6 +667,30 @@ extern int guestfs___match6 (guestfs_h *g, const char *str, const pcre *re, char
> #define match4 guestfs___match4
> #define match6 guestfs___match6
>
> +/* Macro which compiles the regexp once when the library is loaded,
> + * and frees it when the library is unloaded.
> + */
> +#define COMPILE_REGEXP(name,pattern,options) \
> + static void compile_regexp_##name (void) __attribute__((constructor)); \
> + static void free_regexp_##name (void) __attribute__((destructor)); \
> + static pcre *name; \
> + static void \
> + compile_regexp_##name (void) \
> + { \
> + const char *err; \
> + int offset; \
> + name = pcre_compile ((pattern), (options), &err, &offset, NULL); \
> + if (name == NULL) { \
> + ignore_value (write (2, err, strlen (err))); \
> + abort (); \
> + } \
> + } \
> + static void \
> + free_regexp_##name (void) \
> + { \
> + pcre_free (name); \
> + }
Sounds okay, I guess it shouldn't introduce much overhead in the
library loading?
I also wonder whether we can delay the creation of those regexps
(i.e. not just the ones mentioned in this patch) when just needed;
something like the (untested):
#define COMPILE_REGEXP(name,pattern,options) \
static void free_regexp_##name (void) __attribute__((destructor)); \
static pcre *_internal_##name; \
static void \
##name (void) \
{ \
if (_internal_##name == NULL) { \
const char *err; \
int offset; \
_internal_##name = pcre_compile ((pattern), (options), \
&err, &offset, NULL); \
if (_internal_##name == NULL) { \
ignore_value (write (2, err, strlen (err))); \
abort (); \
} \
} \
return _internal_##name; \
} \
static void \
free_regexp_##name (void) \
{ \
if (_internal_##name) \
pcre_free (_internal_##name); \
}
using it e.g.: match (re_major_minor (), ...)
The only issue I could see is that the above is not thread-safe.
--
Pino Toscano
More information about the Libguestfs
mailing list