summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2020-11-09 21:30:36 +0100
committerAleksander Morgado <aleksander@aleksander.es>2020-11-14 13:39:40 +0000
commit6e642418bb36c627b9ad6185b36f78216ecaccfe (patch)
tree94f6eb6c9173534bb86aa269d3bd4e7490a0ff63
parentcca83392f09a2a67178203d493656c4355863106 (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.c57
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;
}