Hi,

        I have been working on some little improvement for Edje recently. The 
first 
patch, "edje_data_file.diff", add support for a data.file entry inside edc 
file. It give the possibility to put text file inside edje directy. It also 
provide EDJE_FILL_TYPE_TILE_WIDTH and EDJE_FILL_TYPE_TILE_HEIGHT for 
fill.type, this give the possibility to scale in one direction, and repeat 
tile in the other direction. This patch is small and will not impact existing 
edje application.

        I also provide a rerun of eet race condition patch. It should apply 
correctly 
and it should not break any thing also.

        The last patch is a more complex patch and need carefull review. It 
replace 
fnmatch by a edje specific match. We did it with a friend, Thomas Claveirole, 
and it work like fnmatch. We did make it work like edje_glob_match, it 
recognize [], ? and *. As it replace all fnmatch call inside edje, it could 
break any existing edje applications, if we didn't handle all case correctly. 
So if you have time, apply this patch to your CVS and test all edje 
application you have (with and without the patch ofcourse). This replacement 
of fnmatch should be more easy to port to other system and it could be faster 
than the original fnmatch version.

        A last topic I would like to discuss is FPU need by Edje. Right now 
without 
hardware floatting point, Edje could loose around 30% of time in soft float 
when you have many objects on the screen. I don't know what would be the best 
solution to this problem, doing some fixed point calculation or caching 
result, updating them when required. If people have idea on this I would like 
to ear as it is something I want to fix.

Cedric
diff -Nrua -X exclude.cvs e17-clean/libs/edje/src/bin/edje_cc_handlers.c e17-dev/libs/edje/src/bin/edje_cc_handlers.c
--- e17-clean/libs/edje/src/bin/edje_cc_handlers.c	2007-11-30 13:40:09.000000000 +0100
+++ e17-dev/libs/edje/src/bin/edje_cc_handlers.c	2007-12-07 15:40:26.000000000 +0100
@@ -48,6 +48,7 @@
 static void st_fonts_font(void);
 
 static void st_data_item(void);
+static void st_data_file(void);
 
 static void ob_styles_style(void);
 static void st_styles_style_name(void);
@@ -167,6 +168,7 @@
      {"images.image", st_images_image},
      {"fonts.font", st_fonts_font},
      {"data.item", st_data_item},
+     {"data.file", st_data_file},
      {"styles.style.name", st_styles_style_name},
      {"styles.style.base", st_styles_style_base},
      {"styles.style.tag", st_styles_style_tag},
