* Add conversion functions to replace the use of snprintf with %a
authordoursse <doursse>
Tue, 25 Sep 2007 18:26:49 +0000 (18:26 +0000)
committerdoursse <doursse@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 25 Sep 2007 18:26:49 +0000 (18:26 +0000)
 * remove useless defines
 * minor cleanups

fixes bugs #181 and #182

git-svn-id: http://svn.enlightenment.org/svn/e/trunk/e17/libs/eet@31805 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

configure.in
eet.pc.in
src/lib/Eet_private.h
src/lib/Makefile.am
src/lib/eet_data.c
src/lib/eet_lib.c
src/lib/eet_utils.c

index 2aa0e61..e5684b5 100644 (file)
@@ -72,28 +72,6 @@ int main (int argc, char **argv) {
 ], AC_MSG_WARN([Cannot check when cross-compiling -- assuming null is okay])
 )
 
-AC_MSG_CHECKING([OS libc C99 '%a' support])
-AC_TRY_RUN([
-#include <stdio.h>
-int main(int argc, char **argv) {
-  char buf[4096];
-  float ival = 0.1234, oval = 0.0;
-  snprintf(buf, sizeof(buf), "%a", (double)ival);
-  sscanf(buf, "%a", &oval);
-  if (ival != oval) return -1;
-  return 0;
-}
-], AC_MSG_RESULT([yes]), [
-       AC_MSG_RESULT([no])
-       AC_MSG_ERROR([Unsupported Operating System!
-Your OS does not support C99's '%a' string format. Eet cannot function without
-it. Please contact your OS vendor to get updates for C99 '%a' floating point
-format read/write support or change operating systems for one with support
-for an already very old standard. (Linux is known to support this, as is
-Solaris 10)])
-], AC_MSG_WARN([Cannot check when cross-compiling -- assuming C99 '%a' support is OK])
-)
-
 if test "x${bindir}" = 'xNONE'; then
   if test "x${prefix}" = "xNONE"; then
     PACKAGE_BIN_DIR="${ac_default_prefix}/bin"
@@ -115,7 +93,7 @@ else
   PACKAGE_LIB_DIR="${libdir}"
 fi
 AC_SUBST(PACKAGE_LIB_DIR)
-               
+
 if test "x${prefix}" = "xNONE"; then
   PACKAGE_DATA_DIR="${ac_default_prefix}/share/${PACKAGE}"
 else
@@ -156,9 +134,6 @@ echo "  Compilation..........: make"
 echo
 echo "  Installation.........: make install"
 echo
-echo "    prefix.........: $prefix"
-echo "    binaries.......: $bindir"
-echo "    libraries......: $libdir"
-echo "    headers........: $includedir"
+echo "    prefix.............: $prefix"
 #echo "    documentation..: $datadir/$PACKAGE/doc"
 echo
index 2c10601..9d2f37c 100644 (file)
--- a/eet.pc.in
+++ b/eet.pc.in
@@ -7,5 +7,5 @@ Name: eet
 Description: Library for speedy data storage, retrieval, and compression
 Version: @VERSION@
 Libs: -L${libdir} -leet
-Libs.private: -lz -ljpeg
+Libs.private: -lz -ljpeg @fnmatch_libs@ @winsock_libs@ -lm
 Cflags: -I${includedir}
index e73f290..0d53d87 100644 (file)
@@ -18,9 +18,9 @@
 #include <ctype.h>
 
 #ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#elif __MINGW32__
-#include <winsock.h>
+# include <netinet/in.h>
+#elif _WIN32
+# include <winsock2.h>
 #endif
 
 #include <zlib.h>
@@ -43,6 +43,8 @@ FILE *_eet_memfile_write_open(void **data, size_t *size);
 void  _eet_memfile_write_close(FILE *f);
 void  _eet_memfile_shutdown(void);
 int   _eet_hash_gen(const char *key, int hash_size);
+int   _eet_string_to_double_convert(const char *src, long long *m, long *e);
+void  _eet_double_to_string_convert(char *des, double d);
 
 #ifndef PATH_MAX
 #define PATH_MAX 4096
index c17c496..8792672 100644 (file)
@@ -6,8 +6,7 @@ AUTOMAKE_OPTIONS     = 1.4 foreign
 MAINTAINERCLEANFILES = Makefile.in
 
 INCLUDES            = -I. \
-                       -I$(top_srcdir)/src/lib \
-                      -I$(top_srcdir)/src/lib/include 
+                       -I$(top_srcdir)/src/lib
 
 lib_LTLIBRARIES      = libeet.la
 include_HEADERS      = Eet.h
@@ -19,6 +18,6 @@ eet_memfile.c \
 eet_utils.c \
 Eet_private.h
 
-libeet_la_LIBADD       = -lz -ljpeg @fnmatch_libs@ @winsock_libs@
+libeet_la_LIBADD       = -lz -ljpeg @fnmatch_libs@ @winsock_libs@ -lm
 libeet_la_DEPENDENCIES = $(top_builddir)/config.h
 libeet_la_LDFLAGS      = @create_shared_lib@ -version-info 9:10:9
