Don't return a static buffer in public API
[platform/upstream/libxkbcommon.git] / src / keysym.c
index 4738fc2..9fd3764 100644 (file)
@@ -37,19 +37,25 @@ authorization from the authors.
 
 #include "ks_tables.h"
 
-char *
-XkbcKeysymToString(KeySym ks)
+void
+xkb_keysym_to_string(uint32_t ks, char *buffer, size_t size)
 {
     int i, n, h, idx;
     const unsigned char *entry;
     unsigned char val1, val2, val3, val4;
 
-    if (!ks || (ks & ((unsigned long) ~0x1fffffff)) != 0)
-        return NULL;
+    if ((ks & ((unsigned long) ~0x1fffffff)) != 0) {
+        snprintf(buffer, size, "Invalid");
+        return;
+    }
 
-    if (ks == XK_VoidSymbol)
-        ks = 0;
+    /* Not listed in keysymdef.h for hysterical raisins. */
+    if (ks == NoSymbol) {
+        snprintf(buffer, size, "NoSymbol");
+        return;
+    }
 
+    /* Try to find it in our hash table. */
     if (ks <= 0x1fffffff) {
         val1 = ks >> 24;
         val2 = (ks >> 16) & 0xff;
@@ -63,8 +69,10 @@ XkbcKeysymToString(KeySym ks)
             entry = &_XkeyTable[idx];
 
             if ((entry[0] == val1) && (entry[1] == val2) &&
-                (entry[2] == val3) && (entry[3] == val4))
-                return ((char *)entry + 4);
+                (entry[2] == val3) && (entry[3] == val4)) {
+               snprintf(buffer, size, "%s", entry + 4);
+               return;
+           }
 
             if (!--n)
                 break;
@@ -75,46 +83,23 @@ XkbcKeysymToString(KeySym ks)
         }
     }
 
-    if (ks >= 0x01000100 && ks <= 0x0110ffff) {
-        KeySym val = ks & 0xffffff;
-        char *s;
-        int i;
-
-        if (val & 0xff0000)
-            i = 10;
-        else
-            i = 6;
-
-        s = malloc(i);
-        if (!s)
-            return s;
-
-        i--;
-        s[i--] = '\0';
-        for (; i; i--) {
-            val1 = val & 0xf;
-            val >>= 4;
-            if (val1 < 10)
-                s[i] = '0' + val1;
-            else
-                s[i] = 'A' + val1 - 10;
-        }
-        s[i] = 'U';
-        return s;
-    }
-
-    return NULL;
+    if (ks >= 0x01000100 && ks <= 0x0110ffff)
+       /* Unnamed Unicode codepoint. */
+        snprintf(buffer, size, "U%lx", ks & 0xffffffUL);
+    else
+       /* Unnamed, non-Unicode, symbol (shouldn't generally happen). */
+       snprintf(buffer, size, "0x%08x", ks);
 }
 
-KeySym
-XkbcStringToKeysym(const char *s)
+uint32_t
+xkb_string_to_keysym(const char *s)
 {
     int i, n, h, c, idx;
     unsigned long sig = 0;
     const char *p = s;
     const unsigned char *entry;
     unsigned char sig1, sig2;
-    KeySym val;
+    uint32_t val;
 
     while ((c = *p++))
         sig = (sig << 1) + c;
@@ -147,30 +132,19 @@ XkbcStringToKeysym(const char *s)
     }
 
     if (*s == 'U') {
-        val = 0;
-
-        for (p = &s[1]; *p; p++) {
-            c = *p;
-
-            if ('0' <= c && c <= '9')
-                val = (val << 4) + c - '0';
-            else if ('a' <= c && c <= 'f')
-                val = (val << 4) + c - 'a' + 10;
-            else if ('A' <= c && c <= 'F')
-                val = (val << 4) + c - 'A' + 10;
-            else
-                return NoSymbol;
-
-            if (val > 0x10ffff)
-                return NoSymbol;
-        }
+        val = strtoul(&s[1], NULL, 16);
 
         if (val < 0x20 || (val > 0x7e && val < 0xa0))
             return NoSymbol;
         if (val < 0x100)
             return val;
+        if (val > 0x10ffff)
+            return NoSymbol;
         return val | 0x01000000;
     }
+    else if (s[0] == '0' && s[1] == 'x') {
+        return strtoul(&s[2], NULL, 16);
+    }
 
     return NoSymbol;
 }