1 #ifndef __EOLIAN_DATABASE_H
2 #define __EOLIAN_DATABASE_H
3 
4 #include <setjmp.h>
5 
6 #include <Eolian.h>
7 
8 extern int _eolian_log_dom;
9 extern Eina_Prefix *_eolian_prefix;
10 
11 #ifdef CRI
12 #undef CRI
13 #endif
14 #define CRI(...) EINA_LOG_DOM_CRIT(_eolian_log_dom, __VA_ARGS__)
15 
16 #ifdef ERR
17 #undef ERR
18 #endif
19 #define ERR(...) EINA_LOG_DOM_ERR(_eolian_log_dom, __VA_ARGS__)
20 
21 #ifdef WRN
22 #undef WRN
23 #endif
24 #define WRN(...) EINA_LOG_DOM_WARN(_eolian_log_dom, __VA_ARGS__)
25 
26 #ifdef INF
27 #undef INF
28 #endif
29 #define INF(...) EINA_LOG_DOM_INFO(_eolian_log_dom, __VA_ARGS__)
30 
31 #ifdef DBG
32 #undef DBG
33 #endif
34 #define DBG(...) EINA_LOG_DOM_DBG(_eolian_log_dom, __VA_ARGS__)
35 
36 struct _Eolian_Unit
37 {
38    const char    *file;
39    Eolian_State  *state;
40    Eina_Hash     *children;
41    Eina_Hash     *classes;
42    Eina_Hash     *constants;
43    Eina_Hash     *errors;
44    Eina_Hash     *aliases;
45    Eina_Hash     *structs;
46    Eina_Hash     *enums;
47    Eina_Hash     *objects;
48    unsigned short version;
49 };
50 
51 typedef struct _Eolian_State_Area
52 {
53    Eolian_Unit unit;
54 
55    Eina_Hash *units;
56 
57    Eina_Hash *classes_f;
58    Eina_Hash *aliases_f;
59    Eina_Hash *structs_f;
60    Eina_Hash *enums_f;
61    Eina_Hash *constants_f;
62    Eina_Hash *errors_f;
63    Eina_Hash *objects_f;
64 } Eolian_State_Area;
65 
66 struct _Eolian_State
67 {
68    Eolian_State_Area main;
69    Eolian_State_Area staging;
70 
71    Eolian_Panic_Cb panic;
72    Eina_Stringshare *panic_msg;
73    jmp_buf jmp_env;
74 
75    Eolian_Error_Cb error;
76    void *error_data;
77 
78    Eina_Hash *filenames_eo; /* filename to full path mapping */
79    Eina_Hash *filenames_eot;
80 
81    Eina_Hash *defer;
82 };
83 
84 struct _Eolian_Object
85 {
86    Eolian_Unit *unit;
87    Eina_Stringshare *file;
88    Eina_Stringshare *name;
89    Eina_Stringshare *c_name;
90    int line;
91    int column;
92    int refcount;
93    Eolian_Object_Type type;
94    Eina_Bool validated: 1;
95    Eina_Bool is_beta: 1;
96 };
97 
98 static inline void
eolian_object_ref(Eolian_Object * obj)99 eolian_object_ref(Eolian_Object *obj)
100 {
101    ++obj->refcount;
102 }
103 
104 static inline Eina_Bool
eolian_object_unref(Eolian_Object * obj)105 eolian_object_unref(Eolian_Object *obj)
106 {
107    return (--obj->refcount > 0);
108 }
109 
110 static inline void
eolian_object_add(Eolian_Object * obj,Eina_Stringshare * name,Eina_Hash * hash)111 eolian_object_add(Eolian_Object *obj, Eina_Stringshare *name, Eina_Hash *hash)
112 {
113    eina_hash_add(hash, name, obj);
114    eolian_object_ref(obj);
115 }
116 
117 #define EOLIAN_OBJECT_ADD(tunit, name, obj, memb) \
118 { \
119    eolian_object_add(&obj->base, name, tunit->state->staging.unit.memb); \
120    eolian_object_add(&obj->base, name, tunit->memb); \
121 }
122 
123 static inline void eolian_state_vlog(const Eolian_State *state, const Eolian_Object *obj, const char *fmt, va_list args) EINA_ARG_NONNULL(1, 3);
124 static inline void eolian_state_log(const Eolian_State *state, const char *fmt, ...) EINA_ARG_NONNULL(1, 2) EINA_PRINTF(2, 3);
125 static inline void eolian_state_log_obj(const Eolian_State *state, const Eolian_Object *obj, const char *fmt, ...) EINA_ARG_NONNULL(1, 2, 3) EINA_PRINTF(3, 4);
126 
127 static inline void eolian_state_panic(Eolian_State *state, const char *fmt, ...) EINA_ARG_NONNULL(1, 2) EINA_PRINTF(2, 3);
128 
129 static inline void
eolian_state_vlog(const Eolian_State * state,const Eolian_Object * obj,const char * fmt,va_list args)130 eolian_state_vlog(const Eolian_State *state, const Eolian_Object *obj,
131                  const char *fmt, va_list args)
132 {
133    Eina_Strbuf *sb = eina_strbuf_new();
134    eina_strbuf_append_vprintf(sb, fmt, args);
135    state->error(obj, eina_strbuf_string_get(sb), state->error_data);
136    eina_strbuf_free(sb);
137 }
138 
139 static inline void
eolian_state_log(const Eolian_State * state,const char * fmt,...)140 eolian_state_log(const Eolian_State *state, const char *fmt, ...)
141 {
142    va_list args;
143    va_start(args, fmt);
144    eolian_state_vlog(state, NULL, fmt, args);
145    va_end(args);
146 }
147 
148 static inline void
eolian_state_log_obj(const Eolian_State * state,const Eolian_Object * obj,const char * fmt,...)149 eolian_state_log_obj(const Eolian_State *state, const Eolian_Object *obj,
150                      const char *fmt, ...)
151 {
152    va_list args;
153    va_start(args, fmt);
154    eolian_state_vlog(state, obj, fmt, args);
155    va_end(args);
156 }
157 
158 static inline void
eolian_state_panic(Eolian_State * state,const char * fmt,...)159 eolian_state_panic(Eolian_State *state, const char *fmt, ...)
160 {
161    va_list args;
162    va_start(args, fmt);
163    state->panic_msg = eina_stringshare_vprintf(fmt, args);
164    va_end(args);
165    longjmp(state->jmp_env, 1);
166 }
167 
168 struct _Eolian_Documentation
169 {
170    Eolian_Object base;
171    Eina_Stringshare *summary;
172    Eina_Stringshare *description;
173    Eina_Stringshare *since;
174    Eina_List *ref_dbg;
175 };
176 
177 struct _Eolian_Class
178 {
179    Eolian_Object base;
180    Eolian_Class_Type type;
181    Eolian_Documentation *doc;
182    Eina_Stringshare *c_prefix;
183    Eina_Stringshare *ev_prefix;
184    Eina_Stringshare *data_type;
185    union {
186       Eolian_Class *parent;
187       Eina_Stringshare *parent_name;
188    };
189    Eina_List *extends; /* Eolian_Class */
190    Eina_List *properties; /* Eolian_Function */
191    Eina_List *methods; /* Eolian_Function */
192    Eina_List *implements; /* Eolian_Implement */
193    Eina_List *constructors; /* Eolian_Constructor */
194    Eina_List *events; /* Eolian_Event */
195    Eina_List *parts; /* Eolian_Part */
196    Eina_List *composite; /* Eolian_Class */
197    Eina_List *requires; /* a list of required other classes only used internally */
198    Eina_List *callables; /* internal for now */
199    Eina_Bool class_ctor_enable:1;
200    Eina_Bool class_dtor_enable:1;
201 };
202 
203 struct _Eolian_Function
204 {
205    Eolian_Object base;
206    Eolian_Object set_base;
207    union { /* lists of Eolian_Function_Parameter */
208        Eina_List *params;
209        struct {
210            Eina_List *prop_values;
211            Eina_List *prop_values_get;
212            Eina_List *prop_values_set;
213            Eina_List *prop_keys;
214            Eina_List *prop_keys_get;
215            Eina_List *prop_keys_set;
216        };
217    };
218    Eolian_Function_Type type;
219    Eolian_Object_Scope get_scope;
220    Eolian_Object_Scope set_scope;
221    Eolian_Type *get_ret_type;
222    Eolian_Type *set_ret_type;
223    Eolian_Expression *get_ret_val;
224    Eolian_Expression *set_ret_val;
225    Eolian_Implement *impl;
226    Eolian_Documentation *get_return_doc;
227    Eolian_Documentation *set_return_doc;
228    Eina_List *ctor_of;
229    Eolian_Class *klass;
230    Eina_Bool obj_is_const :1; /* True if the object has to be const. Useful for a few methods. */
231    Eina_Bool get_return_no_unused :1; /* also used for methods */
232    Eina_Bool set_return_no_unused :1;
233    Eina_Bool get_return_move      :1;
234    Eina_Bool set_return_move      :1;
235    Eina_Bool get_return_by_ref    :1;
236    Eina_Bool set_return_by_ref    :1;
237    Eina_Bool is_static :1;
238 };
239 
240 struct _Eolian_Part
241 {
242    Eolian_Object base;
243    /* when not validated, class name is stored */
244    union
245    {
246       Eina_Stringshare *klass_name;
247       Eolian_Class *klass;
248    };
249    Eolian_Documentation *doc;
250 };
251 
252 struct _Eolian_Function_Parameter
253 {
254    Eolian_Object base;
255    Eolian_Type *type;
256    Eolian_Expression *value;
257    Eolian_Documentation *doc;
258    Eolian_Parameter_Direction param_dir;
259    Eina_Bool optional :1; /* True if this argument is optional */
260    Eina_Bool by_ref   :1;
261    Eina_Bool move     :1;
262 };
263 
264 typedef enum
265 {
266    EOLIAN_C_TYPE_DEFAULT = 0,
267    EOLIAN_C_TYPE_PARAM,
268    EOLIAN_C_TYPE_RETURN
269 } Eolian_C_Type_Type;
270 
271 struct _Eolian_Type
272 {
273    Eolian_Object base;
274    Eolian_Type_Type type;
275    Eolian_Type_Builtin_Type btype;
276    Eolian_Type *base_type;
277    Eolian_Type *next_type;
278    union
279    {
280       Eolian_Class *klass;
281       Eolian_Typedecl *tdecl;
282       Eolian_Error *error;
283    };
284    Eina_Bool is_const  :1;
285    Eina_Bool is_ptr    :1;
286    Eina_Bool move      :1;
287    Eina_Bool ownable   :1;
288 };
289 
290 struct _Eolian_Typedecl
291 {
292    Eolian_Object base;
293    Eolian_Typedecl_Type type;
294    Eolian_Type      *base_type;
295    Eina_Hash        *fields;
296    Eina_List        *field_list;
297    Eolian_Function *function_pointer;
298    Eolian_Documentation *doc;
299    Eina_Stringshare *legacy;
300    Eina_Stringshare *freefunc;
301    Eina_Bool is_extern :1;
302    Eina_Bool ownable :1;
303 };
304 
305 struct _Eolian_Implement
306 {
307    Eolian_Object base;
308    const Eolian_Class *klass;
309    const Eolian_Class *implklass;
310    const Eolian_Function *foo_id;
311    Eolian_Documentation *common_doc;
312    Eolian_Documentation *get_doc;
313    Eolian_Documentation *set_doc;
314    Eina_Bool is_prop_get :1;
315    Eina_Bool is_prop_set :1;
316    Eina_Bool get_pure_virtual :1;
317    Eina_Bool set_pure_virtual :1;
318    Eina_Bool get_auto: 1;
319    Eina_Bool set_auto: 1;
320    Eina_Bool get_empty: 1;
321    Eina_Bool set_empty: 1;
322 };
323 
324 struct _Eolian_Constructor
325 {
326    Eolian_Object base;
327    const Eolian_Class *klass;
328    Eina_Bool is_optional: 1;
329 };
330 
331 struct _Eolian_Event
332 {
333    Eolian_Object base;
334    Eolian_Documentation *doc;
335    Eolian_Type *type;
336    Eolian_Class *klass;
337    Eolian_Object_Scope scope;
338    Eina_Bool is_hot  :1;
339    Eina_Bool is_restart :1;
340 };
341 
342 struct _Eolian_Error
343 {
344    Eolian_Object base;
345    Eina_Stringshare *msg;
346    Eolian_Documentation *doc;
347    Eina_Bool is_extern :1;
348 };
349 
350 struct _Eolian_Struct_Type_Field
351 {
352    Eolian_Object     base;
353    Eolian_Type      *type;
354    Eolian_Documentation *doc;
355    Eina_Bool move     :1;
356    Eina_Bool by_ref   :1;
357 };
358 
359 struct _Eolian_Enum_Type_Field
360 {
361    Eolian_Object      base;
362    Eolian_Typedecl   *base_enum;
363    Eolian_Expression *value;
364    Eolian_Documentation *doc;
365    Eina_Bool is_public_value :1;
366 };
367 
368 struct _Eolian_Expression
369 {
370    Eolian_Object base;
371    Eolian_Expression_Type type;
372    union
373    {
374       struct
375       {
376          Eolian_Binary_Operator binop;
377          Eolian_Expression *lhs;
378          Eolian_Expression *rhs;
379       };
380       struct
381       {
382          union
383          {
384             Eolian_Unary_Operator unop;
385             Eolian_Value_Union value;
386          };
387          Eolian_Expression *expr;
388       };
389    };
390    Eina_Bool weak_lhs :1;
391    Eina_Bool weak_rhs :1;
392 };
393 
394 struct _Eolian_Constant
395 {
396    Eolian_Object         base;
397    Eolian_Type          *base_type;
398    Eolian_Expression    *value;
399    Eolian_Documentation *doc;
400    Eina_Bool is_extern :1;
401 };
402 
403 char *database_class_to_filename(const char *cname);
404 Eina_Bool database_validate(const Eolian_Unit *src);
405 Eina_Bool database_check(const Eolian_State *state);
406 /* if isdep is EINA_TRUE, parse as a dependency of current unit */
407 void database_defer(Eolian_State *state, const char *fname, Eina_Bool isdep);
408 
409 void database_object_add(Eolian_Unit *unit, const Eolian_Object *obj);
410 
411 void database_doc_del(Eolian_Documentation *doc);
412 
413 void database_unit_init(Eolian_State *state, Eolian_Unit *unit, const char *file);
414 void database_unit_del(Eolian_Unit *unit);
415 
416 Eolian_Object_Type database_doc_token_ref_resolve(const Eolian_Doc_Token *tok,
417                                                   const Eolian_Unit *unit1,
418                                                   const Eolian_Unit *unit2,
419                                                   const Eolian_Object **data1,
420                                                   const Eolian_Object **data2);
421 
422 /* types */
423 
424 void database_type_add(Eolian_Unit *unit, Eolian_Typedecl *tp);
425 void database_struct_add(Eolian_Unit *unit, Eolian_Typedecl *tp);
426 void database_enum_add(Eolian_Unit *unit, Eolian_Typedecl *tp);
427 void database_type_del(Eolian_Type *tp);
428 void database_typedecl_del(Eolian_Typedecl *tp);
429 
430 void database_type_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name, Eolian_C_Type_Type ctype, Eina_Bool by_ref);
431 void database_typedecl_to_str(const Eolian_Typedecl *tp, Eina_Strbuf *buf);
432 
433 Eolian_Typedecl *database_type_decl_find(const Eolian_Unit *src, const Eolian_Type *tp);
434 
435 Eina_Bool database_type_is_ownable(const Eolian_Unit *unit, const Eolian_Type *tp, Eina_Bool allow_void, const Eolian_Type **otp);
436 
437 /* expressions */
438 
439 typedef void (*Expr_Obj_Cb)(const Eolian_Object *obj, void *data);
440 
441 Eolian_Value database_expr_eval(const Eolian_Unit *unit, Eolian_Expression *expr, Eolian_Expression_Mask mask, Expr_Obj_Cb cb, void *data);
442 Eolian_Value database_expr_eval_type(const Eolian_Unit *unit, Eolian_Expression *expr, const Eolian_Type *type, Expr_Obj_Cb cb, void *data);
443 void database_expr_del(Eolian_Expression *expr);
444 void database_expr_print(Eolian_Expression *expr);
445 
446 /* variables */
447 
448 void database_constant_del(Eolian_Constant *var);
449 void database_constant_add(Eolian_Unit *unit, Eolian_Constant *var);
450 
451 /* classes */
452 void database_class_del(Eolian_Class *cl);
453 
454 /* functions */
455 void database_function_del(Eolian_Function *fid);
456 void database_function_constructor_add(Eolian_Function *func, const Eolian_Class *klass);
457 Eina_Bool database_function_is_type(Eolian_Function *fid, Eolian_Function_Type ftype);
458 
459 /* func parameters */
460 void database_parameter_del(Eolian_Function_Parameter *pdesc);
461 
462 /* implements */
463 void database_implement_del(Eolian_Implement *impl);
464 
465 /* constructors */
466 void database_constructor_del(Eolian_Constructor *ctor);
467 
468 /* events */
469 void database_event_del(Eolian_Event *event);
470 
471 /* parts */
472 void database_part_del(Eolian_Part *part);
473 
474 /* errors */
475 void database_error_del(Eolian_Error *err);
476 void database_error_add(Eolian_Unit *unit, Eolian_Error *err);
477 
478 #endif
479