index 72f688b..4f8b884 100644 (file)
@@ -1,3 +1,5 @@
+#include <math.h>
+
 #include "Eet.h"
 #include "Eet_private.h"
 
@@ -358,8 +360,9 @@ static int
 eet_data_get_float(void *src, void *src_end, void *dst)
 {
    float *d;
-   float tf;
-   char *s, *str, *p, *prev_locale;
+   long long mantisse;
+   long      exponent;
+   char *s, *str, *p;
    int len;
 
    s = (char *)src;
@@ -369,14 +372,10 @@ eet_data_get_float(void *src, void *src_end, void *dst)
    while ((p < (char *)src_end) && (*p != 0)) {len++; p++;}
    str = alloca(len + 1);
    memcpy(str, s, len);
-   str[len] = 0;
-
-   prev_locale = setlocale(LC_NUMERIC, "C");
-/* solaris atof is broken and doesnt understand %a format as a float */   
-/*   *d = (float)atof(str); */
-   sscanf(str, "%a", &tf);
-   *d = (float)tf;
-   if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
+   str[len] = '\0';
+
+   _eet_string_to_double_convert(str, &mantisse, &exponent);
+   *d = (float)ldexp((double)mantisse, exponent);
    
    return len + 1;
 }
@@ -384,19 +383,17 @@ eet_data_get_float(void *src, void *src_end, void *dst)
 static void *
 eet_data_put_float(const void *src, int *size_ret)
 {
-   float *s;
-   char *d, buf[64], *prev_locale;
-   int len;
+   char   buf[64];
+   char  *d;
+   int    len;
 
-   s = (float *)src;
-   prev_locale = setlocale(LC_NUMERIC, "C");
-   snprintf(buf, sizeof(buf), "%a", (double)(*s));
-   if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
+   _eet_double_to_string_convert(buf, (double)(*(float *)src));
    len = strlen(buf);
    d = malloc(len + 1);
    if (!d) return NULL;
    strcpy(d, buf);
    *size_ret = len + 1;
+
    return d;
 }
 
@@ -404,9 +401,10 @@ eet_data_put_float(const void *src, int *size_ret)
 static int
 eet_data_get_double(void *src, void *src_end, void *dst)
 {
-   double *d;
-   float tf;
-   char *s, *str, *p, *prev_locale;
+   double   *d;
+   long long mantisse;
+   long      exponent;
+   char *s, *str, *p;
    int len;
 
    s = (char *)src;
@@ -416,14 +414,10 @@ eet_data_get_double(void *src, void *src_end, void *dst)
    while ((p < (char *)src_end) && (*p != 0)) {len++; p++;}
    str = alloca(len + 1);
    memcpy(str, s, len);
-   str[len] = 0;
+   str[len] = '\0';
 
-   prev_locale = setlocale(LC_NUMERIC, "C");
-/* solaris atof is broken and doesnt understand %a format as a float */   
-/*   *d = (double)atof(str); */
-   sscanf(str, "%a", &tf);
-   *d = (double)tf;
-   if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
+   _eet_string_to_double_convert(str, &mantisse, &exponent);
+   *d = ldexp((double)mantisse, exponent);
 
    return len + 1;
 }
@@ -431,19 +425,17 @@ eet_data_get_double(void *src, void *src_end, void *dst)
 static void *
 eet_data_put_double(const void *src, int *size_ret)
 {
-   double *s;
-   char *d, buf[128], *prev_locale;
-   int len;
+   char    buf[128];
+   char   *d;
+   int     len;
 
-   s = (double *)src;
-   prev_locale = setlocale(LC_NUMERIC, "C");
-   snprintf(buf, sizeof(buf), "%a", (double)(*s));
-   if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
+   _eet_double_to_string_convert(buf, (double)(*(double *)src));
    len = strlen(buf);
    d = malloc(len + 1);
    if (!d) return NULL;
    strcpy(d, buf);
    *size_ret = len + 1;
+
    return d;
 }
 
index e74aca5..4a36836 100644 (file)
 #undef HAVE_REALPATH
 #endif
 
-#ifdef _WIN32
-
-#ifndef F_SETFD
-#define F_SETFD 2
-#endif
-
-#ifndef PROT_READ
-#define PROT_READ 1
-#endif
-
-#ifndef FD_CLOEXEC
-#define FD_CLOEXEC 1
-#endif
-
-#endif
-
 #define EET_MAGIC_FILE                  0x1ee7ff00
 #define EET_MAGIC_FILE_HEADER           0x1ee7ff01
 
@@ -711,10 +695,10 @@ eet_open(const char *file, Eet_File_Mode mode)
               }
 
             /* This code is useless if we dont want backward compatibility */
-            for (k = name_size; k > 0 && ((uint8_t) * (p + HEADER_SIZE + k)) != 0; --k)
+            for (k = name_size; k > 0 && ((unsigned char) * (p + HEADER_SIZE + k)) != 0; --k)
               ;
 
