source: libabac/abac_set.c @ 63dcd99

abac0-leak
Last change on this file since 63dcd99 was e2a0f26, checked in by Mike Ryan <mikeryan@…>, 14 years ago

derive edges from intersections

  • Property mode set to 100644
File size: 2.1 KB
Line 
1#include <stdlib.h>
2
3#include "abac_set.h"
4#include "abac_util.h"
5
6#include "uthash.h"
7
8typedef struct _abac_set_element_t {
9    char *key;
10    UT_hash_handle hh;
11} abac_set_element_t;
12
13struct _abac_set_t {
14    abac_set_element_t *elts;
15    int size;
16};
17
18/**
19 * Create a new struct.
20 */
21abac_set_t *abac_set_new(void) {
22    abac_set_t *ret = abac_xmalloc(sizeof(abac_set_t));
23    ret->elts = NULL;
24    ret->size = 0;
25    return ret;
26}
27
28/**
29 * Add an item to the set, returns true if it doesn't exist.
30 */
31int abac_set_add(abac_set_t *set, char *value) {
32    abac_set_element_t *elt;
33
34    HASH_FIND_STR(set->elts, value, elt);
35    if (elt) return 0; // already exists
36
37    elt = abac_xmalloc(sizeof(abac_set_element_t));
38    elt->key = abac_xstrdup(value);
39    HASH_ADD_KEYPTR(hh, set->elts, elt->key, strlen(elt->key), elt);
40
41    ++set->size;
42
43    return 1;
44}
45
46/**
47 * Does the set contain the value.
48 */
49int abac_set_contains(abac_set_t *set, char *value) {
50    abac_set_element_t *elt;
51
52    HASH_FIND_STR(set->elts, value, elt);
53    return elt != NULL;
54}
55
56/**
57 * Return a list of the set's elements.
58 */
59abac_list_t *abac_set_elements(abac_set_t *set) {
60    abac_set_element_t *elt;
61    abac_list_t *ret = abac_list_new();
62
63    for (elt = set->elts; elt != NULL; elt = elt->hh.next) {
64        char *next = elt->key;
65        abac_list_add(ret, next);
66    }
67
68    return ret;
69}
70
71/**
72 * Returns the number of elements in the set.
73 */
74int abac_set_size(abac_set_t *set) {
75    return set->size;
76}
77
78/**
79 * Takes the intersection of l and r.
80 */
81void abac_set_intersect(abac_set_t *l, abac_set_t *r) {
82    abac_set_element_t *elt, *next;
83
84    for (elt = l->elts; elt != NULL; elt = next) {
85        next = elt->hh.next;
86
87        // if the rhs doesn't contain this item, remove it
88        if (!abac_set_contains(r, elt->key)) {
89            HASH_DEL(l->elts, elt);
90            free(elt->key);
91            free(elt);
92            --l->size;
93        }
94    }
95}
96
97/**
98 * Destroy a set.
99 */
100void abac_set_free(abac_set_t *set) {
101    abac_set_element_t *elt;
102
103    while ((elt = set->elts) != NULL) {
104        HASH_DEL(set->elts, elt);
105        free(elt->key);
106        free(elt);
107    }
108
109    free(set);
110}
Note: See TracBrowser for help on using the repository browser.