[Libguestfs] [PATCH] lib: Add COMPILE_REGEXP macro to hide regexp constructors/destructors.

Richard W.M. Jones rjones at redhat.com
Fri Nov 28 14:44:30 UTC 2014


[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);                                                   \
+  }
+
 /* stringsbuf.c */
 struct stringsbuf {
   char **argv;
diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c
index fb5cc1a..01a59f1 100644
--- a/src/inspect-fs-unix.c
+++ b/src/inspect-fs-unix.c
@@ -45,135 +45,41 @@
 #include "guestfs-internal-actions.h"
 #include "guestfs_protocol.h"
 
-/* Compile all the regular expressions once when the shared library is
- * loaded.  PCRE is thread safe so we're supposedly OK here if
- * multiple threads call into the libguestfs API functions below
- * simultaneously.
- */
-static pcre *re_fedora;
-static pcre *re_rhel_old;
-static pcre *re_rhel;
-static pcre *re_rhel_no_minor;
-static pcre *re_centos_old;
-static pcre *re_centos;
-static pcre *re_centos_no_minor;
-static pcre *re_scientific_linux_old;
-static pcre *re_scientific_linux;
-static pcre *re_scientific_linux_no_minor;
-static pcre *re_oracle_linux_old;
-static pcre *re_oracle_linux;
-static pcre *re_oracle_linux_no_minor;
-static pcre *re_major_minor;
-static pcre *re_xdev;
-static pcre *re_cciss;
-static pcre *re_mdN;
-static pcre *re_freebsd_mbr;
-static pcre *re_freebsd_gpt;
-static pcre *re_diskbyid;
-static pcre *re_netbsd;
-static pcre *re_opensuse;
-static pcre *re_sles;
-static pcre *re_nld;
-static pcre *re_opensuse_version;
-static pcre *re_sles_version;
-static pcre *re_sles_patchlevel;
-static pcre *re_minix;
-static pcre *re_hurd_dev;
-
-static void compile_regexps (void) __attribute__((constructor));
-static void free_regexps (void) __attribute__((destructor));
-
-static void
-compile_regexps (void)
-{
-  const char *err;
-  int offset;
-
-#define COMPILE(re,pattern,options)                                     \
-  do {                                                                  \
-    re = pcre_compile ((pattern), (options), &err, &offset, NULL);      \
-    if (re == NULL) {                                                   \
-      ignore_value (write (2, err, strlen (err)));                      \
-      abort ();                                                         \
-    }                                                                   \
-  } while (0)
-
-  COMPILE (re_fedora, "Fedora release (\\d+)", 0);
-  COMPILE (re_rhel_old,
-           "Red Hat.*release (\\d+).*Update (\\d+)", 0);
-  COMPILE (re_rhel,
-           "Red Hat.*release (\\d+)\\.(\\d+)", 0);
-  COMPILE (re_rhel_no_minor,
-           "Red Hat.*release (\\d+)", 0);
-  COMPILE (re_centos_old,
-           "CentOS.*release (\\d+).*Update (\\d+)", 0);
-  COMPILE (re_centos,
-           "CentOS.*release (\\d+)\\.(\\d+)", 0);
-  COMPILE (re_centos_no_minor,
-           "CentOS.*release (\\d+)", 0);
-  COMPILE (re_scientific_linux_old,
-           "Scientific Linux.*release (\\d+).*Update (\\d+)", 0);
-  COMPILE (re_scientific_linux,
-           "Scientific Linux.*release (\\d+)\\.(\\d+)", 0);
-  COMPILE (re_scientific_linux_no_minor,
-           "Scientific Linux.*release (\\d+)", 0);
-  COMPILE (re_oracle_linux_old,
-           "Oracle Linux.*release (\\d+).*Update (\\d+)", 0);
-  COMPILE (re_oracle_linux,
-           "Oracle Linux.*release (\\d+)\\.(\\d+)", 0);
-  COMPILE (re_oracle_linux_no_minor,
-           "Oracle Linux.*release (\\d+)", 0);
-  COMPILE (re_major_minor, "(\\d+)\\.(\\d+)", 0);
-  COMPILE (re_xdev, "^/dev/(h|s|v|xv)d([a-z]+)(\\d*)$", 0);
-  COMPILE (re_cciss, "^/dev/(cciss/c\\d+d\\d+)(?:p(\\d+))?$", 0);
-  COMPILE (re_mdN, "^(/dev/md\\d+)$", 0);
-  COMPILE (re_freebsd_mbr, "^/dev/(ada{0,1}|vtbd)(\\d+)s(\\d+)([a-z])$", 0);
-  COMPILE (re_freebsd_gpt, "^/dev/(ada{0,1}|vtbd)(\\d+)p(\\d+)$", 0);
-  COMPILE (re_diskbyid, "^/dev/disk/by-id/.*-part(\\d+)$", 0);
-  COMPILE (re_netbsd, "^NetBSD (\\d+)\\.(\\d+)", 0);
-  COMPILE (re_opensuse, "^(openSUSE|SuSE Linux|SUSE LINUX) ", 0);
-  COMPILE (re_sles, "^SUSE (Linux|LINUX) Enterprise ", 0);
-  COMPILE (re_nld, "^Novell Linux Desktop ", 0);
-  COMPILE (re_opensuse_version, "^VERSION = (\\d+)\\.(\\d+)", 0);
-  COMPILE (re_sles_version, "^VERSION = (\\d+)", 0);
-  COMPILE (re_sles_patchlevel, "^PATCHLEVEL = (\\d+)", 0);
-  COMPILE (re_minix, "^(\\d+)\\.(\\d+)(\\.(\\d+))?", 0);
-  COMPILE (re_hurd_dev, "^/dev/(h)d(\\d+)s(\\d+)$", 0);
-}
-
-static void
-free_regexps (void)
-{
-  pcre_free (re_fedora);
-  pcre_free (re_rhel_old);
-  pcre_free (re_rhel);
-  pcre_free (re_rhel_no_minor);
-  pcre_free (re_centos_old);
-  pcre_free (re_centos);
-  pcre_free (re_centos_no_minor);
-  pcre_free (re_scientific_linux_old);
-  pcre_free (re_scientific_linux);
-  pcre_free (re_scientific_linux_no_minor);
-  pcre_free (re_oracle_linux_old);
-  pcre_free (re_oracle_linux);
-  pcre_free (re_oracle_linux_no_minor);
-  pcre_free (re_major_minor);
-  pcre_free (re_xdev);
-  pcre_free (re_cciss);
-  pcre_free (re_mdN);
-  pcre_free (re_freebsd_mbr);
-  pcre_free (re_freebsd_gpt);
-  pcre_free (re_diskbyid);
-  pcre_free (re_netbsd);
-  pcre_free (re_opensuse);
-  pcre_free (re_sles);
-  pcre_free (re_nld);
-  pcre_free (re_opensuse_version);
-  pcre_free (re_sles_version);
-  pcre_free (re_sles_patchlevel);
-  pcre_free (re_minix);
-  pcre_free (re_hurd_dev);
-}
+COMPILE_REGEXP (re_fedora, "Fedora release (\\d+)", 0)
+COMPILE_REGEXP (re_rhel_old, "Red Hat.*release (\\d+).*Update (\\d+)", 0)
+COMPILE_REGEXP (re_rhel, "Red Hat.*release (\\d+)\\.(\\d+)", 0)
+COMPILE_REGEXP (re_rhel_no_minor, "Red Hat.*release (\\d+)", 0)
+COMPILE_REGEXP (re_centos_old, "CentOS.*release (\\d+).*Update (\\d+)", 0)
+COMPILE_REGEXP (re_centos, "CentOS.*release (\\d+)\\.(\\d+)", 0)
+COMPILE_REGEXP (re_centos_no_minor, "CentOS.*release (\\d+)", 0)
+COMPILE_REGEXP (re_scientific_linux_old,
+                "Scientific Linux.*release (\\d+).*Update (\\d+)", 0)
+COMPILE_REGEXP (re_scientific_linux,
+                "Scientific Linux.*release (\\d+)\\.(\\d+)", 0)
+COMPILE_REGEXP (re_scientific_linux_no_minor,
+                "Scientific Linux.*release (\\d+)", 0)
+  COMPILE_REGEXP (re_oracle_linux_old,
+                  "Oracle Linux.*release (\\d+).*Update (\\d+)", 0)
+COMPILE_REGEXP (re_oracle_linux,
+                "Oracle Linux.*release (\\d+)\\.(\\d+)", 0)
+COMPILE_REGEXP (re_oracle_linux_no_minor, "Oracle Linux.*release (\\d+)", 0)
+COMPILE_REGEXP (re_major_minor, "(\\d+)\\.(\\d+)", 0)
+COMPILE_REGEXP (re_xdev, "^/dev/(h|s|v|xv)d([a-z]+)(\\d*)$", 0)
+COMPILE_REGEXP (re_cciss, "^/dev/(cciss/c\\d+d\\d+)(?:p(\\d+))?$", 0)
+COMPILE_REGEXP (re_mdN, "^(/dev/md\\d+)$", 0)
+COMPILE_REGEXP (re_freebsd_mbr,
+                "^/dev/(ada{0,1}|vtbd)(\\d+)s(\\d+)([a-z])$", 0)
+COMPILE_REGEXP (re_freebsd_gpt, "^/dev/(ada{0,1}|vtbd)(\\d+)p(\\d+)$", 0)
+COMPILE_REGEXP (re_diskbyid, "^/dev/disk/by-id/.*-part(\\d+)$", 0)
+COMPILE_REGEXP (re_netbsd, "^NetBSD (\\d+)\\.(\\d+)", 0)
+COMPILE_REGEXP (re_opensuse, "^(openSUSE|SuSE Linux|SUSE LINUX) ", 0)
+COMPILE_REGEXP (re_sles, "^SUSE (Linux|LINUX) Enterprise ", 0)
+COMPILE_REGEXP (re_nld, "^Novell Linux Desktop ", 0)
+COMPILE_REGEXP (re_opensuse_version, "^VERSION = (\\d+)\\.(\\d+)", 0)
+COMPILE_REGEXP (re_sles_version, "^VERSION = (\\d+)", 0)
+COMPILE_REGEXP (re_sles_patchlevel, "^PATCHLEVEL = (\\d+)", 0)
+COMPILE_REGEXP (re_minix, "^(\\d+)\\.(\\d+)(\\.(\\d+))?", 0)
+COMPILE_REGEXP (re_hurd_dev, "^/dev/(h)d(\\d+)s(\\d+)$", 0)
 
 static void check_architecture (guestfs_h *g, struct inspect_fs *fs);
 static int check_hostname_unix (guestfs_h *g, struct inspect_fs *fs);
-- 
2.1.0




More information about the Libguestfs mailing list