Hey Cedric,

please take a look with clang and fix.


Core was generated by
`/home/likewise-open/SERILOCAL/d.willmann/scm/core/efl/src/bin/edje/.libs/lt-edj'.
Program terminated with signal 11, Segmentation fault.
#0  __memmove_ssse3_back () at
../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:1555
1555    ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S: No such file or
directory.
(gdb) bt
#0  __memmove_ssse3_back () at
../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:1555
#1  0x00007fecfba11769 in _eina_file_escape (path=<optimized out>,
len=<optimized out>, path=<optimized out>, len=<optimized out>)
    at
/home/likewise-open/SERILOCAL/d.willmann/scm/core/efl/src/lib/eina/eina_file_common.c:105
#2  eina_file_path_sanitize (path=<optimized out>) at
../src/lib/eina/eina_file_common.c:138
#3  0x00007fecfba3bd0f in eina_file_open (path=<optimized out>,
shared=<optimized out>)
    at
/home/likewise-open/SERILOCAL/d.willmann/scm/core/efl/src/lib/eina/eina_file.c:851
#4  0x00007fecfbf4d0cd in evas_image_load_file_head_png (ie=<optimized
out>, file=<optimized out>, key=<optimized out>, error=<optimized out>)
    at modules/evas/loaders/png/evas_image_load_png.c:64
#5  0x00007fecfbf1f186 in evas_common_load_rgba_image_module_from_file
(ie=<optimized out>)
    at
/home/likewise-open/SERILOCAL/d.willmann/scm/core/efl/src/lib/evas/common/evas_image_load.c:220
#6  0x00007fecfbef7609 in _evas_cache_image_entry_new (cache=<optimized
out>, hkey=<optimized out>,
    tstamp=<error reading variable: Unhandled dwarf expression opcode
0x0>, file=<optimized out>, key=<optimized out>, lo=<optimized out>,
    error=<optimized out>) at lib/evas/cache/evas_cache_image.c:247
#7  0x00007fecfbef7190 in evas_cache_image_request (cache=<optimized
out>, file=<optimized out>, key=<optimized out>, lo=<optimized out>,
    error=<optimized out>) at lib/evas/cache/evas_cache_image.c:710
#8  0x00007fecfbf202ce in evas_common_load_image_from_file
(file=<optimized out>, key=<optimized out>, lo=<optimized out>,
error=<optimized out>)
    at
/home/likewise-open/SERILOCAL/d.willmann/scm/core/efl/src/lib/evas/common/evas_image_main.c:756
#9  0x00007fecfbf3ad02 in eng_image_load (data=<error reading variable:
Unhandled dwarf expression opcode 0x0>, file=<optimized out>,
    key=<optimized out>, error=<optimized out>, lo=<optimized out>) at
modules/evas/engines/software_generic/evas_engine.c:957
#10 0x00007fecfbeaaab6 in _image_file_set (eo_obj=<optimized out>,
_pd=<optimized out>, list=<optimized out>) at
lib/evas/canvas/evas_object_image.c:561
#11 0x00007fecfa353b54 in _eo_op_internal (op_type=1651454208,
obj=<optimized out>, op=<optimized out>, p_list=<optimized out>)
    at
/home/likewise-open/SERILOCAL/d.willmann/scm/core/efl/src/lib/eo/eo.c:364
#12 0x00007fecfa3535dc in _eo_dov_internal (op_type=1651454208,
obj=<optimized out>, p_list=<optimized out>)
    at
/home/likewise-open/SERILOCAL/d.willmann/scm/core/efl/src/lib/eo/eo.c:404
#13 0x00007fecfa35350e in eo_do_internal (obj=0xe16f90,
op_type=<optimized out>)
    at
/home/likewise-open/SERILOCAL/d.willmann/scm/core/efl/src/lib/eo/eo.c:435
#14 0x00007fecfbea6f19 in evas_object_image_file_set (eo_obj=<optimized
out>, file=<optimized out>, key=<optimized out>)
    at lib/evas/canvas/evas_object_image.c:485
#15 0x000000000040596a in data_write () at bin/edje/edje_cc_out.c:1630
#16 0x0000000000404850 in data_write () at bin/edje/edje_cc_out.c:1589
#17 0x00007fecfaea676d in __libc_start_main (main=0x404090 <main+1136>,
argc=9, ubp_av=0x7fff18f2d5c8, init=<optimized out>, fini=<optimized out>,
    rtld_fini=<optimized out>, stack_end=0x7fff18f2d5b8) at libc-start.c:226
#18 0x0000000000403fc9 in main (argc=<error reading variable: Cannot
access memory at address 0xffffffffffffdf3c>, argv=0x0) at
bin/edje/edje_cc.c:199


Regards,
Daniel




On 14/03/13 17:24, Daniel Willmann - Enlightenment Git wrote:
> asdfuser pushed a commit to branch master.
> 
> commit f90726cf35bb89f14af7b57d8360848a8228dce9
> Author: Daniel Willmann <d.willm...@samsung.com>
> Date:   Thu Mar 14 17:21:48 2013 +0000
> 
>     Revert "eina: improve portability of Eina_File."
>     
>     This reverts commit c002d113f11310b5367bfcd300c0add84bf6f57f.
>     
>     This commit reliably breaks builds with clang. Please test with
>     export CC=clang before you commit again.
>     
>     export CC=clang
>     ./autogen.sh --enable-multisense && make -j 10
>     
>     The error Jenkins gets (I confirmed locally):
>     
>     /bin/bash: line 1: 13549 Segmentation fault      (core dumped)
> EFL_RUN_IN_TREE=1 ./bin/edje/edje_cc -id . -fd . -id ./tests/emotion/data
> tests/emotion/data/theme.edc tests/emotion/data/theme.edj
> ---
>  src/Makefile_Eina.am            |   2 -
>  src/lib/eina/eina_file.c        | 367
> ++++++++++++++++++++++++++++++++++++----
>  src/lib/eina/eina_file_common.c | 303 ---------------------------------
>  src/lib/eina/eina_file_common.h | 100 -----------
>  src/lib/eina/eina_file_win32.c  | 366
> +++++++++++++++++++++++++++++++++------
>  5 files changed, 645 insertions(+), 493 deletions(-)
> 
> diff --git a/src/Makefile_Eina.am b/src/Makefile_Eina.am
> index 91c4ec9..91ebe57 100644
> --- a/src/Makefile_Eina.am
> +++ b/src/Makefile_Eina.am
> @@ -107,8 +107,6 @@ lib/eina/eina_counter.c \
>  lib/eina/eina_cow.c \
>  lib/eina/eina_cpu.c \
>  lib/eina/eina_error.c \
> -lib/eina/eina_file_common.h \
> -lib/eina/eina_file_common.c \
>  lib/eina/eina_fp.c \
>  lib/eina/eina_hamster.c \
>  lib/eina/eina_hash.c \
> diff --git a/src/lib/eina/eina_file.c b/src/lib/eina/eina_file.c
> index d54b703..e498794 100644
> --- a/src/lib/eina/eina_file.c
> +++ b/src/lib/eina/eina_file.c
> @@ -53,7 +53,6 @@
>  #include "eina_mmap.h"
>  #include "eina_log.h"
>  #include "eina_xattr.h"
> -#include "eina_file_common.h"
>  
>  #ifdef HAVE_ESCAPE
>  # include <Escape.h>
> @@ -107,6 +106,50 @@ struct _Eina_File_Iterator
>  };
>  #endif
>  
> +struct _Eina_File
> +{
> +   const char *filename;
> +
> +   Eina_Hash *map;
> +   Eina_Hash *rmap;
> +   void *global_map;
> +
> +   Eina_Lock lock;
> +
> +   unsigned long long length;
> +   time_t mtime;
> +   ino_t inode;
> +#ifdef _STAT_VER_LINUX
> +   unsigned long int mtime_nsec;
> +#endif
> +
> +   int refcount;
> +   int global_refcount;
> +
> +   int fd;
> +
> +   Eina_Bool shared : 1;
> +   Eina_Bool delete_me : 1;
> +   Eina_Bool global_faulty : 1;
> +};
> +
> +typedef struct _Eina_File_Map Eina_File_Map;
> +struct _Eina_File_Map
> +{
> +   void *map;
> +
> +   unsigned long int offset;
> +   unsigned long int length;
> +
> +   int refcount;
> +
> +   Eina_Bool hugetlb : 1;
> +   Eina_Bool faulty : 1;
> +};
> +
> +static Eina_Hash *_eina_file_cache = NULL;
> +static Eina_Lock _eina_file_lock_cache;
> +
>  static int _eina_file_log_dom = -1;
>  
>  /*
> @@ -325,8 +368,8 @@
> _eina_file_stat_ls_iterator_next(Eina_File_Direct_Iterator *it, void
> **data)
>  }
>  #endif
>  
> -void
> -eina_file_real_close(Eina_File *file)
> +static void
> +_eina_file_real_close(Eina_File *file)
>  {
>     if (file->refcount != 0) return;
>  
> @@ -445,6 +488,90 @@ slprintf(char *str, size_t size, const char *format,
> ...)
>     va_end(ap);
>  }
>  
> +static char *
> +_eina_file_escape(const char *path, int *length)
> +{
> +   char *result;
> +   char *p;
> +   char *q;
> +   size_t len;
> +
> +   result = strdup(path ? path : "");
> +   p = result;
> +   q = result;
> +
> +   if (!result)
> +     return NULL;
> +
> +   if (length) len = *length;
> +   else len = strlen(result);
> +
> +   while ((p = strchr(p, '/')))
> +     {
> +     // remove double `/'
> +     if (p[1] == '/')
> +       {
> +          memmove(p, p + 1, --len - (p - result));
> +          result[len] = '\0';
> +       }
> +     else
> +       if (p[1] == '.'
> +           && p[2] == '.')
> +         {
> +            // remove `/../'
> +            if (p[3] == '/')
> +              {
> +                 char tmp;
> +
> +                 len -= p + 3 - q;
> +                 memmove(q, p + 3, len - (q - result));
> +                 result[len] = '\0';
> +                 p = q;
> +
> +                 /* Update q correctly. */
> +                 tmp = *p;
> +                 *p = '\0';
> +                 q = strrchr(result, '/');
> +                 if (!q) q = result;
> +                 *p = tmp;
> +              }
> +            else
> +              // remove '/..$'
> +              if (p[3] == '\0')
> +                {
> +                   len -= p + 2 - q;
> +                   result[len] = '\0';
> +                      break;
> +                }
> +              else
> +                {
> +                   q = p;
> +                   ++p;
> +                }
> +         }
> +        else
> +          if (p[1] == '.'
> +              && p[2] == '/')
> +            {
> +               // remove '/./'
> +               len -= 2;
> +               memmove(p, p + 2, len - (p - result));
> +               result[len] = '\0';
> +               q = p;
> +               ++p;
> +            }
> +       else
> +         {
> +            q = p;
> +            ++p;
> +         }
> +     }
> +
> +   if (length)
> +     *length = len;
> +   return result;
> +}
> +
>  /**
>   * @endcond
>   */
> @@ -556,51 +683,39 @@ eina_file_mmap_faulty(void *addr, long page_size)
>     eina_lock_release(&_eina_file_lock_cache);
>  }
>  
> -/* ================================================================ *
> - *   Simplified logic for portability layer with eina_file_common   *
> - * ================================================================ */  
> +/*=======================================================================
> =====*
> + *                                   API
> *
> +
> *=========================================================================
> ===*/
>  
> -Eina_Bool
> -eina_file_path_relative(const char *path)
> +EAPI char *
> +eina_file_path_sanitize(const char *path)
>  {
> -   if (*path != '/') return EINA_TRUE;
> -   return EINA_FALSE;
> -}
> +   char *result = NULL;
> +   int len;
>  
> -Eina_Tmpstr *
> -eina_file_current_directory_get(const char *path, size_t len)
> -{
> -  char cwd[PATH_MAX];
> -  char *tmp = NULL;
> +   if (!path) return NULL;
>  
> -  tmp = getcwd(cwd, PATH_MAX);
> -  if (!tmp) return NULL;
> +   len = strlen(path);
>  
> -  len += strlen(cwd) + 2;
> -  tmp = alloca(sizeof (char) * len);
> +   if (*path != '/')
> +     {
> +        char cwd[PATH_MAX];
> +        char *tmp = NULL;
>  
> -  slprintf(tmp, len, "%s/%s", cwd, path);
> +        tmp = getcwd(cwd, PATH_MAX);
> +        if (!tmp) return NULL;
>  
> -  return eina_tmpstr_add_length(tmp, len);
> -}
> +        len += strlen(cwd) + 2;
> +        tmp = alloca(sizeof (char) * len);
>  
> -char *
> -eina_file_cleanup(Eina_Tmpstr *path)
> -{
> -   char *result;
> +        slprintf(tmp, len, "%s/%s", cwd, path);
>  
> -   result = strdup(path ? path : "");
> -   eina_tmpstr_del(path);
> +        result = tmp;
> +     }
>  
> -   return result;
> +   return _eina_file_escape(result ? result : path, &len);
>  }
>  
> -/*=======================================================================
> =====*
> - *                                   API
> *
> -
> *=========================================================================
> ===*/
> -
> -
> -
>  EAPI Eina_Bool
>  eina_file_dir_list(const char *dir,
>                     Eina_Bool recursive,
> @@ -882,7 +997,7 @@ eina_file_open(const char *path, Eina_Bool shared)
>       {
>          file->delete_me = EINA_TRUE;
>          eina_hash_del(_eina_file_cache, file->filename, file);
> -        eina_file_real_close(file);
> +        _eina_file_real_close(file);
>          file = NULL;
>       }
>  
> @@ -941,6 +1056,45 @@ eina_file_open(const char *path, Eina_Bool shared)
>     return NULL;
>  }
>  
> +EAPI void
> +eina_file_close(Eina_File *file)
> +{
> +   EINA_SAFETY_ON_NULL_RETURN(file);
> +
> +   eina_lock_take(&file->lock);
> +   file->refcount--;
> +   eina_lock_release(&file->lock);
> +
> +   if (file->refcount != 0) return;
> +   eina_lock_take(&_eina_file_lock_cache);
> +
> +   eina_hash_del(_eina_file_cache, file->filename, file);
> +   _eina_file_real_close(file);
> +
> +   eina_lock_release(&_eina_file_lock_cache);
> +}
> +
> +EAPI size_t
> +eina_file_size_get(Eina_File *file)
> +{
> +   EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
> +   return file->length;
> +}
> +
> +EAPI time_t
> +eina_file_mtime_get(Eina_File *file)
> +{
> +   EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
> +   return file->mtime;
> +}
> +
> +EAPI const char *
> +eina_file_filename_get(Eina_File *file)
> +{
> +   EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
> +   return file->filename;
> +}
> +
>  EAPI void *
>  eina_file_map_all(Eina_File *file, Eina_File_Populate rule)
>  {
> @@ -985,6 +1139,145 @@ eina_file_map_all(Eina_File *file,
> Eina_File_Populate rule)
>     return ret;
>  }
>  
> +typedef struct _Eina_Lines_Iterator Eina_Lines_Iterator;
> +struct _Eina_Lines_Iterator
> +{
> +   Eina_Iterator iterator;
> +
> +   Eina_File *fp;
> +   const char *map;
> +   const char *end;
> +
> +   int boundary;
> +
> +   Eina_File_Line current;
> +};
> +
> +/* search '\r' and '\n' by preserving cache locality and page locality
> +   in doing a search inside 4K boundary.
> + */
> +static inline const char *
> +_eina_fine_eol(const char *start, int boundary, const char *end)
> +{
> +   const char *cr;
> +   const char *lf;
> +   unsigned long long chunk;
> +
> +   while (start < end)
> +     {
> +        chunk = start + boundary < end ? boundary : end - start;
> +        cr = memchr(start, '\r', chunk);
> +        lf = memchr(start, '\n', chunk);
> +        if (cr)
> +          {
> +             if (lf && lf < cr)
> +               return lf + 1;
> +             return cr + 1;
> +          }
> +        else if (lf)
> +           return lf + 1;
> +
> +        start += chunk;
> +        boundary = 4096;
> +     }
> +
> +   return end;
> +}
> +
> +static Eina_Bool
> +_eina_file_map_lines_iterator_next(Eina_Lines_Iterator *it, void **data)
> +{
> +   const char *eol;
> +   unsigned char match;
> +
> +   if (it->current.end >= it->end)
> +     return EINA_FALSE;
> +
> +   match = *it->current.end;
> +   while ((*it->current.end == '\n' || *it->current.end == '\r')
> +          && it->current.end < it->end)
> +     {
> +        if (match == *it->current.end)
> +          it->current.index++;
> +        it->current.end++;
> +     }
> +   it->current.index++;
> +
> +   if (it->current.end == it->end)
> +     return EINA_FALSE;
> +
> +   eol = _eina_fine_eol(it->current.end,
> +                        it->boundary,
> +                        it->end);
> +   it->boundary = (uintptr_t) eol & 0x3FF;
> +   if (it->boundary == 0) it->boundary = 4096;
> +
> +   it->current.start = it->current.end;
> +
> +   it->current.end = eol;
> +   it->current.length = eol - it->current.start - 1;
> +
> +   *data = &it->current;
> +   return EINA_TRUE;
> +}
> +
> +static Eina_File *
> +_eina_file_map_lines_iterator_container(Eina_Lines_Iterator *it)
> +{
> +   return it->fp;
> +}
> +
> +static void
> +_eina_file_map_lines_iterator_free(Eina_Lines_Iterator *it)
> +{
> +   eina_file_map_free(it->fp, (void*) it->map);
> +   eina_file_close(it->fp);
> +
> +   EINA_MAGIC_SET(&it->iterator, 0);
> +   free(it);
> +}
> +
> +EAPI Eina_Iterator *
> +eina_file_map_lines(Eina_File *file)
> +{
> +   Eina_Lines_Iterator *it;
> +
> +   EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
> +
> +   if (file->length == 0) return NULL;
> +
> +   it = calloc(1, sizeof (Eina_Lines_Iterator));
> +   if (!it) return NULL;
> +
> +   EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
> +
> +   it->map = eina_file_map_all(file, EINA_FILE_SEQUENTIAL);
> +   if (!it->map)
> +     {
> +        free(it);
> +        return NULL;
> +     }
> +
> +   eina_lock_take(&file->lock);
> +   file->refcount++;
> +   eina_lock_release(&file->lock);
> +
> +   it->fp = file;
> +   it->boundary = 4096;
> +   it->current.start = it->map;
> +   it->current.end = it->current.start;
> +   it->current.index = 0;
> +   it->current.length = 0;
> +   it->end = it->map + it->fp->length;
> +
> +   it->iterator.version = EINA_ITERATOR_VERSION;
> +   it->iterator.next =
> FUNC_ITERATOR_NEXT(_eina_file_map_lines_iterator_next);
> +   it->iterator.get_container =
> FUNC_ITERATOR_GET_CONTAINER(_eina_file_map_lines_iterator_container);
> +   it->iterator.free =
> FUNC_ITERATOR_FREE(_eina_file_map_lines_iterator_free);
> +
> +   return &it->iterator;
> +}
> +
>  EAPI void *
>  eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
>                    unsigned long int offset, unsigned long int length)
> diff --git a/src/lib/eina/eina_file_common.c
> b/src/lib/eina/eina_file_common.c
> deleted file mode 100644
> index 7f4682d..0000000
> --- a/src/lib/eina/eina_file_common.c
> +++ /dev/null
> @@ -1,303 +0,0 @@
> -/* EINA - EFL data type library
> - * Copyright (C) 2013 Cedric Bail
> - *
> - * This library is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU Lesser General Public
> - * License as published by the Free Software Foundation; either
> - * version 2.1 of the License, or (at your option) any later version.
> - *
> - * This library is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> - * Lesser General Public License for more details.
> - *
> - * You should have received a copy of the GNU Lesser General Public
> - * License along with this library;
> - * if not, see <http://www.gnu.org/licenses/>.
> - */
> -
> -#ifdef HAVE_CONFIG_H
> -# include "config.h"
> -#endif
> -
> -#include <string.h>
> -#include <stdint.h>
> -
> -#define COPY_BLOCKSIZE (4 * 1024 * 1024)
> -
> -#include "eina_config.h"
> -#include "eina_private.h"
> -
> -#include "eina_hash.h"
> -#include "eina_safety_checks.h"
> -#include "eina_file_common.h"
> -
> -#ifdef HAVE_ESCAPE
> -# include <Escape.h>
> -#endif
> -
> -Eina_Hash *_eina_file_cache = NULL;
> -Eina_Lock _eina_file_lock_cache;
> -
> -static char *
> -_eina_file_escape(char *path, size_t len)
> -{
> -   char *result;
> -   char *p;
> -   char *q;
> -
> -   result = path;
> -   p = result;
> -   q = result;
> -
> -   if (!result)
> -     return NULL;
> -
> -   while ((p = strchr(p, '/')))
> -     {
> -     // remove double `/'
> -     if (p[1] == '/')
> -       {
> -          memmove(p, p + 1, --len - (p - result));
> -          result[len] = '\0';
> -       }
> -     else
> -       if (p[1] == '.'
> -           && p[2] == '.')
> -         {
> -            // remove `/../'
> -            if (p[3] == '/')
> -              {
> -                 char tmp;
> -
> -                 len -= p + 3 - q;
> -                 memmove(q, p + 3, len - (q - result));
> -                 result[len] = '\0';
> -                 p = q;
> -
> -                 /* Update q correctly. */
> -                 tmp = *p;
> -                 *p = '\0';
> -                 q = strrchr(result, '/');
> -                 if (!q) q = result;
> -                 *p = tmp;
> -              }
> -            else
> -              // remove '/..$'
> -              if (p[3] == '\0')
> -                {
> -                   len -= p + 2 - q;
> -                   result[len] = '\0';
> -                      break;
> -                }
> -              else
> -                {
> -                   q = p;
> -                   ++p;
> -                }
> -         }
> -        else
> -          if (p[1] == '.'
> -              && p[2] == '/')
> -            {
> -               // remove '/./'
> -               len -= 2;
> -               memmove(p, p + 2, len - (p - result));
> -               result[len] = '\0';
> -               q = p;
> -               ++p;
> -            }
> -       else
> -         {
> -            q = p;
> -            ++p;
> -         }
> -     }
> -
> -   return result;
> -}
> -
> -// Global API
> -
> -EAPI char *
> -eina_file_path_sanitize(const char *path)
> -{
> -   Eina_Tmpstr *result = NULL;
> -   size_t len;
> -
> -   if (!path) return NULL;
> -
> -   len = strlen(path);
> -
> -   if (eina_file_path_relative(path))
> -     result = eina_file_current_directory_get(path, len);
> -   else
> -     result = path;
> -
> -   return _eina_file_escape(eina_file_cleanup(result),
> -                            eina_tmpstr_strlen(result));
> -}
> -
> -EAPI void
> -eina_file_close(Eina_File *file)
> -{
> -   EINA_SAFETY_ON_NULL_RETURN(file);
> -
> -   eina_lock_take(&file->lock);
> -   file->refcount--;
> -   eina_lock_release(&file->lock);
> -   if (file->refcount != 0) return ;
> -
> -   eina_lock_take(&_eina_file_lock_cache);
> -
> -   eina_hash_del(_eina_file_cache, file->filename, file);
> -   eina_file_real_close(file);
> -
> -   eina_lock_release(&_eina_file_lock_cache);
> -}
> -
> -EAPI size_t
> -eina_file_size_get(Eina_File *file)
> -{
> -   EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
> -   return file->length;
> -}
> -
> -EAPI time_t
> -eina_file_mtime_get(Eina_File *file)
> -{
> -   EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
> -  return file->mtime;
> -}
> -
> -EAPI const char *
> -eina_file_filename_get(Eina_File *file)
> -{
> -   EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
> -   return file->filename;
> -}
> -
> -/* search '\r' and '\n' by preserving cache locality and page locality
> -   in doing a search inside 4K boundary.
> - */
> -static inline const char *
> -_eina_fine_eol(const char *start, int boundary, const char *end)
> -{
> -   const char *cr;
> -   const char *lf;
> -   unsigned long long chunk;
> -
> -   while (start < end)
> -     {
> -        chunk = start + boundary < end ? boundary : end - start;
> -        cr = memchr(start, '\r', chunk);
> -        lf = memchr(start, '\n', chunk);
> -        if (cr)
> -          {
> -             if (lf && lf < cr)
> -               return lf + 1;
> -             return cr + 1;
> -          }
> -        else if (lf)
> -           return lf + 1;
> -
> -        start += chunk;
> -        boundary = 4096;
> -     }
> -
> -   return end;
> -}
> -
> -static Eina_Bool
> -_eina_file_map_lines_iterator_next(Eina_Lines_Iterator *it, void **data)
> -{
> -   const char *eol;
> -   unsigned char match;
> -
> -   if (it->current.end >= it->end)
> -     return EINA_FALSE;
> -
> -   match = *it->current.end;
> -   while ((*it->current.end == '\n' || *it->current.end == '\r')
> -          && it->current.end < it->end)
> -     {
> -        if (match == *it->current.end)
> -          it->current.index++;
> -        it->current.end++;
> -     }
> -   it->current.index++;
> -
> -   if (it->current.end == it->end)
> -     return EINA_FALSE;
> -
> -   eol = _eina_fine_eol(it->current.end,
> -                        it->boundary,
> -                        it->end);
> -   it->boundary = (uintptr_t) eol & 0x3FF;
> -   if (it->boundary == 0) it->boundary = 4096;
> -
> -   it->current.start = it->current.end;
> -
> -   it->current.end = eol;
> -   it->current.length = eol - it->current.start - 1;
> -
> -   *data = &it->current;
> -   return EINA_TRUE;
> -}
> -
> -static Eina_File *
> -_eina_file_map_lines_iterator_container(Eina_Lines_Iterator *it)
> -{
> -   return it->fp;
> -}
> -
> -static void
> -_eina_file_map_lines_iterator_free(Eina_Lines_Iterator *it)
> -{
> -   eina_file_map_free(it->fp, (void*) it->map);
> -   eina_file_close(it->fp);
> -
> -   EINA_MAGIC_SET(&it->iterator, 0);
> -   free(it);
> -}
> -
> -EAPI Eina_Iterator *
> -eina_file_map_lines(Eina_File *file)
> -{
> -   Eina_Lines_Iterator *it;
> -
> -   EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
> -
> -   if (file->length == 0) return NULL;
> -
> -   it = calloc(1, sizeof (Eina_Lines_Iterator));
> -   if (!it) return NULL;
> -
> -   EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
> -
> -   it->map = eina_file_map_all(file, EINA_FILE_SEQUENTIAL);
> -   if (!it->map)
> -     {
> -        free(it);
> -        return NULL;
> -     }
> -
> -   eina_lock_take(&file->lock);
> -   file->refcount++;
> -   eina_lock_release(&file->lock);
> -
> -   it->fp = file;
> -   it->boundary = 4096;
> -   it->current.start = it->map;
> -   it->current.end = it->current.start;
> -   it->current.index = 0;
> -   it->current.length = 0;
> -   it->end = it->map + it->fp->length;
> -
> -   it->iterator.version = EINA_ITERATOR_VERSION;
> -   it->iterator.next =
> FUNC_ITERATOR_NEXT(_eina_file_map_lines_iterator_next);
> -   it->iterator.get_container =
> FUNC_ITERATOR_GET_CONTAINER(_eina_file_map_lines_iterator_container);
> -   it->iterator.free =
> FUNC_ITERATOR_FREE(_eina_file_map_lines_iterator_free);
> -
> -   return &it->iterator;
> -}
> diff --git a/src/lib/eina/eina_file_common.h
> b/src/lib/eina/eina_file_common.h
> deleted file mode 100644
> index 3081d23..0000000
> --- a/src/lib/eina/eina_file_common.h
> +++ /dev/null
> @@ -1,100 +0,0 @@
> -/* EINA - EFL data type library
> - * Copyright (C) 2013 Cedric Bail
> - *
> - * This library is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU Lesser General Public
> - * License as published by the Free Software Foundation; either
> - * version 2.1 of the License, or (at your option) any later version.
> - *
> - * This library is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> - * Lesser General Public License for more details.
> - *
> - * You should have received a copy of the GNU Lesser General Public
> - * License along with this library;
> - * if not, see <http://www.gnu.org/licenses/>.
> - */
> -
> -#ifndef EINA_FILE_COMMON_H_
> -# define EINA_FILE_COMMON_H_
> -
> -#include "eina_file.h"
> -#include "eina_tmpstr.h"
> -#include "eina_lock.h"
> -
> -typedef struct _Eina_File_Map Eina_File_Map;
> -typedef struct _Eina_Lines_Iterator Eina_Lines_Iterator;
> -
> -struct _Eina_File
> -{
> -   const char *filename;
> -
> -   Eina_Hash *map;
> -   Eina_Hash *rmap;
> -   void *global_map;
> -
> -   Eina_Lock lock;
> -
> -#ifndef _WIN32
> -   unsigned long long length;
> -   time_t mtime;
> -   ino_t inode;
> -#ifdef _STAT_VER_LINUX
> -   unsigned long int mtime_nsec;
> -#endif
> -#else
> -   ULONGLONG length;
> -   ULONGLONG mtime;
> -#endif
> -
> -   int refcount;
> -   int global_refcount;
> -
> -#ifndef _WIN32
> -   int fd;
> -#else
> -   HANDLE handle;
> -   HANDLE fm;
> -#endif
> -
> -   Eina_Bool shared : 1;
> -   Eina_Bool delete_me : 1;
> -   Eina_Bool global_faulty : 1;
> -};
> -
> -struct _Eina_File_Map
> -{
> -   void *map;
> -
> -   unsigned long int offset;
> -   unsigned long int length;
> -
> -   int refcount;
> -
> -   Eina_Bool hugetlb : 1;
> -   Eina_Bool faulty : 1;
> -};
> -
> -struct _Eina_Lines_Iterator
> -{
> -   Eina_Iterator iterator;
> -
> -   Eina_File *fp;
> -   const char *map;
> -   const char *end;
> -
> -   int boundary;
> -
> -   Eina_File_Line current;
> -};
> -
> -Eina_Bool eina_file_path_relative(const char *path);
> -Eina_Tmpstr *eina_file_current_directory_get(const char *path, size_t
> len);
> -char *eina_file_cleanup(Eina_Tmpstr *path);
> -void eina_file_real_close(Eina_File *file);
> -
> -extern Eina_Hash *_eina_file_cache;
> -extern Eina_Lock _eina_file_lock_cache;
> -
> -#endif /* EINA_FILE_COMMON_H_ */
> diff --git a/src/lib/eina/eina_file_win32.c
> b/src/lib/eina/eina_file_win32.c
> index cb73c0a..8fc6bb4 100644
> --- a/src/lib/eina/eina_file_win32.c
> +++ b/src/lib/eina/eina_file_win32.c
> @@ -41,7 +41,6 @@
>  #include "eina_list.h"
>  #include "eina_lock.h"
>  #include "eina_log.h"
> -#include "eina_file_common.h"
>  
>  
> /*========================================================================
> ====*
>   *                                  Local
> *
> @@ -105,6 +104,42 @@ struct _Eina_File_Direct_Iterator
>     char                  dir[1];
>  };
>  
> +struct _Eina_File
> +{
> +   const char *filename;
> +
> +   Eina_Hash *map;
> +   Eina_Hash *rmap;
> +   void *global_map;
> +
> +   Eina_Lock lock;
> +
> +   ULONGLONG length;
> +   ULONGLONG mtime;
> +
> +   int refcount;
> +   int global_refcount;
> +
> +   HANDLE handle;
> +   HANDLE fm;
> +
> +   Eina_Bool shared : 1;
> +   Eina_Bool delete_me : 1;
> +};
> +
> +struct _Eina_File_Map
> +{
> +   void *map;
> +
> +   unsigned long int offset;
> +   unsigned long int length;
> +
> +   int refcount;
> +};
> +
> +static Eina_Hash *_eina_file_cache = NULL;
> +static Eina_Lock _eina_file_lock_cache;
> +
>  static int _eina_file_log_dom = -1;
>  
>  static Eina_Bool
> @@ -380,8 +415,8 @@
> _eina_file_win32_direct_ls_iterator_free(Eina_File_Direct_Iterator *it)
>     free(it);
>  }
>  
> -void
> -eina_file_real_close(Eina_File *file)
> +static void
> +_eina_file_real_close(Eina_File *file)
>  {
>     eina_hash_free(file->rmap);
>     eina_hash_free(file->map);
> @@ -424,6 +459,175 @@ _eina_file_map_key_hash(const unsigned long int
> *key, int key_length EINA_UNUSED
>       ^ eina_hash_int64(&key[1], sizeof (unsigned long int));
>  }
>  
> +static char *
> +_eina_file_win32_escape(const char *path, size_t *length)
> +{
> +   char *result;
> +   char *p;
> +   char *q;
> +   size_t len;
> +
> +   result = strdup(path ? path : "");
> +   if (!result)
> +     return NULL;
> +
> +   p = result;
> +   while (*p)
> +     {
> +       if (*p == '\\') *p = '/';
> +       p++;
> +     }
> +   p = result;
> +   q = result;
> +
> +   if (!result)
> +     return NULL;
> +
> +   if (length) len = *length;
> +   else len = strlen(result);
> +
> +   while ((p = strchr(p, '/')))
> +     {
> +        // remove double `/'
> +     if (p[1] == '/')
> +          {
> +             memmove(p, p + 1, --len - (p - result));
> +             result[len] = '\0';
> +          }
> +        else
> +          if (p[1] == '.'
> +              && p[2] == '.')
> +            {
> +               // remove `/../'
> +               if (p[3] == '/')
> +                 {
> +                    char tmp;
> +
> +                    len -= p + 3 - q;
> +                    memmove(q, p + 3, len - (q - result));
> +                    result[len] = '\0';
> +                    p = q;
> +
> +                    /* Update q correctly. */
> +                    tmp = *p;
> +                    *p = '\0';
> +                    q = strrchr(result, '/');
> +                    if (!q) q = result;
> +                    *p = tmp;
> +                 }
> +               else
> +                 // remove '/..$'
> +                 if (p[3] == '\0')
> +                   {
> +                      len -= p + 2 - q;
> +                      result[len] = '\0';
> +                      q = p;
> +                      ++p;
> +                   }
> +                 else
> +                   {
> +                      q = p;
> +                      ++p;
> +                   }
> +            }
> +          else
> +            {
> +               q = p;
> +               ++p;
> +            }
> +     }
> +
> +   if (length)
> +     *length = len;
> +
> +   return result;
> +}
> +
> +/* search '\r' and '\n' by preserving cache locality and page locality
> +   in doing a search inside 4K boundary.
> + */
> +static inline const char *
> +_eina_fine_eol(const char *start, int boundary, const char *end)
> +{
> +   const char *cr;
> +   const char *lf;
> +   unsigned long long chunk;
> +
> +   while (start < end)
> +     {
> +        chunk = start + boundary < end ? boundary : end - start;
> +        cr = memchr(start, '\r', chunk);
> +        lf = memchr(start, '\n', chunk);
> +        if (cr)
> +          {
> +             if (lf && lf < cr)
> +               return lf + 1;
> +             return cr + 1;
> +          }
> +        else if (lf)
> +           return lf + 1;
> +
> +        start += chunk;
> +        boundary = 4096;
> +     }
> +
> +   return end;
> +}
> +
> +static Eina_Bool
> +_eina_file_map_lines_iterator_next(Eina_Lines_Iterator *it, void **data)
> +{
> +   const char *eol;
> +   unsigned char match;
> +
> +   if (it->current.end >= it->end)
> +     return EINA_FALSE;
> +
> +   match = *it->current.end;
> +   while ((*it->current.end == '\n' || *it->current.end == '\r')
> +          && it->current.end < it->end)
> +     {
> +        if (match == *it->current.end)
> +          it->current.index++;
> +        it->current.end++;
> +     }
> +   it->current.index++;
> +
> +   if (it->current.end == it->end)
> +     return EINA_FALSE;
> +
> +   eol = _eina_fine_eol(it->current.end,
> +                        it->boundary,
> +                        it->end);
> +   it->boundary = (uintptr_t) eol & 0x3FF;
> +   if (it->boundary == 0) it->boundary = 4096;
> +
> +   it->current.start = it->current.end;
> +
> +   it->current.end = eol;
> +   it->current.length = eol - it->current.start - 1;
> +
> +   *data = &it->current;
> +   return EINA_TRUE;
> +}
> +
> +static Eina_File *
> +_eina_file_map_lines_iterator_container(Eina_Lines_Iterator *it)
> +{
> +   return it->fp;
> +}
> +
> +static void
> +_eina_file_map_lines_iterator_free(Eina_Lines_Iterator *it)
> +{
> +   eina_file_map_free(it->fp, (void*) it->map);
> +   eina_file_close(it->fp);
> +
> +   EINA_MAGIC_SET(&it->iterator, 0);
> +   free(it);
> +}
> +
> +
>  /**
>   * @endcond
>   */
> @@ -480,64 +684,44 @@ eina_file_shutdown(void)
>     return EINA_TRUE;
>  }
>  
> +/*=======================================================================
> =====*
> + *                                   API
> *
> +
> *=========================================================================
> ===*/
>  
> -/* ================================================================ *
> - *   Simplified logic for portability layer with eina_file_common   *
> - * ================================================================ */  
> -
> -Eina_Bool
> -eina_file_path_relative(const char *path)
> -{
> -   if (!evil_path_is_absolute(path)) return EINA_TRUE;
> -   return EINA_FALSE;
> -}
> -
> -Eina_Tmpstr *
> -eina_file_current_directory_get(const char *path, size_t len)
> -{
> -   char *cwd;
> -   char *tmp;
> -   DWORD l;
> -
> -   l = GetCurrentDirectory(0, NULL);
> -   if (l <= 0) return NULL;
> -
> -   cwd = alloca(sizeof(char) * (l + 1));
> -   GetCurrentDirectory(l + 1, cwd);
> -   len += l + 2;
> -   tmp = alloca(sizeof (char) * len);
> -   snprintf(tmp, len, "%s\\%s", cwd, path);
> -   tmp[len - 1] = '\0';
> -
> -   return eina_tmpstr_add_length(tmp, len);
> -}
>  
> -char *
> -eina_file_cleanup(Eina_Tmpstr *path)
> +EAPI char *
> +eina_file_path_sanitize(const char *path)
>  {
> -   char *result;
> -   char *p;
> +   char *result = NULL;
> +   size_t len;
>  
> -   result = strdup(path ? path : "");
> -   eina_tmpstr_del(path);
> +   if (!path) return NULL;
>  
> -   if (!result)
> -     return NULL;
> +   len = strlen(path);
>  
> -   p = result;
> -   while (*p)
> +   if (!evil_path_is_absolute(path))
>       {
> -        if (*p == '\\') *p = '/';
> -        p++;
> +        DWORD l;
> +
> +        l = GetCurrentDirectory(0, NULL);
> +        if (l > 0)
> +          {
> +             char *cwd;
> +             char *tmp;
> +
> +             cwd = alloca(sizeof(char) * (l + 1));
> +             GetCurrentDirectory(l + 1, cwd);
> +             len += l + 2;
> +             tmp = alloca(sizeof (char) * len);
> +             snprintf(tmp, len, "%s\\%s", cwd, path);
> +             tmp[len - 1] = '\0';
> +             result = tmp;
> +          }
>       }
>  
> -   return result;
> +   return _eina_file_win32_escape(result ? result : path, &len);
>  }
>  
> -/*=======================================================================
> =====*
> - *                                   API
> *
> -
> *=========================================================================
> ===*/
> -
>  EAPI Eina_Bool
>  eina_file_dir_list(const char *dir,
>                     Eina_Bool recursive,
> @@ -813,7 +997,7 @@ eina_file_open(const char *path, Eina_Bool shared)
>       {
>          file->delete_me = EINA_TRUE;
>          eina_hash_del(_eina_file_cache, file->filename, file);
> -        eina_file_real_close(file);
> +        _eina_file_real_close(file);
>          file = NULL;
>       }
>  
> @@ -869,6 +1053,45 @@ eina_file_open(const char *path, Eina_Bool shared)
>     return NULL;
>  }
>  
> +EAPI void
> +eina_file_close(Eina_File *file)
> +{
> +   EINA_SAFETY_ON_NULL_RETURN(file);
> +
> +   eina_lock_take(&file->lock);
> +   file->refcount--;
> +   eina_lock_release(&file->lock);
> +
> +   if (file->refcount != 0) return ;
> +   eina_lock_take(&_eina_file_lock_cache);
> +
> +   eina_hash_del(_eina_file_cache, file->filename, file);
> +   _eina_file_real_close(file);
> +
> +   eina_lock_release(&_eina_file_lock_cache);
> +}
> +
> +EAPI size_t
> +eina_file_size_get(Eina_File *file)
> +{
> +   EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
> +   return file->length;
> +}
> +
> +EAPI time_t
> +eina_file_mtime_get(Eina_File *file)
> +{
> +   EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
> +  return file->mtime;
> +}
> +
> +EAPI const char *
> +eina_file_filename_get(Eina_File *file)
> +{
> +   EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
> +   return file->filename;
> +}
> +
>  EAPI Eina_Iterator *eina_file_xattr_get(Eina_File *file EINA_UNUSED)
>  {
>     return NULL;
> @@ -907,6 +1130,47 @@ eina_file_map_all(Eina_File *file,
> Eina_File_Populate rule EINA_UNUSED)
>     return NULL;
>  }
>  
> +EAPI Eina_Iterator *
> +eina_file_map_lines(Eina_File *file)
> +{
> +   Eina_Lines_Iterator *it;
> +
> +   EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
> +
> +   if (file->length == 0) return NULL;
> +
> +   it = calloc(1, sizeof (Eina_Lines_Iterator));
> +   if (!it) return NULL;
> +
> +   EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
> +
> +   it->map = eina_file_map_all(file, EINA_FILE_SEQUENTIAL);
> +   if (!it->map)
> +     {
> +        free(it);
> +        return NULL;
> +     }
> +
> +   eina_lock_take(&file->lock);
> +   file->refcount++;
> +   eina_lock_release(&file->lock);
> +
> +   it->fp = file;
> +   it->boundary = 4096;
> +   it->current.start = it->map;
> +   it->current.end = it->current.start;
> +   it->current.index = 0;
> +   it->current.length = 0;
> +   it->end = it->map + it->fp->length;
> +
> +   it->iterator.version = EINA_ITERATOR_VERSION;
> +   it->iterator.next =
> FUNC_ITERATOR_NEXT(_eina_file_map_lines_iterator_next);
> +   it->iterator.get_container =
> FUNC_ITERATOR_GET_CONTAINER(_eina_file_map_lines_iterator_container);
> +   it->iterator.free =
> FUNC_ITERATOR_FREE(_eina_file_map_lines_iterator_free);
> +
> +   return &it->iterator;
> +}
> +
>  EAPI void *
>  eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
>                    unsigned long int offset, unsigned long int length)
> 


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to