OSDN Git Service

seqmid: restore sequencer address prefix match feature
authorClemens Ladisch <clemens@ladisch.de>
Mon, 13 May 2013 19:16:36 +0000 (21:16 +0200)
committerClemens Ladisch <clemens@ladisch.de>
Mon, 13 May 2013 19:16:36 +0000 (21:16 +0200)
Commit 19892334499e (seq: Fix for snd_seq_parse_address()) removed the
ability to match sequencer client names by any of by their prefixes in
an attempt to avoid wrong matches when one client name is the prefix of
another.

However, the prefix match feature was documented and actually used.

Allow prefixes to match, but only if there is no exact match.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
src/seq/seqmid.c

index 7d8bf1a..23c2a3d 100644 (file)
@@ -383,13 +383,8 @@ int snd_seq_sync_output_queue(snd_seq_t *seq)
  * digit numbers.
  * Actually \a arg need to be only a prefix of the wanted client.
  * That is, if a client named "Foobar XXL Master 2012" with number 128 is available,
- * then parsing "Foobar" will return the address 128:0.
- * However parsing is biased towards small client numbers,
- * thus if also a client named "Foobar" with number 129 exists,
- * then parsing will still yield address 128:0 and not 129:0.
- * If you want be able to access all clients by prefixes
- * then you must write your own parser that checks for matching client names
- * in the order of increasing name lengths.
+ * then parsing "Foobar" will return the address 128:0 if no other client is
+ * an exact match.
  */
 int snd_seq_parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, const char *arg)
 {
@@ -421,14 +416,24 @@ int snd_seq_parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, const char *arg)
                        return -EINVAL;
                if (len <= 0)
                        return -EINVAL;
+               client = -1;
                cinfo.client = -1;
                while (snd_seq_query_next_client(seq, &cinfo) >= 0) {
-                       if ((strlen(cinfo.name) == (size_t)len) &&
-                               ! strncmp(arg, cinfo.name, len)) {
-                               addr->client = cinfo.client;
-                               return 0;
+                       if (!strncmp(arg, cinfo.name, len)) {
+                               if (strlen(cinfo.name) == (size_t)len) {
+                                       /* exact match */
+                                       addr->client = cinfo.client;
+                                       return 0;
+                               }
+                               if (client < 0)
+                                       client = cinfo.client;
                        }
                }
+               if (client >= 0) {
+                       /* prefix match */
+                       addr->client = client;
+                       return 0;
+               }
                return -ENOENT; /* not found */
        }
        return 0;