diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2020-11-09 21:30:36 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2020-11-14 13:39:40 +0000 |
commit | 6e642418bb36c627b9ad6185b36f78216ecaccfe (patch) | |
tree | 94f6eb6c9173534bb86aa269d3bd4e7490a0ff63 | |
parent | cca83392f09a2a67178203d493656c4355863106 (diff) |
kerneldevice,generic: use regex to implement string matching
Instead of the custom simple implementation which only supported the
'*' modifier in the pattern. This allows us to support e.g. attribute
value matches like e.g. 'DATA[0-9]*_CNTL'.
-rw-r--r-- | src/kerneldevice/mm-kernel-device-generic.c | 57 |
1 files changed, 24 insertions, 33 deletions
diff --git a/src/kerneldevice/mm-kernel-device-generic.c b/src/kerneldevice/mm-kernel-device-generic.c index 3b9956b2..90228f17 100644 --- a/src/kerneldevice/mm-kernel-device-generic.c +++ b/src/kerneldevice/mm-kernel-device-generic.c @@ -666,39 +666,30 @@ kernel_device_cmp (MMKernelDevice *a, /*****************************************************************************/ static gboolean -string_match (const gchar *str, - const gchar *original_pattern) +string_match (MMKernelDeviceGeneric *self, + const gchar *str, + const gchar *pattern) { - gchar *pattern; - gchar *start; - gboolean open_prefix = FALSE; - gboolean open_suffix = FALSE; - gboolean match; - - pattern = g_strdup (original_pattern); - start = pattern; - - if (start[0] == '*') { - open_prefix = TRUE; - start++; - } + g_autoptr(GError) inner_error = NULL; + g_autoptr(GRegex) regex = NULL; + g_autoptr(GMatchInfo) match_info = NULL; - if (start[strlen (start) - 1] == '*') { - open_suffix = TRUE; - start[strlen (start) - 1] = '\0'; + regex = g_regex_new (pattern, 0, 0, &inner_error); + if (!regex) { + mm_obj_warn (self, "invalid pattern in rule '%s': %s", pattern, inner_error->message); + return FALSE; + } + g_regex_match_full (regex, str, -1, 0, 0, &match_info, &inner_error); + if (inner_error) { + mm_obj_warn (self, "couldn't apply pattern match in rule '%s': %s", pattern, inner_error->message); + return FALSE; } - if (open_suffix && !open_prefix) - match = g_str_has_prefix (str, start); - else if (!open_suffix && open_prefix) - match = g_str_has_suffix (str, start); - else if (open_suffix && open_prefix) - match = !!strstr (str, start); - else - match = g_str_equal (str, start); + if (!g_match_info_matches (match_info)) + return FALSE; - g_free (pattern); - return match; + mm_obj_dbg (self, "pattern '%s' matched: '%s'", pattern, str); + return TRUE; } static gboolean @@ -731,7 +722,7 @@ check_condition (MMKernelDeviceGeneric *self, /* Device name checks */ if (g_str_equal (match->parameter, "KERNEL")) - return (string_match (mm_kernel_device_get_name (MM_KERNEL_DEVICE (self)), match->value) == condition_equal); + return (string_match (self, mm_kernel_device_get_name (MM_KERNEL_DEVICE (self)), match->value) == condition_equal); /* Device sysfs path checks; we allow both a direct match and a prefix patch */ if (g_str_equal (match->parameter, "DEVPATH")) { @@ -748,22 +739,22 @@ check_condition (MMKernelDeviceGeneric *self, if (match->value[0] && match->value[strlen (match->value) - 1] != '*') prefix_match = g_strdup_printf ("%s/*", match->value); - if (string_match (self->priv->sysfs_path, match->value) == condition_equal) { + if (string_match (self, self->priv->sysfs_path, match->value) == condition_equal) { result = TRUE; goto out; } - if (prefix_match && string_match (self->priv->sysfs_path, prefix_match) == condition_equal) { + if (prefix_match && string_match (self, self->priv->sysfs_path, prefix_match) == condition_equal) { result = TRUE; goto out; } if (g_str_has_prefix (self->priv->sysfs_path, "/sys")) { - if (string_match (&self->priv->sysfs_path[4], match->value) == condition_equal) { + if (string_match (self, &self->priv->sysfs_path[4], match->value) == condition_equal) { result = TRUE; goto out; } - if (prefix_match && string_match (&self->priv->sysfs_path[4], prefix_match) == condition_equal) { + if (prefix_match && string_match (self, &self->priv->sysfs_path[4], prefix_match) == condition_equal) { result = TRUE; goto out; } |