> Is it necessary to parse these examples?  Or maybe we can live with
> your strtonum() fix for now.
I can live with that.

> I don't know.  So unless somebody else gives us some input I'd suggest
> we move forward with your safe diff even if it doesn't fix all the
> cases.
> 
> If it fixes your use case it is already an improvement.

I have attached a strtonum() fix.
To give a short summary on how it works. 
In us == -1 cases, I locate the '%'-symbol stored page_contents[j].name
to calculate length. The length is then used to compare the function
input "name" with page_contents[j].name.

If name match, I then use "len" to position "name" to the
strtonum-function and use the return value to calculate the usage
number.

For people who want to test this patch;
hid_start()
snprintf(usage, sizeof(usage), "%s:%s",
   hid_usage_page(HID_PAGE(test_val)), 
   hid_usage_in_page(test_val));
test_val == hid_parse_usage_in_page(usage)

As mentioned earlier the usage = (16 << 16) | 0xA (16 Unicode) and
higher will fail, but 0 to 9 succeeds.

If wanted I can send the code I used to test this.

Index: usage.c
===================================================================
RCS file: /cvs/src/lib/libusbhid/usage.c,v
retrieving revision 1.16
diff -u -p -r1.16 usage.c
--- usage.c     8 Oct 2014 04:49:36 -0000       1.16
+++ usage.c     2 Jul 2018 19:51:13 -0000
@@ -264,9 +264,9 @@ hid_parse_usage_page(const char *name)
 int
 hid_parse_usage_in_page(const char *name)
 {
-       const char *sep;
+       const char *sep, *fmtsep, *errstr, *fmtname;
        unsigned int l;
-       int k, j;
+       int k, j, us, pu, len;
 
        sep = strchr(name, ':');
        if (sep == NULL)
@@ -278,9 +278,21 @@ hid_parse_usage_in_page(const char *name
        return -1;
  found:
        sep++;
-       for (j = 0; j < pages[k].pagesize; j++)
+       for (j = 0; j < pages[k].pagesize; j++) {
+               us = pages[k].page_contents[j].usage;
+               if (us == -1) {
+                       fmtname = pages[k].page_contents[j].name;
+                       fmtsep = strchr(fmtname, '%');
+                       len = fmtsep - fmtname;
+                       if (fmtsep != NULL && strncmp(sep, fmtname, len) == 0) {
+                               pu = strtonum(sep + len, 0x1, 0xFFFF, &errstr);
+                               if (errstr == NULL)
+                                       return (pages[k].usage << 16) | pu;
+                       }
+               }
                if (strcmp(pages[k].page_contents[j].name, sep) == 0)
                        return (pages[k].usage << 16) |
                            pages[k].page_contents[j].usage;
+       }
        return -1;
 }

Reply via email to