fix symbol redirect detection
[m6w6/ext-psi] / src / parser.h
1 #ifndef _PSI_PARSER_H
2 #define _PSI_PARSER_H
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdarg.h>
7 #include <string.h>
8
9 #include <Zend/zend_types.h>
10
11 #include "parser_proc.h"
12
13 #define BSIZE 256
14
15 typedef int token_t;
16
17 /* in php_psi.h */
18 size_t psi_t_alignment(token_t);
19 size_t psi_t_size(token_t);
20
21 typedef struct PSI_Token {
22 token_t type;
23 unsigned line;
24 size_t size;
25 char text[1];
26 } PSI_Token;
27
28 typedef struct decl_type {
29 char *name;
30 token_t type;
31 struct decl_type *real;
32 struct decl_struct *strct;
33 } decl_type;
34
35 static inline decl_type *init_decl_type(token_t type, const char *name) {
36 decl_type *t = calloc(1, sizeof(*t));
37 t->type = type;
38 t->name = strdup(name);
39 return t;
40 }
41
42 static inline decl_type *real_decl_type(decl_type *type) {
43 while (type->real) {
44 type = type->real;
45 }
46 return type;
47 }
48
49 static inline void free_decl_type(decl_type *type) {
50 free(type->name);
51 free(type);
52 }
53
54 typedef struct decl_typedef {
55 char *alias;
56 decl_type *type;
57 } decl_typedef;
58
59 static inline decl_typedef *init_decl_typedef(const char *name, decl_type *type) {
60 decl_typedef *t = calloc(1, sizeof(*t));
61 t->alias = strdup(name);
62 t->type = type;
63 return t;
64 }
65
66 static inline void free_decl_typedef(decl_typedef *t) {
67 free(t->alias);
68 free_decl_type(t->type);
69 free(t);
70 }
71
72 typedef struct decl_typedefs {
73 size_t count;
74 decl_typedef **list;
75 } decl_typedefs;
76
77 static inline decl_typedefs *add_decl_typedef(decl_typedefs *defs, decl_typedef *def) {
78 if (!defs) {
79 defs = calloc(1, sizeof(*defs));
80 }
81 defs->list = realloc(defs->list, ++defs->count * sizeof(*defs->list));
82 defs->list[defs->count-1] = def;
83 return defs;
84 }
85
86 static void free_decl_typedefs(decl_typedefs *defs) {
87 size_t i;
88
89 for (i = 0; i < defs->count; ++i) {
90 free_decl_typedef(defs->list[i]);
91 }
92 free(defs->list);
93 free(defs);
94 }
95
96 typedef struct decl_var {
97 char *name;
98 unsigned pointer_level;
99 unsigned array_size;
100 struct decl_arg *arg;
101 } decl_var;
102
103 static inline decl_var *init_decl_var(const char *name, unsigned pl, unsigned as) {
104 decl_var *v = calloc(1, sizeof(*v));
105 v->name = (char *) strdup((const char *) name);
106 v->pointer_level = pl;
107 v->array_size = as;
108 return v;
109 }
110
111 static inline void free_decl_var(decl_var *var) {
112 free(var->name);
113 free(var);
114 }
115
116 typedef struct decl_struct_layout {
117 size_t pos;
118 size_t len;
119 } decl_struct_layout;
120
121 static inline decl_struct_layout *init_decl_struct_layout(size_t pos, size_t len) {
122 decl_struct_layout *l = calloc(1, sizeof(*l));
123
124 l->pos = pos;
125 l->len = len;
126 return l;
127 }
128
129 static inline void free_decl_struct_layout(decl_struct_layout *l) {
130 free(l);
131 }
132
133 typedef struct decl_arg {
134 decl_type *type;
135 decl_var *var;
136 decl_struct_layout *layout;
137 struct let_stmt *let;
138 } decl_arg;
139
140 static inline decl_arg *init_decl_arg(decl_type *type, decl_var *var) {
141 decl_arg *arg = calloc(1, sizeof(*arg));
142 arg->type = type;
143 arg->var = var;
144 return arg;
145 }
146
147 static inline void free_decl_arg(decl_arg *arg) {
148 free_decl_type(arg->type);
149 free_decl_var(arg->var);
150 if (arg->layout) {
151 free_decl_struct_layout(arg->layout);
152 }
153 free(arg);
154 }
155
156 typedef struct decl_vars {
157 decl_var **vars;
158 size_t count;
159 } decl_vars;
160
161 static inline decl_vars *init_decl_vars(decl_var *var) {
162 decl_vars *vars = calloc(1, sizeof(*vars));
163 if (var) {
164 vars->count = 1;
165 vars->vars = calloc(1, sizeof(*vars->vars));
166 vars->vars[0] = var;
167 }
168 return vars;
169 }
170
171 static inline decl_vars *add_decl_var(decl_vars *vars, decl_var *var) {
172 vars->vars = realloc(vars->vars, ++vars->count * sizeof(*vars->vars));
173 vars->vars[vars->count-1] = var;
174 return vars;
175 }
176
177 static inline void free_decl_vars(decl_vars *vars) {
178 size_t i;
179
180 for (i = 0; i < vars->count; ++i) {
181 free_decl_var(vars->vars[i]);
182 }
183 free(vars->vars);
184 free(vars);
185 }
186
187 typedef struct decl_args {
188 decl_arg **args;
189 size_t count;
190 } decl_args;
191
192 static inline decl_args *init_decl_args(decl_arg *arg) {
193 decl_args *args = calloc(1, sizeof(*args));
194 if (arg) {
195 args->count = 1;
196 args->args = calloc(1, sizeof(*args->args));
197 args->args[0] = arg;
198 }
199 return args;
200 }
201
202 static inline decl_args *add_decl_arg(decl_args *args, decl_arg *arg) {
203 args->args = realloc(args->args, ++args->count * sizeof(*args->args));
204 args->args[args->count-1] = arg;
205 return args;
206 }
207
208 static inline void free_decl_args(decl_args *args) {
209 size_t i;
210
211 for (i = 0; i < args->count; ++i) {
212 free_decl_arg(args->args[i]);
213 }
214 free(args->args);
215 free(args);
216 }
217
218 typedef struct decl_abi {
219 char *convention;
220 } decl_abi;
221
222 static inline decl_abi *init_decl_abi(const char *convention) {
223 decl_abi *abi = calloc(1, sizeof(*abi));
224 abi->convention = strdup(convention);
225 return abi;
226 }
227
228 static inline void free_decl_abi(decl_abi *abi) {
229 free(abi->convention);
230 free(abi);
231 }
232
233 typedef struct decl {
234 decl_abi *abi;
235 decl_arg *func;
236 decl_args *args;
237 struct impl *impl;
238 struct {
239 void *sym;
240 void *info;
241 void **args;
242 } call;
243 } decl;
244
245 static inline decl* init_decl(decl_abi *abi, decl_arg *func, decl_args *args) {
246 decl *d = calloc(1, sizeof(*d));
247 d->abi = abi;
248 d->func = func;
249 d->args = args;
250 return d;
251 }
252
253 static inline void free_decl(decl *d) {
254 free_decl_abi(d->abi);
255 free_decl_arg(d->func);
256 if (d->args) {
257 free_decl_args(d->args);
258 }
259 free(d);
260 }
261
262 typedef struct decls {
263 size_t count;
264 decl **list;
265 } decls;
266
267 static inline decls *add_decl(decls *decls, decl *decl) {
268 if (!decls) {
269 decls = calloc(1, sizeof(*decls));
270 }
271 decls->list = realloc(decls->list, ++decls->count * sizeof(*decls->list));
272 decls->list[decls->count-1] = decl;
273 return decls;
274 }
275
276 static inline void free_decls(decls *decls) {
277 size_t i;
278
279 for (i = 0; i < decls->count; ++i) {
280 free_decl(decls->list[i]);
281 }
282 free(decls->list);
283 free(decls);
284 }
285
286 typedef struct decl_struct {
287 char *name;
288 decl_args *args;
289 size_t size;
290 } decl_struct;
291
292 static inline decl_struct *init_decl_struct(const char *name, decl_args *args) {
293 decl_struct *s = calloc(1, sizeof(*s));
294 s->name = strdup(name);
295 s->args = args;
296 return s;
297 }
298
299 static inline void free_decl_struct(decl_struct *s) {
300 if (s->args) {
301 free_decl_args(s->args);
302 }
303 free(s->name);
304 free(s);
305 }
306
307 typedef struct decl_structs {
308 size_t count;
309 decl_struct **list;
310 } decl_structs;
311
312 static inline decl_structs *add_decl_struct(decl_structs *ss, decl_struct *s) {
313 if (!ss) {
314 ss = calloc(1, sizeof(*ss));
315 }
316 ss->list = realloc(ss->list, ++ss->count * sizeof(*ss->list));
317 ss->list[ss->count-1] = s;
318 return ss;
319 }
320
321 static inline void free_decl_structs(decl_structs *ss) {
322 size_t i;
323
324 for (i = 0; i < ss->count; ++i) {
325 free_decl_struct(ss->list[i]);
326 }
327 free(ss->list);
328 free(ss);
329 }
330
331 typedef union impl_val {
332 char cval;
333 int8_t i8;
334 uint8_t u8;
335 short sval;
336 int16_t i16;
337 uint16_t u16;
338 int ival;
339 int32_t i32;
340 uint32_t u32;
341 long lval;
342 int64_t i64;
343 uint64_t u64;
344 float fval;
345 double dval;
346 union {
347 zend_bool bval;
348 zend_long lval;
349 zend_string *str;
350 } zend;
351 void *ptr;
352 uint8_t _dbg[sizeof(void *)];
353 } impl_val;
354
355 static inline impl_val *deref_impl_val(impl_val *ret_val, decl_var *var) {
356 unsigned i;
357
358 if (var->arg->var != var) for (i = 1; i < var->pointer_level; ++i) {
359 ret_val = *(void **) ret_val;
360 }
361 return ret_val;
362 }
363
364 static inline impl_val *enref_impl_val(void *ptr, decl_var *var) {
365 impl_val *val, *val_ptr;
366 unsigned i;
367
368 if (!var->pointer_level && real_decl_type(var->arg->type)->type != PSI_T_STRUCT) {
369 return ptr;
370 }
371 val = val_ptr = calloc(var->pointer_level + 1, sizeof(void *));
372 for (i = 1; i < var->pointer_level; ++i) {
373 val_ptr->ptr = (void **) val_ptr + 1;
374 val_ptr = val_ptr->ptr;
375 }
376 val_ptr->ptr = ptr;
377 return val;
378 }
379 typedef struct impl_type {
380 char *name;
381 token_t type;
382 } impl_type;
383
384 static inline impl_type *init_impl_type(token_t type, const char *name) {
385 impl_type *t = calloc(1, sizeof(*t));
386
387 t->type = type;
388 t->name = strdup(name);
389 return t;
390 }
391
392 static inline void free_impl_type(impl_type *type) {
393 free(type->name);
394 free(type);
395 }
396
397 typedef struct impl_var {
398 char *name;
399 unsigned reference:1;
400 } impl_var;
401
402 static inline impl_var *init_impl_var(const char *name, int is_reference) {
403 impl_var *var = calloc(1, sizeof(*var));
404 var->name = strdup(name);
405 var->reference = is_reference;
406 return var;
407 }
408
409 static inline void free_impl_var(impl_var *var) {
410 free(var->name);
411 free(var);
412 }
413
414 typedef struct impl_def_val {
415 token_t type;
416 char *text;
417 } impl_def_val;
418
419 static inline impl_def_val *init_impl_def_val(token_t t, const char *text) {
420 impl_def_val *def = calloc(1, sizeof(*def));
421 def->type = t;
422 def->text = strdup(text);
423 return def;
424 }
425
426 static inline void free_impl_def_val(impl_def_val *def) {
427 free(def->text);
428 free(def);
429 }
430
431 typedef struct impl_arg {
432 impl_type *type;
433 impl_var *var;
434 impl_def_val *def;
435 impl_val val;
436 zval *_zv;
437 } impl_arg;
438
439 static inline impl_arg *init_impl_arg(impl_type *type, impl_var *var, impl_def_val *def) {
440 impl_arg *arg = calloc(1, sizeof(*arg));
441 arg->type = type;
442 arg->var = var;
443 arg->def = def;
444 return arg;
445 }
446
447 static inline void free_impl_arg(impl_arg *arg) {
448 free_impl_type(arg->type);
449 free_impl_var(arg->var);
450 if (arg->def) {
451 free_impl_def_val(arg->def);
452 }
453 free(arg);
454 }
455
456 typedef struct impl_args {
457 impl_arg **args;
458 size_t count;
459 } impl_args;
460
461 static inline impl_args *init_impl_args(impl_arg *arg) {
462 impl_args *args = calloc(1, sizeof(*args));
463 if (arg) {
464 args->count = 1;
465 args->args = calloc(1, sizeof(*args->args));
466 args->args[0] = arg;
467 }
468 return args;
469 }
470
471 static inline impl_args *add_impl_arg(impl_args *args, impl_arg *arg) {
472 args->args = realloc(args->args, ++args->count * sizeof(*args->args));
473 args->args[args->count-1] = arg;
474 return args;
475 }
476
477 static inline void free_impl_args(impl_args *args) {
478 size_t i;
479
480 for (i = 0; i < args->count; ++i) {
481 free_impl_arg(args->args[i]);
482 }
483 free(args->args);
484 free(args);
485 }
486
487 typedef struct impl_func {
488 char *name;
489 impl_args *args;
490 impl_type *return_type;
491 unsigned return_reference:1;
492 } impl_func;
493
494 static inline impl_func *init_impl_func(char *name, impl_args *args, impl_type *type, int ret_reference) {
495 impl_func *func = calloc(1, sizeof(*func));
496 func->name = strdup(name);
497 func->args = args ? args : init_impl_args(NULL);
498 func->return_type = type;
499 func->return_reference = ret_reference;
500 return func;
501 }
502
503 static inline void free_impl_func(impl_func *f) {
504 free_impl_type(f->return_type);
505 free_impl_args(f->args);
506 free(f->name);
507 free(f);
508 }
509
510 typedef struct let_calloc {
511 size_t n;
512 decl_type *type;
513 } let_calloc;
514
515 static inline let_calloc *init_let_calloc(long n, decl_type *type) {
516 let_calloc *alloc = calloc(1, sizeof(*alloc));
517 alloc->n = n;
518 alloc->type = type;
519 return alloc;
520 }
521
522 static inline void free_let_calloc(let_calloc *alloc) {
523 free_decl_type(alloc->type);
524 free(alloc);
525 }
526
527 typedef struct let_func {
528 token_t type;
529 char *name;
530 let_calloc *alloc;
531 } let_func;
532
533 static inline let_func *init_let_func(token_t type, const char *name, let_calloc *alloc) {
534 let_func *func = calloc(1, sizeof(*func));
535 func->type = type;
536 func->name = strdup(name);
537 func->alloc = alloc;
538 return func;
539 }
540
541 static inline void free_let_func(let_func *func) {
542 if (func->alloc) {
543 free_let_calloc(func->alloc);
544 }
545 free(func->name);
546 free(func);
547 }
548
549 typedef struct let_value {
550 let_func *func;
551 impl_var *var;
552 unsigned is_reference:1;
553 } let_value;
554
555 static inline let_value *init_let_value(let_func *func, impl_var *var, int is_reference) {
556 let_value *val = calloc(1, sizeof(*val));
557 val->is_reference = is_reference;
558 val->func = func;
559 val->var = var;
560 return val;
561 }
562
563 static inline void free_let_value(let_value *val) {
564 if (val->func) {
565 free_let_func(val->func);
566 }
567 if (val->var) {
568 free_impl_var(val->var);
569 }
570 free(val);
571 }
572
573 typedef struct let_stmt {
574 decl_var *var;
575 let_value *val;
576 impl_arg *arg;
577 impl_val out;
578 void *ptr;
579 void *mem;
580 } let_stmt;
581
582 static inline let_stmt *init_let_stmt(decl_var *var, let_value *val) {
583 let_stmt *let = calloc(1, sizeof(*let));
584 let->var = var;
585 let->val = val;
586 return let;
587 }
588
589 static inline void free_let_stmt(let_stmt *stmt) {
590 free_decl_var(stmt->var);
591 if (stmt->val) {
592 free_let_value(stmt->val);
593 }
594 free(stmt);
595 }
596
597 struct set_value;
598
599 typedef struct set_func {
600 token_t type;
601 char *name;
602 void (*handler)(zval *, struct set_value *set, impl_val *ret_val);
603 } set_func;
604
605 static inline set_func *init_set_func(token_t type, const char *name) {
606 set_func *func = calloc(1, sizeof(*func));
607 func->type = type;
608 func->name = strdup(name);
609 return func;
610 }
611
612 static inline void free_set_func(set_func *func) {
613 free(func->name);
614 free(func);
615 }
616
617 typedef struct set_value {
618 set_func *func;
619 decl_vars *vars;
620 struct {
621 struct set_value *set;
622 impl_val *val;
623 } outer;
624 struct set_value **inner;
625 size_t count;
626 } set_value;
627
628 static inline set_value *init_set_value(set_func *func, decl_vars *vars) {
629 set_value *val = calloc(1, sizeof(*val));
630 val->func = func;
631 val->vars = vars;
632 return val;
633 }
634 static inline set_value *add_inner_set_value(set_value *val, set_value *inner) {
635 val->inner = realloc(val->inner, ++val->count * sizeof(*val->inner));
636 val->inner[val->count-1] = inner;
637 return val;
638 }
639
640 static inline void free_set_value(set_value *val) {
641 free_set_func(val->func);
642 free_decl_vars(val->vars);
643 if (val->inner) {
644 size_t i;
645 for (i = 0; i < val->count; ++i) {
646 free_set_value(val->inner[i]);
647 }
648 free(val->inner);
649 }
650 free(val);
651 }
652
653 typedef struct set_stmt {
654 impl_var *var;
655 set_value *val;
656 impl_arg *arg;
657 } set_stmt;
658
659 static inline set_stmt *init_set_stmt(impl_var *var, set_value *val) {
660 set_stmt *set = calloc(1, sizeof(*set));
661 set->var = var;
662 set->val = val;
663 return set;
664 }
665
666 static inline void free_set_stmt(set_stmt *set) {
667 free_impl_var(set->var);
668 free_set_value(set->val);
669 free(set);
670 }
671
672 typedef struct return_stmt {
673 set_value *set;
674 decl_arg *decl;
675 } return_stmt;
676
677 static inline return_stmt *init_return_stmt(set_value *val) {
678 return_stmt *ret = calloc(1, sizeof(*ret));
679 ret->set = val;
680 return ret;
681 }
682
683 static inline void free_return_stmt(return_stmt *ret) {
684 //free_set_func(ret->func);
685 //free_decl_var(ret->decl);
686 free_set_value(ret->set);
687 free(ret);
688 }
689
690 typedef struct free_call {
691 char *func;
692 decl_vars *vars;
693 decl *decl;
694 } free_call;
695
696 static inline free_call *init_free_call(const char *func, decl_vars *vars) {
697 free_call *f = calloc(1, sizeof(*f));
698 f->func = strdup(func);
699 f->vars = vars;
700 return f;
701 }
702
703 static inline void free_free_call(free_call *f) {
704 free(f->func);
705 free(f);
706 }
707
708 typedef struct free_calls {
709 free_call **list;
710 size_t count;
711 } free_calls;
712
713 static inline free_calls *init_free_calls(free_call *f) {
714 free_calls *fcs = calloc(1, sizeof(*fcs));
715 if (f) {
716 fcs->count = 1;
717 fcs->list = calloc(1, sizeof(*fcs->list));
718 fcs->list[0] = f;
719 }
720 return fcs;
721 }
722
723 static inline void free_free_calls(free_calls *fcs) {
724 size_t i;
725
726 for (i = 0; i < fcs->count; ++i) {
727 free_free_call(fcs->list[i]);
728 }
729 free(fcs->list);
730 free(fcs);
731 }
732
733 static inline free_calls *add_free_call(free_calls *fcs, free_call *f) {
734 fcs->list = realloc(fcs->list, ++fcs->count * sizeof(*fcs->list));
735 fcs->list[fcs->count-1] = f;
736 return fcs;
737 }
738
739 typedef struct free_stmt {
740 free_calls *calls;
741 } free_stmt;
742
743 static inline free_stmt *init_free_stmt(free_calls *calls) {
744 free_stmt *f = calloc(1, sizeof(*f));
745 f->calls = calls;
746 return f;
747 }
748
749 static inline void free_free_stmt(free_stmt *f) {
750 free_free_calls(f->calls);
751 free(f);
752 }
753
754 typedef struct impl_stmt {
755 token_t type;
756 union {
757 let_stmt *let;
758 set_stmt *set;
759 return_stmt *ret;
760 free_stmt *fre;
761 void *ptr;
762 } s;
763 } impl_stmt;
764
765 static inline impl_stmt *init_impl_stmt(token_t type, void *ptr) {
766 impl_stmt *stmt = calloc(1, sizeof(*stmt));
767 stmt->type = type;
768 stmt->s.ptr = ptr;
769 return stmt;
770 }
771
772 static inline void free_impl_stmt(impl_stmt *stmt) {
773 switch (stmt->type) {
774 case PSI_T_LET:
775 free_let_stmt(stmt->s.let);
776 break;
777 case PSI_T_SET:
778 free_set_stmt(stmt->s.set);
779 break;
780 case PSI_T_RETURN:
781 free_return_stmt(stmt->s.ret);
782 break;
783 case PSI_T_FREE:
784 free_free_stmt(stmt->s.fre);
785 break;
786 }
787 free(stmt);
788 }
789
790 typedef struct impl_stmts {
791 struct {
792 return_stmt **list;
793 size_t count;
794 } ret;
795 struct {
796 let_stmt **list;
797 size_t count;
798 } let;
799 struct {
800 set_stmt **list;
801 size_t count;
802 } set;
803 struct {
804 free_stmt **list;
805 size_t count;
806 } fre;
807 } impl_stmts;
808
809 static inline void *add_impl_stmt_ex(void *list, size_t count, void *stmt) {
810 list = realloc(list, count * sizeof(list));
811 ((void **)list)[count-1] = stmt;
812 return list;
813 }
814
815 static inline impl_stmts *add_impl_stmt(impl_stmts *stmts, impl_stmt *stmt) {
816 switch (stmt->type) {
817 case PSI_T_RETURN:
818 stmts->ret.list = add_impl_stmt_ex(stmts->ret.list, ++stmts->ret.count, stmt->s.ret);
819 break;
820 case PSI_T_LET:
821 stmts->let.list = add_impl_stmt_ex(stmts->let.list, ++stmts->let.count, stmt->s.let);
822 break;
823 case PSI_T_SET:
824 stmts->set.list = add_impl_stmt_ex(stmts->set.list, ++stmts->set.count, stmt->s.set);
825 break;
826 case PSI_T_FREE:
827 stmts->fre.list = add_impl_stmt_ex(stmts->fre.list, ++stmts->fre.count, stmt->s.fre);
828 break;
829 }
830 free(stmt);
831 return stmts;
832 }
833
834 static inline impl_stmts *init_impl_stmts(impl_stmt *stmt) {
835 impl_stmts *stmts = calloc(1, sizeof(*stmts));
836 return add_impl_stmt(stmts, stmt);
837 }
838
839 static inline void free_impl_stmts(impl_stmts *stmts) {
840 size_t i;
841
842 for (i = 0; i < stmts->let.count; ++i) {
843 free_let_stmt(stmts->let.list[i]);
844 }
845 free(stmts->let.list);
846 for (i = 0; i < stmts->ret.count; ++i) {
847 free_return_stmt(stmts->ret.list[i]);
848 }
849 free(stmts->ret.list);
850 for (i = 0; i < stmts->set.count; ++i) {
851 free_set_stmt(stmts->set.list[i]);
852 }
853 free(stmts->set.list);
854 for (i = 0; i < stmts->fre.count; ++i) {
855 free_free_stmt(stmts->fre.list[i]);
856 }
857 free(stmts->fre.list);
858 free(stmts);
859 }
860
861 typedef struct impl {
862 impl_func *func;
863 impl_stmts *stmts;
864 decl *decl;
865 } impl;
866
867 static inline impl *init_impl(impl_func *func, impl_stmts *stmts) {
868 impl *i = calloc(1, sizeof(*i));
869 i->func = func;
870 i->stmts = stmts;
871 return i;
872 }
873
874 static inline void free_impl(impl *impl) {
875 free_impl_func(impl->func);
876 free_impl_stmts(impl->stmts);
877 free(impl);
878 }
879
880 typedef struct impls {
881 size_t count;
882 impl **list;
883 } impls;
884
885 static inline impls *add_impl(impls *impls, impl *impl) {
886 if (!impls) {
887 impls = calloc(1, sizeof(*impls));
888 }
889 impls->list = realloc(impls->list, ++impls->count * sizeof(*impls->list));
890 impls->list[impls->count-1] = impl;
891 return impls;
892 }
893
894 static void free_impls(impls *impls) {
895 size_t i;
896
897 for (i = 0; i < impls->count; ++i) {
898 free_impl(impls->list[i]);
899 }
900 free(impls->list);
901 free(impls);
902 }
903
904 typedef struct const_type {
905 token_t type;
906 char *name;
907 } const_type;
908
909 static inline const_type *init_const_type(token_t type, const char *name) {
910 const_type *ct = calloc(1, sizeof(*ct));
911 ct->type = type;
912 ct->name = strdup(name);
913 return ct;
914 }
915
916 static inline void free_const_type(const_type *type) {
917 free(type->name);
918 free(type);
919 }
920
921 typedef struct constant {
922 const_type *type;
923 char *name;
924 impl_def_val *val;
925 } constant;
926
927 static inline constant *init_constant(const_type *type, const char *name, impl_def_val *val) {
928 constant *c = calloc(1, sizeof(*c));
929 c->type = type;
930 c->name = strdup(name);
931 c->val = val;
932 return c;
933 }
934
935 static inline void free_constant(constant *constant) {
936 free_const_type(constant->type);
937 free(constant->name);
938 free_impl_def_val(constant->val);
939 free(constant);
940 }
941
942 typedef struct constants {
943 size_t count;
944 constant **list;
945 } constants;
946
947 static inline constants *add_constant(constants *constants, constant *constant) {
948 if (!constants) {
949 constants = calloc(1, sizeof(*constants));
950 }
951 constants->list = realloc(constants->list, ++constants->count * sizeof(*constants->list));
952 constants->list[constants->count-1] = constant;
953 return constants;
954 }
955
956 static inline void free_constants(constants *c) {
957 size_t i;
958
959 for (i = 0; i < c->count; ++i) {
960 free_constant(c->list[i]);
961 }
962 free(c->list);
963 free(c);
964 }
965
966 #define PSI_ERROR 16
967 #define PSI_WARNING 32
968 typedef void (*psi_error_cb)(int type, const char *msg, ...);
969
970 typedef struct decl_file {
971 char *ln;
972 char *fn;
973 } decl_file;
974
975 static inline void free_decl_file(decl_file *file) {
976 if (file->ln) {
977 free(file->ln);
978 }
979 if (file->fn) {
980 free(file->fn);
981 }
982 memset(file, 0, sizeof(*file));
983 }
984
985 typedef struct decl_libs {
986 void **dl;
987 size_t count;
988 } decl_libs;
989
990 static inline void free_decl_libs(decl_libs *libs) {
991 if (libs->dl) {
992 size_t i;
993 for (i = 0; i < libs->count; ++i) {
994 if (libs->dl[i]) {
995 dlclose(libs->dl[i]);
996 }
997 }
998 free(libs->dl);
999 }
1000 memset(libs, 0, sizeof(*libs));
1001 }
1002
1003 static inline void add_decl_lib(decl_libs *libs, void *dlopened) {
1004 libs->dl = realloc(libs->dl, ++libs->count * sizeof(*libs->dl));
1005 libs->dl[libs->count-1] = dlopened;
1006 }
1007
1008 #define PSI_DATA(D) ((PSI_Data *) (D))
1009 #define PSI_DATA_MEMBERS \
1010 constants *consts; \
1011 decl_typedefs *defs; \
1012 decl_structs *structs; \
1013 decls *decls; \
1014 impls *impls; \
1015 union { \
1016 decl_file file; \
1017 decl_libs libs; \
1018 } psi; \
1019 psi_error_cb error
1020 typedef struct PSI_Data {
1021 PSI_DATA_MEMBERS;
1022 } PSI_Data;
1023
1024 static inline PSI_Data *PSI_DataExchange(PSI_Data *dest, PSI_Data *src) {
1025 if (!dest) {
1026 dest = malloc(sizeof(*dest));
1027 }
1028 memcpy(dest, src, sizeof(*dest));
1029 memset(src, 0, sizeof(*src));
1030 return dest;
1031 }
1032
1033 static inline void PSI_DataDtor(PSI_Data *data) {
1034 if (data->consts) {
1035 free_constants(data->consts);
1036 }
1037 if (data->defs) {
1038 free_decl_typedefs(data->defs);
1039 }
1040 if (data->structs) {
1041 free_decl_structs(data->structs);
1042 }
1043 if (data->decls) {
1044 free_decls(data->decls);
1045 }
1046 if (data->impls) {
1047 free_impls(data->impls);
1048 }
1049 free_decl_file(&data->psi.file);
1050 }
1051
1052 typedef struct PSI_Parser {
1053 PSI_DATA_MEMBERS;
1054 FILE *fp;
1055 unsigned flags;
1056 unsigned errors;
1057 void *proc;
1058 size_t line;
1059 token_t num;
1060 char *cur, *tok, *lim, *eof, *ctx, *mrk, buf[BSIZE];
1061 } PSI_Parser;
1062
1063 static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) {
1064 PSI_Token *T;
1065 size_t token_len;
1066
1067 if (P->cur <= P->tok) {
1068 return NULL;
1069 }
1070
1071 token_len = P->cur - P->tok;
1072
1073 T = calloc(1, sizeof(*T) + token_len);
1074 T->type = P->num;
1075 T->line = P->line;
1076 T->size = token_len;
1077 T->text[token_len] = 0;
1078 memcpy(T->text, P->tok, token_len);
1079
1080 return T;
1081 }
1082
1083 #define PSI_PARSER_DEBUG 0x1
1084
1085 PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, psi_error_cb error, unsigned flags);
1086 void PSI_ParserSyntaxError(PSI_Parser *P, const char *fn, size_t ln, const char *msg, ...);
1087 size_t PSI_ParserFill(PSI_Parser *P, size_t n);
1088 token_t PSI_ParserScan(PSI_Parser *P);
1089 void PSI_ParserParse(PSI_Parser *P, PSI_Token *T);
1090 void PSI_ParserDtor(PSI_Parser *P);
1091 void PSI_ParserFree(PSI_Parser **P);
1092
1093 #endif