static Efreet_Desktop * efreet_util_cache_find(const char *search, const char *what1, const char *what2) { char **keys; int num, i; Efreet_Desktop *ret = NULL; if (!efreet_cache_check(&cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL; if ((!what1) && (!what2)) return NULL; keys = eet_list(cache, search, &num); if (!keys) return NULL; for (i = 0; i < num; i++) { const char *data; int size, id; char key[PATH_MAX]; data = eet_read_direct(cache, keys[i], &size); if (!data) continue; if (!((what1 && !strcmp(what1, data)) || (what2 && !strcmp(what2, data)))) continue; id = atoi(keys[i]); snprintf(key, sizeof(key), "%d::op", id); data = eet_read_direct(cache, key, &size); if (!data) continue; ret = efreet_desktop_get(data); if (ret) break; } free(keys); return ret; }
static Eina_List * efreet_util_cache_glob_list(const char *search, const char *what) { char **keys; int num, i; Eina_List *ret = NULL; if (!efreet_cache_check(&cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL; if (!what) return NULL; keys = eet_list(cache, search, &num); if (!keys) return NULL; for (i = 0; i < num; i++) { const char *data; int size, id; char key[PATH_MAX]; Efreet_Desktop *desk; data = eet_read_direct(cache, keys[i], &size); if (!data) continue; if (!efreet_util_glob_match(data, what)) continue; id = atoi(keys[i]); snprintf(key, sizeof(key), "%d::op", id); data = eet_read_direct(cache, key, &size); if (!data) continue; desk = efreet_desktop_get(data); if (desk) ret = eina_list_append(ret, desk); } free(keys); return ret; }
/** * Find all desktops where exec matches a glob pattern * * This list must be freed using EINA_LIST_FREE / efreet_desktop_free * * @param glob the pattern to match * @return a list of desktops */ EAPI Eina_List * efreet_util_desktop_exec_glob_list(const char *glob) { char **keys; int num, i; Eina_List *ret = NULL; if (!efreet_cache_check(&cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL; if (!glob) return NULL; keys = eet_list(cache, "*::e", &num); if (!keys) return NULL; for (i = 0; i < num; i++) { const char *data; char *exe; int size, id; char key[PATH_MAX]; Efreet_Desktop *desk; data = eet_read_direct(cache, keys[i], &size); if (!data) continue; exe = ecore_file_app_exe_get(data); if (!exe) continue; if (!efreet_util_glob_match(exe, glob)) { free(exe); continue; } free(exe); id = atoi(keys[i]); snprintf(key, sizeof(key), "%d::op", id); data = eet_read_direct(cache, key, &size); if (!data) continue; desk = efreet_desktop_get(data); if (desk) ret = eina_list_append(ret, desk); } free(keys); return ret; }
/** * Find a desktop by exec * * return value must be freed by efreet_desktop_free * * @param exec the exec name * @return a desktop */ EAPI Efreet_Desktop * efreet_util_desktop_exec_find(const char *exec) { char **keys; int num, i; Efreet_Desktop *ret = NULL; if (!efreet_cache_check(&cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL; if (!exec) return NULL; keys = eet_list(cache, "*::e", &num); if (!keys) return NULL; for (i = 0; i < num; i++) { const char *data, *file; char *exe; int size, id; char key[PATH_MAX]; data = eet_read_direct(cache, keys[i], &size); if (!data) continue; exe = ecore_file_app_exe_get(data); if (!exe) continue; file = ecore_file_file_get(exe); if (!file) continue; if (strcmp(exec, exe) && strcmp(exec, file)) { free(exe); continue; } free(exe); id = atoi(keys[i]); snprintf(key, sizeof(key), "%d::op", id); data = eet_read_direct(cache, key, &size); if (!data) continue; ret = efreet_desktop_get(data); if (ret) break; } free(keys); return ret; }
static Eina_Bool _evas_gl_common_shader_binary_checksum_check(Evas_GL_Shared *shared, Eet_File *ef) { Eina_Bool ret = EINA_FALSE; const char *old_hash; int len = 0; if (!ef) return EINA_FALSE; _evas_gl_common_shader_binary_hash(shared); old_hash = eet_read_direct(ef, SHADER_EET_CHECKSUM, &len); if (old_hash && (len == (eina_stringshare_strlen(shared->shaders_checksum) + 1)) && (!strcmp(shared->shaders_checksum, old_hash))) ret = EINA_TRUE; return ret; }
/** * Find all desktop categories * This list must be freed using EINA_LIST_FREE * * @return an Eina_List of category names (const char *) */ EAPI Eina_List * efreet_util_desktop_categories_list(void) { char **keys; int num, i; Eina_List *ret = NULL; if (!efreet_cache_check(&cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL; keys = eet_list(cache, "*::ca", &num); if (!keys) return NULL; for (i = 0; i < num; i++) { const char *data; int size; data = eet_read_direct(cache, keys[i], &size); if (!data) continue; if (eina_list_search_unsorted(ret, EINA_COMPARE_CB(strcmp), data)) continue; ret = eina_list_append(ret, data); } free(keys); return ret; }
END_TEST START_TEST(eet_test_file_data) { Eet_Data_Descriptor *edd; Eet_Test_Ex_Type *result; Eet_Dictionary *ed; Eet_File *ef; char **list; char *file; Eet_Data_Descriptor_Class eddc; Eet_Test_Ex_Type etbt; int size; int test; int tmpfd; file = strdup("/tmp/eet_suite_testXXXXXX"); eet_init(); eet_test_ex_set(&etbt, 0); etbt.list = eina_list_prepend(etbt.list, eet_test_ex_set(NULL, 1)); etbt.list = eina_list_prepend(etbt.list, eet_test_ex_set(NULL, 1)); etbt.hash = eina_hash_string_superfast_new(NULL); eina_hash_add(etbt.hash, EET_TEST_KEY1, eet_test_ex_set(NULL, 2)); etbt.hash = eina_hash_string_superfast_new(NULL); eina_hash_add(etbt.hash, EET_TEST_KEY2, eet_test_ex_set(NULL, 2)); etbt.ilist = eina_list_prepend(etbt.ilist, &i42); etbt.ilist = eina_list_prepend(etbt.ilist, &i42); etbt.ihash = eina_hash_string_superfast_new(NULL); eina_hash_add(etbt.ihash, EET_TEST_KEY1, &i7); etbt.ihash = eina_hash_string_superfast_new(NULL); eina_hash_add(etbt.ihash, EET_TEST_KEY2, &i7); etbt.slist = eina_list_prepend(NULL, "test"); etbt.shash = eina_hash_string_superfast_new(NULL); eina_hash_add(etbt.shash, EET_TEST_KEY1, "test"); memset(&etbt.charray, 0, sizeof(etbt.charray)); etbt.charray[0] = "test"; eet_test_setup_eddc(&eddc); eddc.name = "Eet_Test_Ex_Type"; eddc.size = sizeof(Eet_Test_Ex_Type); edd = eet_data_descriptor_file_new(&eddc); fail_if(!edd); eet_build_ex_descriptor(edd, EINA_FALSE); fail_if(-1 == (tmpfd = mkstemp(file))); fail_if(!!close(tmpfd)); /* Insert an error in etbt. */ etbt.i = 0; /* Save the encoded data in a file. */ ef = eet_open(file, EET_FILE_MODE_READ_WRITE); fail_if(!ef); fail_if(!eet_data_write(ef, edd, EET_TEST_FILE_KEY1, &etbt, 0)); result = eet_data_read(ef, edd, EET_TEST_FILE_KEY1); fail_if(!result); fail_if(eet_mode_get(ef) != EET_FILE_MODE_READ_WRITE); /* Test string space. */ ed = eet_dictionary_get(ef); fail_if(!eet_dictionary_string_check(ed, result->str)); fail_if(eet_dictionary_string_check(ed, result->istr)); eet_close(ef); /* Attempt to replace etbt by the correct one. */ etbt.i = EET_TEST_INT; ef = eet_open(file, EET_FILE_MODE_READ_WRITE); fail_if(!ef); fail_if(!eet_data_write(ef, edd, EET_TEST_FILE_KEY1, &etbt, 0)); result = eet_data_read(ef, edd, EET_TEST_FILE_KEY1); fail_if(!result); /* Test the resulting data. */ fail_if(eet_test_ex_check(result, 0, EINA_FALSE) != 0); eet_close(ef); /* Read back the data. */ ef = eet_open(file, EET_FILE_MODE_READ_WRITE); fail_if(!ef); fail_if(!eet_data_write(ef, edd, EET_TEST_FILE_KEY2, &etbt, 0)); result = eet_data_read(ef, edd, EET_TEST_FILE_KEY1); fail_if(!result); /* Test string space. */ ed = eet_dictionary_get(ef); fail_if(!ed); fail_if(!eet_dictionary_string_check(ed, result->str)); fail_if(eet_dictionary_string_check(ed, result->istr)); /* Test the resulting data. */ fail_if(eet_test_ex_check(result, 0, EINA_FALSE) != 0); fail_if(eet_test_ex_check(eina_list_data_get(result->list), 1, EINA_FALSE) != 0); fail_if(eina_list_data_get(result->ilist) == NULL); fail_if(*((int *)eina_list_data_get(result->ilist)) != 42); fail_if(eina_list_data_get(result->slist) == NULL); fail_if(strcmp(eina_list_data_get(result->slist), "test") != 0); fail_if(eina_hash_find(result->shash, EET_TEST_KEY1) == NULL); fail_if(strcmp(eina_hash_find(result->shash, EET_TEST_KEY1), "test") != 0); fail_if(strcmp(result->charray[0], "test") != 0); test = 0; if (result->hash) eina_hash_foreach(result->hash, func, &test); fail_if(test != 0); if (result->ihash) eina_hash_foreach(result->ihash, func7, &test); fail_if(test != 0); list = eet_list(ef, "keys/*", &size); fail_if(eet_num_entries(ef) != 2); fail_if(size != 2); fail_if(!(strcmp(list[0], EET_TEST_FILE_KEY1) == 0 && strcmp(list[1], EET_TEST_FILE_KEY2) == 0) && !(strcmp(list[0], EET_TEST_FILE_KEY2) == 0 && strcmp(list[1], EET_TEST_FILE_KEY1) == 0)); free(list); fail_if(eet_delete(ef, NULL) != 0); fail_if(eet_delete(NULL, EET_TEST_FILE_KEY1) != 0); fail_if(eet_delete(ef, EET_TEST_FILE_KEY1) == 0); list = eet_list(ef, "keys/*", &size); fail_if(size != 1); fail_if(eet_num_entries(ef) != 1); /* Test some more wrong case */ fail_if(eet_data_read(ef, edd, "plop") != NULL); fail_if(eet_data_read(ef, edd, EET_TEST_FILE_KEY1) != NULL); /* Reinsert and reread data */ fail_if(!eet_data_write(ef, edd, EET_TEST_FILE_KEY1, &etbt, 0)); fail_if(eet_data_read(ef, edd, EET_TEST_FILE_KEY1) == NULL); fail_if(eet_read_direct(ef, EET_TEST_FILE_KEY1, &size) == NULL); eet_close(ef); fail_if(unlink(file) != 0); eet_shutdown(); }
static int _evas_gl_common_shader_binary_save(Evas_GL_Shared *shared) { char bin_dir_path[PATH_MAX]; char bin_file_path[PATH_MAX]; char tmp_file_name[PATH_MAX]; int tmpfd = -1, copy; Eina_Tmpstr *tmp_file_path = NULL; Eet_File *ef = NULL; Evas_GL_Program *p; Eina_Iterator *it; char pname[32]; /* use eet */ if (!eet_init()) return 0; if (!evas_gl_common_file_cache_dir_check(bin_dir_path, sizeof(bin_dir_path))) { if (!evas_gl_common_file_cache_mkpath(bin_dir_path)) return 0; /* we can't make directory */ } copy = evas_gl_common_file_cache_file_check(bin_dir_path, SHADER_EET_CACHENAME, bin_file_path, sizeof(bin_dir_path)); /* use mkstemp for writing */ snprintf(tmp_file_name, sizeof(tmp_file_name), "%s.XXXXXX.cache", bin_file_path); tmpfd = eina_file_mkstemp(tmp_file_name, &tmp_file_path); if (tmpfd < 0) goto error; /* copy old file */ if (copy) { ef = eet_open(tmp_file_path, EET_FILE_MODE_READ); if (!ef) goto save; if (!_evas_gl_common_shader_binary_checksum_check(shared, ef)) copy = EINA_FALSE; eet_close(ef); if (copy) eina_file_copy(bin_file_path, tmp_file_path, EINA_FILE_COPY_DATA, NULL, NULL); } save: ef = eet_open(tmp_file_path, copy ? EET_FILE_MODE_READ_WRITE : EET_FILE_MODE_WRITE); if (!ef) goto error; if (!_evas_gl_common_shader_binary_checksum_write(shared, ef)) goto error; it = eina_hash_iterator_data_new(shared->shaders_hash); EINA_ITERATOR_FOREACH(it, p) { if (!p->bin_saved) { int len = 0; sprintf(pname, SHADER_PROG_NAME_FMT, p->flags); eet_read_direct(ef, pname, &len); if (len > 0) p->bin_saved = 1; // assume bin data is correct else _evas_gl_common_shader_program_binary_save(p, ef); } } eina_iterator_free(it); if (shared->shaders_cache) { eet_close(shared->shaders_cache); shared->shaders_cache = NULL; eet_shutdown(); } if (eet_close(ef) != EET_ERROR_NONE) goto destroyed; if (rename(tmp_file_path, bin_file_path) < 0) goto destroyed; eina_tmpstr_del(tmp_file_path); close(tmpfd); eet_shutdown(); shared->needs_shaders_flush = 0; return 1; destroyed: ef = NULL; error: if (tmpfd >= 0) close(tmpfd); if (ef) eet_close(ef); if (evas_gl_common_file_cache_file_exists(tmp_file_path)) unlink(tmp_file_path); eina_tmpstr_del(tmp_file_path); eet_shutdown(); return 0; }
static Evas_GL_Program * _evas_gl_common_shader_program_binary_load(Eet_File *ef, unsigned int flags) { int num = 0, length = 0; int *formats = NULL; void *data = NULL; char pname[32]; GLint ok = 0, prg, vtx = GL_NONE, frg = GL_NONE; Evas_GL_Program *p = NULL; Eina_Bool direct = 1; if (!ef || !glsym_glProgramBinary) return NULL; sprintf(pname, SHADER_PROG_NAME_FMT, flags); data = (void *) eet_read_direct(ef, pname, &length); if (!data) { data = eet_read(ef, pname, &length); direct = 0; } if ((!data) || (length <= 0)) goto finish; glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &num); if (num <= 0) goto finish; formats = calloc(num, sizeof(int)); if (!formats) goto finish; glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, formats); if (!formats[0]) goto finish; prg = glCreateProgram(); #if 1 // TODO: invalid rendering error occurs when attempting to use a // glProgramBinary. in order to render correctly we should create a dummy // vertex shader. vtx = glCreateShader(GL_VERTEX_SHADER); glAttachShader(prg, vtx); frg = glCreateShader(GL_FRAGMENT_SHADER); glAttachShader(prg, frg); #endif glsym_glProgramBinary(prg, formats[0], data, length); _attributes_bind(prg); glGetProgramiv(prg, GL_LINK_STATUS, &ok); if (!ok) { gl_compile_link_error(prg, "load a program object", EINA_FALSE); ERR("Abort load of program (%s)", pname); glDeleteProgram(prg); goto finish; } p = calloc(1, sizeof(*p)); p->flags = flags; p->prog = prg; p->reset = EINA_TRUE; p->bin_saved = EINA_TRUE; p->uniform.mvp = glGetUniformLocation(prg, "mvp"); p->uniform.rotation_id = glGetUniformLocation(prg, "rotation_id"); evas_gl_common_shader_textures_bind(p); finish: if (vtx) glDeleteShader(vtx); if (frg) glDeleteShader(frg); free(formats); if (!direct) free(data); return p; }
/* * (params[0] | (top of stack)) == filename * params[1 | 0] == key * params[2 | 1] == (cipher pass) */ static const Elixir_Loader_File * _elixir_eet_request(int param, const char **params) { Elixir_Loader_File *result = NULL; Elixir_Eet_Filename *top = NULL; Elixir_Eet_Filename *lookup = NULL; Eet_File *eet = NULL; char *filename; char *section = NULL; char *compiled_key; char *content = NULL; char *compiled = NULL; const char *key; const char *cipher; Eina_Bool free_compiled = EINA_FALSE; Eina_Bool free_content = EINA_FALSE; int content_length; int compiled_length; unsigned int i; if (param < 1 || param > 3) return NULL; cipher = NULL; switch (param) { case 1: if (stack && eina_array_count_get(stack) > 0) { top = eina_array_data_get(stack, eina_array_count_get(stack) - 1); filename = top->filename; key = params[0]; } else { filename = (char*) params[0]; key = "elixir/main"; } break; case 2: filename = (char*) params[0]; key = params[1]; break; case 3: filename = (char*) params[0]; key = params[1]; cipher = params[2]; break; default: return NULL; } filename = elixir_exe_canonicalize(filename); if (!filename) return NULL; section = strdup(key); if (!section) goto on_error; eet = eet_open(filename, EET_FILE_MODE_READ); if (!eet) goto on_error; /* Use a cache to prevent useless security check. */ lookup = eina_hash_find(cache, filename); if (lookup && lookup->eet == eet) { eet_close(eet); if (top != lookup) { eina_array_push(stack, lookup); top = lookup; } eet = lookup->eet; lru = eina_list_remove(lru, lookup); } else { /* Lookup is no longer valid, remove it from cache. */ if (lookup) { lru = eina_list_remove(lru, lookup); eina_hash_del(cache, filename, lookup); } if (!_elixir_eet_security_check(eet)) goto on_error; } compiled_key = alloca(strlen(key) + 2); snprintf(compiled_key, strlen(key) + 2, "%sx", key); if (cipher) { free_content = EINA_TRUE; content = eet_read_cipher(eet, key, &content_length, cipher); if (!content) goto on_error; compiled = eet_read_cipher(eet, compiled_key, &compiled_length, cipher); } else { content = (char*) eet_read_direct(eet, key, &content_length); if (!content) { free_content = EINA_TRUE; content = eet_read(eet, key, &content_length); } if (!content) goto on_error; compiled = (char*) eet_read_direct(eet, compiled_key, &compiled_length); if (!compiled) { free_compiled = EINA_TRUE; compiled = eet_read(eet, compiled_key, &compiled_length); } } if (memchr(content, '\0', content_length)) goto on_error; if (compiled) { for (i = 0; i < sizeof (_jsx_header) / sizeof (_jsx_header[0]); ++i) if (*(unsigned int*) compiled == _jsx_header[i]) break; if (i == sizeof (_jsx_header) / sizeof (_jsx_header[0])) if (free_compiled) { free(compiled); free_compiled = EINA_FALSE; compiled = NULL; } } result = malloc(sizeof (Elixir_Loader_File)); if (!result) goto on_error; result->content_length = content_length; result->content = content; result->free_content = free_content; result->compiled_length = compiled_length; result->compiled = compiled; result->free_compiled = free_compiled; /* Ref counting helper to find current open file. */ if (top) { top->reference++; free(filename); } else { top = malloc(sizeof (Elixir_Eet_Filename) + strlen(filename)); if (!top) goto on_error; top->reference = 1; top->filename = filename; top->eet = eet; eina_array_push(stack, top); eina_hash_add(cache, filename, top); } result->file = top; result->section = section; return result; on_error: if (result) free(result); if (content && free_content) free(content); if (compiled && free_compiled) free(compiled); if (eet) eet_close(eet); if (section) free(section); free(filename); return NULL; }