isl_tab: optionally save dual solution
[platform/upstream/isl.git] / isl_name.c
1 #include <string.h>
2 #include "isl_name.h"
3
4 struct isl_name *isl_name_alloc(struct isl_ctx *ctx, const char *s)
5 {
6         const char *copy = strdup(s);
7         struct isl_name *name;
8
9         if (!copy)
10                 return NULL;
11         name = isl_alloc_type(ctx, struct isl_name);
12         if (!name)
13                 return NULL;
14
15         name->ref = 1;
16         name->name = copy;
17
18         return name;
19 }
20
21 static int isl_name_has_name(const void *entry, const void *val)
22 {
23         struct isl_name *name = (struct isl_name *)entry;
24         const char *s = (const char *)val;
25
26         return !strcmp(name->name, s);
27 }
28
29 struct isl_name *isl_name_get(struct isl_ctx *ctx, const char *name)
30 {
31         struct isl_hash_table_entry *entry;
32         uint32_t name_hash;
33
34         name_hash = isl_hash_string(isl_hash_init(), name);
35         entry = isl_hash_table_find(ctx, &ctx->name_hash, name_hash,
36                                         isl_name_has_name, name, 1);
37         if (!entry)
38                 return NULL;
39         if (entry->data)
40                 return isl_name_copy(ctx, entry->data);
41         entry->data = isl_name_alloc(ctx, name);
42         if (!entry->data)
43                 ctx->name_hash.n--;
44         return entry->data;
45 }
46
47 struct isl_name *isl_name_copy(struct isl_ctx *ctx, struct isl_name *name)
48 {
49         if (!name)
50                 return NULL;
51
52         name->ref++;
53         return name;
54 }
55
56 static int isl_name_eq(const void *entry, const void *name)
57 {
58         return entry == name;
59 }
60
61 void isl_name_free(struct isl_ctx *ctx, struct isl_name *name)
62 {
63         uint32_t name_hash;
64         struct isl_hash_table_entry *entry;
65
66         if (!name)
67                 return;
68
69         if (--name->ref > 0)
70                 return;
71
72         name_hash = isl_hash_string(isl_hash_init(), name->name);
73         entry = isl_hash_table_find(ctx, &ctx->name_hash, name_hash,
74                                         isl_name_eq, name, 0);
75         isl_assert(ctx, entry, return);
76         isl_hash_table_remove(ctx, &ctx->name_hash, entry);
77
78         free((char *)name->name);
79         free(name);
80 }