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"
31 #include "zend_types.h"
36 #if PSI_THREADED_PARSER
39 pthread_mutex_t psi_string_mutex
= PTHREAD_MUTEX_INITIALIZER
;
41 zend_string
*psi_string_init_interned(const char *buf
, size_t len
, int p
)
45 pthread_mutex_lock(&psi_string_mutex
);
46 str
= zend_string_init_interned(buf
, len
, p
);
47 pthread_mutex_unlock(&psi_string_mutex
);
52 zend_string
*psi_new_interned_string(zend_string
*str
)
56 pthread_mutex_lock(&psi_string_mutex
);
57 new_str
= zend_new_interned_string(str
);
58 pthread_mutex_unlock(&psi_string_mutex
);
65 static void psi_data_ctor_internal(struct psi_data
*data
,
66 psi_error_cb error
, unsigned flags
)
71 if (data
->flags
& PSI_DEBUG
) {
72 int fd
= psi_fdopen(getenv("PSI_DEBUG"));
77 data
->debug_fd
= STDERR_FILENO
;
82 struct psi_data
*psi_data_ctor_with_dtors(struct psi_data
*data
,
83 psi_error_cb error
, unsigned flags
)
86 data
= pecalloc(1, sizeof(*data
), 1);
89 psi_data_ctor_internal(data
, error
, flags
);
91 if (!data
->file
.libnames
) {
92 data
->file
.libnames
= psi_plist_init((psi_plist_dtor
) psi_names_free
);
94 if (!data
->file
.dlopened
) {
95 data
->file
.dlopened
= psi_plist_init((psi_plist_dtor
) psi_libs_free
);
99 data
->consts
= psi_plist_init((psi_plist_dtor
) psi_const_free
);
102 data
->types
= psi_plist_init((psi_plist_dtor
) psi_decl_arg_free
);
104 if (!data
->structs
) {
105 data
->structs
= psi_plist_init((psi_plist_dtor
) psi_decl_struct_free
);
108 data
->unions
= psi_plist_init((psi_plist_dtor
) psi_decl_union_free
);
111 data
->enums
= psi_plist_init((psi_plist_dtor
) psi_decl_enum_free
);
114 data
->decls
= psi_plist_init((psi_plist_dtor
) psi_decl_free
);
117 data
->vars
= psi_plist_init((psi_plist_dtor
) psi_decl_extvar_free
);
120 data
->impls
= psi_plist_init((psi_plist_dtor
) psi_impl_free
);
125 struct psi_data
*psi_data_ctor(struct psi_data
*data
, psi_error_cb error
,
129 data
= pecalloc(1, sizeof(*data
), 1);
132 psi_data_ctor_internal(data
, error
, flags
);
134 if (!data
->file
.libnames
) {
135 data
->file
.libnames
= psi_plist_init(NULL
);
137 if (!data
->file
.dlopened
) {
138 data
->file
.dlopened
= psi_plist_init(NULL
);
142 data
->consts
= psi_plist_init(NULL
);
145 data
->types
= psi_plist_init(NULL
);
147 if (!data
->structs
) {
148 data
->structs
= psi_plist_init(NULL
);
151 data
->unions
= psi_plist_init(NULL
);
154 data
->enums
= psi_plist_init(NULL
);
157 data
->decls
= psi_plist_init(NULL
);
160 data
->vars
= psi_plist_init(NULL
);
163 data
->impls
= psi_plist_init(NULL
);
168 struct psi_data
*psi_data_exchange(struct psi_data
*dest
, struct psi_data
*src
)
171 dest
= pemalloc(sizeof(*dest
), 1);
174 memset(src
, 0, sizeof(*src
));
178 void psi_data_dtor(struct psi_data
*data
)
180 if (data
->debug_fd
) {
181 close(data
->debug_fd
);
184 psi_plist_free(data
->consts
);
187 psi_plist_free(data
->types
);
190 psi_plist_free(data
->structs
);
193 psi_plist_free(data
->unions
);
196 psi_plist_free(data
->enums
);
199 psi_plist_free(data
->decls
);
202 psi_plist_free(data
->vars
);
205 psi_plist_free(data
->impls
);
208 psi_decl_file_dtor(&data
->file
);
211 void psi_data_dump(struct psi_dump
*dump
, struct psi_data
*D
)
216 if (D
->file
.filename
) {
217 PSI_DUMP(dump
, "// filename=%s (%u errors)\n", D
->file
.filename
->val
, D
->errors
);
219 while (psi_plist_get(D
->file
.libnames
, i
++, &libname
)) {
220 PSI_DUMP(dump
, "lib \"%s\";\n", libname
);
222 if (psi_plist_count(D
->types
)) {
224 struct psi_decl_arg
*def
;
226 while (psi_plist_get(D
->types
, i
++, &def
)) {
227 PSI_DUMP(dump
, "typedef ");
228 psi_decl_arg_dump(dump
, def
, 0);
229 PSI_DUMP(dump
, ";\n");
231 PSI_DUMP(dump
, "\n");
233 if (psi_plist_count(D
->unions
)) {
235 struct psi_decl_union
*unn
;
237 while (psi_plist_get(D
->unions
, i
++, &unn
)) {
238 if (!psi_decl_type_is_anon(unn
->name
, "union")) {
239 psi_decl_union_dump(dump
, unn
);
240 PSI_DUMP(dump
, "\n");
243 PSI_DUMP(dump
, "\n");
245 if (psi_plist_count(D
->structs
)) {
247 struct psi_decl_struct
*strct
;
249 while (psi_plist_get(D
->structs
, i
++, &strct
)) {
250 if (!psi_decl_type_is_anon(strct
->name
, "struct")) {
251 psi_decl_struct_dump(dump
, strct
);
252 PSI_DUMP(dump
, "\n");
255 PSI_DUMP(dump
, "\n");
257 if (psi_plist_count(D
->enums
)) {
259 struct psi_decl_enum
*enm
;
261 while (psi_plist_get(D
->enums
, i
++, &enm
)) {
262 if (true || !psi_decl_type_is_anon(enm
->name
, "enum")) {
263 psi_decl_enum_dump(dump
, enm
, 0);
264 PSI_DUMP(dump
, "\n");
267 PSI_DUMP(dump
, "\n");
269 if (psi_plist_count(D
->consts
)) {
273 while (psi_plist_get(D
->consts
, i
++, &c
)) {
274 psi_const_dump(dump
, c
);
275 PSI_DUMP(dump
, "\n");
277 PSI_DUMP(dump
, "\n");
279 if (psi_plist_count(D
->decls
)) {
281 struct psi_decl
*decl
;
283 while (psi_plist_get(D
->decls
, i
++, &decl
)) {
285 PSI_DUMP(dump
, "/* extvar accessor \n");
287 psi_decl_dump(dump
, decl
);
289 PSI_DUMP(dump
, " */");
291 PSI_DUMP(dump
, "\n");
293 PSI_DUMP(dump
, "\n");
295 if (psi_plist_count(D
->vars
)) {
297 struct psi_decl_extvar
*evar
;
299 while (psi_plist_get(D
->vars
, i
++, &evar
)) {
300 psi_decl_extvar_dump(dump
, evar
);
302 PSI_DUMP(dump
, "\n");
304 if (psi_plist_count(D
->impls
)) {
306 struct psi_impl
*impl
;
308 while (psi_plist_get(D
->impls
, i
++, &impl
)) {
309 psi_impl_dump(dump
, impl
);
310 PSI_DUMP(dump
, "\n");
312 PSI_DUMP(dump
, "\n");