Commit 651e1dab04cc4ecb67b9e7c83d634fd34c0723b6

Ran Benita 2012-08-31T18:47:28

atom: separate lookup logic from atom_intern This would allow us to add a non-interning xkb_atom_lookup function. Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/src/atom.c b/src/atom.c
index a8dc7d2..b5521ab 100644
--- a/src/atom.c
+++ b/src/atom.c
@@ -139,24 +139,16 @@ atom_strdup(struct atom_table *table, xkb_atom_t atom)
     return strdup_safe(atom_text(table, atom));
 }
 
-/*
- * If steal is true, we do not strdup @string; therefore it must be
- * dynamically allocated, not be free'd by the caller and not be used
- * afterwards. Use to avoid some redundant allocations.
- */
-xkb_atom_t
-atom_intern(struct atom_table *table, const char *string,
-            bool steal)
+static bool
+find_node_pointer(struct atom_table *table, const char *string,
+                  struct atom_node ***np_out, unsigned int *fingerprint_out)
 {
     struct atom_node **np;
-    struct atom_node *nd;
     unsigned i;
     int comp;
     unsigned int fp = 0;
     size_t len;
-
-    if (!string)
-        return XKB_ATOM_NONE;
+    bool found = false;
 
     len = strlen(string);
     np = &table->root;
@@ -166,10 +158,12 @@ atom_intern(struct atom_table *table, const char *string,
     }
 
     while (*np) {
-        if (fp < (*np)->fingerprint)
+        if (fp < (*np)->fingerprint) {
             np = &((*np)->left);
-        else if (fp > (*np)->fingerprint)
+        }
+        else if (fp > (*np)->fingerprint) {
             np = &((*np)->right);
+        }
         else {
             /* now start testing the strings */
             comp = strncmp(string, (*np)->string, len);
@@ -180,13 +174,39 @@ atom_intern(struct atom_table *table, const char *string,
                 np = &((*np)->right);
             }
             else {
-                if (steal)
-                    free(UNCONSTIFY(string));
-                return (*np)->atom;
+                found = true;
+                break;
             }
         }
     }
 
+    *fingerprint_out = fp;
+    *np_out = np;
+    return found;
+}
+
+/*
+ * If steal is true, we do not strdup @string; therefore it must be
+ * dynamically allocated, not be free'd by the caller and not be used
+ * afterwards. Use to avoid some redundant allocations.
+ */
+xkb_atom_t
+atom_intern(struct atom_table *table, const char *string,
+            bool steal)
+{
+    struct atom_node **np;
+    struct atom_node *nd;
+    unsigned int fp;
+
+    if (!string)
+        return XKB_ATOM_NONE;
+
+    if (find_node_pointer(table, string, &np, &fp)) {
+        if (steal)
+            free(UNCONSTIFY(string));
+        return (*np)->atom;
+    }
+
     nd = malloc(sizeof(*nd));
     if (!nd)
         return XKB_ATOM_NONE;