mirror of
https://github.com/Gnucash/gnucash.git
synced 2026-09-03 20:53:02 -05:00
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:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user