]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
utils: add utilitiy to generate list of sysnum by prefix of sysname
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sat, 2 Apr 2022 01:46:22 +0000 (10:46 +0900)
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sat, 2 Apr 2022 01:46:22 +0000 (10:46 +0900)
It's typically used to generate the list of sysnum over sysfs by sysname
prefix.

This commit adds utility for it.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
12 files changed:
src/ctl/meson.build
src/ctl/query.c
src/hwdep/meson.build
src/hwdep/query.c
src/rawmidi/meson.build
src/rawmidi/query.c
src/seq/meson.build
src/seq/query.c
src/timer/meson.build
src/timer/query.c
src/utils/sysfs.c
src/utils/utils.h

index 9e4058df73aa708b8988728aca5816ebf0ea7fd4..4dfc6f1c6c1e16195e86110b6cbeda49abb38aa2 100644 (file)
@@ -32,7 +32,6 @@ privates = files(
 
 dependencies = [
   gobject_dependency,
-  libudev_dependency,
   utils_dependencies,
 ]
 
index a06b8dc38c43824c095958239e6399225c4f8165..1b89f814e91ad3c8808ab22f8769d8901b98723e 100644 (file)
@@ -3,13 +3,6 @@
 
 #include <utils.h>
 
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdbool.h>
-
-#include <libudev.h>
-
 /**
  * SECTION: query
  * @Title: Global functions in ALSACtl
 #define generate_file_error(exception, errno, msg) \
         g_set_error_literal(exception, G_FILE_ERROR, g_file_error_from_errno(errno), msg)
 
-static void prepare_udev_enum(struct udev_enumerate **enumerator,
-                              GError **error)
-{
-    struct udev *ctx;
-    int err;
-
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        return;
-    }
-
-    *enumerator = udev_enumerate_new(ctx);
-    if (*enumerator == NULL) {
-        generate_file_error(error, errno, "udev_enumerate_new()");
-        udev_unref(ctx);
-        return;
-    }
-
-    err = udev_enumerate_add_match_subsystem(*enumerator, "sound");
-    if (err < 0) {
-        generate_file_error(error, -err, "udev_enumerate_add_match_subsystem()");
-        udev_enumerate_unref(*enumerator);
-        udev_unref(ctx);
-        return;
-    }
-
-    err = udev_enumerate_scan_devices(*enumerator);
-    if (err < 0) {
-        generate_file_error(error, -err, "udev_enumerate_scan_devices()");
-        udev_enumerate_unref(*enumerator);
-        udev_unref(ctx);
-    }
-}
-
-static struct udev_device *detect_dev(struct udev_enumerate *enumerator,
-                                      struct udev_list_entry *entry,
-                                      const char *prefix)
-{
-    struct udev *ctx = udev_enumerate_get_udev(enumerator);
-    const char *syspath;
-    struct udev_device *dev;
-    const char *sysname;
-
-    syspath = udev_list_entry_get_name(entry);
-    if (syspath == NULL)
-        return NULL;
-
-    dev = udev_device_new_from_syspath(ctx, syspath);
-    if (dev == NULL)
-        return NULL;
-
-    sysname = udev_device_get_sysname(dev);
-    if (sysname == NULL) {
-        udev_device_unref(dev);
-        return NULL;
-    }
-
-    if (strstr(sysname, prefix) != sysname) {
-        udev_device_unref(dev);
-        return NULL;
-    }
-
-    return dev;
-}
-
-static void release_udev_enum(struct udev_enumerate *enumerator)
-{
-    struct udev *ctx = udev_enumerate_get_udev(enumerator);
-
-    udev_enumerate_unref(enumerator);
-    udev_unref(ctx);
-}
-
-static int compare_guint(const void *l, const void *r)
-{
-    const guint *x = l;
-    const guint *y = r;
-
-    return *x > *y;
-}
-
 /**
  * alsactl_get_card_id_list:
  * @entries: (array length=entry_count)(out): The list of numerical ID for sound
@@ -116,58 +27,15 @@ static int compare_guint(const void *l, const void *r)
 void alsactl_get_card_id_list(guint **entries, gsize *entry_count,
                               GError **error)
 {
-    struct udev_enumerate *enumerator = NULL;
-    struct udev_list_entry *entry, *entry_list;
-    unsigned int count;
-    unsigned int index;
+    int err;
 
     g_return_if_fail(entries != NULL);
     g_return_if_fail(entry_count != NULL);
     g_return_if_fail(error == NULL || *error == NULL);
 
-    prepare_udev_enum(&enumerator, error);
-    if (*error != NULL)
-        return;
-
-    entry_list = udev_enumerate_get_list_entry(enumerator);
-
-    count = 0;
-    udev_list_entry_foreach(entry, entry_list) {
-        struct udev_device *dev = detect_dev(enumerator, entry, "card");
-        if (dev != NULL) {
-            ++count;
-            udev_device_unref(dev);
-        }
-    }
-
-    // Nothing available.
-    if (count == 0)
-        goto end;
-
-    *entries = g_malloc0_n(count, sizeof(**entries));
-
-    index = 0;
-    udev_list_entry_foreach(entry, entry_list) {
-        struct udev_device *dev = detect_dev(enumerator, entry, "card");
-        if (dev != NULL) {
-            const char *sysnum = udev_device_get_sysnum(dev);
-            long val;
-
-            if (!long_from_string(sysnum, &val)) {
-                (*entries)[index] = val;
-                ++index;
-            }
-            udev_device_unref(dev);
-        }
-    }
-
-    g_warn_if_fail(index == count);
-
-    *entry_count = count;
-
-    qsort(*entries, count, sizeof(guint), compare_guint);
-end:
-    release_udev_enum(enumerator);
+    err = generate_card_sysnum_list(entries, entry_count);
+    if (err < 0)
+        generate_file_error(error, -err, "Fail to generate list of card sysnum");
 }
 
 /**
index 8e8d3f2a436d02564318d516eb6ec8ec50b27acb..5a905335b21d07dfd4b2a3cbe21eedf4da65e194 100644 (file)
@@ -24,7 +24,6 @@ privates = files(
 
 dependencies = [
   gobject_dependency,
-  libudev_dependency,
   utils_dependencies,
 ]
 
index 942c18c71291fb42bcc9c150a1b42a573797262d..f2e61c3934974047c4d2f7bc2f13240730090760 100644 (file)
@@ -3,17 +3,12 @@
 
 #include <utils.h>
 
-#include <stdio.h>
-#include <errno.h>
-#include <stdbool.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
 
-#include <libudev.h>
-
 /**
  * SECTION: query
  * @Title: Global functions in ALSAHwdep
  *                     descriptor
  */
 
-// 'C' is required apart from emulation of Open Sound System.
-#define PREFIX_SYSNAME_TEMPLATE     "hwC%u"
-
 #define generate_file_error(error, errno, msg) \
         g_set_error_literal(error, G_FILE_ERROR, g_file_error_from_errno(errno), msg)
 
 #define generate_file_error_fmt(error, errno, fmt, msg) \
         g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno), fmt, msg)
 
