isl_input.c: accept_affine_factor: avoid double free on invalid input
[platform/upstream/isl.git] / isl_name.c
1 /*
2  * Copyright 2008-2009 Katholieke Universiteit Leuven
3  *
4  * Use of this software is governed by the GNU LGPLv2.1 license
5  *
6  * Written by Sven Verdoolaege, K.U.Leuven, Departement
7  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
8  */
9
10 #include <string.h>
11 #include "isl_name.h"
12
13 struct isl_name *isl_name_alloc(struct isl_ctx *ctx, const char *s)
14 {
15         const char *copy = strdup(s);
16         struct isl_name *name;
17
18         if (!copy)
19                 return NULL;
20         name = isl_alloc_type(ctx, struct isl_name);
21         if (!name)
22                 goto error;
23
24         name->ref = 1;
25         name->name = copy;
26
27         name->hash = isl_hash_init();
28         name->hash = isl_hash_string(name->hash, s);
29
30         return name;
31 error:
32         free((char *)copy);
33         return NULL;
34 }
35
36 static int isl_name_has_name(const void *entry, const void *val)
37 {
38         struct isl_name *name = (struct isl_name *)entry;
39         const char *s = (const char *)val;
40
41         return !strcmp(name->name, s);
42 }
43
44 struct isl_name *isl_name_get(struct isl_ctx *ctx, const char *name)
45 {
46         struct isl_hash_table_entry *entry;
47         uint32_t name_hash;
48
49         name_hash = isl_hash_string(isl_hash_init(), name);
50         entry = isl_hash_table_find(ctx, &ctx->name_hash, name_hash,
51                                         isl_name_has_name, name, 1);
52         if (!entry)
53                 return NULL;
54         if (entry->data)
55                 return isl_name_copy(ctx, entry->data);
56         entry->data = isl_name_alloc(ctx, name);
57         if (!entry->data)
58                 ctx->name_hash.n--;
59         return entry->data;
60 }
61
62 struct isl_name *isl_name_copy(struct isl_ctx *ctx, struct isl_name *name)
63 {
64         if (!name)
65                 return NULL;
66
67         name->ref++;
68         return name;
69 }
70
71 static int isl_name_eq(const void *entry, const void *name)
72 {
73         return entry == name;
74 }
75
76 uint32_t isl_hash_name(uint32_t hash, struct isl_name *name)
77 {
78         if (name)
79                 isl_hash_hash(hash, name->hash);
80
81         return hash;
82 }
83
84 void isl_name_free(struct isl_ctx *ctx, struct isl_name *name)
85 {
86         uint32_t name_hash;
87         struct isl_hash_table_entry *entry;
88
89         if (!name)
90                 return;
91
92         if (--name->ref > 0)
93                 return;
94
95         name_hash = isl_hash_string(isl_hash_init(), name->name);
96         entry = isl_hash_table_find(ctx, &ctx->name_hash, name_hash,
97                                         isl_name_eq, name, 0);
98         isl_assert(ctx, entry, return);
99         isl_hash_table_remove(ctx, &ctx->name_hash, entry);
100
101         free((char *)name->name);
102         free(name);
103 }