return NULL;
}
+static void
+_edje_collection_program_add(Edje_Program ***array,
+ unsigned int *count,
+ Edje_Program *add)
+{
+ Edje_Program **tmp;
+
+ tmp = realloc(*array, sizeof (Edje_Program*) * (*count + 1));
+ if (!tmp) return ;
+
+ tmp[(*count)++] = add;
+ *array = tmp;
+}
+
+Eina_Bool
+edje_program_is_strncmp(const char *str)
+{
+ unsigned int length;
+
+ length = strlen(str);
+
+ if (strpbrk(str, "*?[\\") != str + length)
+ return EINA_FALSE;
+ if (str[length] == '['
+ || str[length] == '\\')
+ return EINA_FALSE;
+ return EINA_TRUE;
+}
+
+Eina_Bool
+edje_program_is_strrncmp(const char *str)
+{
+ if (*str != '*' && *str != '?')
+ return EINA_FALSE;
+ if (strpbrk(str + 1, "*?[\\") != NULL)
+ return EINA_FALSE;
+ return EINA_TRUE;
+}
+
Edje_Part_Collection *
_edje_collection_convert(Edje_File *file, Old_Edje_Part_Collection *oedc)
{
Edje_Part_Collection_Directory_Entry *ce;
Edje_Part_Collection *edc;
Old_Edje_Part *part;
+ Edje_Program *pg;
Edje_Data *di;
Eina_List *l;
unsigned int k;
if (!edc) return NULL;
ce->ref = edc;
- edc->programs = oedc->programs;
- oedc->programs = NULL;
+ EINA_LIST_FREE(oedc->programs, pg)
+ {
+ if (!pg->signal && !pg->source)
+ _edje_collection_program_add(&edc->programs.nocmp,
+ &edc->programs.nocmp_count,
+ pg);
+ else if (pg->signal && strpbrk(pg->signal, "*?[\\") == NULL
+ && pg->source && strpbrk(pg->source, "*?[\\") == NULL)
+ _edje_collection_program_add(&edc->programs.strcmp,
+ &edc->programs.strcmp_count,
+ pg);
+ else if (pg->signal && edje_program_is_strncmp(pg->signal)
+ && pg->source && edje_program_is_strncmp(pg->source))
+ _edje_collection_program_add(&edc->programs.strncmp,
+ &edc->programs.strncmp_count,
+ pg);
+ else if (pg->signal && edje_program_is_strrncmp(pg->signal)
+ && pg->source && edje_program_is_strrncmp(pg->source))
+ _edje_collection_program_add(&edc->programs.strrncmp,
+ &edc->programs.strrncmp_count,
+ pg);
+ else
+ _edje_collection_program_add(&edc->programs.fnmatch,
+ &edc->programs.fnmatch_count,
+ pg);
+ }
edc->data = eina_hash_string_small_new(NULL);
EINA_LIST_FREE(oedc->data, di)
const Edje_File *_edje_file_get(void);
void _edje_file_set(const Edje_File *edf);
+Eina_Bool edje_program_is_strncmp(const char *str);
+Eina_Bool edje_program_is_strrncmp(const char *str);
+
#endif
}
static void
+_edje_part_program_id_set(Edje_Program *epr, int old_id, int new_id)
+{
+ Edje_Program_Target *pt;
+ Eina_List *ll, *l_next;
+
+ if (epr->action != EDJE_ACTION_TYPE_STATE_SET)
+ return;
+
+ EINA_LIST_FOREACH_SAFE(epr->targets, ll, l_next, pt)
+ {
+ if (pt->id == old_id)
+ {
+ if (new_id == -1)
+ epr->targets = eina_list_remove_list(epr->targets, ll);
+ else
+ pt->id = new_id;
+ }
+ }
+}
+
+static void
_edje_part_id_set(Edje *ed, Edje_Real_Part *rp, int new_id)
{
/* This function change the id of a given real_part.
* is lost.
* If new Id = -1 then all the depencies will be deleted
*/
- int old_id;
Edje_Part *part;
- Eina_List *l, *ll, *l_next;
- Edje_Program *epr;
unsigned int j;
+ int old_id;
part = rp->part;
}
/*...and also in programs targets */
- EINA_LIST_FOREACH(ed->collection->programs, l, epr)
- {
- Edje_Program_Target *pt;
-
- if (epr->action != EDJE_ACTION_TYPE_STATE_SET)
- continue;
+#define EDJE_EDIT_PROGRAM_ID_SET(Array, Ed, It, Old, New) \
+ for (It = 0; It < Ed->collection->programs.Array##_count; ++It) \
+ _edje_part_program_id_set(Ed->collection->programs.Array[It], Old, New);
- EINA_LIST_FOREACH_SAFE(epr->targets, ll, l_next, pt)
- {
- if (pt->id == old_id)
- {
- if (new_id == -1)
- epr->targets = eina_list_remove_list(epr->targets, ll);
- else
- pt->id = new_id;
- }
- }
- }
+ EDJE_EDIT_PROGRAM_ID_SET(fnmatch, ed, j, old_id, new_id);
+ EDJE_EDIT_PROGRAM_ID_SET(strcmp, ed, j, old_id, new_id);
+ EDJE_EDIT_PROGRAM_ID_SET(strncmp, ed, j, old_id, new_id);
+ EDJE_EDIT_PROGRAM_ID_SET(strrncmp, ed, j, old_id, new_id);
+ EDJE_EDIT_PROGRAM_ID_SET(nocmp, ed, j, old_id, new_id);
/* Adjust table_parts */
if (new_id >= 0)
}
static void
+_edje_part_program_id_switch(Edje_Program *epr, int id1, int id2)
+{
+ Edje_Program_Target *pt;
+ Eina_List *ll;
+
+ if (epr->action != EDJE_ACTION_TYPE_STATE_SET)
+ return;
+
+ EINA_LIST_FOREACH(epr->targets, ll, pt)
+ {
+ if (pt->id == id1) pt->id = id2;
+ else if (pt->id == id2) pt->id = id1;
+ }
+}
+
+static void
_edje_parts_id_switch(Edje *ed, Edje_Real_Part *rp1, Edje_Real_Part *rp2)
{
/* This function switch the id of two parts.
*/
int id1;
int id2;
- Eina_List *l, *ll;
- Edje_Program *epr;
unsigned int i;
//printf("SWITCH ID OF PART %d AND %d\n", rp1->part->id, rp2->part->id);
}
//...and also in programs targets
- EINA_LIST_FOREACH(ed->collection->programs, l, epr)
- {
- Edje_Program_Target *pt;
-
- if (epr->action != EDJE_ACTION_TYPE_STATE_SET)
- continue;
-
- EINA_LIST_FOREACH(epr->targets, ll, pt)
- {
- if (pt->id == id1) pt->id = id2;
- else if (pt->id == id2) pt->id = id1;
- }
- }
+#define EDJE_EDIT_PROGRAM_SWITCH(Array, Ed, It, Id1, Id2) \
+ for (It = 0; It < Ed->collection->programs.Array##_count; ++It) \
+ _edje_part_program_id_switch(Ed->collection->programs.Array[i], Id1, Id2);
+
+ EDJE_EDIT_PROGRAM_SWITCH(fnmatch, ed, i, id1, id2);
+ EDJE_EDIT_PROGRAM_SWITCH(strcmp, ed, i, id1, id2);
+ EDJE_EDIT_PROGRAM_SWITCH(strncmp, ed, i, id1, id2);
+ EDJE_EDIT_PROGRAM_SWITCH(strrncmp, ed, i, id1, id2);
+ EDJE_EDIT_PROGRAM_SWITCH(nocmp, ed, i, id1, id2);
//TODO Real part dependencies are ok?
}
/* Init Edje_Part_Collection */
pc->id = id;
pc->references = 0;
- pc->programs = NULL;
+ memset(&pc->programs, 0, sizeof (pc->programs));
pc->parts = NULL;
pc->data = NULL;
pc->script = NULL;
//Add program to group
pc = ed->collection;
- pc->programs = eina_list_append(pc->programs, epr);
+
+ /* By default, source and signal are empty, so they fill in nocmp category */
+ ed->collection->programs.nocmp = realloc(ed->collection->programs.nocmp,
+ sizeof (Edje_Program*) * ed->collection->programs.nocmp_count);
+ ed->collection->programs.nocmp[ed->collection->programs.nocmp_count++] = epr;
//Init Edje_Program
- epr->id = eina_list_count(pc->programs) - 1;
+ epr->id = ed->table_programs_size;
epr->name = eina_stringshare_add(name);
epr->signal = NULL;
epr->source = NULL;
return EINA_TRUE;
}
+static void
+_edje_edit_program_remove(Edje *ed, Edje_Program *p)
+{
+ Edje_Program ***array;
+ unsigned int *count;
+ unsigned int i;
+
+ if (!p->signal && !p->source)
+ {
+ array = &ed->collection->programs.nocmp;
+ count = &ed->collection->programs.nocmp_count;
+ }
+ else if (p->signal && strpbrk(p->signal, "*?[\\") == NULL
+ && p->source && strpbrk(p->source, "*?[\\") == NULL)
+ {
+ array = &ed->collection->programs.strcmp;
+ count = &ed->collection->programs.strcmp_count;
+ }
+ else if (p->signal && edje_program_is_strncmp(p->signal)
+ && p->source && edje_program_is_strncmp(p->source))
+ {
+ array = &ed->collection->programs.strncmp;
+ count = &ed->collection->programs.strncmp_count;
+ }
+ else if (p->signal && edje_program_is_strrncmp(p->signal)
+ && p->source && edje_program_is_strrncmp(p->source))
+ {
+ array = &ed->collection->programs.strrncmp;
+ count = &ed->collection->programs.strrncmp_count;
+ }
+ else
+ {
+ array = &ed->collection->programs.fnmatch;
+ count = &ed->collection->programs.fnmatch_count;
+ }
+
+ for (i = 0; i < *count; ++i)
+ if ((*array)[i] == p)
+ {
+ memmove(*array + i, *array + i + 1, sizeof (Edje_Program *) * (*count - i -1));
+ (*count)--;
+ break;
+ }
+}
+
+static void
+_edje_edit_program_insert(Edje *ed, Edje_Program *p)
+{
+ Edje_Program ***array;
+ unsigned int *count;
+
+ if (!p->signal && !p->source)
+ {
+ array = &ed->collection->programs.nocmp;
+ count = &ed->collection->programs.nocmp_count;
+ }
+ else if (p->signal && strpbrk(p->signal, "*?[\\") == NULL
+ && p->source && strpbrk(p->source, "*?[\\") == NULL)
+ {
+ array = &ed->collection->programs.strcmp;
+ count = &ed->collection->programs.strcmp_count;
+ }
+ else if (p->signal && edje_program_is_strncmp(p->signal)
+ && p->source && edje_program_is_strncmp(p->source))
+ {
+ array = &ed->collection->programs.strncmp;
+ count = &ed->collection->programs.strncmp_count;
+ }
+ else if (p->signal && edje_program_is_strrncmp(p->signal)
+ && p->source && edje_program_is_strrncmp(p->source))
+ {
+ array = &ed->collection->programs.strrncmp;
+ count = &ed->collection->programs.strrncmp_count;
+ }
+ else
+ {
+ array = &ed->collection->programs.fnmatch;
+ count = &ed->collection->programs.fnmatch_count;
+ }
+
+ *array = realloc(*array, sizeof (Edje_Program *) * (*count + 1));
+ *array[(*count)++] = p;
+}
+
EAPI Eina_Bool
edje_edit_program_del(Evas_Object *obj, const char *prog)
{
- Eina_List *l, *l_next, *rem;
+ Eina_List *l, *l_next;
+ Edje_Program_Target *prt;
+ Edje_Program_After *pa;
Edje_Part_Collection *pc;
Edje_Program *p;
int id, i;
pc = ed->collection;
- rem = eina_list_nth_list(pc->programs, epr->id);
- l = eina_list_last(pc->programs);
- if (rem != l)
+ //Remove program from programs list
+ id = epr->id;
+ _edje_edit_program_remove(ed, epr);
+
+ /* fix table program */
+ if (epr->id != ed->table_programs_size - 1)
{
/* If the removed program is not the last in the list/table,
* put the last one in its place and update references to it later */
- p = eina_list_data_get(l);
- pc->programs = eina_list_remove_list(pc->programs, l);
- pc->programs = eina_list_append_relative_list(pc->programs, p, rem);
-
- ed->table_programs[epr->id] = p;
- old_id = p->id;
- p->id = epr->id;
+ ed->table_programs[epr->id] = ed->table_programs[ed->table_programs_size - 1];
+ old_id = ed->table_programs_size - 1;
+ ed->table_programs[epr->id]->id = epr->id;
}
- //Remove program from programs list
- id = epr->id;
- pc->programs = eina_list_remove(pc->programs, epr);
-
//Free Edje_Program
_edje_if_string_free(ed, epr->name);
_edje_if_string_free(ed, epr->signal);
_edje_if_string_free(ed, epr->state);
_edje_if_string_free(ed, epr->state2);
- while (epr->targets)
- {
- Edje_Program_Target *prt;
-
- prt = eina_list_data_get(epr->targets);
- epr->targets = eina_list_remove_list(epr->targets, epr->targets);
- free(prt);
- }
- while (epr->after)
- {
- Edje_Program_After *pa;
-
- pa = eina_list_data_get(epr->after);
- epr->after = eina_list_remove_list(epr->after, epr->after);
- free(pa);
- }
+ EINA_LIST_FREE(epr->targets, prt)
+ free(prt);
+ EINA_LIST_FREE(epr->after, pa)
+ free(pa);
free(epr);
ed->table_programs_size--;
if (!source) return EINA_FALSE;
- //printf("SET SOURCE for program: %s [%s]\n", prog, source);
-
+ /* Remove from program array */
+ _edje_edit_program_remove(ed, epr);
_edje_if_string_free(ed, epr->source);
+
+ /* Insert it back */
epr->source = eina_stringshare_add(source);
+ _edje_edit_program_insert(ed, epr);
//Update patterns
- if (ed->patterns.programs.sources_patterns)
- edje_match_patterns_free(ed->patterns.programs.sources_patterns);
- ed->patterns.programs.sources_patterns = edje_match_programs_source_init(ed->collection->programs);
+ _edje_programs_patterns_clean(ed);
+ _edje_programs_patterns_init(ed);
return EINA_TRUE;
}
if (!signal) return EINA_FALSE;
- //printf("SET SIGNAL for program: %s [%s]\n", prog, signal);
-
+ /* Remove from program array */
+ _edje_edit_program_remove(ed, epr);
_edje_if_string_free(ed, epr->signal);
+
+ /* Insert it back */
epr->signal = eina_stringshare_add(signal);
+ _edje_edit_program_insert(ed, epr);
//Update patterns
- if (ed->patterns.programs.signals_patterns)
- edje_match_patterns_free(ed->patterns.programs.signals_patterns);
- ed->patterns.programs.signals_patterns = edje_match_programs_signal_init(ed->collection->programs);
+ _edje_programs_patterns_clean(ed);
+ _edje_programs_patterns_init(ed);
return EINA_TRUE;
}
}
static Eina_Bool
-_edje_edit_collection_save(Eet_File *eetf, Edje_Part_Collection *epc)
+_edje_edit_collection_save(Edje *ed, Eet_File *eetf, Edje_Part_Collection *epc)
{
Old_Edje_Part_Description *oepd;
Old_Edje_Part_Collection oepc;
Edje_Data *di;
char buf[256];
unsigned int i;
+ int j;
Eina_Bool err = EINA_TRUE;
memset(&oepc, 0, sizeof(oepc));
snprintf(buf, sizeof(buf), "collections/%i", epc->id);
- oepc.programs = epc->programs;
+ for (j = 0; j < ed->table_programs_size; ++j)
+ oepc.programs = eina_list_append(oepc.programs, ed->table_programs[j]);
it = eina_hash_iterator_tuple_new(epc->data);
EINA_ITERATOR_FOREACH(it, tu)
}
// FIXME
+ oepc.programs = eina_list_free(oepc.programs);
EINA_LIST_FREE(oepc.data, di)
free(di);
EINA_LIST_FREE(oepc.parts, oep)
{
INF("** Writing Edje_Part_Collection* ed->collection "
"[id: %d]", ed->collection->id);
- if (!_edje_edit_collection_save(eetf, ed->collection))
+ if (!_edje_edit_collection_save(ed, eetf, ed->collection))
{
eet_close(eetf);
return EINA_FALSE;
{
INF("** Writing hash Edje_Part_Collection* ed->collection "
"[id: %d]", ce->id);
- if(!_edje_edit_collection_save(eetf, ce->ref))
+ if(!_edje_edit_collection_save(ed, eetf, ce->ref))
{
eet_close(eetf);
return EINA_FALSE;
{
INF("** Writing cache Edje_Part_Collection* ed->collection "
"[id: %d]", edc->id);
- if(!_edje_edit_collection_save(eetf, edc))
+ if(!_edje_edit_collection_save(ed, eetf, edc))
{
eet_close(eetf);
return EINA_FALSE;
edje_edit_print_internal_status(Evas_Object *obj)
{
Edje_Program *epr;
- Eina_List *l;
unsigned int i;
+ int j;
GET_ED_OR_RETURN();
WRN(" WRONG (table[%id]->name = '%s')", p->id, rp->part->name);
}
- INF("*** Programs [table:%d list:%d]", ed->table_programs_size,
- eina_list_count(ed->collection->programs));
- EINA_LIST_FOREACH(ed->collection->programs, l, epr)
+ INF("*** Programs [table:%d list:%d,%d,%d,%d,%d]", ed->table_programs_size,
+ ed->collection->programs.fnmatch_count,
+ ed->collection->programs.strcmp_count,
+ ed->collection->programs.strncmp_count,
+ ed->collection->programs.strrncmp_count,
+ ed->collection->programs.nocmp_count);
+ for(j = 0; j < ed->table_programs_size; ++j)
{
- Edje_Program *epr2;
-
- epr2 = ed->table_programs[epr->id % ed->table_programs_size];
- printf(" [%d]%s ", epr->id, epr->name);
- if (epr == epr2)
- printf(" OK!\n");
- else
- WRN(" WRONG (table[%id]->name = '%s')", epr->id, epr2->name);
+ epr = ed->table_programs[i % ed->table_programs_size];
+ printf(" [%d]%s\n", epr->id, epr->name);
}
printf("\n");
NULL);
ed->patterns.programs.exact_match = NULL;
- ed->patterns.programs.globing = eina_list_free(ed->patterns.programs.globing);
+ free(ed->patterns.programs.u.programs.globing);
+ ed->patterns.programs.u.programs.globing = NULL;
}
void
_edje_programs_patterns_init(Edje *ed)
{
Edje_Signals_Sources_Patterns *ssp = &ed->patterns.programs;
+ Edje_Program **all;
+ unsigned int i, j;
if (ssp->signals_patterns)
return;
- ssp->globing = edje_match_program_hash_build(ed->collection->programs,
- &ssp->exact_match);
-
- ssp->signals_patterns = edje_match_programs_signal_init(ssp->globing);
- ssp->sources_patterns = edje_match_programs_source_init(ssp->globing);
+ edje_match_program_hash_build(ed->collection->programs.strcmp,
+ ed->collection->programs.strcmp_count,
+ &ssp->exact_match);
+
+ j = ed->collection->programs.strncmp_count
+ + ed->collection->programs.strrncmp_count
+ + ed->collection->programs.fnmatch_count
+ + ed->collection->programs.nocmp_count;
+ if (j == 0) return ;
+
+ all = malloc(sizeof (Edje_Program *) * j);
+ if (!all) return ;
+ j = 0;
+
+ /* FIXME: Build specialized data type for each case */
+#define EDJE_LOAD_PROGRAMS_ADD(Array, Ed, It, Git, All) \
+ for (It = 0; It < Ed->collection->programs.Array##_count; ++It, ++Git) \
+ All[Git] = Ed->collection->programs.Array[It];
+
+ EDJE_LOAD_PROGRAMS_ADD(fnmatch, ed, i, j, all);
+ EDJE_LOAD_PROGRAMS_ADD(strncmp, ed, i, j, all);
+ EDJE_LOAD_PROGRAMS_ADD(strrncmp, ed, i, j, all);
+ /* FIXME: Do a special pass for that one */
+ EDJE_LOAD_PROGRAMS_ADD(nocmp, ed, i, j, all);
+
+ ssp->u.programs.globing = all;
+ ssp->u.programs.count = j;
+ ssp->signals_patterns = edje_match_programs_signal_init(all, j);
+ ssp->sources_patterns = edje_match_programs_source_init(all, j);
}
int
}
_edje_programs_patterns_init(ed);
-
- n = eina_list_count(ed->collection->programs);
+
+ n = ed->collection->programs.fnmatch_count +
+ ed->collection->programs.strcmp_count +
+ ed->collection->programs.strncmp_count +
+ ed->collection->programs.strrncmp_count +
+ ed->collection->programs.nocmp_count;
if (n > 0)
{
Edje_Program *pr;
- Eina_List *l;
+ unsigned int i;
- /* FIXME: keeping a table AND a list is just bad - nuke list */
ed->table_programs = malloc(sizeof(Edje_Program *) * n);
- ed->table_programs_size = n;
- /* FIXME: check malloc return */
- n = 0;
- EINA_LIST_FOREACH(ed->collection->programs, l, pr)
+ if (ed->table_programs)
{
- ed->table_programs[n] = pr;
- n++;
+ ed->table_programs_size = n;
+
+#define EDJE_LOAD_BUILD_TABLE(Array, Ed, It, Tmp) \
+ for (It = 0; It < Ed->collection->programs.Array##_count; ++It) \
+ { \
+ Tmp = Ed->collection->programs.Array[It]; \
+ Ed->table_programs[Tmp->id] = Tmp; \
+ }
+
+ EDJE_LOAD_BUILD_TABLE(fnmatch, ed, i, pr);
+ EDJE_LOAD_BUILD_TABLE(strcmp, ed, i, pr);
+ EDJE_LOAD_BUILD_TABLE(strncmp, ed, i, pr);
+ EDJE_LOAD_BUILD_TABLE(strrncmp, ed, i, pr);
+ EDJE_LOAD_BUILD_TABLE(nocmp, ed, i, pr);
}
}
_edje_ref(ed);
_edje_file_set(prev);
}
+static void
+_edje_program_free(Edje_Program *pr, Eina_Bool free_strings)
+{
+ Edje_Program_Target *prt;
+ Edje_Program_After *pa;
+
+ if (free_strings)
+ {
+ if (pr->name) eina_stringshare_del(pr->name);
+ if (pr->signal) eina_stringshare_del(pr->signal);
+ if (pr->source) eina_stringshare_del(pr->source);
+ if (pr->filter.part) eina_stringshare_del(pr->filter.part);
+ if (pr->filter.state) eina_stringshare_del(pr->filter.state);
+ if (pr->state) eina_stringshare_del(pr->state);
+ if (pr->state2) eina_stringshare_del(pr->state2);
+ }
+ EINA_LIST_FREE(pr->targets, prt)
+ free(prt);
+ EINA_LIST_FREE(pr->after, pa)
+ free(pa);
+ free(pr);
+}
+
void
_edje_collection_free(Edje_File *edf, Edje_Part_Collection *ec, Edje_Part_Collection_Directory_Entry *ce)
{
- Edje_Program *pr;
unsigned int i;
_edje_embryo_script_shutdown(ec);
- EINA_LIST_FREE(ec->programs, pr)
- {
- Edje_Program_Target *prt;
- Edje_Program_After *pa;
-
- if (edf->free_strings)
- {
- if (pr->name) eina_stringshare_del(pr->name);
- if (pr->signal) eina_stringshare_del(pr->signal);
- if (pr->source) eina_stringshare_del(pr->source);
- if (pr->filter.part) eina_stringshare_del(pr->filter.part);
- if (pr->filter.state) eina_stringshare_del(pr->filter.state);
- if (pr->state) eina_stringshare_del(pr->state);
- if (pr->state2) eina_stringshare_del(pr->state2);
- }
- EINA_LIST_FREE(pr->targets, prt)
- free(prt);
- EINA_LIST_FREE(pr->after, pa)
- free(pa);
- free(pr);
- }
+
+#define EDJE_LOAD_PROGRAM_FREE(Array, Ec, It, FreeStrings) \
+ for (It = 0; It < Ec->programs.Array##_count; ++It) \
+ _edje_program_free(Ec->programs.Array[It], FreeStrings); \
+ free(Ec->programs.Array);
+
+ EDJE_LOAD_PROGRAM_FREE(fnmatch, ec, i, edf->free_strings);
+ EDJE_LOAD_PROGRAM_FREE(strcmp, ec, i, edf->free_strings);
+ EDJE_LOAD_PROGRAM_FREE(strncmp, ec, i, edf->free_strings);
+ EDJE_LOAD_PROGRAM_FREE(strrncmp, ec, i, edf->free_strings);
+ EDJE_LOAD_PROGRAM_FREE(nocmp, ec, i, edf->free_strings);
+
for (i = 0; i < ec->parts_count; ++i)
{
Edje_Part *ep;
/* Exported function. */
-#define EDJE_MATCH_INIT(Func, Type, Source, Show) \
+#define EDJE_MATCH_INIT_LIST(Func, Type, Source, Show) \
Edje_Patterns* \
- Func(Eina_List *lst) \
+ Func(const Eina_List *lst) \
{ \
Edje_Patterns *r; \
size_t i; \
return r; \
}
-EDJE_MATCH_INIT(edje_match_collection_dir_init,
- Edje_Part_Collection_Directory_Entry,
- entry, 0);
-EDJE_MATCH_INIT(edje_match_programs_signal_init,
- Edje_Program,
- signal, 0);
-EDJE_MATCH_INIT(edje_match_programs_source_init,
- Edje_Program,
- source, 0);
-EDJE_MATCH_INIT(edje_match_callback_signal_init,
- Edje_Signal_Callback,
- signal, 0);
-EDJE_MATCH_INIT(edje_match_callback_source_init,
- Edje_Signal_Callback,
- source, 0);
+#define EDJE_MATCH_INIT_ARRAY(Func, Type, Source, Show) \
+ Edje_Patterns* \
+ Func(Type * const *lst, unsigned int count) \
+ { \
+ Edje_Patterns *r; \
+ size_t i; \
+ \
+ if (!lst || count == 0) \
+ return NULL; \
+ \
+ r = malloc(sizeof (Edje_Patterns) + \
+ count \
+ * sizeof(*r->finals) \
+ * sizeof(*r->patterns)); \
+ if (!r) return NULL; \
+ \
+ r->ref = 1; \
+ r->delete_me = 0; \
+ r->patterns_size = count; \
+ r->max_length = 0; \
+ r->patterns = (const char **) r->finals + r->patterns_size + 1; \
+ \
+ for (i = 0; i < count; ++i) \
+ { \
+ const char *str; \
+ size_t j; \
+ \
+ if (!lst[i]) \
+ { \
+ free(r); \
+ return NULL; \
+ } \
+ \
+ str = lst[i]->Source; \
+ if (!str) str = ""; \
+ r->patterns[i] = str; \
+ \
+ if (Show) \
+ INF("%lu [%s]", (unsigned long)i, str); \
+ \
+ r->finals[i] = 0; \
+ for (j = 0; str[j]; ++j) \
+ if (str[j] != '*') \
+ r->finals[i] = j + 1; \
+ \
+ if (j > r->max_length) \
+ r->max_length = j; \
+ } \
+ \
+ if (!_edje_match_states_alloc(r, 2)) \
+ { \
+ free(r); \
+ return NULL; \
+ } \
+ \
+ return r; \
+ }
+
+EDJE_MATCH_INIT_LIST(edje_match_collection_dir_init,
+ Edje_Part_Collection_Directory_Entry,
+ entry, 0);
+EDJE_MATCH_INIT_ARRAY(edje_match_programs_signal_init,
+ Edje_Program,
+ signal, 0);
+EDJE_MATCH_INIT_ARRAY(edje_match_programs_source_init,
+ Edje_Program,
+ source, 0);
+EDJE_MATCH_INIT_LIST(edje_match_callback_signal_init,
+ Edje_Signal_Callback,
+ signal, 0);
+EDJE_MATCH_INIT_LIST(edje_match_callback_source_init,
+ Edje_Signal_Callback,
+ source, 0);
static Eina_Bool
_edje_match_collection_dir_exec_finals(const size_t *finals,
const size_t *source_finals,
const Edje_States *signal_states,
const Edje_States *source_states,
- Eina_List *programs,
+ Edje_Program **programs,
Eina_Bool (*func)(Edje_Program *pr, void *data),
void *data)
{
{
Edje_Program *pr;
- pr = eina_list_nth(programs, signal_states->states[i].idx);
+ pr = programs[signal_states->states[i].idx];
if (pr)
{
if (func(pr, data))
const Edje_Patterns *ppat_source,
const char *signal,
const char *source,
- Eina_List *programs,
+ Edje_Program **programs,
Eina_Bool (*func)(Edje_Program *pr, void *data),
void *data)
{
Eina_List *
-edje_match_program_hash_build(const Eina_List *callbacks,
+edje_match_program_hash_build(Edje_Program * const *programs,
+ unsigned int count,
Eina_Rbtree **tree)
{
Eina_List *result = NULL;
Eina_Rbtree *new = NULL;
- Edje_Program *program;
- const Eina_List *l;
+ unsigned int i;
- EINA_LIST_FOREACH(callbacks, l, program)
+ for (i = 0; i < count; ++i)
{
- if (program->signal && strpbrk(program->signal, "*?[\\") == NULL
- && program->source && strpbrk(program->source, "*?[\\") == NULL)
+ if (programs[i]->signal && strpbrk(programs[i]->signal, "*?[\\") == NULL
+ && programs[i]->source && strpbrk(programs[i]->source, "*?[\\") == NULL)
{
Edje_Signal_Source_Char *item;
- item = (Edje_Signal_Source_Char*) eina_rbtree_inline_lookup(new, program->signal, 0,
- EINA_RBTREE_CMP_KEY_CB(_edje_signal_source_key_cmp), program->source);
+ item = (Edje_Signal_Source_Char*) eina_rbtree_inline_lookup(new, programs[i]->signal, 0,
+ EINA_RBTREE_CMP_KEY_CB(_edje_signal_source_key_cmp), programs[i]->source);
if (!item)
{
item = malloc(sizeof (Edje_Signal_Source_Char));
if (!item) continue;
- item->signal = program->signal;
- item->source = program->source;
+ item->signal = programs[i]->signal;
+ item->source = programs[i]->source;
item->list = NULL;
new = eina_rbtree_inline_insert(new, EINA_RBTREE_GET(item),
EINA_RBTREE_CMP_NODE_CB(_edje_signal_source_node_cmp), NULL);
}
- item->list = eina_list_prepend(item->list, program);
+ item->list = eina_list_prepend(item->list, programs[i]);
}
else
- result = eina_list_prepend(result, program);
+ result = eina_list_prepend(result, programs[i]);
}
*tree = new;
struct _Edje_Part_Collection
{
- Eina_List *programs; /* a list of Edje_Program *//* FIXME: use multiple array */
+ struct { /* list of Edje_Program */
+ Edje_Program **fnmatch; /* complex match with "*?[\" */
+ unsigned int fnmatch_count;
+
+ Edje_Program **strcmp; /* No special caractere, plain strcmp does the work */
+ unsigned int strcmp_count;
+
+ Edje_Program **strncmp; /* Finish by * or ?, plain strncmp does the work */
+ unsigned int strncmp_count;
+
+ Edje_Program **strrncmp; /* Start with * or ?, reverse strncmp will do the job */
+ unsigned int strrncmp_count;
+
+ Edje_Program **nocmp; /* Empty signal/source that will never match */
+ unsigned int nocmp_count;
+ } programs;
Edje_Part **parts; /* an array of Edje_Part */
unsigned int parts_count;
};
struct _Edje_Signals_Sources_Patterns
+
{
Edje_Patterns *signals_patterns;
Edje_Patterns *sources_patterns;
Eina_Rbtree *exact_match;
- Eina_List *globing;
+
+ union {
+ struct {
+ Edje_Program **globing;
+ unsigned int count;
+ } programs;
+ struct {
+ Eina_List *globing;
+ } callbacks;
+ } u;
};
typedef struct _Edje_Signals_Sources_Patterns Edje_Signals_Sources_Patterns;
size_t finals[];
};
-Edje_Patterns *edje_match_collection_dir_init(Eina_List *lst);
-Edje_Patterns *edje_match_programs_signal_init(Eina_List *lst);
-Edje_Patterns *edje_match_programs_source_init(Eina_List *lst);
-Edje_Patterns *edje_match_callback_signal_init(Eina_List *lst);
-Edje_Patterns *edje_match_callback_source_init(Eina_List *lst);
+Edje_Patterns *edje_match_collection_dir_init(const Eina_List *lst);
+Edje_Patterns *edje_match_programs_signal_init(Edje_Program * const *array,
+ unsigned int count);
+Edje_Patterns *edje_match_programs_source_init(Edje_Program * const *array,
+ unsigned int count);
+Edje_Patterns *edje_match_callback_signal_init(const Eina_List *lst);
+Edje_Patterns *edje_match_callback_source_init(const Eina_List *lst);
Eina_Bool edje_match_collection_dir_exec(const Edje_Patterns *ppat,
const char *string);
const Edje_Patterns *ppat_source,
const char *signal,
const char *source,
- Eina_List *programs,
+ Edje_Program **programs,
Eina_Bool (*func)(Edje_Program *pr, void *data),
void *data);
int edje_match_callback_exec(Edje_Patterns *ppat_signal,
void edje_match_patterns_free(Edje_Patterns *ppat);
-Eina_List *edje_match_program_hash_build(const Eina_List *callbacks,
+Eina_List *edje_match_program_hash_build(Edje_Program * const * programs,
+ unsigned int count,
Eina_Rbtree **tree);
Eina_List *edje_match_callback_hash_build(const Eina_List *callbacks,
Eina_Rbtree **tree);
NULL);
ed->patterns.callbacks.exact_match = NULL;
- ed->patterns.callbacks.globing = eina_list_free(ed->patterns.callbacks.globing);
+ ed->patterns.callbacks.u.callbacks.globing = eina_list_free(ed->patterns.callbacks.u.callbacks.globing);
}
static void
Edje_Signals_Sources_Patterns *ssp = &ed->patterns.callbacks;
if ((ssp->signals_patterns) || (ssp->sources_patterns) ||
- (ssp->globing) || (ssp->exact_match))
+ (ssp->u.callbacks.globing) || (ssp->exact_match))
return;
- ssp->globing = edje_match_callback_hash_build(ed->callbacks,
- &ssp->exact_match);
+ ssp->u.callbacks.globing = edje_match_callback_hash_build(ed->callbacks,
+ &ssp->exact_match);
- ssp->signals_patterns = edje_match_callback_signal_init(ssp->globing);
- ssp->sources_patterns = edje_match_callback_source_init(ssp->globing);
+ ssp->signals_patterns = edje_match_callback_signal_init(ssp->u.callbacks.globing);
+ ssp->sources_patterns = edje_match_callback_source_init(ssp->u.callbacks.globing);
}
/* FIXME: what if we delete the evas object??? */
data.matched = 0;
data.matches = NULL;
#endif
- if (ed->collection->programs)
+ if (ed->table_programs_size > 0)
{
const Eina_List *match;
const Eina_List *l;
Edje_Program *pr;
- if (ed->patterns.programs.globing)
+ if (ed->patterns.programs.u.programs.globing)
if (edje_match_programs_exec(ed->patterns.programs.signals_patterns,
ed->patterns.programs.sources_patterns,
sig,
src,
- ed->patterns.programs.globing,
+ ed->patterns.programs.u.programs.globing,
_edje_glob_callback,
&data) == 0)
goto break_prog;
int r = 1;
_edje_callbacks_patterns_init(ed);
- if (ed->patterns.callbacks.globing)
+ if (ed->patterns.callbacks.u.callbacks.globing)
r = edje_match_callback_exec(ed->patterns.callbacks.signals_patterns,
ed->patterns.callbacks.sources_patterns,
sig,
src,
- ed->patterns.callbacks.globing,
+ ed->patterns.callbacks.u.callbacks.globing,
ed);
if (!r)