mdev: optional support for regex pattern group substitution.
authorDenis Vlasenko <vda.linux@googlemail.com>
Sat, 29 Mar 2008 17:26:10 +0000 (17:26 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sat, 29 Mar 2008 17:26:10 +0000 (17:26 -0000)
+142 bytes.

testsuite/mdev.tests
util-linux/Config.in
util-linux/mdev.c

index 777c5c540b060e292a082fe893f5ad059cde25d7..81c440d1f050576dbfe1198cd5475d98e1c78756 100755 (executable)
@@ -76,6 +76,23 @@ br--r--r-- 1 0 0 sda
 " \
        "" ""
 
+# continuing to use directory structure from prev test
+rm -rf mdev.testdir/dev/*
+# here we complicate things by having non-matching group 1 and using %0
+echo "s([0-9])*d([a-z]+) 0:0 644 >sd/%2_%0" >mdev.testdir/etc/mdev.conf
+testing "mdev regexp substring match + replace" \
+       "env - ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1;
+       ls -lnR mdev.testdir/dev | $FILTER_LS2" \
+"\
+mdev.testdir/dev:
+drwxr-xr-x 2 0 0 sd
+lrwxrwxrwx 1 0 0 sda -> sd/a_sda
+
+mdev.testdir/dev/sd:
+brw-r--r-- 1 0 0 a_sda
+" \
+       "" ""
+
 # clean up
 rm -rf mdev.testdir
 
index 1f4322bec659e989bbf8c4703215731ee585d009..869ec61d5fdcae3f7698a06e287c30eaae671bcb 100644 (file)
@@ -321,6 +321,13 @@ config FEATURE_MDEV_RENAME
 
          For more information, please see docs/mdev.txt
 
+config FEATURE_MDEV_RENAME_REGEXP
+       bool "Support regular expressions substitutions when renaming device"
+       default n
+       depends on FEATURE_MDEV_RENAME
+       help
+         Add support for regular expressions substitutions when renaming device.
+
 config FEATURE_MDEV_EXEC
        bool "Support command execution at device addition/removal"
        default n
index c8d603bcfcc9875bab68d3a4f5beca7c5d479bfc..9d77f6a1fb4907b8d37e22f309ea308cf5ba3a99 100644 (file)
@@ -84,6 +84,8 @@ static void make_device(char *path, int delete)
                        goto end_parse;
 
                while ((line = xmalloc_fgetline(fp)) != NULL) {
+                       regmatch_t off[1+9*ENABLE_FEATURE_MDEV_RENAME_REGEXP];
+
                        ++lineno;
                        trim(line);
                        if (!line[0])
@@ -95,16 +97,24 @@ static void make_device(char *path, int delete)
                        next = next_field(line);
                        {
                                regex_t match;
-                               regmatch_t off;
                                int result;
 
                                /* Is this it? */
                                xregcomp(&match, line, REG_EXTENDED);
-                               result = regexec(&match, device_name, 1, &off, 0);
+                               result = regexec(&match, device_name, ARRAY_SIZE(off), off, 0);
                                regfree(&match);
 
+                               //bb_error_msg("matches:");
+                               //for (int i = 0; i < ARRAY_SIZE(off); i++) {
+                               //      if (off[i].rm_so < 0) continue;
+                               //      bb_error_msg("match %d: '%.*s'\n", i,
+                               //              (int)(off[i].rm_eo - off[i].rm_so),
+                               //              device_name + off[i].rm_so);
+                               //}
+
                                /* If not this device, skip rest of line */
-                               if (result || off.rm_so || off.rm_eo != strlen(device_name))
+                               /* (regexec returns whole pattern as "range" 0) */
+                               if (result || off[0].rm_so || off[0].rm_eo != strlen(device_name))
                                        goto next_line;
                        }
 
@@ -152,7 +162,35 @@ static void make_device(char *path, int delete)
                                val = next;
                                next = next_field(val);
                                if (*val == '>') {
+#if ENABLE_FEATURE_MDEV_RENAME_REGEXP
+                                       /* substitute %1..9 with off[1..9], if any */
+                                       char *s, *p;
+                                       unsigned i, n;
+
+                                       n = 0;
+                                       s = val;
+                                       while (*s && *s++ == '%')
+                                               n++;
+                                       
+                                       p = alias = xzalloc(strlen(val) + n * strlen(device_name));
+                                       s = val + 1;
+                                       while (*s) {
+                                               *p = *s;
+                                               if ('%' == *s) {
+                                                       i = (s[1] - '0');
+                                                       if (i <= 9 && off[i].rm_so >= 0) {
+                                                               n = off[i].rm_eo - off[i].rm_so;
+                                                               strncpy(p, device_name + off[i].rm_so, n);
+                                                               p += n - 1;
+                                                               s++;
+                                                       }
+                                               }
+                                               p++;
+                                               s++;
+                                       }
+#else
                                        alias = xstrdup(val + 1);
+#endif
                                }
                        }