]> jfr.im git - solanum.git/blobdiff - src/capability.c
update NEWS
[solanum.git] / src / capability.c
index c4236cb268dc189b6d33c96b4d1bf0291d6532fe..daf72657bdb98e8556d04784f0c4af27fbc38390 100644 (file)
@@ -21,6 +21,7 @@
 #include "stdinc.h"
 #include "capability.h"
 #include "irc_dictionary.h"
+#include "s_assert.h"
 
 static rb_dlink_list capability_indexes = { NULL, NULL, 0 };
 
@@ -46,12 +47,14 @@ capability_get(struct CapabilityIndex *idx, const char *cap)
        struct CapabilityEntry *entry;
 
        s_assert(idx != NULL);
+       if (cap == NULL)
+               return 0;
 
        entry = irc_dictionary_retrieve(idx->cap_dict, cap);
        if (entry != NULL && !(entry->flags & CAP_ORPHANED))
                return (1 << entry->value);
 
-       return 0xFFFFFFFF;
+       return 0;
 }
 
 unsigned int
@@ -83,6 +86,21 @@ capability_put(struct CapabilityIndex *idx, const char *cap)
        return (1 << entry->value);
 }
 
+unsigned int
+capability_put_anonymous(struct CapabilityIndex *idx)
+{
+       unsigned int value;
+
+       s_assert(idx != NULL);
+       if (!idx->highest_bit)
+               return 0xFFFFFFFF;
+       value = 1 << idx->highest_bit;
+       idx->highest_bit++;
+       if (idx->highest_bit % (sizeof(unsigned int) * 8) == 0)
+               idx->highest_bit = 0;
+       return value;
+}
+
 void
 capability_orphan(struct CapabilityIndex *idx, const char *cap)
 {
@@ -159,7 +177,7 @@ capability_index_list(struct CapabilityIndex *idx, unsigned int cap_mask)
 
        DICTIONARY_FOREACH(entry, &iter, idx->cap_dict)
        {
-               if (entry->value & cap_mask)
+               if ((1 << entry->value) & cap_mask)
                {
                        tl = rb_sprintf(t, "%s ", entry->cap);
                        t += tl;
@@ -207,3 +225,33 @@ capability_index_get_required(struct CapabilityIndex *idx)
 
        return mask;
 }
+
+void
+capability_index_stats(void (*cb)(const char *line, void *privdata), void *privdata)
+{
+       rb_dlink_node *node;
+       char buf[BUFSIZE];
+
+       RB_DLINK_FOREACH(node, capability_indexes.head)
+       {
+               struct CapabilityIndex *idx = node->data;
+               struct DictionaryIter iter;
+               struct CapabilityEntry *entry;
+
+               rb_snprintf(buf, sizeof buf, "'%s': allocated bits - %d", idx->name, (idx->highest_bit - 1));
+               cb(buf, privdata);
+
+               DICTIONARY_FOREACH(entry, &iter, idx->cap_dict)
+               {
+                       rb_snprintf(buf, sizeof buf, "bit %d: '%s'", entry->value, entry->cap);
+                       cb(buf, privdata);
+               }
+
+               rb_snprintf(buf, sizeof buf, "'%s': remaining bits - %u", idx->name,
+                           (unsigned int)((sizeof(unsigned int) * 8) - (idx->highest_bit - 1)));
+               cb(buf, privdata);
+       }
+
+       rb_snprintf(buf, sizeof buf, "%ld capability indexes", rb_dlink_list_length(&capability_indexes));
+       cb(buf, privdata);
+}