], 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"
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
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
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}
#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>
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
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
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
+#include <math.h>
+
#include "Eet.h"
#include "Eet_private.h"
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;
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;
}
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;
}
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;
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;
}
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;
}
#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
}
/* 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)
{
}
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);
+#include <stdio.h>
+#include <math.h>
+
int
_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);
+}