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