@@ -704,6 +706,92 @@
 /**
     @page edcref
     @block
+        data
+    @context
+        data {
+            file: "arbitraryname" "filename";
+            file: "othername" "otherfilename";
+            ..
+        }
+    @description
+        The "data" block is used to pass arbitrary parameters from the theme to
+        the application. Unlike the "images" and "fonts" blocks, additional
+        "data" blocks can only be included inside the "group" block.
+    @endblock
+
+    @property
+        file
+    @parameters
+        [parameter name] [parameter filename]
+    @effect
+        Defines each additional parameter.
+    @endproperty
+ */
+static void
+st_data_file(void)
+{
+   const char *data;
+   const char *over;
+   Edje_Data *di;
+   char *filename;
+   char *value;
+   int fd;
+   int i;
+   struct stat buf;
+
+   check_arg_count(2);
+
+   di = mem_alloc(SZ(Edje_Data));
+   di->key = parse_str(0);
+   filename = parse_str(1);
+
+   fd = open(filename, O_RDONLY);
+   if (fd < 0)
+     {
+        fprintf(stderr, "%s: Error. %s:%i when opening file \"%s\": \"%s\"\n",
+                progname, file_in, line, filename, strerror(errno));
+        exit(-1);
+     }
+
+   if (fstat(fd, &buf))
+     {
+        fprintf(stderr, "%s: Error. %s:%i when stating file \"%s\": \"%s\"\n",
+                progname, file_in, line, filename, strerror(errno));
+        exit(-1);
+     }
+
+   data = mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
+   if (!data)
+     {
+        fprintf(stderr, "%s: Error. %s:%i when mapping file \"%s\": \"%s\"\n",
+                progname, file_in, line, filename, strerror(errno));
+        exit(-1);
+     }
+
+   over = data;
+   for (i = 0; i < buf.st_size; ++i, ++over)
+     if (*over == '\0')
+       {
+          fprintf(stderr, "%s: Error. %s:%i file \"%s\" is a binary file.\n",
+                  progname, file_in, line, filename);
+          exit(-1);
+       }
+
+   value = malloc(sizeof (char) * buf.st_size + 1);
+   snprintf(value, buf.st_size + 1, "%s", data);
+
+   munmap((void*)data, buf.st_size);
+   close(fd);
+
+   di->value = value;
+   edje_file->data = evas_list_append(edje_file->data, di);
+
+   free(filename);
+}
+
+/**
+    @page edcref
+    @block
         color_classes
     @context
         color_classes {
@@ -3054,6 +3142,8 @@
    ed->fill.type = parse_enum(0,
                               "SCALE", EDJE_FILL_TYPE_SCALE,
                               "TILE", EDJE_FILL_TYPE_TILE,
+			      "TILE-WIDTH", EDJE_FILL_TYPE_TILE_WIDTH,
+			      "TILE-HEIGHT", EDJE_FILL_TYPE_TILE_HEIGHT,
                               NULL);
 }
 
diff -Nrua -X exclude.cvs e17-clean/libs/edje/src/bin/edje_main.h e17-dev/libs/edje/src/bin/edje_main.h
--- e17-clean/libs/edje/src/bin/edje_main.h	2007-09-28 14:34:06.000000000 +0200
+++ e17-dev/libs/edje/src/bin/edje_main.h	2007-12-07 15:38:48.000000000 +0100
@@ -5,6 +5,7 @@
 #include <config.h>
 #endif
 
+#include <sys/mman.h>
 #include <Evas.h>
 #include <Ecore.h>
 #include <Ecore_Evas.h>
diff -Nrua -X exclude.cvs e17-clean/libs/edje/src/lib/edje_calc.c e17-dev/libs/edje/src/lib/edje_calc.c
--- e17-clean/libs/edje/src/lib/edje_calc.c	2007-10-20 19:28:28.000000000 +0200
+++ e17-dev/libs/edje/src/lib/edje_calc.c	2007-11-29 00:19:31.000000000 +0100
@@ -1055,7 +1055,7 @@
 	  {
 	     int fw;
 
-             if (desc->fill.type == EDJE_FILL_TYPE_TILE)
+             if (desc->fill.type == EDJE_FILL_TYPE_TILE || desc->fill.type == EDJE_FILL_TYPE_TILE_WIDTH)
 	       evas_object_image_size_get(ep->object, &fw, NULL);
 	     else
 	       fw = params->w;
@@ -1066,7 +1066,7 @@
 	if (flags & FLAG_Y)
 	  {
 	     int fh;
-             if (desc->fill.type == EDJE_FILL_TYPE_TILE)
+             if (desc->fill.type == EDJE_FILL_TYPE_TILE || desc->fill.type == EDJE_FILL_TYPE_TILE_HEIGHT)
 	       evas_object_image_size_get(ep->object, NULL, &fh);
 	     else
 	       fh = params->h;
diff -Nrua -X exclude.cvs e17-clean/libs/edje/src/lib/edje_private.h e17-dev/libs/edje/src/lib/edje_private.h
--- e17-clean/libs/edje/src/lib/edje_private.h	2007-10-20 19:28:28.000000000 +0200
+++ e17-dev/libs/edje/src/lib/edje_private.h	2007-12-18 18:30:54.000000000 +0100
@@ -903,6 +903,8 @@
 typedef enum _Edje_Fill
 {
    EDJE_FILL_TYPE_SCALE = 0,
-     EDJE_FILL_TYPE_TILE
+   EDJE_FILL_TYPE_TILE,
+   EDJE_FILL_TYPE_TILE_WIDTH,
+   EDJE_FILL_TYPE_TILE_HEIGHT
 } Edje_Fill;
 
diff -Nrua -X exclude.cvs e17-clean/libs/edje/src/lib/edje_load.c e17-dev/libs/edje/src/lib/edje_load.c
--- e17-clean/libs/edje/src/lib/edje_load.c	2007-09-28 14:34:06.000000000 +0200
+++ e17-dev/libs/edje/src/lib/edje_load.c	2007-12-17 17:02:53.000000000 +0100
@@ -158,15 +158,16 @@
      {
 	if (edf->collection_dir)
 	  {
-	     Evas_List *l;
+             Edje_Patterns      *patterns;
 
-	     for (l = edf->collection_dir->entries; l; l = l->next)
-	       {
-		  Edje_Part_Collection_Directory_Entry *ce;
-
-		  ce = l->data;
-		  if (_edje_glob_match(ce->entry, glob)) return 1;
-	       }
+             patterns = edje_match_collection_dir_init(edf->collection_dir->entries);
+             if (edje_match_collection_dir_exec(patterns,
+                                                glob))
+               {
+                  edje_match_patterns_free(patterns);
+                  return 1;
+               }
+             edje_match_patterns_free(patterns);
 	  }
 	_edje_cache_file_unref(edf);
      }
diff -Nrua -X exclude.cvs e17-clean/libs/edje/src/lib/edje_match.c e17-dev/libs/edje/src/lib/edje_match.c
--- e17-clean/libs/edje/src/lib/edje_match.c	1970-01-01 01:00:00.000000000 +0100
+++ e17-dev/libs/edje/src/lib/edje_match.c	2007-12-18 18:19:56.000000000 +0100
@@ -0,0 +1,546 @@
+#include <stdlib.h>
+#include <stddef.h>
+#include <Evas.h>
+
+#include "Edje.h"
+#include "edje_private.h"
+
+/* States manipulations. */
+
+typedef struct _Edje_State      Edje_State;
+struct _Edje_State
+{
+  size_t        idx;
+  size_t        pos;
+};
+
+typedef struct _Edje_States     Edje_States;
+struct _Edje_States
+{
+  size_t         size;
+  Edje_State    *states;
+  _Bool         *has;
+};
+
+static void
+_edje_match_states_free(Edje_States      *states,
+                        size_t            states_size)
+{
+   (void) states_size;
+   free(states);
+}
+
+static Edje_States*
+_edje_match_states_alloc(size_t n,
+                         size_t patterns_size,
+                         size_t patterns_max_length)
+{
+   Edje_States  *l;
+
+   const size_t  array_len      = (patterns_max_length + 1) * patterns_size;
+   const size_t  states_size    = sizeof (*l->states) * array_len;
+   const size_t  has_size       = sizeof (*l->has) * array_len;
+   const size_t  states_has_size= states_size + has_size;
+   const size_t  struct_size    = sizeof (*l) + states_has_size;
+
+   unsigned char        *states;
+   unsigned char        *has;
+
+   size_t        i;
+
+   l = malloc(n * struct_size);
+   if (!l) return NULL;
+
+   states = (unsigned char *) (l + n);
+   has = states + states_size;
+
+   for (i = 0; i < n; ++i)
+     {
+        l[i].states = (Edje_State *) states;
+        l[i].has = (_Bool *) has;
+        states += states_has_size;
+        has += states_has_size;
+     }
+
+   return l;
+}
+
+static void
+_edje_match_states_insert(Edje_States    *list,
+                          size_t          patterns_max_length,
+                          size_t          idx,
+                          size_t          pos)
+{
+   {
+      const size_t i = idx * (patterns_max_length + 1) + pos;
+
+      if (list->has[i]) return;
+      list->has[i] = 1;
+   }
+
+   const size_t i = list->size;
+
+   list->states[i].idx = idx;
+   list->states[i].pos = pos;
+   ++list->size;
+}
+
+static void
+_edje_match_states_clear(Edje_States     *list,
+                         size_t           patterns_size,
+                         size_t           patterns_max_length)
+{
+   list->size = 0;
+   memset(list->has, 0, patterns_size * (patterns_max_length + 1) * sizeof (*list->has));
+}
+
+/* Token manipulation. */
+
+enum status
+  {
+    patterns_not_found		= 0,
+    patterns_found		= 1,
+    patterns_syntax_error	= 2
+  };
+
+static size_t
+_edje_match_patterns_exec_class_token(enum status	*status,
+                                      const char	*cl_tok,
+                                      char		 c)
+{
+  if (! *cl_tok)
+    {
+      *status = patterns_syntax_error;
+      return 0;
+    }
+  else if (cl_tok[1] == '-' && cl_tok[2] != ']')
+    {
+      if (*cl_tok <= c && c <= cl_tok[2])
+	*status = patterns_found;
+      return 3;
+    }
+  else
+    {
+      if (c == *cl_tok)
+	*status = patterns_found;
+      return 1;
+    }
+}
+
+static Edje_Match_Error
+_edje_match_patterns_exec_class_complement(const char *cl_tok, size_t *ret)
+{
+  switch (*cl_tok)
+    {
+     case 0:
+        return EDJE_MATCH_SYNTAX_ERROR;
+
+     case '!':
+        *ret = 1;
+        return EDJE_MATCH_OK;
+
+    default:
+       *ret = 0;
+       return EDJE_MATCH_OK;
+    }
+}
+
+static Edje_Match_Error
+_edje_match_patterns_exec_class(const char	*cl,
+                                char		 c,
+                                size_t          *ret)
+{
+   enum status	status = patterns_not_found;
+   int		pos = 1;
+   size_t       neg;
+
+   if (_edje_match_patterns_exec_class_complement(cl + 1, &neg) != EDJE_MATCH_OK)
+     return EDJE_MATCH_SYNTAX_ERROR;
+
+   pos += neg;
+
+   do
+     pos += _edje_match_patterns_exec_class_token(&status, cl + pos, c);
+   while (cl[pos] && cl[pos] != ']');
+
+   if (status == patterns_syntax_error || ! cl[pos])
+     return EDJE_MATCH_SYNTAX_ERROR;
+
+   if (status == patterns_found)
+     *ret = neg ? 0 : pos + 1;
+   else
+     *ret = neg ? pos + 1 : 0;
+
+   return EDJE_MATCH_OK;
+}
+
+static Edje_Match_Error
+_edje_match_patterns_exec_token(const char	*tok,
+                                char		 c,
+                                size_t          *ret)
+{
+  switch (*tok)
+    {
+    case '\\':
+      if (tok[1])
+        {
+           *ret = tok[1] == c ? 2 : 0;
+           return EDJE_MATCH_OK;
+        }
+      return EDJE_MATCH_SYNTAX_ERROR;
+
+    case '?':
+      *ret = 1;
+      return EDJE_MATCH_OK;
+
+    case '[':
+       return _edje_match_patterns_exec_class(tok, c, ret);
+
+    default:
+       *ret = *tok == c ? 1 : 0;
+       return EDJE_MATCH_OK;
+    }
+}
+
+static void
+_edje_match_patterns_exec_init_states(Edje_States       *states,
+                                      size_t		 patterns_size,
+                                      size_t             patterns_max_length)
+{
+   size_t       i;
+
+   states->size = patterns_size;
+
+   memset(states->has,
+          0,
+          patterns_size * (patterns_max_length + 1) * sizeof (*states->has));
+   for (i = 0; i < patterns_size; ++i)
+     {
+        states->states[i].idx = i;
+        states->states[i].pos = 0;
+        states->has[i * (patterns_max_length + 1)] = 1;
+     }
+}
+
+/* Exported function. */
+
+#define EDJE_MATCH_INIT(Func, Type, Source, Show)               \
+  Edje_Patterns*                                                \
+  Func(Evas_List *lst)                                          \
+  {                                                             \
+     Edje_Patterns      *r;                                     \
+     size_t              i;                                     \
+                                                                \
+     if (!lst || evas_list_count(lst) <= 0)                     \
+       return NULL;                                             \
+                                                                \
+     r = malloc(sizeof (Edje_Patterns) +                        \
+                evas_list_count(lst)                            \
+                * sizeof (*r->finals)                           \
+                * sizeof(*r->patterns));                        \
+     if (!r) return NULL;                                       \
+                                                                \
+     r->patterns_size = evas_list_count(lst);                   \
+     r->max_length = 0;                                         \
+     r->patterns = (const char **) r->finals + r->patterns_size + 1;    \
+                                                                \
+     for (i = 0; lst; ++i)                                      \
+       {                                                        \
+          const char    *str;                                   \
+          Type          *data;                                  \
+          size_t         j;                                     \
+                                                                \
+          data = evas_list_data(lst);                           \
+          if (!data)                                            \
+            {                                                   \
+               free(r);                                         \
+               return NULL;                                     \
+            }                                                   \
+                                                                \
+          str = data->Source;                                   \
+          if (!str) str = "";                                   \
+          r->patterns[i] = str;                                 \
+                                                                \
+          if (Show)                                             \
+            fprintf(stderr, "%i [%s]\n", 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;                                  \
+                                                                \
+          lst = evas_list_next(lst);                            \
+       }                                                        \
+                                                                \
+     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, 1);
+EDJE_MATCH_INIT(edje_match_callback_source_init,
+                Edje_Signal_Callback,
+                source, 1);
+
+static int
+_edje_match_collection_dir_exec_finals(const size_t      *finals,
+                                       const Edje_States *states)
+{
+   size_t       i;
+
+   for (i = 0; i < states->size; ++i)
+     if (states->states[i].pos >= finals[states->states[i].idx])
+       return 1;
+   return 0;
+}
+
+static int
+edje_match_programs_exec_check_finals(const size_t      *signal_finals,
+                                      const size_t      *source_finals,
+                                      const Edje_States *signal_states,
+                                      const Edje_States *source_states,
+                                      Evas_List         *programs,
+                                      int (*func)(Edje_Program *pr, void *data),
+                                      void              *data)
+{
+   size_t       i;
+   size_t       j;
+
+   for (i = 0; i < signal_states->size; ++i)
+     if (signal_states->states[i].pos >= signal_finals[signal_states->states[i].idx])
+       for (j = 0; j < source_states->size; ++j)
+         if (signal_states->states[i].idx == source_states->states[j].idx
+             && source_states->states[j].pos >= source_finals[source_states->states[j].idx])
+           {
+              Edje_Program  *pr;
+
+              pr = evas_list_nth(programs, signal_states->states[i].idx);
+              if (pr)
+                {
+                   if (func(pr, data))
+                     return 0;
+                }
+       }
+
+   return 1;
+}
+
+static int
+edje_match_callback_exec_check_finals(const size_t      *signal_finals,
+                                      const size_t      *source_finals,
+                                      const Edje_States *signal_states,
+                                      const Edje_States *source_states,
+                                      Evas_List         *callbacks,
+                                      Edje              *ed)
+{
+   size_t       i;
+   size_t       j;
+   int          r = 1;
+
+   for (i = 0; i < signal_states->size; ++i)
+     if (signal_states->states[i].pos >= signal_finals[signal_states->states[i].idx])
+       for (j = 0; j < source_states->size; ++j)
+         if (signal_states->states[i].idx == source_states->states[j].idx
+             && source_states->states[j].pos >= source_finals[source_states->states[j].idx])
+           {
+              Edje_Signal_Callback      *escb;
+
+              escb = evas_list_nth(callbacks, signal_states->states[i].idx);
+              if (escb)
+                {
+                   if ((!escb->just_added)
+                       && (!escb->delete_me))
+                     {
+                        escb->func(escb->data, ed->obj, escb->signal, escb->source);
+                        r = 2;
+                     }
+                   if (_edje_block_break(ed))
+                     return 0;
+                }
+       }
+
+   return r;
+}
+
+
+static Edje_States*
+_edje_match_fn(const Edje_Patterns      *ppat,
+               const char               *string,
+               Edje_States              *states)
+{
+   Edje_States  *new_states = states + 1;
+   const char   *c;
+
+   for (c = string; *c && states->size; ++c)
+     {
+        size_t  i;
+
+        _edje_match_states_clear(new_states, ppat->patterns_size, ppat->max_length);
+
+        for (i = 0; i < states->size; ++i)
+          {
+             const size_t       idx = states->states[i].idx;
+             const size_t       pos = states->states[i].pos;
+
+             if (!ppat->patterns[idx][pos])
+               continue;
+             else if (ppat->patterns[idx][pos] == '*')
+               {
+                  _edje_match_states_insert(states, ppat->max_length, idx, pos + 1);
+                  _edje_match_states_insert(new_states, ppat->max_length, idx, pos);
+               }
+             else
+               {
+                  size_t        m;
+
+                  if (_edje_match_patterns_exec_token(ppat->patterns[idx] + pos,
+                                                      *c,
+                                                      &m) != EDJE_MATCH_OK)
+                    return NULL;
+
+                  if (m)
+                    _edje_match_states_insert(new_states, ppat->max_length, idx, pos + m);
+               }
+          }
+        {
+           Edje_States  *tmp = states;
+
+           states = new_states;
+           new_states = tmp;
+        }
+     }
+
+   return states;
+}
+
+int
+edje_match_collection_dir_exec(const Edje_Patterns      *ppat,
+                               const char               *string)
+{
+   Edje_States  *states = _edje_match_states_alloc(2,
+                                                   ppat->patterns_size,
+                                                   ppat->max_length);
+   Edje_States  *result;
+   int           r = 0;
+
+   if (!states)
+     return 0;
+   _edje_match_patterns_exec_init_states(states, ppat->patterns_size, ppat->max_length);
+
+   result = _edje_match_fn(ppat, string, states);
+
+   if (result)
+     r = _edje_match_collection_dir_exec_finals(ppat->finals, result);
+
+   _edje_match_states_free(states, 2);
+   return r;
+}
+
+int
+edje_match_programs_exec(const Edje_Patterns    *ppat_signal,
+                         const Edje_Patterns    *ppat_source,
+                         const char             *signal,
+                         const char             *source,
+                         Evas_List              *programs,
+                         int (*func)(Edje_Program *pr, void *data),
+                         void                   *data)
+{
+   Edje_States  *signal_states = _edje_match_states_alloc(2,
+                                                          ppat_signal->patterns_size,
+                                                          ppat_signal->max_length);
+   Edje_States  *source_states = _edje_match_states_alloc(2,
+                                                          ppat_source->patterns_size,
+                                                          ppat_source->max_length);
+   Edje_States  *signal_result;
+   Edje_States  *source_result;
+   int           r = 0;
+
+   if (!signal_states || !source_states)
+     return 0;
+
+   _edje_match_patterns_exec_init_states(signal_states,
+                                         ppat_signal->patterns_size,
+                                         ppat_signal->max_length);
+   _edje_match_patterns_exec_init_states(source_states,
+                                         ppat_source->patterns_size,
+                                         ppat_source->max_length);
+
+   signal_result = _edje_match_fn(ppat_signal, signal, signal_states);
+   source_result = _edje_match_fn(ppat_source, source, source_states);
+
+   if (signal_result && source_result)
+     r = edje_match_programs_exec_check_finals(ppat_signal->finals,
+                                               ppat_source->finals,
+                                               signal_result,
+                                               source_result,
+                                               programs,
+                                               func,
+                                               data);
+
+   _edje_match_states_free(source_states, 2);
+   _edje_match_states_free(signal_states, 2);
+   return r;
+}
+
+int
+edje_match_callback_exec(const Edje_Patterns    *ppat_signal,
+                         const Edje_Patterns    *ppat_source,
+                         const char             *signal,
+                         const char             *source,
+                         Evas_List              *callbacks,
+                         Edje                   *ed)
+{
+   Edje_States  *signal_states = _edje_match_states_alloc(2,
+                                                          ppat_signal->patterns_size,
+                                                          ppat_signal->max_length);
+   Edje_States  *source_states = _edje_match_states_alloc(2,
+                                                          ppat_source->patterns_size,
+                                                          ppat_source->max_length);
+   Edje_States  *signal_result;
+   Edje_States  *source_result;
+   int           r = 0;
+
+   if (!signal_states || !source_states)
+     return 0;
+
+   _edje_match_patterns_exec_init_states(signal_states,
+                                         ppat_signal->patterns_size,
+                                         ppat_signal->max_length);
+   _edje_match_patterns_exec_init_states(source_states,
+                                         ppat_source->patterns_size,
+                                         ppat_source->max_length);
+
+   signal_result = _edje_match_fn(ppat_signal, signal, signal_states);
+   source_result = _edje_match_fn(ppat_source, source, source_states);
+
+   if (signal_result && source_result)
+     r = edje_match_callback_exec_check_finals(ppat_signal->finals,
+                                               ppat_source->finals,
+                                               signal_result,
+                                               source_result,
+                                               callbacks,
+                                               ed);
+
+   _edje_match_states_free(source_states, 2);
+   _edje_match_states_free(signal_states, 2);
+   return r;
+}
+
+void
+edje_match_patterns_free(Edje_Patterns *ppat)
+{
+   free(ppat);
+}
+
diff -Nrua -X exclude.cvs e17-clean/libs/edje/src/lib/edje_private.h e17-dev/libs/edje/src/lib/edje_private.h
--- e17-clean/libs/edje/src/lib/edje_private.h	2007-10-20 19:28:28.000000000 +0200
+++ e17-dev/libs/edje/src/lib/edje_private.h	2007-12-18 18:30:54.000000000 +0100
@@ -903,9 +903,49 @@
 typedef enum _Edje_Fill
 {
    EDJE_FILL_TYPE_SCALE = 0,
      EDJE_FILL_TYPE_TILE
 } Edje_Fill;
 
+typedef enum _Edje_Match_Error
+{
+  EDJE_MATCH_OK,
+  EDJE_MATCH_ALLOC_ERROR,
+  EDJE_MATCH_SYNTAX_ERROR
+} Edje_Match_Error;
+
+typedef struct _Edje_Patterns   Edje_Patterns;
+struct _Edje_Patterns
+{
+  const char    **patterns;
+  size_t          patterns_size;
+  size_t          max_length;
+  size_t          finals[];
+};
+
+Edje_Patterns   *edje_match_collection_dir_init(Evas_List *lst);
+Edje_Patterns   *edje_match_programs_signal_init(Evas_List *lst);
+Edje_Patterns   *edje_match_programs_source_init(Evas_List *lst);
+Edje_Patterns   *edje_match_callback_signal_init(Evas_List *lst);
+Edje_Patterns   *edje_match_callback_source_init(Evas_List *lst);
+
+int              edje_match_collection_dir_exec(const Edje_Patterns      *ppat,
+                                                const char               *string);
+int              edje_match_programs_exec(const Edje_Patterns    *ppat_signal,
+                                          const Edje_Patterns    *ppat_source,
+                                          const char             *signal,
+                                          const char             *source,
+                                          Evas_List              *programs,
+                                          int (*func)(Edje_Program *pr, void *data),
+                                          void                   *data);
+int              edje_match_callback_exec(const Edje_Patterns    *ppat_signal,
+                                          const Edje_Patterns    *ppat_source,
+                                          const char             *signal,
+                                          const char             *source,
+                                          Evas_List              *callbacks,
+                                          Edje                   *ed);
+
+void             edje_match_patterns_free(Edje_Patterns *ppat);
+
 EAPI extern Eet_Data_Descriptor *_edje_edd_edje_file;
 EAPI extern Eet_Data_Descriptor *_edje_edd_edje_style;
 EAPI extern Eet_Data_Descriptor *_edje_edd_edje_style_tag;
@@ -998,7 +1040,6 @@
 void              _edje_text_class_hash_free(void);
 
 Edje             *_edje_fetch(Evas_Object *obj);
-int               _edje_glob_match(const char *str, const char *glob);
 int               _edje_freeze(Edje *ed);
 int               _edje_thaw(Edje *ed);
 int               _edje_block(Edje *ed);
diff -Nrua -X exclude.cvs e17-clean/libs/edje/src/lib/edje_program.c e17-dev/libs/edje/src/lib/edje_program.c
--- e17-clean/libs/edje/src/lib/edje_program.c	2007-09-28 14:34:06.000000000 +0200
+++ e17-dev/libs/edje/src/lib/edje_program.c	2007-12-18 17:18:54.000000000 +0100
@@ -823,12 +823,46 @@
    _edje_message_send(ed, EDJE_QUEUE_SCRIPT, EDJE_MESSAGE_SIGNAL, 0, &emsg);
 }
 
