#define MAPTYPE_CHANNEL 2
static int map_index(lua_State *L)
{
- map_t *m = *(map_t **)luaL_checkudata(L, 1, "map");
+ map_base *m = *(map_base **)luaL_checkudata(L, 1, "map");
const char *key = luaL_checkstring(L, 2);
void *value = map_get(m, key);
if (!value)
static int map_newindex(lua_State *L)
{
- map_t *m = *(map_t **)luaL_checkudata(L, 1, "map");
+ map_base *m = *(map_base **)luaL_checkudata(L, 1, "map");
const char *key = luaL_checkstring(L, 2);
luaL_checkany(L, 3);
if (lua_isnil(L, 3)) {
}
static int map_pairs(lua_State *L)
{
- map_t *m = *(map_t **)luaL_checkudata(L, 1, "map");
+ map_base *m = *(map_base **)luaL_checkudata(L, 1, "map");
lua_pushcfunction(L, map_iter_next);
map_iter_t *it = (map_iter_t *)lua_newuserdatauv(L, sizeof(map_iter_t), 2);
memset(it, 0, sizeof(*it));
lua_pushnil(L);
return 3;
}
-static void map_push(lua_State *L, map_t *map, int type)
+static void map_push(lua_State *L, map_base *map, int type)
{
- *(map_t **)lua_newuserdatauv(L, sizeof(map_t *), 1) = map;
+ *(map_base **)lua_newuserdatauv(L, sizeof(map_base *), 1) = map;
luaL_setmetatable(L, "map");
lua_pushinteger(L, type);
lua_setiuservalue(L, -2, 1);
size_t wbufLen;
char umode;
char regstate;
- map_t channels;
- map_t invites;
- map_t monitor;
+ channelmap channels;
+ channelmap invites;
+ stringset monitor;
int cookie;
time_t signon;
time_t lastactivity;
char *topic_who;
time_t topic_when;
time_t creation;
- map_t members;
- map_t o;
- map_t v;
+ clientmap members;
+ clientmap o;
+ clientmap v;
int member_count;
char dmode;
- map_t listb;
- map_t liste;
- map_t listI;
- map_t listq;
- map_t listwo;
- map_t listwv;
- map_t invitees;
+ stringset listb;
+ stringset liste;
+ stringset listI;
+ stringset listq;
+ stringset listwo;
+ stringset listwv;
+ clientmap invitees;
char *chankey;
int member_limit;
};
#define DMODE_TOPICPROT 32
#define is_chanop(chan, client) (!!map_get(&(chan)->o, (client)->key))
#define is_chanvoice(chan, client) (!!map_get(&(chan)->v, (client)->key))
-extern map_t client_map;
-extern map_t channel_map;
-extern map_t autojoin;
+extern clientmap client_map;
+extern channelmap channel_map;
+extern stringset autojoin;
extern struct client_data *clients;
extern struct client_data *dyingclients;
struct dynarr databuf;
-map_t client_map = {};
-map_t channel_map = {};
-map_t autojoin = {};
+clientmap client_map = {};
+channelmap channel_map = {};
+stringset autojoin = {};
const char *hostname = IRCDHOSTNAME;
void sendbuf(struct client_data *client) {
static void sendbuf_chan(struct channel *chan) {
sendbuf_chan_caps(chan, 0, 0);
}
-static void sendbuf_list_sans_self_caps(struct client_data *client, map_t *ls, int cookie, int positive, int negative) {
+static void sendbuf_list_sans_self_caps(struct client_data *client, clientmap *ls, int cookie, int positive, int negative) {
struct client_data *cl;
map_foreach(ls, 0, &cl)
if (client != cl) {
sendbuf(cl);
}
}
-static void sendbuf_list_sans_self(struct client_data *client, map_t *ls, int cookie) {
+static void sendbuf_list_sans_self(struct client_data *client, clientmap *ls, int cookie) {
sendbuf_list_sans_self_caps(client, ls, cookie, 0, 0);
}
void sendbuf_monitor(const char *nick, int cookie, int positive, int negative)
*p++ = '\0';
return umodes;
}
-static int match_list(struct client_data *cl, map_t *list)
+static int match_list(struct client_data *cl, stringset *list)
{
const char *key;
map_foreach(list, &key, 0)
err_unknowncommand(client, "MODE"), sendbuf(client);
return;
}
- map_t *list;
+ stringset *list;
while (*p) {
switch (*p) {
case '+': is_plus = 1; break;
#include "map.h"
#include <stdlib.h>
#include <string.h>
-static int ent_find(map_t *root, const char *key, int *found)
+static int ent_find(map_base *root, const char *key, int *found)
{
int lo = 0;
int hi = root->len;
*found = 0;
return lo;
}
-void *map_get(map_t *root, const char *key)
+void *map_get(map_base *root, const char *key)
{
int found;
int i = ent_find(root, key, &found);
return found ? root->ptr[i].value : 0;
}
-int map_set(map_t *root, const char *key, const void *value, void **oldvalue)
+int map_set(map_base *root, const char *key, const void *value, void **oldvalue)
{
int found;
int i = ent_find(root, key, &found);
}
return 0;
}
-void map_free(map_t *root)
+void map_free(map_base *root)
{
while (root->len) {
free(root->ptr[--root->len].key);
it->index++;
return 1;
}
-void *map_pop(map_t *root)
+void *map_pop(map_base *root)
{
return root->len ? root->ptr[root->len-1].value : 0;
}
char *key;
void *value;
};
-typedef struct map {
+struct map_base {
struct map_value *ptr;
size_t len, cap;
-} map_t;
+};
typedef struct map_iter {
- map_t *root;
+ map_base *root;
size_t index;
} map_iter_t;
+struct clientmap : map_base {
+};
+struct channelmap : map_base {
+};
+struct stringset : map_base {
+};
+
/* A map abstract data type with following properties:
* - keys are lexicographically-sorted unique NUL-terminated strings
* - values are non-NULL pointers
/* Return the associated value for a given key.
* Dynarr complexity: O(log n) */
-void *map_get(map_t *root, const char *key);
+void *map_get(map_base *root, const char *key);
/* Associate a new value with a given key.
* Returns 0 on success, -1 on allocation error.
* If oldvalue is not NULL, it receives the old value of key.
* Dynarr complexity: O(n) */
-NODISCARD int map_set(map_t *root, const char *key, const void *value, void **oldvalue);
+NODISCARD int map_set(map_base *root, const char *key, const void *value, void **oldvalue);
/* Remove a key.
* Same as associating a key to NULL. No allocation failures. */
#define map_unset(root, key, oldvalue) ((void)map_set((root), (key), 0, (oldvalue)))
/* Removes all keys from the map and frees any associated memory.
* The map_t is reset to zero-initialized state and can be used again.
* Dynarr complexity: O(n) */
-void map_free(map_t *root);
+void map_free(map_base *root);
/* Iterate over a map.
*
* }
* map_free(&map);
*/
-NODISCARD void *map_pop(map_t *root);
+NODISCARD void *map_pop(map_base *root);
#endif