1 /*******************************************************************************
2 Copyright (c) 2016, Michael Wallner <mike@php.net>.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
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.
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 *******************************************************************************/
26 #include "php_psi_stdinc.h"
30 #include "php_globals.h"
35 static void psi_data_ctor_internal(struct psi_data
*data
,
36 psi_error_cb error
, unsigned flags
)
41 if (data
->flags
& PSI_DEBUG
) {
42 int fd
= psi_fdopen(getenv("PSI_DEBUG"));
47 data
->debug_fd
= STDERR_FILENO
;
52 struct psi_data
*psi_data_ctor_with_dtors(struct psi_data
*data
,
53 psi_error_cb error
, unsigned flags
)
56 data
= pecalloc(1, sizeof(*data
), 1);
59 psi_data_ctor_internal(data
, error
, flags
);
61 if (!data
->file
.libnames
) {
62 data
->file
.libnames
= psi_plist_init((psi_plist_dtor
) psi_names_free
);
64 if (!data
->file
.dlopened
) {
65 data
->file
.dlopened
= psi_plist_init((psi_plist_dtor
) psi_libs_free
);
69 data
->consts
= psi_plist_init((psi_plist_dtor
) psi_const_free
);
72 data
->types
= psi_plist_init((psi_plist_dtor
) psi_decl_arg_free
);
75 data
->structs
= psi_plist_init((psi_plist_dtor
) psi_decl_struct_free
);
78 data
->unions
= psi_plist_init((psi_plist_dtor
) psi_decl_union_free
);
81 data
->enums
= psi_plist_init((psi_plist_dtor
) psi_decl_enum_free
);
84 data
->decls
= psi_plist_init((psi_plist_dtor
) psi_decl_free
);
87 data
->vars
= psi_plist_init((psi_plist_dtor
) psi_decl_extvar_free
);
90 data
->impls
= psi_plist_init((psi_plist_dtor
) psi_impl_free
);
95 struct psi_data
*psi_data_ctor(struct psi_data
*data
, psi_error_cb error
,
99 data
= pecalloc(1, sizeof(*data
), 1);
102 psi_data_ctor_internal(data
, error
, flags
);
104 if (!data
->file
.libnames
) {
105 data
->file
.libnames
= psi_plist_init(NULL
);
107 if (!data
->file
.dlopened
) {
108 data
->file
.dlopened
= psi_plist_init(NULL
);
112 data
->consts
= psi_plist_init(NULL
);
115 data
->types
= psi_plist_init(NULL
);
117 if (!data
->structs
) {
118 data
->structs
= psi_plist_init(NULL
);
121 data
->unions
= psi_plist_init(NULL
);
124 data
->enums
= psi_plist_init(NULL
);
127 data
->decls
= psi_plist_init(NULL
);
130 data
->vars
= psi_plist_init(NULL
);
133 data
->impls
= psi_plist_init(NULL
);
138 struct psi_data
*psi_data_exchange(struct psi_data
*dest
, struct psi_data
*src
)
141 dest
= pemalloc(sizeof(*dest
), 1);
144 memset(src
, 0, sizeof(*src
));
148 void psi_data_dtor(struct psi_data
*data
)
150 if (data
->debug_fd
) {
151 close(data
->debug_fd
);
154 psi_plist_free(data
->consts
);
157 psi_plist_free(data
->types
);
160 psi_plist_free(data
->structs
);
163 psi_plist_free(data
->unions
);
166 psi_plist_free(data
->enums
);
169 psi_plist_free(data
->decls
);
172 psi_plist_free(data
->vars
);
175 psi_plist_free(data
->impls
);
178 psi_decl_file_dtor(&data
->file
);
181 void psi_data_dump(struct psi_dump
*dump
, struct psi_data
*D
)
186 if (D
->file
.filename
) {
187 PSI_DUMP(dump
, "// filename=%s (%u errors)\n", D
->file
.filename
->val
, D
->errors
);
189 while (psi_plist_get(D
->file
.libnames
, i
++, &libname
)) {
190 PSI_DUMP(dump
, "lib \"%s\";\n", libname
);
192 if (psi_plist_count(D
->types
)) {
194 struct psi_decl_arg
*def
;
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");
201 PSI_DUMP(dump
, "\n");
203 if (psi_plist_count(D
->unions
)) {
205 struct psi_decl_union
*unn
;
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");
213 PSI_DUMP(dump
, "\n");
215 if (psi_plist_count(D
->structs
)) {
217 struct psi_decl_struct
*strct
;
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");
225 PSI_DUMP(dump
, "\n");
227 if (psi_plist_count(D
->enums
)) {
229 struct psi_decl_enum
*enm
;
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");
237 PSI_DUMP(dump
, "\n");
239 if (psi_plist_count(D
->consts
)) {
243 while (psi_plist_get(D
->consts
, i
++, &c
)) {
244 psi_const_dump(dump
, c
);
245 PSI_DUMP(dump
, "\n");
247 PSI_DUMP(dump
, "\n");
249 if (psi_plist_count(D
->decls
)) {
251 struct psi_decl
*decl
;
253 while (psi_plist_get(D
->decls
, i
++, &decl
)) {
255 PSI_DUMP(dump
, "/* extvar accessor \n");
257 psi_decl_dump(dump
, decl
);
259 PSI_DUMP(dump
, " */");
261 PSI_DUMP(dump
, "\n");
263 PSI_DUMP(dump
, "\n");
265 if (psi_plist_count(D
->vars
)) {
267 struct psi_decl_extvar
*evar
;
269 while (psi_plist_get(D
->vars
, i
++, &evar
)) {
270 psi_decl_extvar_dump(dump
, evar
);
272 PSI_DUMP(dump
, "\n");
274 if (psi_plist_count(D
->impls
)) {
276 struct psi_impl
*impl
;
278 while (psi_plist_get(D
->impls
, i
++, &impl
)) {
279 psi_impl_dump(dump
, impl
);
280 PSI_DUMP(dump
, "\n");
282 PSI_DUMP(dump
, "\n");