+struct _Edje_Program_Data
+{
+#ifdef EDJE_PROGRAM_CACHE
+  Evas_List        *matches;
+  int               matched;
+#endif
+  Edje             *ed;
+};
+
+static int found = 0;
+static int _edje_glob_callback(Edje_Program *pr, void *dt)
+{
+   struct _Edje_Program_Data    *data = dt;
+
+#ifdef EDJE_PROGRAM_CACHE
+   data->matched++;
+#endif
+
+   found = 1;
+   _edje_program_run(data->ed, pr, 0, pr->signal, pr->source);
+   if (_edje_block_break(data->ed))
+     {
+#ifdef EDJE_PROGRAM_CACHE
+        evas_list_free(data->matches);
+        data->matches = NULL;
+#endif
+        return 1;
+     }
+
+#ifdef EDJE_PROGRAM_CACHE
+   data->matches = evas_list_append(data->matches, pr);
+#endif
+
+   return 0;
+}
+
 /* FIXME: what if we delete the evas object??? */
 void
 _edje_emit_handle(Edje *ed, const char *sig, const char *src)
 {
-   Evas_List *l;
-
    if (ed->delete_me) return;
    if (!sig) sig = "";
    if (!src) src = "";
@@ -883,35 +917,42 @@
 #endif
 	if (!done)
 	  {
-#ifdef EDJE_PROGRAM_CACHE
-	     int matched = 0;
-	     Evas_List *matches = NULL;
-#endif
-
-	     for (l = ed->collection->programs; l; l = l->next)
-	       {
-		  Edje_Program *pr;
+             struct _Edje_Program_Data  data;
 
-		  pr = l->data;
-		  if ((_edje_glob_match(sig, pr->signal)) &&
-		      (_edje_glob_match(src, pr->source)))
-		    {
-#ifdef EDJE_PROGRAM_CACHE
-		       matched++;
-#endif
-		       _edje_program_run(ed, pr, 0, sig, src);
-		       if (_edje_block_break(ed))
-			 {
-#ifdef EDJE_PROGRAM_CACHE
-			    evas_list_free(matches);
-#endif
-			    goto break_prog;
-			 }
+             data.ed = ed;
 #ifdef EDJE_PROGRAM_CACHE
-		       matches = evas_list_append(matches, pr);
+	     data.matched = 0;
+	     data.matches = NULL;
 #endif
-		    }
-	       }
+             Edje_Patterns      *signals_patterns;
+             Edje_Patterns      *sources_patterns;
+
+             if (ed->collection->programs)
+               {
+                  found = 0;
+                  signals_patterns = edje_match_programs_signal_init(ed->collection->programs);
+                  sources_patterns = edje_match_programs_source_init(ed->collection->programs);
+
+                  if (edje_match_programs_exec(signals_patterns,
+                                               sources_patterns,
+                                               sig,
+                                               src,
+                                               ed->collection->programs,
+                                               _edje_glob_callback,
+                                               &data) == 0)
+                    {
+                       edje_match_patterns_free(signals_patterns);
+                       edje_match_patterns_free(sources_patterns);
+                       goto break_prog;
+                    }
+
+                  if (!found)
+                    fprintf(stderr, "NOT FOUND [%s][%s]\n", sig, src);
+
+                  edje_match_patterns_free(signals_patterns);
+                  edje_match_patterns_free(sources_patterns);
+               }
+
 #ifdef EDJE_PROGRAM_CACHE
 	     if (tmps)
 	       {
@@ -920,7 +961,7 @@
 		    evas_hash_add(ec->prog_cache.no_matches, tmps, ed);
 		  else
 		    ec->prog_cache.matches =
-		    evas_hash_add(ec->prog_cache.matches, tmps, matches);
+		    evas_hash_add(ec->prog_cache.matches, tmps, data.matches);
 	       }
 #endif
 	  }
@@ -940,25 +981,43 @@
 static void
 _edje_emit_cb(Edje *ed, const char *sig, const char *src)
 {
-   Evas_List *l;
+   Edje_Patterns        *signals_patterns;
+   Edje_Patterns        *sources_patterns;
+   Evas_List            *l;
 
    if (ed->delete_me) return;
    _edje_ref(ed);
    _edje_freeze(ed);
    _edje_block(ed);
    ed->walking_callbacks = 1;
-   for (l = ed->callbacks; l; l = l->next)
+
+   if (ed->callbacks)
      {
-	Edje_Signal_Callback *escb;
+        int     r;
+
+        signals_patterns = edje_match_callback_signal_init(ed->callbacks);
+        sources_patterns = edje_match_callback_source_init(ed->callbacks);
 
-	escb = l->data;
-	if ((!escb->just_added) &&
-	    (!escb->delete_me) &&
-	    (_edje_glob_match(sig, escb->signal)) &&
-	    (_edje_glob_match(src, escb->source)))
-	  escb->func(escb->data, ed->obj, sig, src);
-	if (_edje_block_break(ed)) goto break_prog;
+        r = edje_match_callback_exec(signals_patterns,
+                                     sources_patterns,
+                                     sig,
+                                     src,
+                                     ed->callbacks,
+                                     ed);
+
+        fprintf(stderr, "[%s][%s] = %i\n", sig, src, r);
+
+        if (!r)
+          {
+             edje_match_patterns_free(signals_patterns);
+             edje_match_patterns_free(sources_patterns);
+             goto break_prog;
+          }
+
+        edje_match_patterns_free(signals_patterns);
+        edje_match_patterns_free(sources_patterns);
      }
+
    ed->walking_callbacks = 0;
    if ((ed->delete_callbacks) || (ed->just_added_callbacks))
      {
diff -Nrua -X exclude.cvs e17-clean/libs/edje/src/lib/edje_util.c e17-dev/libs/edje/src/lib/edje_util.c
--- e17-clean/libs/edje/src/lib/edje_util.c	2007-12-18 18:01:52.000000000 +0100
+++ e17-dev/libs/edje/src/lib/edje_util.c	2007-12-18 16:16:59.000000000 +0100
@@ -1951,20 +1951,6 @@
 }
 
 int
-_edje_glob_match(const char *str, const char *glob)
-{
-   if ((!glob) || (glob[0] == 0))
-     {
-	if ((!str) || (str[0] == 0)) return 1;
-	if ((glob) && (glob[0] == '*')) return 1;
-	return 0;
-     }
-   if (glob[0] == '*') return 1;
-   if ((glob) && (str) && (!fnmatch(glob, str, 0))) return 1;
-   return 0;
-}
-
-int
 _edje_freeze(Edje *ed)
 {
    ed->freeze++;
diff -Nrua -X exclude.cvs e17-clean/libs/edje/src/lib/Makefile.am e17-dev/libs/edje/src/lib/Makefile.am
--- e17-clean/libs/edje/src/lib/Makefile.am	2007-11-30 13:40:09.000000000 +0100
+++ e17-dev/libs/edje/src/lib/Makefile.am	2007-12-17 16:04:37.000000000 +0100
@@ -34,6 +34,7 @@
 edje_message_queue.c \
 edje_private.h \
 edje_cache.c \
+edje_match.c \
 edje_textblock_styles.c
 
 libedje_la_LIBADD       = -lm @EDJE_LIBS@ @fnmatch_libs@
diff -Nrua -X exclude.cvs e17-clean/libs/eet/src/lib/Eet.h e17-dev/libs/eet/src/lib/Eet.h
--- e17-clean/libs/eet/src/lib/Eet.h	2007-11-30 13:40:09.000000000 +0100
+++ e17-dev/libs/eet/src/lib/Eet.h	2007-11-30 13:38:19.000000000 +0100
@@ -249,7 +249,7 @@
     * If the eet file handle is not valid NULL is returned and size_ret is
     * filled with 0.
     */
-   EAPI void	 *eet_read_direct  (Eet_File *ef, const char *name, int *size_ret);
+   EAPI const void *eet_read_direct(Eet_File *ef, const char *name, int *size_ret);
 
    /**
     * Write a specified entry to an eet file handle
diff -Nrua -X exclude.cvs e17-clean/libs/eet/src/lib/eet_data.c e17-dev/libs/eet/src/lib/eet_data.c
--- e17-clean/libs/eet/src/lib/eet_data.c	2007-11-30 13:40:09.000000000 +0100
+++ e17-dev/libs/eet/src/lib/eet_data.c	2007-11-30 13:38:19.000000000 +0100
@@ -906,7 +906,7 @@
 eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
 {
    void *data_dec;
-   void *data;
+   const void *data;
    int	size;
    int	required_free = 0;
 
diff -Nrua -X exclude.cvs e17-clean/libs/eet/src/lib/eet_image.c e17-dev/libs/eet/src/lib/eet_image.c
--- e17-clean/libs/eet/src/lib/eet_image.c	2007-03-20 18:54:12.000000000 +0100
+++ e17-dev/libs/eet/src/lib/eet_image.c	2006-12-20 12:24:26.000000000 +0100
@@ -733,7 +733,7 @@
    unsigned int *d = NULL;
    int		free_data = 0;
 
-   data = eet_read_direct (ef, name, &size);
+   data = (void*) eet_read_direct (ef, name, &size);
    if (!data)
      {
 	data = eet_read(ef, name, &size);
@@ -759,7 +759,7 @@
    int	d;
    int	free_data = 0;
 
-   data = eet_read_direct (ef, name, &size);
+   data = (void*) eet_read_direct (ef, name, &size);
    if (!data)
      {
 	data = eet_read(ef, name, &size);
diff -Nrua -X exclude.cvs e17-clean/libs/eet/src/lib/eet_lib.c e17-dev/libs/eet/src/lib/eet_lib.c
--- e17-clean/libs/eet/src/lib/eet_lib.c	2007-11-30 13:40:09.000000000 +0100
+++ e17-dev/libs/eet/src/lib/eet_lib.c	2007-12-03 16:08:44.000000000 +0100
@@ -23,20 +23,20 @@
 
 struct _Eet_File
 {
-   char            *path;
-   FILE            *fp;
-   Eet_File_Header *header;
-   unsigned char   *data;
-   
-   int              magic;
-   int              references;
-
-   Eet_File_Mode    mode;
-   int		    data_size;
-   time_t	    mtime;
+   char                 *path;
+   FILE                 *fp;
+   Eet_File_Header      *header;
+   const unsigned char  *data;
+
+   int                   magic;
+   int                   references;
+
+   Eet_File_Mode         mode;
+   int                   data_size;
+   time_t                mtime;
 
-   unsigned char    writes_pending : 1;
-   unsigned char    delete_me_now : 1;
+   unsigned char         writes_pending : 1;
+   unsigned char         delete_me_now : 1;
 };
 
 struct _Eet_File_Header
@@ -448,21 +448,211 @@
 		  num++;
 	       }
 	  }
-	
+
 	for (i = 0; i < num; i++)
 	  eet_close(closelist[i]);
      }
 }
 
+static Eet_File*
+eet_internal_read (Eet_File *ef)
+{
+   const unsigned char	*dyn_buf = NULL;
+   const unsigned char	*p = NULL;
+   int			index = 0;
+   int			num_entries;
+   int			byte_entries;
+   int			i;
+
+   if (eet_test_close((ef->data == (void *)-1) || (ef->data == NULL), ef))
+     return NULL;
+
+   if (eet_test_close(ef->data_size < sizeof(int) * 3, ef))
+     return NULL;
+
+   /* build header table if read mode */
+   /* geat header */
+   index += sizeof(int);
+   if (eet_test_close((int)ntohl(*((int *)ef->data)) != EET_MAGIC_FILE, ef))
+     return NULL;
+
+#define EXTRACT_INT(Value, Pointer, Index) \
+        { \
+	   int tmp; \
+	   memcpy(&tmp, Pointer + Index, sizeof(int)); \
+	   Value = ntohl(tmp); \
+	   Index += sizeof(int); \
+        }
+
+   /* get entries count and byte count */
+   EXTRACT_INT(num_entries, ef->data, index);
+   EXTRACT_INT(byte_entries, ef->data, index);
+
+   /* we cant have <= 0 values here - invalid */
+   if (eet_test_close((num_entries <= 0) || (byte_entries <= 0), ef))
+     return NULL;
+
+   /* we can't have more entires than minimum bytes for those! invalid! */
+   if (eet_test_close((num_entries * 20) > byte_entries, ef))
+     return NULL;
+
+   /* allocate header */
+   ef->header = calloc(1, sizeof(Eet_File_Header));
+   if (eet_test_close(!ef->header, ef))
+     return NULL;
+
+   ef->header->magic = EET_MAGIC_FILE_HEADER;
+
+   /* allocate directory block in ram */
+   ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
+   if (eet_test_close(!ef->header->directory, ef))
+     return NULL;
+
+   /* 8 bit hash table (256 buckets) */
+   ef->header->directory->size = 8;
+   /* allocate base hash table */
+   ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size));
+   if (eet_test_close(!ef->header->directory->nodes, ef))
+     return NULL;
+
+   /* actually read the directory block - all of it, into ram */
+   dyn_buf = ef->data + index;
+
+   /* parse directory block */
+   p = dyn_buf;
+
+   for (i = 0; i < num_entries; i++)
+     {
+	Eet_File_Node	*efn;
+	void		*data = NULL;
+	int		indexn = 0;
+	int		name_size;
+	int		hash;
+	int		k;
+
+#define HEADER_SIZE (sizeof(int) * 5)
+
+	/* out directory block is inconsistent - we have oveerun our */
+	/* dynamic block buffer before we finished scanning dir entries */
+	if (eet_test_close(p + HEADER_SIZE >= (dyn_buf + byte_entries), ef))
+	  return NULL;
+
+	/* allocate all the ram needed for this stored node accounting */
+	efn = malloc (sizeof(Eet_File_Node));
+	if (eet_test_close(!efn, ef))
+	  return NULL;
+
+	/* get entrie header */
+	EXTRACT_INT(efn->offset, p, indexn);
+	EXTRACT_INT(efn->compression, p, indexn);
+	EXTRACT_INT(efn->size, p, indexn);
+	EXTRACT_INT(efn->data_size, p, indexn);
+	EXTRACT_INT(name_size, p, indexn);
+
+	/* invalid size */
+	if (eet_test_close(efn->size <= 0, ef))
+	  {
+	     free (efn);
+	     return NULL;
+	  }
+
+	/* invalid name_size */
+	if (eet_test_close(name_size <= 0, ef))
+	  {
+	     free (efn);
+	     return NULL;
+	  }
+
+	/* reading name would mean falling off end of dyn_buf - invalid */
+	if (eet_test_close((p + 16 + name_size) > (dyn_buf + byte_entries), ef))
+	  {
+	     free (efn);
+	     return NULL;
+	  }
+
+	/* This code is useless if we dont want backward compatibility */
+	for (k = name_size; k > 0 && ((unsigned char) * (p + HEADER_SIZE + k)) != 0; --k)
+	  ;
+
+	efn->free_name = ((unsigned char) * (p + HEADER_SIZE + k)) != 0;
+
+	if (efn->free_name)
+	  {
+	     efn->name = malloc(sizeof(char) * name_size + 1);
+	     if (eet_test_close(efn->name == NULL, ef))
+	       {
+		  free (efn);
+		  return NULL;
+	       }
+
+	     strncpy(efn->name, (char *)p + HEADER_SIZE, name_size);
+	     efn->name[name_size] = 0;
+
+	     printf("File: %s is not up to date for key \"%s\" - needs rebuilding sometime\n", ef->path, efn->name);
+	  }
+	else
+	  /* The only really usefull peace of code for efn->name (no backward compatibility) */
+	  efn->name = (char*)((unsigned char*)(p + HEADER_SIZE));
+
+	/* get hash bucket it should go in */
+	hash = _eet_hash_gen(efn->name, ef->header->directory->size);
+	efn->next = ef->header->directory->nodes[hash];
+	ef->header->directory->nodes[hash] = efn;
+
+	/* read-only mode, so currently we have no data loaded */
+	if (ef->mode == EET_FILE_MODE_READ)
+	  efn->data = NULL;
+	/* read-write mode - read everything into ram */
+	else
+	  {
+	     data = malloc(efn->size);
+	     if (data)
+	       memcpy(data, ef->data + efn->offset, efn->size);
+	     efn->data = data;
+	  }
+	/* advance */
+	p += HEADER_SIZE + name_size;
+     }
+   return ef;
+}
+
+EAPI Eet_File *
+eet_memopen_read(const void *data, size_t size)
+{
+   Eet_File	*ef;
+
+   if (data == NULL || size == 0)
+     return NULL;
+
+   ef = malloc (sizeof (Eet_File));
+   if (!ef)
+     return NULL;
+
+   ef->path = NULL;
+   ef->magic = EET_MAGIC_FILE;
+   ef->references = 1;
+   ef->mode = EET_FILE_MODE_READ;
+   ef->header = NULL;
+   ef->mtime = 0;
+   ef->delete_me_now = 1;
+   ef->fp = NULL;
+   ef->data = data;
+   ef->data_size = size;
+
+   return eet_internal_read(ef);
+}
+
 EAPI Eet_File *
 eet_open(const char *file, Eet_File_Mode mode)
 {
+   FILE         *fp;
    Eet_File	*ef;
-   struct stat	file_stat;
+   struct stat	 file_stat;
+
 #ifdef _WIN32
-   HANDLE       h;
+   HANDLE        h;
 #endif
-   
+
    if (!file)
      return NULL;
 
@@ -490,17 +680,27 @@
 	ef = eet_cache_find((char *)file, eet_writers, eet_writers_num);
      }
 
