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>master
parent
f205d0f9b6
commit
651e1dab04
76
src/atom.c
76
src/atom.c
|
@ -139,6 +139,52 @@ atom_strdup(struct atom_table *table, xkb_atom_t atom)
|
|||
return strdup_safe(atom_text(table, atom));
|
||||
}
|
||||
|
||||
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;
|
||||
unsigned i;
|
||||
int comp;
|
||||
unsigned int fp = 0;
|
||||
size_t len;
|
||||
bool found = false;
|
||||
|
||||
len = strlen(string);
|
||||
np = &table->root;
|
||||
for (i = 0; i < (len + 1) / 2; i++) {
|
||||
fp = fp * 27 + string[i];
|
||||
fp = fp * 27 + string[len - 1 - i];
|
||||
}
|
||||
|
||||
while (*np) {
|
||||
if (fp < (*np)->fingerprint) {
|
||||
np = &((*np)->left);
|
||||
}
|
||||
else if (fp > (*np)->fingerprint) {
|
||||
np = &((*np)->right);
|
||||
}
|
||||
else {
|
||||
/* now start testing the strings */
|
||||
comp = strncmp(string, (*np)->string, len);
|
||||
if (comp < 0 || (comp == 0 && len < strlen((*np)->string))) {
|
||||
np = &((*np)->left);
|
||||
}
|
||||
else if (comp > 0) {
|
||||
np = &((*np)->right);
|
||||
}
|
||||
else {
|
||||
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
|
||||
|
@ -150,42 +196,16 @@ atom_intern(struct atom_table *table, const char *string,
|
|||
{
|
||||
struct atom_node **np;
|
||||
struct atom_node *nd;
|
||||
unsigned i;
|
||||
int comp;
|
||||
unsigned int fp = 0;
|
||||
size_t len;
|
||||
unsigned int fp;
|
||||
|
||||
if (!string)
|
||||
return XKB_ATOM_NONE;
|
||||
|
||||
len = strlen(string);
|
||||
np = &table->root;
|
||||
for (i = 0; i < (len + 1) / 2; i++) {
|
||||
fp = fp * 27 + string[i];
|
||||
fp = fp * 27 + string[len - 1 - i];
|
||||
}
|
||||
|
||||
while (*np) {
|
||||
if (fp < (*np)->fingerprint)
|
||||
np = &((*np)->left);
|
||||
else if (fp > (*np)->fingerprint)
|
||||
np = &((*np)->right);
|
||||
else {
|
||||
/* now start testing the strings */
|
||||
comp = strncmp(string, (*np)->string, len);
|
||||
if (comp < 0 || (comp == 0 && len < strlen((*np)->string))) {
|
||||
np = &((*np)->left);
|
||||
}
|
||||
else if (comp > 0) {
|
||||
np = &((*np)->right);
|
||||
}
|
||||
else {
|
||||
if (find_node_pointer(table, string, &np, &fp)) {
|
||||
if (steal)
|
||||
free(UNCONSTIFY(string));
|
||||
return (*np)->atom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nd = malloc(sizeof(*nd));
|
||||
if (!nd)
|
||||
|
|
Loading…
Reference in New Issue