-static void prepare_udev_enum(struct udev_enumerate **enumerator, GError **error)
-{
-    struct udev *ctx;
-    int err;
-
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        return;
-    }
-
-    *enumerator = udev_enumerate_new(ctx);
-    if (*enumerator == NULL) {
-        generate_file_error(error, errno, "udev_enumerate_new()");
-        udev_unref(ctx);
-        return;
-    }
-
-    err = udev_enumerate_add_match_subsystem(*enumerator, "sound");
-    if (err < 0) {
-        generate_file_error(error, -err, "udev_enumerate_add_match_subsystem()");
-        udev_enumerate_unref(*enumerator);
-        udev_unref(ctx);
-        return;
-    }
-
-    err = udev_enumerate_scan_devices(*enumerator);
-    if (err < 0) {
-        generate_file_error(error, -err, "udev_enumerate_scan_devices()");
-        udev_enumerate_unref(*enumerator);
-        udev_unref(ctx);
-    }
-}
-
-static struct udev_device *detect_dev(struct udev_enumerate *enumerator,
-                                      struct udev_list_entry *entry,
-                                      const char *prefix)
-{
-    struct udev *ctx = udev_enumerate_get_udev(enumerator);
-    const char *syspath;
-    struct udev_device *dev;
-    const char *sysname;
-
-    syspath = udev_list_entry_get_name(entry);
-    if (syspath == NULL)
-        return NULL;
-
-    dev = udev_device_new_from_syspath(ctx, syspath);
-    if (dev == NULL)
-        return NULL;
-
-    sysname = udev_device_get_sysname(dev);
-    if (sysname == NULL) {
-        udev_device_unref(dev);
-        return NULL;
-    }
-
-    if (strstr(sysname, prefix) != sysname) {
-        udev_device_unref(dev);
-        return NULL;
-    }
-
-    return dev;
-}
-
-static void release_udev_enum(struct udev_enumerate *enumerator)
-{
-    struct udev *ctx = udev_enumerate_get_udev(enumerator);
-
-    udev_enumerate_unref(enumerator);
-    udev_unref(ctx);
-}
-
-static int compare_guint(const void *l, const void *r)
-{
-    const guint *x = l;
-    const guint *y = r;
-
-    return *x > *y;
-}
-
-static unsigned int calculate_digits(unsigned int number)
-{
-    unsigned int digits = 0;
-
-    while (true) {
-        number /= 10;
-        ++digits;
-        if (number == 0)
-            break;
-    }
-
-    return digits;
-}
-
 /**
  * alsahwdep_get_device_id_list:
  * @card_id: The numerical ID of sound card.
@@ -140,66 +37,15 @@ static unsigned int calculate_digits(unsigned int number)
 void alsahwdep_get_device_id_list(guint card_id, guint **entries,
                                   gsize *entry_count, GError **error)
 {
-    struct udev_enumerate *enumerator = NULL;
-    unsigned int length;
-    char *prefix = NULL;
-    struct udev_list_entry *entry, *entry_list;
-    unsigned int count;
-    unsigned int index;
+    int err;
 
     g_return_if_fail(entries != NULL);
     g_return_if_fail(entry_count != NULL);
     g_return_if_fail(error == NULL || *error == NULL);
 
-    prepare_udev_enum(&enumerator, error);
-    if (*error != NULL)
-        return;
-
-    length = strlen(PREFIX_SYSNAME_TEMPLATE) + calculate_digits(card_id) + 1;
-    prefix = g_malloc0(length);
-
-    snprintf(prefix, length, PREFIX_SYSNAME_TEMPLATE, card_id);
-
-    entry_list = udev_enumerate_get_list_entry(enumerator);
-
-    count = 0;
-    udev_list_entry_foreach(entry, entry_list) {
-        struct udev_device *dev = detect_dev(enumerator, entry, prefix);
-        if (dev != NULL) {
-            ++count;
-            udev_device_unref(dev);
-        }
-    }
-
-    // Nothing available.
-    if (count == 0)
-        goto end;
-
-    *entries = g_malloc0_n(count, sizeof(**entries));
-
-    index = 0;
-    udev_list_entry_foreach(entry, entry_list) {
-        struct udev_device *dev = detect_dev(enumerator, entry, prefix);
-        if (dev != NULL) {
-            const char *sysnum = udev_device_get_sysnum(dev);
-            long val;
-
-            if (!long_from_string(sysnum, &val)) {
-                (*entries)[index] = (guint)val;
-                ++index;
-            }
-            udev_device_unref(dev);
-        }
-    }
-
-    g_warn_if_fail(index == count);
-
-    *entry_count = count;
-
-    qsort(*entries, count, sizeof(guint), compare_guint);
-end:
-    g_free(prefix);
-    release_udev_enum(enumerator);
+    err = generate_hwdep_sysnum_list(entries, entry_count, card_id);
+    if (err < 0)
+        generate_file_error(error, -err, "Fail to generate list of hwdep sysnum");
 }
 
 /**
index 02994070683ead4b36d6e58f26fe76b46f4285b7..1831d8c1f8debd579b3dc93f7f0d26439baf4550 100644 (file)
@@ -30,7 +30,6 @@ privates = files(
 
 dependencies = [
   gobject_dependency,
-  libudev_dependency,
   utils_dependencies,
 ]
 
index a4db8c130ba530f594e5ce9c863eaa46fe76d231..8b0e58275923fcf81d0643122b7fdae9cfd42451 100644 (file)
@@ -3,17 +3,12 @@
 
 #include <utils.h>
 
-#include <stdio.h>
-#include <errno.h>
-#include <stdbool.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
 
-#include <libudev.h>
-
 /**
  * SECTION: query
  * @Title: Global functions in ALSARawmidi
  *                     descriptor
  */
 
