#include #include "common.h" struct parser_s { Eina_List *attrs; //FIXME: Use Inlist Ecore_Thread *thread; }; typedef struct parser_attr_s { Eina_Stringshare *keyword; attr_value value; } parser_attr; typedef struct part_name_thread_data_s { parser_data *pd; char *utf8; int cur_pos; const char *part_name; void (*cb)(void *data, Eina_Stringshare *part_name); void *cb_data; } part_name_td; static void parser_type_init(parser_data *pd) { parser_attr *attr; //FIXME: construct from the configuration file. Eina_List *types = NULL; types = eina_list_append(types, eina_stringshare_add("RECT")); types = eina_list_append(types, eina_stringshare_add("TEXT")); types = eina_list_append(types, eina_stringshare_add("IMAGE")); types = eina_list_append(types, eina_stringshare_add("SWALLOW")); types = eina_list_append(types, eina_stringshare_add("TEXTBLOCK")); types = eina_list_append(types, eina_stringshare_add("GRADIENT")); types = eina_list_append(types, eina_stringshare_add("GROUP")); types = eina_list_append(types, eina_stringshare_add("BOX")); types = eina_list_append(types, eina_stringshare_add("TABLE")); types = eina_list_append(types, eina_stringshare_add("EXTERNAL")); types = eina_list_append(types, eina_stringshare_add("PROXY")); types = eina_list_append(types, eina_stringshare_add("SPACER")); attr = calloc(1, sizeof(parser_attr)); attr->keyword = eina_stringshare_add("type"); attr->value.strs = types; pd->attrs = eina_list_append(pd->attrs, attr); Eina_List *comps = NULL; comps = eina_list_append(comps, eina_stringshare_add("RAW")); comps = eina_list_append(comps, eina_stringshare_add("USER")); comps = eina_list_append(comps, eina_stringshare_add("COMP")); comps = eina_list_append(comps, eina_stringshare_add("LOSSY")); attr = calloc(1, sizeof(parser_attr)); attr->keyword = eina_stringshare_add("image"); attr->value.strs = comps; pd->attrs = eina_list_append(pd->attrs, attr); Eina_List *transit = NULL; transit = eina_list_append(transit, eina_stringshare_add("LINEAR")); transit = eina_list_append(transit, eina_stringshare_add("ACCELERATE")); transit = eina_list_append(transit, eina_stringshare_add("DECELERATE")); transit = eina_list_append(transit, eina_stringshare_add("SINUSOIDAL")); transit = eina_list_append(transit, eina_stringshare_add("ACCELERATE_FACTOR")); transit = eina_list_append(transit, eina_stringshare_add("DECELERATE_FACTOR")); transit = eina_list_append(transit, eina_stringshare_add("SINUSOIDAL_FACTOR")); transit = eina_list_append(transit, eina_stringshare_add("DIVISOR_INTERP")); transit = eina_list_append(transit, eina_stringshare_add("BOUNCE")); transit = eina_list_append(transit, eina_stringshare_add("SPRING")); attr = calloc(1, sizeof(parser_attr)); attr->keyword = eina_stringshare_add("transition"); attr->value.strs = transit; pd->attrs = eina_list_append(pd->attrs, attr); attr = calloc(1, sizeof(parser_attr)); attr->keyword = eina_stringshare_add("color"); attr->value.min = 0; attr->value.max = 255; attr->value.integer = EINA_TRUE; pd->attrs = eina_list_append(pd->attrs, attr); attr = calloc(1, sizeof(parser_attr)); attr->keyword = eina_stringshare_add("relative"); attr->value.min = 0.0; attr->value.max = 1; pd->attrs = eina_list_append(pd->attrs, attr); attr = calloc(1, sizeof(parser_attr)); attr->keyword = eina_stringshare_add("scale"); attr->value.min = 0; attr->value.max = 1; attr->value.integer = EINA_TRUE; pd->attrs = eina_list_append(pd->attrs, attr); attr = calloc(1, sizeof(parser_attr)); attr->keyword = eina_stringshare_add("fixed"); attr->value.min = 0; attr->value.max = 1; attr->value.integer = EINA_TRUE; pd->attrs = eina_list_append(pd->attrs, attr); attr = calloc(1, sizeof(parser_attr)); attr->keyword = eina_stringshare_add("aspect"); attr->value.min = 0.0; attr->value.max = 1.0; pd->attrs = eina_list_append(pd->attrs, attr); attr = calloc(1, sizeof(parser_attr)); attr->keyword = eina_stringshare_add("align"); attr->value.min = 0.0; attr->value.max = 1.0; pd->attrs = eina_list_append(pd->attrs, attr); attr = calloc(1, sizeof(parser_attr)); attr->keyword = eina_stringshare_add("size"); attr->value.min = 1; attr->value.max = 255; attr->value.integer = EINA_TRUE; pd->attrs = eina_list_append(pd->attrs, attr); attr = calloc(1, sizeof(parser_attr)); attr->keyword = eina_stringshare_add("min"); attr->value.min = 0; attr->value.max = 1000; attr->value.integer = EINA_TRUE; pd->attrs = eina_list_append(pd->attrs, attr); attr = calloc(1, sizeof(parser_attr)); attr->keyword = eina_stringshare_add("max"); attr->value.min = 0; attr->value.max = 1000; attr->value.integer = EINA_TRUE; pd->attrs = eina_list_append(pd->attrs, attr); attr = calloc(1, sizeof(parser_attr)); attr->keyword = eina_stringshare_add("mouse_events"); attr->value.min = 0; attr->value.max = 1000; attr->value.integer = EINA_TRUE; pd->attrs = eina_list_append(pd->attrs, attr); } attr_value * parser_attribute_get(parser_data *pd, const char *text, const char *cur) { if (!text || !cur) return NULL; char *p = (char *) cur; Eina_List *l; parser_attr *attr; Eina_Bool instring = EINA_FALSE; Eina_Bool necessary = EINA_FALSE; while (p >= text) { if (*p == ':') { necessary = EINA_TRUE; break; } if (*p == '\"') instring = !instring; p--; } if (!p || instring || !necessary) return NULL; while (p > text) { if ((*p == ';') || (*p == '.') || (*p == ' ')) break; p--; } if (!p) return NULL; if (p != text) p++; EINA_LIST_FOREACH(pd->attrs, l, attr) { if (strstr(p, attr->keyword)) return &attr->value; } return NULL; } parser_data * parser_init() { parser_data *pd = calloc(1, sizeof(parser_data)); parser_type_init(pd); return pd; } void parser_term(parser_data *pd) { if (pd->thread) ecore_thread_cancel(pd->thread); Eina_List *l, *ll; parser_attr *attr; Eina_Stringshare *str; EINA_LIST_FOREACH(pd->attrs, l, attr) { eina_stringshare_del(attr->keyword); EINA_LIST_FOREACH(attr->value.strs, ll, str) eina_stringshare_del(str); eina_list_free(attr->value.strs); free(attr); } eina_list_free(pd->attrs); free(pd); } const char * parser_markup_escape(parser_data *pd EINA_UNUSED, const char *str) { const char *escaped = strchr(str, '>'); if (!escaped) return str; if ((escaped + 1) >= (str + strlen(str))) return str; escaped++; return escaped; } static void part_name_thread_blocking(void *data, Ecore_Thread *thread EINA_UNUSED) { part_name_td *td = data; char *utf8 = td->utf8; int cur_pos = td->cur_pos; char *p = utf8; char *end = utf8 + cur_pos; const char *quot = "\""; int quot_len = 1; // strlen("""); const char *part = "part"; int part_len = 4; //strlen("part"); const char *parts = "parts"; int parts_len = 5; //strlen("parts"); int bracket = 0; const char *part_name = NULL; int part_name_len = 0; Eina_Bool part_in = EINA_FALSE; while (p <= end) { //Skip "" range if (*p == *quot) { p += quot_len; p = strstr(p, quot); if (!p) goto end; p += quot_len; } if (part_in && (*p == '{')) { bracket++; p++; continue; } if (part_in && (*p == '}') && (p < end)) { bracket--; p++; if (bracket == 0) part_in = EINA_FALSE; continue; } if (strncmp(p, parts, parts_len)) { if (!strncmp(p, part, part_len)) { p += part_len; char *name_begin = strstr(p, quot); if (!name_begin) goto end; name_begin += quot_len; p = name_begin; char *name_end = strstr(p, quot); if (!name_end) goto end; part_name = name_begin; part_name_len = name_end - name_begin; p = name_end + quot_len; bracket = 1; part_in = EINA_TRUE; continue; } } p++; } if (part_name) { if (bracket == 0) { part_name = NULL; goto end; } else part_name = eina_stringshare_add_length(part_name, part_name_len); } end: if (utf8) { free(utf8); td->utf8 = NULL; } td->part_name = part_name; } static void part_name_thread_end(void *data, Ecore_Thread *thread EINA_UNUSED) { part_name_td *td = data; Eina_Stringshare *part_name = td->part_name; td->cb(td->cb_data, part_name); td->pd->thread = NULL; free(td); } static void part_name_thread_cancel(void *data, Ecore_Thread *thread EINA_UNUSED) { part_name_td *td = data; td->pd->thread = NULL; if (td->utf8) free(td->utf8); free(td); } void parser_part_name_get(parser_data *pd, Evas_Object *entry, void (*cb)(void *data, Eina_Stringshare *part_name), void *data) { if (pd->thread) ecore_thread_cancel(pd->thread); part_name_td *td = calloc(1, sizeof(part_name_td)); if (!td) return; Evas_Object *tb = elm_entry_textblock_get(entry); char *text = (char *) evas_object_textblock_text_markup_get(tb); if (!text) return; char *utf8 = elm_entry_markup_to_utf8(text); if (!utf8) return; td->pd = pd; td->utf8 = utf8; td->cur_pos = elm_entry_cursor_pos_get(entry); td->cb = cb; td->cb_data = data; pd->thread = ecore_thread_run(part_name_thread_blocking, part_name_thread_end, part_name_thread_cancel, td); } Eina_Stringshare *parser_group_name_get(parser_data *pd EINA_UNUSED, Evas_Object *entry) { Evas_Object *tb = elm_entry_textblock_get(entry); char *text = (char *) evas_object_textblock_text_markup_get(tb); char *p = text; const char *quot = """; int quot_len = 6; // strlen("""); const char *group = "group"; int group_len = 5; //strlen("group"); while (p < (text + strlen(text))) { //Skip "" range if (!strncmp(p, quot, quot_len)) { p += quot_len; p = strstr(p, quot); if (!p) return NULL; p += quot_len; } if (!strncmp(p, group, group_len)) { p += group_len; char *name_begin = strstr(p, quot); if (!name_begin) return NULL; name_begin += quot_len; p = name_begin; char *name_end = strstr(p, quot); if (!name_end) return NULL; return eina_stringshare_add_length(name_begin, name_end - name_begin); break; } p++; } return NULL; }