-            efn->free_name = ((uint8_t) * (p + HEADER_SIZE + k)) != 0;
+            efn->free_name = ((unsigned char) * (p + HEADER_SIZE + k)) != 0;
 
             if (efn->free_name)
               {
@@ -732,7 +716,7 @@ eet_open(const char *file, Eet_File_Mode mode)
               }
             else
               /* The only really usefull peace of code for efn->name (no backward compatibility) */
-              efn->name = (char*)((uint8_t*)(p + HEADER_SIZE));
+              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);
index 898d87f..d4bac8a 100644 (file)
@@ -1,3 +1,6 @@
+#include <stdio.h>
+#include <math.h>
+
 int
 _eet_hash_gen(const char *key, int hash_size)
 {
@@ -33,3 +36,164 @@ _eet_hash_gen(const char *key, int hash_size)
    return hash_num;
 }
 
+/* On Windows (using MinGW or VC++), printf-like functions */
+/* rely on MSVCRT, which does not fully support the C99    */
+/* specifications. In particular, they do not support the  */
+/* modifier character %a.                                  */
+
+
+/* That function converts a string created by a valid %a   */
+/* modifier to a double.                                   */
+/*                                                         */
+/* The string must have the following format:              */
+/*                                                         */
+/*  [-]0xh.hhhhhp[+-]e                                     */
+/*                                                         */
+/* where e is a decimal number.                            */
+/* If n is the number of cyphers after the point, the      */
+/* returned mantisse and exponents are                     */
+/*                                                         */
+/*  mantisse: [-]hhhhhh                                    */
+/*  exponent: 2^([+-]e - 4 * n)                            */
+int
+_eet_string_to_double_convert(const char *src, long long *m, long *e)
+{
+   const char *str;
+   double      val;
+   long long   mantisse;
+   long        exponent;
+   int         nbr_decimals;
+   char        sign;
+
+   str = src;
+   sign = +1;
+
+   if (*str == '-')
+     {
+        sign = -1;
+        str++;
+     }
+   else if (*str == '0')
+     {
+        str++;
+        if (*str == 'x')
+          str++;
+        else
+          {
+             fprintf(stderr, "[Eet] Error during conversion\n");
+             return 0;
+          }
+     }
+   else
+     {
+        fprintf(stderr, "[Eet] Error during conversion\n");
+        return 0;
+     }
+
+   nbr_decimals = 0;
+   mantisse = (*str >= 'a') ? *str - 'a'  + 10 : *str - '0';
+   str++;
+   if (*str == '.')
+     {
+        str++;
+        while (*str != 'p')
+          {
+             mantisse <<= 4;
+             mantisse += (*str >= 'a') ? *str - 'a'  + 10 : *str - '0';
+             str++;
+             nbr_decimals++;
+          }
+     }
+   if (sign < 0)
+     mantisse = -mantisse;
+   if (*str != 'p')
+     {
+        fprintf(stderr, "[Eet] Error during conversion\n");
+        return 0;
+     }
+   sign = +1;
+   str++;
+   if (*str == '-')
+     {
+        sign = -1;
+        str++;
+     }
+   else if (*str == '+') str++;
+
+   exponent = 0;
+   while (*str != '\0')
+     {
+        exponent *= 10;
+        exponent += *str - '0';
+        str++;
+     }
+
+   if (sign < 0)
+     exponent = -exponent;
+
+   *m = mantisse;
+   *e = exponent - (nbr_decimals << 2);
+
+   return 1;
+}
+
+/* That function converts a double to a string that as the */
+/* following format:                                       */
+/*                                                         */
+/*  [-]0xh.hhhhhp[+-]e                                     */
+/*                                                         */
+/* where h is a hexadecimal number and e a decimal number. */
+void
+_eet_double_to_string_convert(char *des, double d)
+{
+   static const char look_up_table[] = {'0', '1', '2', '3', '4',
+                                        '5', '6', '7', '8', '9',
+                                        'a', 'b', 'c', 'd', 'e', 'f'};
+   int p;
+   int i;
+
+   char *str = des;
+
+   if (d < 0.0)
+     {
+        *(des++) = '-';
+        d = -d;
+     }
+
+   d = frexp(d, &p);
+
+   if (p)
+     {
+        d *= 2;
+        p -= 1;
+     }
+
+   *(des++) = '0';
+   *(des++) = 'x';
+   *(des++) = look_up_table[(size_t)d];
+   *(des++) = '.';
+
+   for (i = 0; i < 16; i++)
+     {
+        d -= floor(d);
+        d *= 16;
+        *(des++) = look_up_table[(size_t)d];
+     }
+
+   while (*(des - 1) == '0')
+     des--;
+
+   if (*(des - 1) == '.')
+     des--;
+
+   *(des++) = 'p';
+   if (p < 0)
+     {
+        *(des++) = '-';
+        p = -p;
+     }
+   else
+     *(des++) = '+';
+
+   sprintf(des, "%d", p);
+}