1 /*
2 * YASM associated data storage (libyasm internal use)
3 *
4 * Copyright (C) 2003-2007 Peter Johnson
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27 #include "util.h"
28
29 #include "coretype.h"
30 #include "assocdat.h"
31
32
33 typedef struct assoc_data_item {
34 const yasm_assoc_data_callback *callback;
35 void *data;
36 } assoc_data_item;
37
38 struct yasm__assoc_data {
39 assoc_data_item *vector;
40 size_t size;
41 size_t alloc;
42 };
43
44
45 yasm__assoc_data *
yasm__assoc_data_create(void)46 yasm__assoc_data_create(void)
47 {
48 yasm__assoc_data *assoc_data = yasm_xmalloc(sizeof(yasm__assoc_data));
49
50 assoc_data->size = 0;
51 assoc_data->alloc = 2;
52 assoc_data->vector = yasm_xmalloc(assoc_data->alloc *
53 sizeof(assoc_data_item));
54
55 return assoc_data;
56 }
57
58 void *
yasm__assoc_data_get(yasm__assoc_data * assoc_data,const yasm_assoc_data_callback * callback)59 yasm__assoc_data_get(yasm__assoc_data *assoc_data,
60 const yasm_assoc_data_callback *callback)
61 {
62 size_t i;
63
64 if (!assoc_data)
65 return NULL;
66
67 for (i=0; i<assoc_data->size; i++) {
68 if (assoc_data->vector[i].callback == callback)
69 return assoc_data->vector[i].data;
70 }
71 return NULL;
72 }
73
74 yasm__assoc_data *
yasm__assoc_data_add(yasm__assoc_data * assoc_data_arg,const yasm_assoc_data_callback * callback,void * data)75 yasm__assoc_data_add(yasm__assoc_data *assoc_data_arg,
76 const yasm_assoc_data_callback *callback, void *data)
77 {
78 yasm__assoc_data *assoc_data;
79 assoc_data_item *item = NULL;
80 size_t i;
81
82 /* Create a new assoc_data if necessary */
83 if (assoc_data_arg)
84 assoc_data = assoc_data_arg;
85 else
86 assoc_data = yasm__assoc_data_create();
87
88 /* See if there's already assocated data for this callback */
89 for (i=0; i<assoc_data->size; i++) {
90 if (assoc_data->vector[i].callback == callback)
91 item = &assoc_data->vector[i];
92 }
93
94 /* No? Then append a new one */
95 if (!item) {
96 assoc_data->size++;
97 if (assoc_data->size > assoc_data->alloc) {
98 assoc_data->alloc *= 2;
99 assoc_data->vector =
100 yasm_xrealloc(assoc_data->vector,
101 assoc_data->alloc * sizeof(assoc_data_item));
102 }
103 item = &assoc_data->vector[assoc_data->size-1];
104 item->callback = callback;
105 item->data = NULL;
106 }
107
108 /* Delete existing data (if any) */
109 if (item->data && item->data != data)
110 item->callback->destroy(item->data);
111
112 item->data = data;
113
114 return assoc_data;
115 }
116
117 void
yasm__assoc_data_destroy(yasm__assoc_data * assoc_data)118 yasm__assoc_data_destroy(yasm__assoc_data *assoc_data)
119 {
120 size_t i;
121
122 if (!assoc_data)
123 return;
124
125 for (i=0; i<assoc_data->size; i++)
126 assoc_data->vector[i].callback->destroy(assoc_data->vector[i].data);
127 yasm_xfree(assoc_data->vector);
128 yasm_xfree(assoc_data);
129 }
130
131 void
yasm__assoc_data_print(const yasm__assoc_data * assoc_data,FILE * f,int indent_level)132 yasm__assoc_data_print(const yasm__assoc_data *assoc_data, FILE *f,
133 int indent_level)
134 {
135 /*TODO*/
136 }
137