-// 'C' is required apart from emulation of Open Sound System.
-#define PREFIX_SYSNAME_TEMPLATE     "midiC%u"
-
 #define generate_file_error(error, errno, msg)    \
     g_set_error_literal(error, G_FILE_ERROR, g_file_error_from_errno(errno), msg)
 
 #define generate_file_error_fmt(error, errno, fmt, msg) \
     g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno), fmt, msg)
 
-static void prepare_udev_enum(struct udev_enumerate **enumerator, GError **error)
-{
-    struct udev *ctx;
-    int err;
-
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        return;
-    }
-
-    *enumerator = udev_enumerate_new(ctx);
-    if (*enumerator == NULL) {
-        generate_file_error(error, errno, "udev_enumerate_new()");
-        udev_unref(ctx);
-        return;
-    }
-
-    err = udev_enumerate_add_match_subsystem(*enumerator, "sound");
-    if (err < 0) {
-        generate_file_error(error, -err, "udev_enumerate_add_match_subsystem()");
-        udev_enumerate_unref(*enumerator);
-        udev_unref(ctx);
-        return;
-    }
-
-    err = udev_enumerate_scan_devices(*enumerator);
-    if (err < 0) {
-        generate_file_error(error, -err, "udev_enumerate_scan_devices()");
-        udev_enumerate_unref(*enumerator);
-        udev_unref(ctx);
-    }
-}
-
-static struct udev_device *detect_dev(struct udev_enumerate *enumerator,
-                                      struct udev_list_entry *entry,
-                                      const char *prefix)
-{
-    struct udev *ctx = udev_enumerate_get_udev(enumerator);
-    const char *syspath;
-    struct udev_device *dev;
-    const char *sysname;
-
-    syspath = udev_list_entry_get_name(entry);
-    if (syspath == NULL)
-        return NULL;
-
-    dev = udev_device_new_from_syspath(ctx, syspath);
-    if (dev == NULL)
-        return NULL;
-
-    sysname = udev_device_get_sysname(dev);
-    if (sysname == NULL) {
-        udev_device_unref(dev);
-        return NULL;
-    }
-
-    if (strstr(sysname, prefix) != sysname) {
-        udev_device_unref(dev);
-        return NULL;
-    }
-
-    return dev;
-}
-
-static void release_udev_enum(struct udev_enumerate *enumerator)
-{
-    struct udev *ctx = udev_enumerate_get_udev(enumerator);
-
-    udev_enumerate_unref(enumerator);
-    udev_unref(ctx);
-}
-
-static int compare_guint(const void *l, const void *r)
-{
-    const guint *x = l;
-    const guint *y = r;
-
-    return *x > *y;
-}
-
-static unsigned int calculate_digits(unsigned int number)
-{
-    unsigned int digits = 0;
-
-    while (true) {
-        number /= 10;
-        ++digits;
-        if (number == 0)
-            break;
-    }
-
-    return digits;
-}
-
 /**
  * alsarawmidi_get_device_id_list:
  * @card_id: The numerical ID of sound card.
@@ -140,66 +37,15 @@ static unsigned int calculate_digits(unsigned int number)
 void alsarawmidi_get_device_id_list(guint card_id, guint **entries,
                                     gsize *entry_count, GError **error)
 {
-    struct udev_enumerate *enumerator = NULL;
-    unsigned int length;
-    char *prefix = NULL;
-    struct udev_list_entry *entry, *entry_list;
-    unsigned int count;
-    unsigned int index;
+    int err;
 
     g_return_if_fail(entries != NULL);
     g_return_if_fail(entry_count != NULL);
     g_return_if_fail(error == NULL || *error == NULL);
 
-    prepare_udev_enum(&enumerator, error);
-    if (*error != NULL)
-        return;
-
-    length = strlen(PREFIX_SYSNAME_TEMPLATE) + calculate_digits(card_id) + 1;
-    prefix = g_malloc0(length);
-
-    snprintf(prefix, length, PREFIX_SYSNAME_TEMPLATE, card_id);
-
-    entry_list = udev_enumerate_get_list_entry(enumerator);
-
-    count = 0;
-    udev_list_entry_foreach(entry, entry_list) {
-        struct udev_device *dev = detect_dev(enumerator, entry, prefix);
-        if (dev != NULL) {
-            ++count;
-            udev_device_unref(dev);
-        }
-    }
-
-    // Nothing available.
-    if (count == 0)
-        goto end;
-
-    *entries = g_malloc0_n(count, sizeof(**entries));
-
-    index = 0;
-    udev_list_entry_foreach(entry, entry_list) {
-        struct udev_device *dev = detect_dev(enumerator, entry, prefix);
-        if (dev != NULL) {
-            const char *sysnum = udev_device_get_sysnum(dev);
-            long val;
-
-            if (!long_from_string(sysnum, &val)) {
-                (*entries)[index] = (guint)val;
-                ++index;
-            }
-            udev_device_unref(dev);
-        }
-    }
-
-    g_warn_if_fail(index == count);
-
-    *entry_count = count;
-
-    qsort(*entries, count, sizeof(guint), compare_guint);
-end:
-    g_free(prefix);
-    release_udev_enum(enumerator);
+    err = generate_rawmidi_sysnum_list(entries, entry_count, card_id);
+    if (err < 0)
+        generate_file_error(error, -err, "Fail to generate list of rawmidi sysnum");
 }
 
 /**
index 875b34ebb075acc2588076b240cea0734a6d0139..ee3b241f7f5ea4b2e5c298114866cfea777d66e8 100644 (file)
@@ -62,7 +62,6 @@ privates = files(
 
 dependencies = [
   gobject_dependency,
-  libudev_dependency,
   utils_dependencies,
   alsatimer_dependency,
 ]
index 09b640b9017784088999d5b6ab61c4ba429cbb58..8daefbacf9a035784c4b37cc3f89ac7710069468 100644 (file)
@@ -1,16 +1,13 @@
 // SPDX-License-Identifier: LGPL-3.0-or-later
 #include "privates.h"
-#include "utils.h"
 
-#include <errno.h>
+#include <utils.h>
+
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <unistd.h>
 #include <sys/ioctl.h>
-#include <stdbool.h>
-
-#include <libudev.h>
+#include <unistd.h>
 
 /**
  * SECTION: query
index a273c4eb5f79538100cd813a0c63d713304d344f..2c3a1fbd13fcf5b545f1b60568ac9e25ffcbb368 100644 (file)
@@ -44,7 +44,6 @@ privates = files(
 
 dependencies = [
   gobject_dependency,
-  libudev_dependency,
   utils_dependencies,
 ]
 
index d7e80bf527fc620c706ba3fd90d8611b8f974e38..8deba025924b1e6b1d44b38b6823a9920adc03f4 100644 (file)
@@ -3,20 +3,16 @@
 
 #include <utils.h>
 
-#include <stdio.h>
-#include <stdbool.h>
-#include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <unistd.h>
 #include <sys/ioctl.h>
+#include <unistd.h>
+#include <stdio.h>
 #include <stdbool.h>
 
 #include <time.h>
 
-#include <libudev.h>
-
 /**
  * SECTION: query
  * @Title: Global functions in ALSATimer
index d7d8306ee87fc8622d38bfcce100c1af95984e9c..c8e5b263e9738f07b406008ac6ea69d00c35e9cb 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+#include <stdlib.h>
 
 #define SOUND_SUBSYSTEM     "sound"
 
@@ -43,3 +44,131 @@ err_ctx:
     udev_unref(ctx);
     return err;
 }
+
+static int detect_device(struct udev_device **device, struct udev *ctx,
+                         struct udev_list_entry *entry, const char *prefix)
+{
+    const char *syspath;
+    struct udev_device *dev;
+    const char *sysname;
+
+    syspath = udev_list_entry_get_name(entry);
+    if (syspath == NULL)
+        return -errno;
+
+    dev = udev_device_new_from_syspath(ctx, syspath);
+    if (dev == NULL)
+        return -errno;
+
+    sysname = udev_device_get_sysname(dev);
+    if (sysname == NULL) {
+        udev_device_unref(dev);
+        return -errno;
+    }
+
+    if (strstr(sysname, prefix) != sysname) {
+        udev_device_unref(dev);
+        return -ENODEV;
+    }
+
+    *device = dev;
+
+    return 0;
+}
+
+static int compare_u32(const void *l, const void *r)
+{
+    const unsigned int *x = l;
+    const unsigned int *y = r;
+
+    return *x > *y;
+}
+
+int generate_sysnum_list_by_sysname_prefix(unsigned int **entries, unsigned long *entry_count,
+                                           const char *prefix)
+{
+    struct udev *ctx;
+    struct udev_enumerate *enumerator;
+    unsigned int count;
+    struct udev_list_entry *entry, *entry_list;
+    unsigned int index;
+    int err;
+
+    ctx = udev_new();
+    if (ctx == NULL)
+        return -errno;
+
+    enumerator = udev_enumerate_new(ctx);
+    if (enumerator == NULL) {
+        err = -errno;
+        goto err_ctx;
+    }
+
+    err = udev_enumerate_add_match_subsystem(enumerator, SOUND_SUBSYSTEM);
+    if (err < 0) {
+        goto err_enum;
+    }
+
+    err = udev_enumerate_scan_devices(enumerator);
+    if (err < 0)
+        goto err_enum;
+
+    count = 0;
+    entry_list = udev_enumerate_get_list_entry(enumerator);
+    udev_list_entry_foreach(entry, entry_list) {
+        struct udev_device *dev;
+        int err;
+
+        err = detect_device(&dev, ctx, entry, prefix);
+        if (err < 0)
+            continue;
+
+         ++count;
+         udev_device_unref(dev);
+    }
+
+    // Nothing available.
+    if (count == 0)
+        goto err_enum;
+
+    *entries = calloc(count, sizeof(**entries));
+    if (*entries == NULL) {
+        err = -ENOMEM;
+        goto err_enum;
+    }
+
+    index = 0;
+    udev_list_entry_foreach(entry, entry_list) {
+        struct udev_device *dev;
+        const char *sysnum;
+        long val;
+        int err;
+
+        err = detect_device(&dev, ctx, entry, prefix);
+        if (err < 0)
+            continue;
+
+        sysnum = udev_device_get_sysnum(dev);
+        if (sysnum != NULL && !long_from_string(sysnum, &val)) {
+            (*entries)[index] = (unsigned int)val;
+            ++index;
+        }
+
+        udev_device_unref(dev);
+    }
+
+    if (index != count) {
+        err = -ENODATA;
+        goto err_enum;
+    }
+
+    *entry_count = count;
+
+    qsort(*entries, count, sizeof(unsigned int), compare_u32);
+err_enum:
+    udev_enumerate_unref(enumerator);
+err_ctx:
+    udev_unref(ctx);
+
+    return err;
+}
index 051e30d709c52f299318fe9a49f4096bc85c2ac9..a3861d616b13098704aff4435043b9f26cddde35 100644 (file)
@@ -6,10 +6,15 @@
 #include <stdarg.h>
 #include <libudev.h>
 
-#define CARD_SYSNAME_TEMPLATE           "card%u"
+#define CARD_SYSNAME_PREFIX             "card"
+#define CARD_SYSNAME_TEMPLATE           CARD_SYSNAME_PREFIX "%u"
 #define CONTROL_SYSNAME_TEMPLATE        "controlC%u"
-#define RAWMIDI_SYSNAME_TEMPLATE        "midiC%uD%u"
-#define HWDEP_SYSNAME_TEMPLATE          "hwC%uD%u"
+// 'C' is required apart from emulation of Open Sound System.
+#define RAWMIDI_SYSNAME_PREFIX_TEMPLATE "midiC%u"
+#define RAWMIDI_SYSNAME_TEMPLATE        RAWMIDI_SYSNAME_PREFIX_TEMPLATE "D%u"
+// 'C' is required apart from emulation of Open Sound System.
+#define HWDEP_SYSNAME_PREFIX_TEMPLATE   "hwC%u"
+#define HWDEP_SYSNAME_TEMPLATE          HWDEP_SYSNAME_PREFIX_TEMPLATE "D%u"
 #define TIMER_SYSNAME                   "timer"
 #define SEQ_SYSNAME                     "seq"
 
@@ -20,6 +25,9 @@ int allocate_string(char **dst, const char *template, va_list ap);
 int lookup_and_allocate_string_by_sysname(char **name, const char *sysname,
                                           const char *(*func)(struct udev_device *));
 
+int generate_sysnum_list_by_sysname_prefix(unsigned int **entries, unsigned long *entry_count,
+                                           const char *prefix);
+
 static inline int lookup_and_allocate_name_by_sysname(char **name,
                                                       const char *(*func)(struct udev_device *),
                                                       const char *fmt, va_list ap)
@@ -121,4 +129,39 @@ static inline int lookup_and_allocate_seq_devname(char **devname)
     return lookup_and_allocate_devname_by_sysname(devname, SEQ_SYSNAME);
 }
 
+static inline int generate_sysnum_list(unsigned int **entries, unsigned long *entry_count,
+                                       const char *fmt, ...)
+{
+    char *prefix;
+    va_list ap;
+    int err;
+
+    va_start(ap, fmt);
+    err = allocate_string(&prefix, fmt, ap);
+    va_end(ap);
+
+    if (err >= 0)
+        err = generate_sysnum_list_by_sysname_prefix(entries, entry_count, prefix);
+    free(prefix);
+
+    return err;
+}
+
+static inline int generate_card_sysnum_list(unsigned int **entries, unsigned long *entry_count)
+{
+    return generate_sysnum_list(entries, entry_count, CARD_SYSNAME_PREFIX);
+}
+
+static inline int generate_hwdep_sysnum_list(unsigned int **entries, unsigned long *entry_count,
+                                             unsigned int card_id)
+{
+    return generate_sysnum_list(entries, entry_count, HWDEP_SYSNAME_PREFIX_TEMPLATE, card_id);
+}
+
+static inline int generate_rawmidi_sysnum_list(unsigned int **entries, unsigned long *entry_count,
+                                               unsigned int card_id)
+{
+    return generate_sysnum_list(entries, entry_count, RAWMIDI_SYSNAME_PREFIX_TEMPLATE, card_id);
+}
+
 #endif