str_map::key_cmp -> str_map::key_xfrm
It seemed to be almost too easy to be true, and it actually was. Now it should work.
This commit is contained in:
parent
996e0912c2
commit
d28b722489
52
src/common.c
52
src/common.c
@ -578,10 +578,9 @@ struct str_map
|
|||||||
size_t len; ///< Number of entries in the table
|
size_t len; ///< Number of entries in the table
|
||||||
void (*free) (void *); ///< Callback to destruct the payload
|
void (*free) (void *); ///< Callback to destruct the payload
|
||||||
|
|
||||||
/// Callback to compare keys for equivalence
|
/// Callback that transforms all key values for storage and comparison;
|
||||||
// FIXME: they may still end up on a different index, and actually should;
|
/// has to behave exactly like strxfrm().
|
||||||
// delete this callback and put strxfrm() in its place
|
size_t (*key_xfrm) (char *dest, const char *src, size_t n);
|
||||||
int (*key_cmp) (const char *, const char *);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// As long as you don't remove the current entry, you can modify the map.
|
// As long as you don't remove the current entry, you can modify the map.
|
||||||
@ -604,7 +603,7 @@ str_map_init (struct str_map *self)
|
|||||||
self->alloc = STR_MAP_MIN_ALLOC;
|
self->alloc = STR_MAP_MIN_ALLOC;
|
||||||
self->len = 0;
|
self->len = 0;
|
||||||
self->free = NULL;
|
self->free = NULL;
|
||||||
self->key_cmp = strcmp;
|
self->key_xfrm = NULL;
|
||||||
self->map = xcalloc (self->alloc, sizeof *self->map);
|
self->map = xcalloc (self->alloc, sizeof *self->map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,13 +697,13 @@ str_map_resize (struct str_map *self, size_t new_size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
str_map_set (struct str_map *self, const char *key, void *value)
|
str_map_set_real (struct str_map *self, const char *key, void *value)
|
||||||
{
|
{
|
||||||
uint64_t pos = str_map_pos (self, key);
|
uint64_t pos = str_map_pos (self, key);
|
||||||
struct str_map_link *iter = self->map[pos];
|
struct str_map_link *iter = self->map[pos];
|
||||||
for (; iter; iter = iter->next)
|
for (; iter; iter = iter->next)
|
||||||
{
|
{
|
||||||
if (self->key_cmp (key, iter->key))
|
if (strcmp (key, iter->key))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Storing the same data doesn't destroy it
|
// Storing the same data doesn't destroy it
|
||||||
@ -748,16 +747,40 @@ str_map_set (struct str_map *self, const char *key, void *value)
|
|||||||
self->len++;
|
self->len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
str_map_set (struct str_map *self, const char *key, void *value)
|
||||||
|
{
|
||||||
|
if (!self->key_xfrm)
|
||||||
|
{
|
||||||
|
str_map_set_real (self, key, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char tmp[self->key_xfrm (NULL, key, 0) + 1];
|
||||||
|
self->key_xfrm (tmp, key, sizeof tmp);
|
||||||
|
str_map_set_real (self, tmp, value);
|
||||||
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
str_map_find (struct str_map *self, const char *key)
|
str_map_find_real (struct str_map *self, const char *key)
|
||||||
{
|
{
|
||||||
struct str_map_link *iter = self->map[str_map_pos (self, key)];
|
struct str_map_link *iter = self->map[str_map_pos (self, key)];
|
||||||
for (; iter; iter = iter->next)
|
for (; iter; iter = iter->next)
|
||||||
if (!self->key_cmp (key, (const char *) iter + sizeof *iter))
|
if (!strcmp (key, (const char *) iter + sizeof *iter))
|
||||||
return iter->data;
|
return iter->data;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
str_map_find (struct str_map *self, const char *key)
|
||||||
|
{
|
||||||
|
if (!self->key_xfrm)
|
||||||
|
return str_map_find_real (self, key);
|
||||||
|
|
||||||
|
char tmp[self->key_xfrm (NULL, key, 0) + 1];
|
||||||
|
self->key_xfrm (tmp, key, sizeof tmp);
|
||||||
|
return str_map_find_real (self, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
// --- File descriptor utilities -----------------------------------------------
|
// --- File descriptor utilities -----------------------------------------------
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1727,7 +1750,7 @@ irc_process_buffer (struct str *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
irc_tolower (char c)
|
irc_tolower (int c)
|
||||||
{
|
{
|
||||||
if (c == '[') return '{';
|
if (c == '[') return '{';
|
||||||
if (c == ']') return '}';
|
if (c == ']') return '}';
|
||||||
@ -1736,6 +1759,15 @@ irc_tolower (char c)
|
|||||||
return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c;
|
return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
irc_strxfrm (char *dest, const char *src, size_t n)
|
||||||
|
{
|
||||||
|
size_t len = strlen (src);
|
||||||
|
while (n-- && (*dest++ = irc_tolower (*src++)))
|
||||||
|
;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
irc_strcmp (const char *a, const char *b)
|
irc_strcmp (const char *a, const char *b)
|
||||||
{
|
{
|
||||||
|
@ -378,12 +378,12 @@ server_context_init (struct server_context *self)
|
|||||||
|
|
||||||
self->server_name = NULL;
|
self->server_name = NULL;
|
||||||
str_map_init (&self->users);
|
str_map_init (&self->users);
|
||||||
self->users.key_cmp = irc_strcmp;
|
self->users.key_xfrm = irc_strxfrm;
|
||||||
// TODO: set channel_free() as the free function?
|
// TODO: set channel_free() as the free function?
|
||||||
str_map_init (&self->channels);
|
str_map_init (&self->channels);
|
||||||
self->channels.key_cmp = irc_strcmp;
|
self->channels.key_xfrm = irc_strxfrm;
|
||||||
str_map_init (&self->handlers);
|
str_map_init (&self->handlers);
|
||||||
self->handlers.key_cmp = irc_strcmp;
|
self->handlers.key_xfrm = irc_strxfrm;
|
||||||
|
|
||||||
poller_init (&self->poller);
|
poller_init (&self->poller);
|
||||||
self->quitting = false;
|
self->quitting = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user