-   if (stat(file, &file_stat))
-     {
-	if (mode == EET_FILE_MODE_WRITE)
-	  memset(&file_stat, 0, sizeof(file_stat));
-	else
-	  return NULL;
-     }
-   else if (file_stat.st_size == 0)
-     {
-	return NULL;
-     }
+   /* try open the file based on mode */
+   if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE)) {
+      fp = fopen(file, "rb");
+      if (fp == NULL)
+        return NULL;
+
+      if (fstat(fileno(fp), &file_stat))
+        {
+           fclose(fp);
+           return NULL;
+        }
+   } else {
+        if (mode != EET_FILE_MODE_WRITE)
+          return NULL;
+
+        memset(&file_stat, 0, sizeof(file_stat));
+
+        /* opening for write - delete old copy of file right away */
+        unlink(file);
+        fp = fopen(file, "wb");
+   }
 
    /* We found one */
    if (ef && (file_stat.st_mtime != ef->mtime))
@@ -509,10 +709,11 @@
 	eet_close(ef);
 	ef = NULL;
      }
-   
+
    if (ef)
      {
 	/* reference it up and return it */
+        fclose(fp);
 	ef->references++;
 	return ef;
      }
@@ -523,6 +724,7 @@
      return NULL;
 
    /* fill some of the members */
