[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Libguestfs] [PATCH 4/5] inspect: Don't assume number of captures in match functions



It is possible for the pcre library to return a variable number of captures for
a single regular expression. e.g.:

  ^/dev/(cciss/c\d+d\d+)(?:p(\d+))?$

This will return either 1 or 2 captures depending on whether the device has a
partition suffix. The current match wrappers don't allow for this, and require
that a predictable number of matches are returned.

This change updates match, match1, match2, and match3 to ignore the specific
number of matches returned. Instead, any returned captures are assigned to the
given arguments, and any remaining arguments are set to NULL.
---
 src/match.c |   43 +++++++++++++------------------------------
 1 files changed, 13 insertions(+), 30 deletions(-)

diff --git a/src/match.c b/src/match.c
index 68b2d4b..6038e41 100644
--- a/src/match.c
+++ b/src/match.c
@@ -39,12 +39,6 @@ guestfs___match (guestfs_h *g, const char *str, const pcre *re)
   r = pcre_exec (re, NULL, str, len, 0, 0, vec, sizeof vec / sizeof vec[0]);
   if (r == PCRE_ERROR_NOMATCH)
     return 0;
-  if (r != 1) {
-    /* Internal error -- should not happen. */
-    warning (g, "%s: %s: pcre_exec returned unexpected error code %d when matching against the string \"%s\"\n",
-             __FILE__, __func__, r, str);
-    return 0;
-  }
 
   return 1;
 }
@@ -62,14 +56,8 @@ guestfs___match1 (guestfs_h *g, const char *str, const pcre *re)
   r = pcre_exec (re, NULL, str, len, 0, 0, vec, sizeof vec / sizeof vec[0]);
   if (r == PCRE_ERROR_NOMATCH)
     return NULL;
-  if (r != 2) {
-    /* Internal error -- should not happen. */
-    warning (g, "%s: %s: internal error: pcre_exec returned unexpected error code %d when matching against the string \"%s\"",
-             __FILE__, __func__, r, str);
-    return NULL;
-  }
 
-  return safe_strndup (g, &str[vec[2]], vec[3]-vec[2]);
+  return r == 2 ? safe_strndup (g, &str[vec[2]], vec[3]-vec[2]) : NULL;
 }
 
 /* Match a regular expression which contains exactly two captures. */
@@ -83,15 +71,12 @@ guestfs___match2 (guestfs_h *g, const char *str, const pcre *re,
   r = pcre_exec (re, NULL, str, len, 0, 0, vec, 30);
   if (r == PCRE_ERROR_NOMATCH)
     return 0;
-  if (r != 3) {
-    /* Internal error -- should not happen. */
-    warning (g, "%s: %s: internal error: pcre_exec returned unexpected error code %d when matching against the string \"%s\"",
-             __FILE__, __func__, r, str);
-    return 0;
-  }
 
-  *ret1 = safe_strndup (g, &str[vec[2]], vec[3]-vec[2]);
-  *ret2 = safe_strndup (g, &str[vec[4]], vec[5]-vec[4]);
+  *ret1 = NULL;
+  *ret2 = NULL;
+
+  if (r > 1) *ret1 = safe_strndup (g, &str[vec[2]], vec[3]-vec[2]);
+  if (r > 2) *ret2 = safe_strndup (g, &str[vec[4]], vec[5]-vec[4]);
 
   return 1;
 }
@@ -107,16 +92,14 @@ guestfs___match3 (guestfs_h *g, const char *str, const pcre *re,
   r = pcre_exec (re, NULL, str, len, 0, 0, vec, 30);
   if (r == PCRE_ERROR_NOMATCH)
     return 0;
-  if (r != 4) {
-    /* Internal error -- should not happen. */
-    warning (g, "%s: %s: internal error: pcre_exec returned unexpected error code %d when matching against the string \"%s\"",
-             __FILE__, __func__, r, str);
-    return 0;
-  }
 
-  *ret1 = safe_strndup (g, &str[vec[2]], vec[3]-vec[2]);
-  *ret2 = safe_strndup (g, &str[vec[4]], vec[5]-vec[4]);
-  *ret3 = safe_strndup (g, &str[vec[6]], vec[7]-vec[6]);
+  *ret1 = NULL;
+  *ret2 = NULL;
+  *ret3 = NULL;
+
+  if (r > 1) *ret1 = safe_strndup (g, &str[vec[2]], vec[3]-vec[2]);
+  if (r > 2) *ret2 = safe_strndup (g, &str[vec[4]], vec[5]-vec[4]);
+  if (r > 3) *ret3 = safe_strndup (g, &str[vec[6]], vec[7]-vec[6]);
 
   return 1;
 }

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]