#include #include "eo_parser.h" #include "eolian_database.h" Eina_List *_classes = NULL; Eina_Hash *_aliases = NULL; Eina_Hash *_structs = NULL; Eina_Hash *_filenames = NULL; Eina_Hash *_tfilenames = NULL; static int _database_init_count = 0; int database_init() { if (_database_init_count > 0) return ++_database_init_count; eina_init(); _aliases = eina_hash_stringshared_new(EINA_FREE_CB(database_type_del)); _structs = eina_hash_stringshared_new(EINA_FREE_CB(database_type_del)); _filenames = eina_hash_string_small_new(free); _tfilenames = eina_hash_string_small_new(free); return ++_database_init_count; } int database_shutdown() { if (_database_init_count <= 0) { ERR("Init count not greater than 0 in shutdown."); return 0; } _database_init_count--; if (_database_init_count == 0) { Eolian_Class *class; EINA_LIST_FREE(_classes, class) database_class_del(class); eina_hash_free(_aliases); eina_hash_free(_structs); eina_hash_free(_filenames); eina_hash_free(_tfilenames); eina_shutdown(); } return _database_init_count; } #define EO_SUFFIX ".eo" #define EOT_SUFFIX ".eot" static char * join_path(const char *path, const char *file) { Eina_Strbuf *buf = eina_strbuf_new(); char *ret; eina_strbuf_append(buf, path); eina_strbuf_append_char(buf, '/'); eina_strbuf_append(buf, file); ret = eina_strbuf_string_steal(buf); eina_strbuf_free(buf); return ret; } static void _scan_cb(const char *name, const char *path, void *data EINA_UNUSED) { size_t len; Eina_Bool is_eo = eina_str_has_suffix(name, EO_SUFFIX); if (!is_eo && !eina_str_has_suffix(name, EOT_SUFFIX)) return; len = strlen(name) - (is_eo ? sizeof(EO_SUFFIX) : sizeof(EOT_SUFFIX)) + 1; eina_hash_add(is_eo ? _filenames : _tfilenames, eina_stringshare_add_length(name, len), join_path(path, name)); } EAPI Eina_Bool eolian_directory_scan(const char *dir) { if (!dir) return EINA_FALSE; eina_file_dir_list(dir, EINA_TRUE, _scan_cb, NULL); return EINA_TRUE; } EAPI Eina_Bool eolian_system_directory_scan() { Eina_Bool ret; Eina_Strbuf *buf = eina_strbuf_new(); eina_strbuf_append(buf, eina_prefix_data_get(_eolian_prefix)); eina_strbuf_append(buf, "/include"); ret = eolian_directory_scan(eina_strbuf_string_get(buf)); eina_strbuf_free(buf); return ret; } static char * _eolian_class_to_filename(const char *filename) { char *ret; Eina_Strbuf *strbuf = eina_strbuf_new(); eina_strbuf_append(strbuf, filename); eina_strbuf_replace_all(strbuf, ".", "_"); ret = eina_strbuf_string_steal(strbuf); eina_strbuf_free(strbuf); eina_str_tolower(&ret); return ret; } EAPI Eina_Bool eolian_eot_file_parse(const char *filepath) { return eo_parser_database_fill(filepath, EINA_TRUE); } EAPI Eina_Bool eolian_eo_file_parse(const char *filepath) { const Eina_List *itr; const Eolian_Class *class = eolian_class_find_by_file(filepath); const char *inherit_name; Eolian_Implement *impl; if (!class) { if (!eo_parser_database_fill(filepath, EINA_FALSE)) return EINA_FALSE; class = eolian_class_find_by_file(filepath); if (!class) { ERR("No class for file %s", filepath); return EINA_FALSE; } } EINA_LIST_FOREACH(eolian_class_inherits_list_get(class), itr, inherit_name) { if (!eolian_class_find_by_name(inherit_name)) { char *filename = _eolian_class_to_filename(inherit_name); filepath = eina_hash_find(_filenames, filename); if (!filepath) { ERR("Unable to find a file for class %s", inherit_name); return EINA_FALSE; } if (!eolian_eo_file_parse(filepath)) return EINA_FALSE; if (!eolian_class_find_by_name(inherit_name)) { ERR("Unable to find class %s", inherit_name); return EINA_FALSE; } free(filename); } } EINA_LIST_FOREACH(eolian_class_implements_list_get(class), itr, impl) { const Eolian_Class *impl_class; const Eolian_Function *impl_func; Eolian_Function_Type impl_type = EOLIAN_UNRESOLVED; eolian_implement_information_get(impl, &impl_class, &impl_func, &impl_type); if (!impl_func) { ERR("Unable to find function %s", eolian_implement_full_name_get(impl)); return EINA_FALSE; } } return EINA_TRUE; } static Eina_Bool _tfile_parse(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata) { Eina_Bool *ret = fdata; if (*ret) *ret = eolian_eot_file_parse(data); return *ret; } EAPI Eina_Bool eolian_all_eot_files_parse() { Eina_Bool ret = EINA_TRUE; eina_hash_foreach(_tfilenames, _tfile_parse, &ret); return ret; } static Eina_Bool _file_parse(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata) { Eina_Bool *ret = fdata; if (*ret) *ret = eolian_eo_file_parse(data); return *ret; } EAPI Eina_Bool eolian_all_eo_files_parse() { Eina_Bool ret = EINA_TRUE; eina_hash_foreach(_filenames, _file_parse, &ret); return ret; }