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>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
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;