administrativa
[m6w6/ext-psi] / src / data.c
1 /*******************************************************************************
2 Copyright (c) 2016, Michael Wallner <mike@php.net>.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
18 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *******************************************************************************/
25
26 #include "php_psi_stdinc.h"
27 #include "php_psi.h"
28 #include "data.h"
29
30 #include "php_globals.h"
31
32 #include <dlfcn.h>
33 #include <ctype.h>
34
35 static void psi_data_ctor_internal(struct psi_data *data,
36 psi_error_cb error, unsigned flags)
37 {
38 data->error = error;
39 data->flags = flags;
40
41 if (data->flags & PSI_DEBUG) {
42 int fd = psi_fdopen(getenv("PSI_DEBUG"));
43
44 if (fd > 0) {
45 data->debug_fd = fd;
46 } else {
47 data->debug_fd = STDERR_FILENO;
48 }
49 }
50 }
51
52 struct psi_data *psi_data_ctor_with_dtors(struct psi_data *data,
53 psi_error_cb error, unsigned flags)
54 {
55 if (!data) {
56 data = pecalloc(1, sizeof(*data), 1);
57 }
58
59 psi_data_ctor_internal(data, error, flags);
60
61 if (!data->file.libnames) {
62 data->file.libnames = psi_plist_init((psi_plist_dtor) psi_names_free);
63 }
64 if (!data->file.dlopened) {
65 data->file.dlopened = psi_plist_init((psi_plist_dtor) psi_libs_free);
66 }
67
68 if (!data->consts) {
69 data->consts = psi_plist_init((psi_plist_dtor) psi_const_free);
70 }
71 if (!data->types) {
72 data->types = psi_plist_init((psi_plist_dtor) psi_decl_arg_free);
73 }
74 if (!data->structs) {
75 data->structs = psi_plist_init((psi_plist_dtor) psi_decl_struct_free);
76 }
77 if (!data->unions) {
78 data->unions = psi_plist_init((psi_plist_dtor) psi_decl_union_free);
79 }
80 if (!data->enums) {
81 data->enums = psi_plist_init((psi_plist_dtor) psi_decl_enum_free);
82 }
83 if (!data->decls) {
84 data->decls = psi_plist_init((psi_plist_dtor) psi_decl_free);
85 }
86 if (!data->vars) {
87 data->vars = psi_plist_init((psi_plist_dtor) psi_decl_extvar_free);
88 }
89 if (!data->impls) {
90 data->impls = psi_plist_init((psi_plist_dtor) psi_impl_free);
91 }
92 return data;
93 }
94
95 struct psi_data *psi_data_ctor(struct psi_data *data, psi_error_cb error,
96 unsigned flags)
97 {
98 if (!data) {
99 data = pecalloc(1, sizeof(*data), 1);
100 }
101
102 psi_data_ctor_internal(data, error, flags);
103
104 if (!data->file.libnames) {
105 data->file.libnames = psi_plist_init(NULL);
106 }
107 if (!data->file.dlopened) {
108 data->file.dlopened = psi_plist_init(NULL);
109 }
110
111 if (!data->consts) {
112 data->consts = psi_plist_init(NULL);
113 }
114 if (!data->types) {
115 data->types = psi_plist_init(NULL);
116 }
117 if (!data->structs) {
118 data->structs = psi_plist_init(NULL);
119 }
120 if (!data->unions) {
121 data->unions = psi_plist_init(NULL);
122 }
123 if (!data->enums) {
124 data->enums = psi_plist_init(NULL);
125 }
126 if (!data->decls) {
127 data->decls = psi_plist_init(NULL);
128 }
129 if (!data->vars) {
130 data->vars = psi_plist_init(NULL);
131 }
132 if (!data->impls) {
133 data->impls = psi_plist_init(NULL);
134 }
135 return data;
136 }
137
138 struct psi_data *psi_data_exchange(struct psi_data *dest, struct psi_data *src)
139 {
140 if (!dest) {
141 dest = pemalloc(sizeof(*dest), 1);
142 }
143 *dest = *src;
144 memset(src, 0, sizeof(*src));
145 return dest;
146 }
147
148 void psi_data_dtor(struct psi_data *data)
149 {
150 if (data->debug_fd) {
151 close(data->debug_fd);
152 }
153 if (data->consts) {
154 psi_plist_free(data->consts);
155 }
156 if (data->types) {
157 psi_plist_free(data->types);
158 }
159 if (data->structs) {
160 psi_plist_free(data->structs);
161 }
162 if (data->unions) {
163 psi_plist_free(data->unions);
164 }
165 if (data->enums) {
166 psi_plist_free(data->enums);
167 }
168 if (data->decls) {
169 psi_plist_free(data->decls);
170 }
171 if (data->vars) {
172 psi_plist_free(data->vars);
173 }
174 if (data->impls) {
175 psi_plist_free(data->impls);
176 }
177
178 psi_decl_file_dtor(&data->file);
179 }
180
181 void psi_data_dump(struct psi_dump *dump, struct psi_data *D)
182 {
183 size_t i = 0;
184 char *libname;
185
186 if (D->file.filename) {
187 PSI_DUMP(dump, "// filename=%s (%u errors)\n", D->file.filename->val, D->errors);
188 }
189 while (psi_plist_get(D->file.libnames, i++, &libname)) {
190 PSI_DUMP(dump, "lib \"%s\";\n", libname);
191 }
192 if (psi_plist_count(D->types)) {
193 size_t i = 0;
194 struct psi_decl_arg *def;
195
196 while (psi_plist_get(D->types, i++, &def)) {
197 PSI_DUMP(dump, "typedef ");
198 psi_decl_arg_dump(dump, def, 0);
199 PSI_DUMP(dump, ";\n");
200 }
201 PSI_DUMP(dump, "\n");
202 }
203 if (psi_plist_count(D->unions)) {
204 size_t i = 0;
205 struct psi_decl_union *unn;
206
207 while (psi_plist_get(D->unions, i++, &unn)) {
208 if (!psi_decl_type_is_anon(unn->name, "union")) {
209 psi_decl_union_dump(dump, unn);
210 PSI_DUMP(dump, "\n");
211 }
212 }
213 PSI_DUMP(dump, "\n");
214 }
215 if (psi_plist_count(D->structs)) {
216 size_t i = 0;
217 struct psi_decl_struct *strct;
218
219 while (psi_plist_get(D->structs, i++, &strct)) {
220 if (!psi_decl_type_is_anon(strct->name, "struct")) {
221 psi_decl_struct_dump(dump, strct);
222 PSI_DUMP(dump, "\n");
223 }
224 }
225 PSI_DUMP(dump, "\n");
226 }
227 if (psi_plist_count(D->enums)) {
228 size_t i = 0;
229 struct psi_decl_enum *enm;
230
231 while (psi_plist_get(D->enums, i++, &enm)) {
232 if (true || !psi_decl_type_is_anon(enm->name, "enum")) {
233 psi_decl_enum_dump(dump, enm, 0);
234 PSI_DUMP(dump, "\n");
235 }
236 }
237 PSI_DUMP(dump, "\n");
238 }
239 if (psi_plist_count(D->consts)) {
240 size_t i = 0;
241 struct psi_const *c;
242
243 while (psi_plist_get(D->consts, i++, &c)) {
244 psi_const_dump(dump, c);
245 PSI_DUMP(dump, "\n");
246 }
247 PSI_DUMP(dump, "\n");
248 }
249 if (psi_plist_count(D->decls)) {
250 size_t i = 0;
251 struct psi_decl *decl;
252
253 while (psi_plist_get(D->decls, i++, &decl)) {
254 if (decl->extvar) {
255 PSI_DUMP(dump, "/* extvar accessor \n");
256 }
257 psi_decl_dump(dump, decl);
258 if (decl->extvar) {
259 PSI_DUMP(dump, " */");
260 }
261 PSI_DUMP(dump, "\n");
262 }
263 PSI_DUMP(dump, "\n");
264 }
265 if (psi_plist_count(D->vars)) {
266 size_t i = 0;
267 struct psi_decl_extvar *evar;
268
269 while (psi_plist_get(D->vars, i++, &evar)) {
270 psi_decl_extvar_dump(dump, evar);
271 }
272 PSI_DUMP(dump, "\n");
273 }
274 if (psi_plist_count(D->impls)) {
275 size_t i = 0;
276 struct psi_impl *impl;
277
278 while (psi_plist_get(D->impls, i++, &impl)) {
279 psi_impl_dump(dump, impl);
280 PSI_DUMP(dump, "\n");
281 }
282 PSI_DUMP(dump, "\n");
283 }
284 }