Drop workarounds for potential guile issues with long long

- The workarounds for long long were added more than 12
years back (pre guile 1.6). One would reasonably assume this issue would
have been fixed by now.
- But more importantly, we can guarantee a proper 64 type
conversion by replacing scm_to/from_long_long with scm_to/from_int64
which is always 64bit, just as gint64

I have chosen nonetheless to keep this change in a separate commit so
it's easier to track if some obscure platform still manages to screw
this up.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@22655 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Geert Janssens
2012-12-15 17:59:35 +00:00
parent f10395dade
commit 935c613267
2 changed files with 2 additions and 96 deletions
-28
View File
@@ -400,34 +400,6 @@ AC_SUBST(GUILE_INCS)
AC_SUBST(GUILE_LIBS)
AC_SUBST(GUILE)
### Check size of long_long - some guile's are broken.
AC_MSG_CHECKING(if guile long_long is at least as big as gint64)
AS_SCRUB_INCLUDE(CFLAGS)
GNC_OLDCFLAGS="$CFLAGS"
GNC_OLDLDFLAGS="$LDFLAGS"
CFLAGS="${GNOME_CFLAGS} ${GUILE_INCS} ${CFLAGS} ${GLIB_CFLAGS}"
LDFLAGS="${LDFLAGS} ${GLIB_LIBS}"
AC_TRY_RUN([
#include <glib.h>
#include <libguile/__scm.h>
int main(int argc, char *argv[]) {
return(!(sizeof(long_long) >= sizeof(gint64)));
}
],[
AC_MSG_RESULT(yes)
AC_CHECK_LIB(guile, scm_long_long2num,
AC_DEFINE(GUILE_LONG_LONG_OK,1,is sizeof(long_long) >= sizeof(gint64)))
],[
AC_MSG_RESULT(no)
],[
AC_MSG_RESULT(assuming yes)
AC_CHECK_LIB(guile, scm_long_long2num,
AC_DEFINE(GUILE_LONG_LONG_OK,1,is sizeof(long_long) >= sizeof(gint64)))
])
CFLAGS="$GNC_OLDCFLAGS"
LDFLAGS="$GNC_OLDLDFLAGS"
# One of the places this is critical is in gnc_scm_to_gint64 and inverse.
# However, I'm sure we require this elsewhere, so don't remove this test
# unless you've done sufficient code review/testing.
+2 -68
View File
@@ -2229,79 +2229,13 @@ gnc_scm2query (SCM query_scm)
SCM
gnc_gint64_to_scm(const gint64 x)
{
#if GUILE_LONG_LONG_OK
return scm_from_long_long(x);
#else
const gchar negative_p = (x < 0);
const guint64 magnitude = negative_p ? -x : x;
const guint32 lower_half = (guint32) (magnitude & 0xFFFFFFFF);
const guint32 upper_half = (guint32) (magnitude >> 32);
SCM result;
result = scm_sum(scm_ash(scm_from_ulong(upper_half), scm_from_int(32)),
scm_from_ulong(lower_half));
if (negative_p)
{
return scm_difference(SCM_INUM0, result);
}
else
{
return result;
}
#endif
return scm_from_int64(x);
}
gint64
gnc_scm_to_gint64(SCM num)
{
#if GUILE_LONG_LONG_OK
return scm_to_long_long(num);
#else
static SCM bits00to15_mask = SCM_BOOL_F;
SCM magnitude = scm_abs(num);
SCM bits;
unsigned long c_bits;
long long c_result = 0;
int i;
/* This doesn't work -- atm (bit-extract 4000 0 32) proves it */
/*
SCM lower = scm_bit_extract(magnitude, scm_from_int(0), scm_from_int(32));
*/
if (bits00to15_mask == SCM_BOOL_F)
{
bits00to15_mask = scm_from_ulong(0xFFFF);
scm_gc_protect_object (bits00to15_mask);
}
/*
* This isn't very complicated (IMHO). We work from the "top" of
* the number downwards. We assume this is no more than a 64-bit
* number, otherwise it will fail right away. Anyways, we keep
* taking the top 16 bits of the number and move it to c_result.
* Then we 'remove' those bits from the original number and continue
* with the next 16 bits down, and so on. -- warlord@mit.edu
* 2001/02/13
*/
for (i = 48; i >= 0; i -= 16)
{
bits = scm_ash(magnitude, scm_from_int(-i));
c_bits = scm_to_ulong(scm_logand(bits, bits00to15_mask));
c_result += ((long long)c_bits << i);
magnitude = scm_difference(magnitude, scm_ash(bits, scm_from_int(i)));
}
if (scm_negative_p(num) != SCM_BOOL_F)
{
return(- c_result);
}
else
{
return(c_result);
}
#endif
return scm_to_int64(num);
}
int