+   ef->fp = fp;
    ef->path = ((char *)ef) + sizeof(Eet_File);
    strcpy(ef->path, file);
    ef->magic = EET_MAGIC_FILE;
@@ -534,21 +736,6 @@
    ef->data = NULL;
    ef->data_size = 0;
 
-   /* try open the file based on mode */
-   if ((ef->mode == EET_FILE_MODE_READ) || (ef->mode == EET_FILE_MODE_READ_WRITE))
-     ef->fp = fopen(ef->path, "rb");
-   else
-     {
-	if (eet_test_close(ef->mode != EET_FILE_MODE_WRITE, ef))
-	  return NULL;
-	else
-	  {
-	     /* opening for write - delete old copy of file right away */
-	     unlink(ef->path);
-	     ef->fp = fopen(ef->path, "wb");
-	  }
-     }
-
    /* if we can't open - bail out */
    if (eet_test_close(!ef->fp, ef))
      return NULL;
@@ -565,12 +752,6 @@
    /* if we opened for read or read-write */
    if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE))
      {
-	unsigned char		*dyn_buf = NULL;
-	unsigned char		*p = NULL;
-	int			index = 0;
-	int			num_entries;
-	int			byte_entries;
-	int			i;
 #ifdef _WIN32
 	HANDLE                  fm;
 #endif
@@ -595,152 +776,9 @@
 	CloseHandle(fm);
 #endif
 
-	if (eet_test_close((ef->data == (void *)-1) || (ef->data == NULL), ef))
+	ef = eet_internal_read(ef);
+	if (!ef)
 	  return NULL;
-	
-	/* build header table if read mode */
-	/* geat header */
-	index += sizeof(int);
-	if (eet_test_close((int)ntohl(*((int *)ef->data)) != EET_MAGIC_FILE, ef))
-	  return NULL;
-
-#define EXTRACT_INT(Value, Pointer, Index) \
-        { \
-	   int tmp; \
-	   memcpy(&tmp, Pointer + Index, sizeof(int)); \
-	   Value = ntohl(tmp); \
-	   Index += sizeof(int); \
-        }
-
-	/* get entries count and byte count */
-	EXTRACT_INT(num_entries, ef->data, index);
-	EXTRACT_INT(byte_entries, ef->data, index);
-
-	/* we cant have <= 0 values here - invalid */
-//     if (eet_test_close((num_entries <= 0) || (byte_entries <= 0), ef))
-//	  return NULL;
-
-	/* we can't have more entires than minimum bytes for those! invalid! */
-	if (eet_test_close((num_entries * 20) > byte_entries, ef))
-	  return NULL;
-
-	/* allocate header */
-	ef->header = calloc(1, sizeof(Eet_File_Header));
-	if (eet_test_close(!ef->header, ef))
-	  return NULL;
-
-	ef->header->magic = EET_MAGIC_FILE_HEADER;
-
-	/* allocate directory block in ram */
-	ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
-	if (eet_test_close(!ef->header->directory, ef))
-	  return NULL;
-
-	/* 8 bit hash table (256 buckets) */
-	ef->header->directory->size = 8;
-	/* allocate base hash table */
-	ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size));
-	if (eet_test_close(!ef->header->directory->nodes, ef))
-	  return NULL;
-
-	/* actually read the directory block - all of it, into ram */
-	dyn_buf = ef->data + index;
-
-	/* parse directory block */
-	p = dyn_buf;
-
-	for (i = 0; i < num_entries; i++)
-	  {
-	     Eet_File_Node	*efn;
-	     void		*data = NULL;
-	     int		indexn = 0;
-	     int		name_size;
-	     int		hash;
-	     int		k;
-
-#define HEADER_SIZE (sizeof(int) * 5)
-
-	     /* out directory block is inconsistent - we have oveerun our */
-	     /* dynamic block buffer before we finished scanning dir entries */
-	     if (eet_test_close(p + HEADER_SIZE >= (dyn_buf + byte_entries), ef))
-	       return NULL;
-
-	     /* allocate all the ram needed for this stored node accounting */
-	     efn = malloc (sizeof(Eet_File_Node));
-	     if (eet_test_close(!efn, ef))
-	       return NULL;
-
-	     /* get entrie header */
-	     EXTRACT_INT(efn->offset, p, indexn);
-	     EXTRACT_INT(efn->compression, p, indexn);
-	     EXTRACT_INT(efn->size, p, indexn);
-	     EXTRACT_INT(efn->data_size, p, indexn);
-	     EXTRACT_INT(name_size, p, indexn);
-
-	     /* invalid size */
-	     if (eet_test_close(efn->size <= 0, ef))
-	       {
-		  free (efn);
-		  return NULL;
-	       }
-
-	     /* invalid name_size */
-	     if (eet_test_close(name_size <= 0, ef))
-	       {
-		  free (efn);
-		  return NULL;
-	       }
-	     
-	     /* reading name would mean falling off end of dyn_buf - invalid */
-	     if (eet_test_close((p + 16 + name_size) > (dyn_buf + byte_entries), ef))
-	       {
-		  free (efn);
-		  return NULL;
-	       }
-
-	     /* This code is useless if we dont want backward compatibility */
-	     for (k = name_size; k > 0 && ((unsigned char) * (p + HEADER_SIZE + k)) != 0; --k)
-	       ;
-
-	     efn->free_name = ((unsigned char) * (p + HEADER_SIZE + k)) != 0;
-
-	     if (efn->free_name)
-	       {
-		  efn->name = malloc(sizeof(char) * name_size + 1);
-		  if (eet_test_close(efn->name == NULL, ef))
-		    {
-		       free (efn);
-		       return NULL;
-		    }
-
-		  strncpy(efn->name, (char *)p + HEADER_SIZE, name_size);
-		  efn->name[name_size] = 0;
-
-		  printf("File: %s is not up to date for key \"%s\" - needs rebuilding sometime\n", ef->path, efn->name);
-	       }
-	     else
-	       /* The only really usefull peace of code for efn->name (no backward compatibility) */
-	       efn->name = (char*)((unsigned char *)(p + HEADER_SIZE));
-
-	     /* get hash bucket it should go in */
-	     hash = _eet_hash_gen(efn->name, ef->header->directory->size);
-	     efn->next = ef->header->directory->nodes[hash];
-	     ef->header->directory->nodes[hash] = efn;
-
-	     /* read-only mode, so currently we have no data loaded */
-	     if (mode == EET_FILE_MODE_READ)
-	       efn->data = NULL;
-	     /* read-write mode - read everything into ram */
-	     else
-	       {
-		  data = malloc(efn->size);
-		  if (data)
-		    memcpy(data, ef->data + efn->offset, efn->size);
-                  efn->data = data;
-	       }
-	     /* advance */
-	     p += HEADER_SIZE + name_size;
-	  }
      }
 
    /* we need to delete the original file in read-write mode and re-open for writing */
@@ -847,16 +885,18 @@
 	  }
 	free(ef->header);
      }
+
 #ifndef _WIN32
-   if (ef->data) munmap(ef->data, ef->data_size);
+   if (ef->data) munmap((void*)ef->data, ef->data_size);
 #else
    if (ef->data) UnmapViewOfFile (ef->data);
 #endif
+
    if (ef->fp) fclose(ef->fp);
 
    /* zero out ram for struct - caution tactic against stale memory use */
    memset(ef, 0, sizeof(Eet_File));
-   
+
    /* free it */
    free(ef);
    return err;
@@ -961,11 +1001,11 @@
    return data;
 }
 
-EAPI void *
+EAPI const void *
 eet_read_direct(Eet_File *ef, const char *name, int *size_ret)
 {
-   void *data = NULL;
-   int size = 0;
+   const void	*data = NULL;
+   int		 size = 0;
    Eet_File_Node *efn;
    
    if (size_ret)
-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services
for just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to