diff --git a/harbour/ChangeLog b/harbour/ChangeLog index f486abdb82..bc1ca6d392 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,23 @@ past entries belonging to these authors: Viktor Szakats. */ +2009-05-27 05:34 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/harbour.spec + * harbour/mpkg_tgz.sh + + added hbformat + + * harbour/include/hbdefs.h + * harbour/include/hbapi.h + * harbour/source/common/hbarch.c + * redefined macros used to store/retrieve integer and double values + to/from byte arrays in little and big endian order. + Now GCC uses inline functions which are hardly optimized by compiler + giving on x86 machines the same code as direct casting (with the + exception to march=i686 where putting double value forces strict + alignment to avoid hidden CPU exception) but they respect strict + aliasing rules. It also means that now GCC builds always respect + strict alignment even if HB_STRICT_ALIGNMENT macro is not set. + 2009-05-27 04:42 UTC+0200 Viktor Szakats (harbour.01 syenar hu) * include/hbsetup.h * source/common/hbver.c diff --git a/harbour/harbour.spec b/harbour/harbour.spec index 7ffa73b0bc..0a48edb533 100644 --- a/harbour/harbour.spec +++ b/harbour/harbour.spec @@ -442,7 +442,7 @@ then export HB_USER_LDFLAGS="${CC_HB_USER_LDFLAGS} -L${HB_LIB_INSTALL} -l%{name}" export HB_USER_PRGFLAGS="\"-D_DEFAULT_INC_DIR='${_DEFAULT_INC_DIR}'\" ${HB_USER_PRGFLAGS}" - for utl in hbmk2 hbrun hbi18n + for utl in hbmk2 hbrun hbi18n hbformat do pushd utils/${utl} rm -fR "./${HB_ARCHITECTURE}/${HB_COMPILER}" @@ -616,8 +616,9 @@ rm -rf $RPM_BUILD_ROOT #%{_bindir}/hbtest %{_bindir}/hbrun %{_bindir}/hbi18n -%{_bindir}/hbmk.cfg +%{_bindir}/hbformat %{_bindir}/hbmk2 +%verify(not md5 mtime) %config %{_bindir}/hbmk.cfg %{_mandir}/man1/*.1* %dir %{_includedir}/%{name} %attr(644,root,root) %{_includedir}/%{name}/* diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index 6b304ad19c..8ad294cf91 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -911,16 +911,16 @@ extern HB_EXPORT PHB_ITEM hb_strFormat( PHB_ITEM pItemReturn, PHB_ITEM pItemFor /* architecture dependent number conversions */ extern HB_EXPORT void hb_put_ieee754( BYTE * ptr, double d ); -extern HB_EXPORT double hb_get_ieee754( BYTE * ptr ); +extern HB_EXPORT double hb_get_ieee754( const BYTE * ptr ); extern HB_EXPORT void hb_put_ord_ieee754( BYTE * ptr, double d ); -extern HB_EXPORT double hb_get_ord_ieee754( BYTE * ptr ); -extern HB_EXPORT double hb_get_rev_double( BYTE * ptr ); -extern HB_EXPORT double hb_get_std_double( BYTE * ptr ); +extern HB_EXPORT double hb_get_ord_ieee754( const BYTE * ptr ); +extern HB_EXPORT double hb_get_rev_double( const BYTE * ptr ); +extern HB_EXPORT double hb_get_std_double( const BYTE * ptr ); #if defined( HB_LONG_LONG_OFF ) -extern HB_EXPORT double hb_get_le_int64( BYTE * ptr ); -extern HB_EXPORT double hb_get_le_uint64( BYTE * ptr ); -extern HB_EXPORT void hb_put_le_uint64( BYTE * ptr, double d ); +extern HB_EXPORT double hb_get_le_int64( const BYTE * ptr ); +extern HB_EXPORT double hb_get_le_uint64( const BYTE * ptr ); +extern HB_EXPORT void hb_put_le_uint64( const BYTE * ptr, double d ); #endif /* dynamic symbol table management */ diff --git a/harbour/include/hbdefs.h b/harbour/include/hbdefs.h index c9efdab122..38803a92a4 100644 --- a/harbour/include/hbdefs.h +++ b/harbour/include/hbdefs.h @@ -698,8 +698,10 @@ typedef int hbInt; typedef unsigned int hbUInt; typedef long hbLong; typedef unsigned long hbULong; -typedef LONGLONG hbLongLong; -typedef ULONGLONG hbULongLong; +#if !defined( HB_LONG_LONG_OFF ) + typedef LONGLONG hbLongLong; + typedef ULONGLONG hbULongLong; +#endif typedef double hbDouble; /* typedef hbIntMax; */ /* TOFIX */ /* typedef hbDoubleMax; */ /* TOFIX */ @@ -804,80 +806,310 @@ typedef long hbVMIntMax; /* TOFIX */ #define HB_COUNTER_PTR( p ) ((HB_COUNTER*) ((BYTE *) (p)-HB_COUNTER_OFFSET)) +#if defined( HB_PDP_ENDIAN ) + #error PDP-Endian support unimplemented. If you have such machine do it yourself. +#endif + /* * These macros are necessary for architectures which need * strict alignment for pointers. */ -#if defined( HB_BIG_ENDIAN ) -# if defined( HB_ARCH_64BIT ) -# define HB_PUT_LONG( p, v ) HB_PUT_BE_UINT64( p, ( UINT64 ) ( v ) ) -# define HB_GET_LONG( p ) HB_GET_BE_UINT64( p ) -# else -# define HB_PUT_LONG( p, v ) HB_PUT_BE_UINT32( p, ( UINT32 ) ( v ) ) -# define HB_GET_LONG( p ) HB_GET_BE_UINT32( p ) -# endif -# define HB_PUT_UINT32( p, v ) HB_PUT_BE_UINT32( p, ( UINT32 ) ( v ) ) -# define HB_GET_UINT32( p ) HB_GET_BE_UINT32( p ) -#else -# if defined( HB_ARCH_64BIT ) -# define HB_PUT_LONG( p, v ) HB_PUT_LE_UINT64( p, ( UINT64 ) ( v ) ) -# define HB_GET_LONG( p ) HB_GET_LE_UINT64( p ) -# else -# define HB_PUT_LONG( p, v ) HB_PUT_LE_UINT32( p, ( UINT32 ) ( v ) ) -# define HB_GET_LONG( p ) HB_GET_LE_UINT32( p ) -# endif -# define HB_PUT_UINT32( p, v ) HB_PUT_LE_UINT32( p, ( UINT32 ) ( v ) ) -# define HB_GET_UINT32( p ) HB_GET_LE_UINT32( p ) -#endif - #if !defined( HB_STRICT_ALIGNMENT ) # define HB_PUT_PTR( p, v ) do { *( void ** ) ( p ) = ( void * ) ( v ); } while ( 0 ) # define HB_GET_PTR( p ) ( *( void ** ) ( p ) ) #else -# define HB_PUT_PTR( p, v ) HB_PUT_LONG( p, v ) -# define HB_GET_PTR( p ) ( ( void * ) HB_GET_LONG( p ) ) +# if defined( HB_BIG_ENDIAN ) +# if defined( HB_ARCH_64BIT ) +# define HB_PUT_PTR( p, v ) HB_PUT_BE_UINT64( p, ( UINT64 ) ( v ) ) +# define HB_GET_PTR( p ) ( ( void * ) HB_GET_BE_UINT64( p ) ) +# else +# define HB_PUT_PTR( p, v ) HB_PUT_BE_UINT32( p, ( UINT32 ) ( v ) ) +# define HB_GET_PTR( p ) ( ( void * ) HB_GET_BE_UINT32( p ) ) +# endif +# else +# if defined( HB_ARCH_64BIT ) +# define HB_PUT_PTR( p, v ) HB_PUT_LE_UINT64( p, ( UINT64 ) ( v ) ) +# define HB_GET_PTR( p ) ( ( void * ) HB_GET_LE_UINT64( p ) ) +# else +# define HB_PUT_PTR( p, v ) HB_PUT_LE_UINT32( p, ( UINT32 ) ( v ) ) +# define HB_GET_PTR( p ) ( ( void * ) HB_GET_LE_UINT32( p ) ) +# endif +# endif #endif - -/* Macros to store/retrive double value */ -#if defined( __GNUC__ ) -# define HB_GET_REV_DOUBLE( p ) \ - ( { \ - union { \ - double dbl; \ - BYTE buffer[ 8 ]; \ - } u; \ - u.buffer[ 0 ] = (( BYTE * )( p ))[ 7 ]; \ - u.buffer[ 1 ] = (( BYTE * )( p ))[ 6 ]; \ - u.buffer[ 2 ] = (( BYTE * )( p ))[ 5 ]; \ - u.buffer[ 3 ] = (( BYTE * )( p ))[ 4 ]; \ - u.buffer[ 4 ] = (( BYTE * )( p ))[ 3 ]; \ - u.buffer[ 5 ] = (( BYTE * )( p ))[ 2 ]; \ - u.buffer[ 6 ] = (( BYTE * )( p ))[ 1 ]; \ - u.buffer[ 7 ] = (( BYTE * )( p ))[ 0 ]; \ - u.dbl; \ - } ) -# define HB_GET_STD_DOUBLE( p ) \ - ( { \ - union { \ - double dbl; \ - BYTE buffer[ 8 ]; \ - } u; \ - u.buffer[ 0 ] = (( BYTE * )( p ))[ 0 ]; \ - u.buffer[ 1 ] = (( BYTE * )( p ))[ 1 ]; \ - u.buffer[ 2 ] = (( BYTE * )( p ))[ 2 ]; \ - u.buffer[ 3 ] = (( BYTE * )( p ))[ 3 ]; \ - u.buffer[ 4 ] = (( BYTE * )( p ))[ 4 ]; \ - u.buffer[ 5 ] = (( BYTE * )( p ))[ 5 ]; \ - u.buffer[ 6 ] = (( BYTE * )( p ))[ 6 ]; \ - u.buffer[ 7 ] = (( BYTE * )( p ))[ 7 ]; \ - u.dbl; \ - } ) +#if defined( HB_BIG_ENDIAN ) +# define HB_PUT_UINT32( p, v ) HB_PUT_BE_UINT32( p, ( UINT32 ) ( v ) ) +# define HB_GET_UINT32( p ) HB_GET_BE_UINT32( p ) #else -# define HB_GET_REV_DOUBLE( p ) hb_get_rev_double( ( BYTE * ) ( p ) ) -# define HB_GET_STD_DOUBLE( p ) hb_get_std_double( ( BYTE * ) ( p ) ) +# define HB_PUT_UINT32( p, v ) HB_PUT_LE_UINT32( p, ( UINT32 ) ( v ) ) +# define HB_GET_UINT32( p ) HB_GET_LE_UINT32( p ) #endif -#define HB_PUT_REV_DOUBLE( p, d ) \ +/* Macros to store/retrieve integer and double values at/from byte address */ +#if defined( __GNUC__ ) + +# if ( __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 3 ) ) && \ + ! defined( __ICC ) +# define HB_BUILTIN_BSWAP 1 +# else +# define HB_BUILTIN_BSWAP 0 +# endif + typedef union + { + UINT16 val; + BYTE buf[2]; + } HB_U16CAST, * PHB_U16CAST; + + typedef union + { + UINT32 val; + BYTE buf[4]; + } HB_U32CAST, * PHB_U32CAST; + +# if !defined( HB_LONG_LONG_OFF ) || defined( HB_ARCH_64BIT ) + typedef union + { + UINT64 val; + BYTE buf[8]; + } HB_U64CAST, * PHB_U64CAST; +# endif + + typedef union + { + double val; + BYTE buf[8]; +# if !defined( HB_LONG_LONG_OFF ) || defined( HB_ARCH_64BIT ) + UINT64 i64; +# endif + } HB_DBLCAST, * PHB_DBLCAST; + + static __inline__ UINT16 _hb_get_std_uint16( const BYTE * buf ) + { + HB_U16CAST u; + memcpy( u.buf, buf, sizeof( u.buf ) ); + return u.val; + } + + static __inline__ void _hb_put_std_uint16( BYTE * buf, UINT16 val ) + { + HB_U16CAST u; + u.val = val; + memcpy( buf, u.buf, sizeof( u.buf ) ); + } + + static __inline__ UINT16 _hb_get_rev_uint16( const BYTE * buf ) + { + HB_U16CAST u; + u.buf[ 0 ] = buf[ 1 ]; + u.buf[ 1 ] = buf[ 0 ]; + return u.val; + } + + static __inline__ void _hb_put_rev_uint16( BYTE * buf, UINT16 val ) + { + HB_U16CAST u; + u.val = val; + buf[ 0 ] = u.buf[ 1 ]; + buf[ 1 ] = u.buf[ 0 ]; + } + + static __inline__ UINT32 _hb_get_std_uint32( const BYTE * buf ) + { + HB_U32CAST u; + memcpy( u.buf, buf, sizeof( u.buf ) ); + return u.val; + } + + static __inline__ void _hb_put_std_uint32( BYTE * buf, UINT32 val ) + { + HB_U32CAST u; + u.val = val; + memcpy( buf, u.buf, sizeof( u.buf ) ); + } + + static __inline__ UINT32 _hb_get_rev_uint32( const BYTE * buf ) + { + HB_U32CAST u; +# if HB_BUILTIN_BSWAP + memcpy( u.buf, buf, sizeof( u.buf ) ); + return __builtin_bswap32( u.val ); +# else + u.buf[ 0 ] = buf[ 3 ]; + u.buf[ 1 ] = buf[ 2 ]; + u.buf[ 2 ] = buf[ 1 ]; + u.buf[ 3 ] = buf[ 0 ]; + return u.val; +# endif + } + + static __inline__ void _hb_put_rev_uint32( BYTE * buf, UINT32 val ) + { + HB_U32CAST u; +# if HB_BUILTIN_BSWAP + u.val = __builtin_bswap32( val ); + memcpy( buf, u.buf, sizeof( u.buf ) ); +# else + u.val = val; + buf[ 0 ] = u.buf[ 3 ]; + buf[ 1 ] = u.buf[ 2 ]; + buf[ 2 ] = u.buf[ 1 ]; + buf[ 3 ] = u.buf[ 0 ]; +# endif + } + +# if !defined( HB_LONG_LONG_OFF ) || defined( HB_ARCH_64BIT ) + static __inline__ UINT64 _hb_get_std_uint64( const BYTE * buf ) + { + HB_U64CAST u; + memcpy( u.buf, buf, sizeof( u.buf ) ); + return u.val; + } + + static __inline__ void _hb_put_std_uint64( BYTE * buf, UINT64 val ) + { + HB_U64CAST u; + u.val = val; + memcpy( buf, u.buf, sizeof( u.buf ) ); + } + + static __inline__ UINT64 _hb_get_rev_uint64( const BYTE * buf ) + { + HB_U64CAST u; +# if HB_BUILTIN_BSWAP + memcpy( u.buf, buf, sizeof( u.buf ) ); + return __builtin_bswap64( u.val ); +# else + u.buf[ 0 ] = buf[ 7 ]; + u.buf[ 1 ] = buf[ 6 ]; + u.buf[ 2 ] = buf[ 5 ]; + u.buf[ 3 ] = buf[ 4 ]; + u.buf[ 4 ] = buf[ 3 ]; + u.buf[ 5 ] = buf[ 2 ]; + u.buf[ 6 ] = buf[ 1 ]; + u.buf[ 7 ] = buf[ 0 ]; + return u.val; +# endif + } + + static __inline__ void _hb_put_rev_uint64( BYTE * buf, UINT64 val ) + { + HB_U64CAST u; +# if HB_BUILTIN_BSWAP + u.val = __builtin_bswap64( val ); + memcpy( buf, u.buf, sizeof( u.buf ) ); +# else + u.val = val; + buf[ 0 ] = u.buf[ 7 ]; + buf[ 1 ] = u.buf[ 6 ]; + buf[ 2 ] = u.buf[ 5 ]; + buf[ 3 ] = u.buf[ 4 ]; + buf[ 4 ] = u.buf[ 3 ]; + buf[ 5 ] = u.buf[ 2 ]; + buf[ 6 ] = u.buf[ 1 ]; + buf[ 7 ] = u.buf[ 0 ]; +# endif + } +# endif + + static __inline__ double _hb_get_std_double( const BYTE * buf ) + { + HB_DBLCAST u; + memcpy( u.buf, buf, sizeof( u.buf ) ); + return u.val; + } + + static __inline__ void _hb_put_std_double( BYTE * buf, double val ) + { + HB_DBLCAST u; + u.val = val; + memcpy( buf, u.buf, sizeof( u.buf ) ); + } + + static __inline__ double _hb_get_rev_double( const BYTE * buf ) + { + HB_DBLCAST u; +# if ( !defined( HB_LONG_LONG_OFF ) || defined( HB_ARCH_64BIT ) ) && \ + HB_BUILTIN_BSWAP + memcpy( u.buf, buf, sizeof( u.buf ) ); + u.i64 = __builtin_bswap64( u.i64 ); + return u.val; +# else + u.buf[ 0 ] = buf[ 7 ]; + u.buf[ 1 ] = buf[ 6 ]; + u.buf[ 2 ] = buf[ 5 ]; + u.buf[ 3 ] = buf[ 4 ]; + u.buf[ 4 ] = buf[ 3 ]; + u.buf[ 5 ] = buf[ 2 ]; + u.buf[ 6 ] = buf[ 1 ]; + u.buf[ 7 ] = buf[ 0 ]; + return u.val; +# endif + } + + static __inline__ void _hb_put_rev_double( BYTE * buf, double val ) + { + HB_DBLCAST u; +# if ( !defined( HB_LONG_LONG_OFF ) || defined( HB_ARCH_64BIT ) ) && \ + HB_BUILTIN_BSWAP + u.val = val; + u.i64 = __builtin_bswap64( u.i64 ); + memcpy( buf, u.buf, sizeof( u.buf ) ); +# else + u.val = val; + buf[ 0 ] = u.buf[ 7 ]; + buf[ 1 ] = u.buf[ 6 ]; + buf[ 2 ] = u.buf[ 5 ]; + buf[ 3 ] = u.buf[ 4 ]; + buf[ 4 ] = u.buf[ 3 ]; + buf[ 5 ] = u.buf[ 2 ]; + buf[ 6 ] = u.buf[ 1 ]; + buf[ 7 ] = u.buf[ 0 ]; +# endif + } + +# define HB_GET_STD_DOUBLE( p ) _hb_get_std_double( ( const BYTE * ) ( p ) ) +# define HB_GET_REV_DOUBLE( p ) _hb_get_rev_double( ( const BYTE * ) ( p ) ) +# define HB_PUT_STD_DOUBLE( p, d ) _hb_put_std_double( ( BYTE * ) ( p ), d ) +# define HB_PUT_REV_DOUBLE( p, d ) _hb_put_rev_double( ( BYTE * ) ( p ), d ) + +# if defined( HB_BIG_ENDIAN ) + +# define HB_GET_BE_UINT16( p ) _hb_get_std_uint16( ( BYTE * ) ( p ) ) +# define HB_PUT_BE_UINT16( p, w ) _hb_put_std_uint16( ( BYTE * ) ( p ), w ) +# define HB_GET_BE_UINT32( p ) _hb_get_std_uint32( ( BYTE * ) ( p ) ) +# define HB_PUT_BE_UINT32( p, l ) _hb_put_std_uint32( ( BYTE * ) ( p ), l ) +# define HB_GET_BE_UINT64( p ) _hb_get_std_uint64( ( BYTE * ) ( p ) ) +# define HB_PUT_BE_UINT64( p, q ) _hb_put_std_uint64( ( BYTE * ) ( p ), q ) + +# define HB_GET_LE_UINT16( p ) _hb_get_rev_uint16( ( BYTE * ) ( p ) ) +# define HB_PUT_LE_UINT16( p, w ) _hb_put_rev_uint16( ( BYTE * ) ( p ), w ) +# define HB_GET_LE_UINT32( p ) _hb_get_rev_uint32( ( BYTE * ) ( p ) ) +# define HB_PUT_LE_UINT32( p, l ) _hb_put_rev_uint32( ( BYTE * ) ( p ), l ) +# define HB_GET_LE_UINT64( p ) _hb_get_rev_uint64( ( BYTE * ) ( p ) ) +# define HB_PUT_LE_UINT64( p, q ) _hb_put_rev_uint64( ( BYTE * ) ( p ), q ) + +# else /* HB_LITTLE_ENDIAN */ + +# define HB_GET_BE_UINT16( p ) _hb_get_rev_uint16( ( BYTE * ) ( p ) ) +# define HB_PUT_BE_UINT16( p, w ) _hb_put_rev_uint16( ( BYTE * ) ( p ), w ) +# define HB_GET_BE_UINT32( p ) _hb_get_rev_uint32( ( BYTE * ) ( p ) ) +# define HB_PUT_BE_UINT32( p, l ) _hb_put_rev_uint32( ( BYTE * ) ( p ), l ) +# define HB_GET_BE_UINT64( p ) _hb_get_rev_uint64( ( BYTE * ) ( p ) ) +# define HB_PUT_BE_UINT64( p, q ) _hb_put_rev_uint64( ( BYTE * ) ( p ), q ) + +# define HB_GET_LE_UINT16( p ) _hb_get_std_uint16( ( BYTE * ) ( p ) ) +# define HB_PUT_LE_UINT16( p, w ) _hb_put_std_uint16( ( BYTE * ) ( p ), w ) +# define HB_GET_LE_UINT32( p ) _hb_get_std_uint32( ( BYTE * ) ( p ) ) +# define HB_PUT_LE_UINT32( p, l ) _hb_put_std_uint32( ( BYTE * ) ( p ), l ) +# define HB_GET_LE_UINT64( p ) _hb_get_std_uint64( ( BYTE * ) ( p ) ) +# define HB_PUT_LE_UINT64( p, q ) _hb_put_std_uint64( ( BYTE * ) ( p ), q ) + +# endif + +#else /* ! __GNUC__ */ + +# define HB_GET_STD_DOUBLE( p ) hb_get_std_double( ( BYTE * ) ( p ) ) +# define HB_GET_REV_DOUBLE( p ) hb_get_rev_double( ( BYTE * ) ( p ) ) +# define HB_PUT_REV_DOUBLE( p, d ) \ do { \ union { \ double dbl; \ @@ -893,7 +1125,7 @@ typedef long hbVMIntMax; /* TOFIX */ (( BYTE * )( p ))[ 1 ] = u.buffer[ 6 ]; \ (( BYTE * )( p ))[ 0 ] = u.buffer[ 7 ]; \ } while ( 0 ) -#define HB_PUT_STD_DOUBLE( p, d ) \ +# define HB_PUT_STD_DOUBLE( p, d ) \ do { \ union { \ double dbl; \ @@ -910,45 +1142,16 @@ typedef long hbVMIntMax; /* TOFIX */ (( BYTE * )( p ))[ 7 ] = u.buffer[ 7 ]; \ } while ( 0 ) -/* - * HB_FORCE_IEEE754_DOUBLE will can be used on platforms which use differ - * double format and we want to force storing double number as IEEE754 - * double value for sharing binary data (f.e. PCODE in .hrb files or CDX - * indexes or DBFs with "B" fields. - */ -#if defined( HB_FORCE_IEEE754_DOUBLE ) +# if !defined( HB_STRICT_ALIGNMENT ) && defined( HB_LITTLE_ENDIAN ) -# define HB_GET_LE_DOUBLE( p ) hb_get_ieee754( ( BYTE * ) ( p ) ) -# define HB_PUT_LE_DOUBLE( p, d ) hb_put_ieee754( ( BYTE * ) ( p ), ( d ) ) -# define HB_DBL2ORD( d, o ) hb_put_ord_ieee754( ( o ), *( d ) ) -# define HB_ORD2DBL( o, d ) do { \ - *d = hb_get_ord_ieee754( ( BYTE * ) ( o ) ); \ - } while( 0 ) + #define HB_GET_LE_UINT16( p ) ( *( UINT16 * )( p ) ) + #define HB_PUT_LE_UINT16( p, w ) ( *( UINT16 * )( p ) = ( UINT16 ) ( w ) ) + #define HB_GET_LE_UINT32( p ) ( *( UINT32 * )( p ) ) + #define HB_PUT_LE_UINT32( p, l ) ( *( UINT32 * )( p ) = ( UINT32 ) ( l ) ) + #define HB_GET_LE_UINT64( p ) ( *( UINT64 * )( p ) ) + #define HB_PUT_LE_UINT64( p, q ) ( *( UINT64 * )( p ) = ( UINT64 ) ( q ) ) -#elif defined( HB_STRICT_ALIGNMENT ) - -# if defined( HB_LITTLE_ENDIAN ) -# define HB_GET_LE_DOUBLE( p ) HB_GET_STD_DOUBLE( ( p ) ) -# define HB_PUT_LE_DOUBLE( p, d ) HB_PUT_STD_DOUBLE( ( p ), ( d ) ) -# elif defined( HB_BIG_ENDIAN ) -# define HB_GET_LE_DOUBLE( p ) HB_GET_REV_DOUBLE( ( p ) ) -# define HB_PUT_LE_DOUBLE( p, d ) HB_PUT_REV_DOUBLE( ( p ), ( d ) ) -# endif - -#else - -# if defined( HB_LITTLE_ENDIAN ) -# define HB_GET_LE_DOUBLE( p ) ( *( double * )( p ) ) -# define HB_PUT_LE_DOUBLE( p, d ) ( *( double * )( p ) = ( double ) ( d ) ) -# elif defined( HB_BIG_ENDIAN ) -# define HB_GET_LE_DOUBLE( p ) HB_GET_REV_DOUBLE( ( p ) ) -# define HB_PUT_LE_DOUBLE( p, d ) HB_PUT_REV_DOUBLE( ( p ), ( d ) ) -# endif - -#endif - -/* Now the rest of endian macros */ -#if defined( HB_STRICT_ALIGNMENT ) || !defined( HB_LITTLE_ENDIAN ) +# else #define HB_GET_LE_UINT16( p ) ( ( UINT16 ) \ ( ( ( UINT16 ) (( BYTE * )( p ))[0] ) | \ @@ -972,25 +1175,34 @@ typedef long hbVMIntMax; /* TOFIX */ (( BYTE * )( p ))[0] = ( BYTE )( w ); \ (( BYTE * )( p ))[1] = ( BYTE )( (w) >> 8 ); \ } while ( 0 ) - #define HB_PUT_LE_UINT32( p, w ) do { \ - (( BYTE * )( p ))[0] = ( BYTE )( w ); \ - (( BYTE * )( p ))[1] = ( BYTE )( (w) >> 8 ); \ - (( BYTE * )( p ))[2] = ( BYTE )( (w) >> 16 ); \ - (( BYTE * )( p ))[3] = ( BYTE )( (w) >> 24 ); \ + #define HB_PUT_LE_UINT32( p, l ) do { \ + (( BYTE * )( p ))[0] = ( BYTE )( l ); \ + (( BYTE * )( p ))[1] = ( BYTE )( (l) >> 8 ); \ + (( BYTE * )( p ))[2] = ( BYTE )( (l) >> 16 ); \ + (( BYTE * )( p ))[3] = ( BYTE )( (l) >> 24 ); \ } while ( 0 ) - #define HB_PUT_LE_UINT64( p, w ) do { \ - (( BYTE * )( p ))[0] = ( BYTE )( w ); \ - (( BYTE * )( p ))[1] = ( BYTE )( (w) >> 8 ); \ - (( BYTE * )( p ))[2] = ( BYTE )( (w) >> 16 ); \ - (( BYTE * )( p ))[3] = ( BYTE )( (w) >> 24 ); \ - (( BYTE * )( p ))[4] = ( BYTE )( (w) >> 32 ); \ - (( BYTE * )( p ))[5] = ( BYTE )( (w) >> 40 ); \ - (( BYTE * )( p ))[6] = ( BYTE )( (w) >> 48 ); \ - (( BYTE * )( p ))[7] = ( BYTE )( (w) >> 56 ); \ + #define HB_PUT_LE_UINT64( p, q ) do { \ + (( BYTE * )( p ))[0] = ( BYTE )( q ); \ + (( BYTE * )( p ))[1] = ( BYTE )( (q) >> 8 ); \ + (( BYTE * )( p ))[2] = ( BYTE )( (q) >> 16 ); \ + (( BYTE * )( p ))[3] = ( BYTE )( (q) >> 24 ); \ + (( BYTE * )( p ))[4] = ( BYTE )( (q) >> 32 ); \ + (( BYTE * )( p ))[5] = ( BYTE )( (q) >> 40 ); \ + (( BYTE * )( p ))[6] = ( BYTE )( (q) >> 48 ); \ + (( BYTE * )( p ))[7] = ( BYTE )( (q) >> 56 ); \ } while ( 0 ) -#endif +# endif -#if defined( HB_STRICT_ALIGNMENT ) || !defined( HB_BIG_ENDIAN ) +# if !defined( HB_STRICT_ALIGNMENT ) && defined( HB_BIG_ENDIAN ) + + #define HB_GET_BE_UINT16( p ) ( *( UINT16 * )( p ) ) + #define HB_PUT_BE_UINT16( p, w ) ( *( UINT16 * )( p ) = ( UINT16 ) ( w ) ) + #define HB_GET_BE_UINT32( p ) ( *( UINT32 * )( p ) ) + #define HB_PUT_BE_UINT32( p, l ) ( *( UINT32 * )( p ) = ( UINT32 ) ( l ) ) + #define HB_GET_BE_UINT64( p ) ( *( UINT64 * )( p ) ) + #define HB_PUT_BE_UINT64( p, q ) ( *( UINT64 * )( p ) = ( UINT64 ) ( q ) ) + +# else #define HB_GET_BE_UINT16( p ) ( ( UINT16 ) \ ( ( ( UINT16 ) (( BYTE * )( p ))[0] << 8 ) | \ @@ -1014,80 +1226,61 @@ typedef long hbVMIntMax; /* TOFIX */ (( BYTE * )( p ))[0] = ( BYTE )( (w) >> 8 ); \ (( BYTE * )( p ))[1] = ( BYTE )( w ); \ } while ( 0 ) - #define HB_PUT_BE_UINT32( p, w ) do { \ - (( BYTE * )( p ))[0] = ( BYTE )( (w) >> 24 ); \ - (( BYTE * )( p ))[1] = ( BYTE )( (w) >> 16 ); \ - (( BYTE * )( p ))[2] = ( BYTE )( (w) >> 8 ); \ - (( BYTE * )( p ))[3] = ( BYTE )( w ); \ + #define HB_PUT_BE_UINT32( p, l ) do { \ + (( BYTE * )( p ))[0] = ( BYTE )( (l) >> 24 ); \ + (( BYTE * )( p ))[1] = ( BYTE )( (l) >> 16 ); \ + (( BYTE * )( p ))[2] = ( BYTE )( (l) >> 8 ); \ + (( BYTE * )( p ))[3] = ( BYTE )( l ); \ } while ( 0 ) - #define HB_PUT_BE_UINT64( p, w ) do { \ - (( BYTE * )( p ))[0] = ( BYTE )( (w) >> 56 ); \ - (( BYTE * )( p ))[1] = ( BYTE )( (w) >> 48 ); \ - (( BYTE * )( p ))[2] = ( BYTE )( (w) >> 40 ); \ - (( BYTE * )( p ))[3] = ( BYTE )( (w) >> 32 ); \ - (( BYTE * )( p ))[4] = ( BYTE )( (w) >> 24 ); \ - (( BYTE * )( p ))[5] = ( BYTE )( (w) >> 16 ); \ - (( BYTE * )( p ))[6] = ( BYTE )( (w) >> 8 ); \ - (( BYTE * )( p ))[7] = ( BYTE )( w ); \ + #define HB_PUT_BE_UINT64( p, q ) do { \ + (( BYTE * )( p ))[0] = ( BYTE )( (q) >> 56 ); \ + (( BYTE * )( p ))[1] = ( BYTE )( (q) >> 48 ); \ + (( BYTE * )( p ))[2] = ( BYTE )( (q) >> 40 ); \ + (( BYTE * )( p ))[3] = ( BYTE )( (q) >> 32 ); \ + (( BYTE * )( p ))[4] = ( BYTE )( (q) >> 24 ); \ + (( BYTE * )( p ))[5] = ( BYTE )( (q) >> 16 ); \ + (( BYTE * )( p ))[6] = ( BYTE )( (q) >> 8 ); \ + (( BYTE * )( p ))[7] = ( BYTE )( q ); \ } while ( 0 ) -#endif - -/* - * 24 bit integers are not directly supported by any processor we used so far - * so we always have to build them from BYTEs and cannot use C casting - */ -#define HB_GET_LE_INT24( p ) ( ( INT32 ) \ - ( ( ( INT32 ) (( BYTE * )( p ))[0] ) | \ - ( ( INT32 ) (( BYTE * )( p ))[1] << 8 ) | \ - ( ( INT32 ) (( BYTE * )( p ))[2] << 16 ) | \ - ( ( INT32 ) ((( BYTE * )( p ))[2] & 0x80 ? 0xFF : 0x00 ) << 24 ) ) ) -#define HB_GET_LE_UINT24( p ) ( ( UINT32 ) \ - ( ( ( UINT32 ) (( BYTE * )( p ))[0] ) | \ - ( ( UINT32 ) (( BYTE * )( p ))[1] << 8 ) | \ - ( ( UINT32 ) (( BYTE * )( p ))[2] << 16 ) ) ) -#define HB_PUT_LE_UINT24( p, w ) do { \ - (( BYTE * )( p ))[0] = ( BYTE )( w ); \ - (( BYTE * )( p ))[1] = ( BYTE )( (w) >> 8 ); \ - (( BYTE * )( p ))[2] = ( BYTE )( (w) >> 16 ); \ - } while ( 0 ) -#define HB_GET_BE_INT24( p ) ( ( INT32 ) \ - ( ( ( INT32 ) (( BYTE * )( p ))[2] ) | \ - ( ( INT32 ) (( BYTE * )( p ))[1] << 8 ) | \ - ( ( INT32 ) (( BYTE * )( p ))[0] << 16 ) | \ - ( ( INT32 ) ((( BYTE * )( p ))[0] & 0x80 ? 0xFF : 0x00 ) << 24 ) ) ) -#define HB_GET_BE_UINT24( p ) ( ( UINT32 ) \ - ( ( ( UINT32 ) (( BYTE * )( p ))[2] ) | \ - ( ( UINT32 ) (( BYTE * )( p ))[1] << 8 ) | \ - ( ( UINT32 ) (( BYTE * )( p ))[0] << 16 ) ) ) -#define HB_PUT_BE_UINT24( p, w ) do { \ - (( BYTE * )( p ))[2] = ( BYTE )( w ); \ - (( BYTE * )( p ))[1] = ( BYTE )( (w) >> 8 ); \ - (( BYTE * )( p ))[0] = ( BYTE )( (w) >> 16 ); \ - } while ( 0 ) - - -#if defined( HB_PDP_ENDIAN ) - #error PDP-Endian support unimplemented. If you have such machine do it yourself. -#elif defined( HB_BIG_ENDIAN ) - /* We use Big-Endian here */ - -# ifndef HB_STRICT_ALIGNMENT - - #define HB_GET_BE_UINT16( p ) ( *( UINT16 * )( p ) ) - #define HB_PUT_BE_UINT16( p, w ) ( *( UINT16 * )( p ) = ( UINT16 ) ( w ) ) - #define HB_GET_BE_UINT32( p ) ( *( UINT32 * )( p ) ) - #define HB_PUT_BE_UINT32( p, l ) ( *( UINT32 * )( p ) = ( UINT32 ) ( l ) ) - #define HB_GET_BE_UINT64( p ) ( *( UINT64 * )( p ) ) - #define HB_PUT_BE_UINT64( p, l ) ( *( UINT64 * )( p ) = ( UINT64 ) ( l ) ) - # endif - #define HB_USHORT_FROM_LE( w ) HB_MKUSHORT( HB_HIBYTE( w ), HB_LOBYTE( w ) ) - #define HB_ULONG_FROM_LE( l ) HB_MKULONG( HB_UHBYTE( l ), HB_ULBYTE( l ), HB_HIBYTE( l ), HB_LOBYTE( l ) ) - #define HB_USHORT_TO_LE( w ) HB_USHORT_FROM_LE( w ) - #define HB_ULONG_TO_LE( l ) HB_ULONG_FROM_LE( l ) +#endif /* ! __GNUC__ */ + +/* + * HB_FORCE_IEEE754_DOUBLE will can be used on platforms which use differ + * double format and we want to force storing double number as IEEE754 + * double value for sharing binary data (f.e. PCODE in .hrb files or CDX + * indexes or DBFs with "B" fields. + */ +#if defined( HB_FORCE_IEEE754_DOUBLE ) + +# define HB_GET_LE_DOUBLE( p ) hb_get_ieee754( ( BYTE * ) ( p ) ) +# define HB_PUT_LE_DOUBLE( p, d ) hb_put_ieee754( ( BYTE * ) ( p ), ( d ) ) +# define HB_DBL2ORD( d, o ) hb_put_ord_ieee754( ( o ), *( d ) ) +# define HB_ORD2DBL( o, d ) do { \ + *d = hb_get_ord_ieee754( ( BYTE * ) ( o ) ); \ + } while( 0 ) + +#elif defined( HB_BIG_ENDIAN ) + +# define HB_GET_LE_DOUBLE( p ) HB_GET_REV_DOUBLE( ( p ) ) +# define HB_PUT_LE_DOUBLE( p, d ) HB_PUT_REV_DOUBLE( ( p ), ( d ) ) + +#elif defined( HB_STRICT_ALIGNMENT ) || defined( __GNUC__ ) + +# define HB_GET_LE_DOUBLE( p ) HB_GET_STD_DOUBLE( ( p ) ) +# define HB_PUT_LE_DOUBLE( p, d ) HB_PUT_STD_DOUBLE( ( p ), ( d ) ) + +#else + +# define HB_GET_LE_DOUBLE( p ) ( *( double * )( p ) ) +# define HB_PUT_LE_DOUBLE( p, d ) ( *( double * )( p ) = ( double ) ( d ) ) + +#endif + +#if ! defined( HB_FORCE_IEEE754_DOUBLE ) +# if defined( HB_BIG_ENDIAN ) -# ifndef HB_FORCE_IEEE754_DOUBLE #define HB_ORD2DBL( o, d ) do { \ if ( ( ( BYTE * ) ( o ) )[ 0 ] & 0x80 ) { \ ( ( BYTE * ) ( d ) )[ 0 ] = ( ( BYTE * ) ( o ) )[ 0 ]; \ @@ -1130,28 +1323,9 @@ typedef long hbVMIntMax; /* TOFIX */ ( ( BYTE * ) ( o ) )[ 6 ] = ( ( BYTE * ) ( d ) )[ 6 ] ^ ( BYTE ) 0xFF; \ ( ( BYTE * ) ( o ) )[ 7 ] = ( ( BYTE * ) ( d ) )[ 7 ] ^ ( BYTE ) 0xFF; \ } } while ( 0 ) -# endif -#else /* HB_LITTLE_ENDIAN */ - /* We use Little-Endian here */ +# else /* HB_LITTLE_ENDIAN */ -# ifndef HB_STRICT_ALIGNMENT - - #define HB_GET_LE_UINT16( p ) ( *( UINT16 * )( p ) ) - #define HB_PUT_LE_UINT16( p, w ) ( *( UINT16 * )( p ) = ( UINT16 ) ( w ) ) - #define HB_GET_LE_UINT32( p ) ( *( UINT32 * )( p ) ) - #define HB_PUT_LE_UINT32( p, l ) ( *( UINT32 * )( p ) = ( UINT32 ) ( l ) ) - #define HB_GET_LE_UINT64( p ) ( *( UINT64 * )( p ) ) - #define HB_PUT_LE_UINT64( p, l ) ( *( UINT64 * )( p ) = ( UINT64 ) ( l ) ) - -# endif - - #define HB_USHORT_FROM_LE( w ) ( ( USHORT )( w ) ) - #define HB_ULONG_FROM_LE( l ) ( ( ULONG )( l ) ) - #define HB_USHORT_TO_LE( w ) ( ( USHORT )( w ) ) - #define HB_ULONG_TO_LE( l ) ( ( ULONG )( l ) ) - -# ifndef HB_FORCE_IEEE754_DOUBLE #define HB_ORD2DBL( o, d ) do { \ if ( ( ( BYTE * ) ( o ) )[ 0 ] & 0x80 ) { \ ( ( BYTE * ) ( d ) )[ 0 ] = ( ( BYTE * ) ( o ) )[ 7 ]; \ @@ -1196,7 +1370,44 @@ typedef long hbVMIntMax; /* TOFIX */ } } while ( 0 ) # endif -#endif +#endif /* ! defined( HB_FORCE_IEEE754_DOUBLE ) */ + + +/* Now the rest of endian macros */ + +/* + * 24 bit integers are not directly supported by any processor we used so far + * so we always have to build them from BYTEs and cannot use C casting + */ +#define HB_GET_LE_INT24( p ) ( ( INT32 ) \ + ( ( ( INT32 ) (( BYTE * )( p ))[0] ) | \ + ( ( INT32 ) (( BYTE * )( p ))[1] << 8 ) | \ + ( ( INT32 ) (( BYTE * )( p ))[2] << 16 ) | \ + ( ( INT32 ) ((( BYTE * )( p ))[2] & 0x80 ? 0xFF : 0x00 ) << 24 ) ) ) +#define HB_GET_LE_UINT24( p ) ( ( UINT32 ) \ + ( ( ( UINT32 ) (( BYTE * )( p ))[0] ) | \ + ( ( UINT32 ) (( BYTE * )( p ))[1] << 8 ) | \ + ( ( UINT32 ) (( BYTE * )( p ))[2] << 16 ) ) ) +#define HB_PUT_LE_UINT24( p, u ) do { \ + (( BYTE * )( p ))[0] = ( BYTE )( u ); \ + (( BYTE * )( p ))[1] = ( BYTE )( (u) >> 8 ); \ + (( BYTE * )( p ))[2] = ( BYTE )( (u) >> 16 ); \ + } while ( 0 ) +#define HB_GET_BE_INT24( p ) ( ( INT32 ) \ + ( ( ( INT32 ) (( BYTE * )( p ))[2] ) | \ + ( ( INT32 ) (( BYTE * )( p ))[1] << 8 ) | \ + ( ( INT32 ) (( BYTE * )( p ))[0] << 16 ) | \ + ( ( INT32 ) ((( BYTE * )( p ))[0] & 0x80 ? 0xFF : 0x00 ) << 24 ) ) ) +#define HB_GET_BE_UINT24( p ) ( ( UINT32 ) \ + ( ( ( UINT32 ) (( BYTE * )( p ))[2] ) | \ + ( ( UINT32 ) (( BYTE * )( p ))[1] << 8 ) | \ + ( ( UINT32 ) (( BYTE * )( p ))[0] << 16 ) ) ) +#define HB_PUT_BE_UINT24( p, u ) do { \ + (( BYTE * )( p ))[2] = ( BYTE )( u ); \ + (( BYTE * )( p ))[1] = ( BYTE )( (u) >> 8 ); \ + (( BYTE * )( p ))[0] = ( BYTE )( (u) >> 16 ); \ + } while ( 0 ) + #define HB_GET_LE_INT16( p ) (( INT16 ) HB_GET_LE_UINT16( p )) #define HB_GET_LE_INT32( p ) (( INT32 ) HB_GET_LE_UINT32( p )) diff --git a/harbour/mpkg_tgz.sh b/harbour/mpkg_tgz.sh index 2fa100037f..dd9fa6cafc 100755 --- a/harbour/mpkg_tgz.sh +++ b/harbour/mpkg_tgz.sh @@ -273,7 +273,7 @@ then export HB_USER_LDFLAGS="-L${HB_LIB_INSTALL} -l${name} ${ADD_LIBS} ${HB_USER_LDFLAGS}" export HB_USER_PRGFLAGS="\"-D_DEFAULT_INC_DIR='${_DEFAULT_INC_DIR}'\" ${HB_USER_PRGFLAGS}" - for utl in hbmk2 hbrun hbi18n hbtest + for utl in hbmk2 hbrun hbi18n hbformat hbtest do (cd "utils/${utl}" rm -fR "./${HB_ARCHITECTURE}/${HB_COMPILER}" diff --git a/harbour/source/common/hbarch.c b/harbour/source/common/hbarch.c index 5942657675..d1eb5b7c28 100644 --- a/harbour/source/common/hbarch.c +++ b/harbour/source/common/hbarch.c @@ -119,7 +119,7 @@ void hb_put_ieee754( BYTE * ptr, double d ) #endif } -double hb_get_ieee754( BYTE * ptr ) +double hb_get_ieee754( const BYTE * ptr ) { int iExp, iSig; #if defined( HB_LONG_LONG_OFF ) @@ -194,7 +194,7 @@ void hb_put_ord_ieee754( BYTE * ptr, double d ) HB_PUT_BE_UINT32( ptr + 4, l1 ); } -double hb_get_ord_ieee754( BYTE * ptr ) +double hb_get_ord_ieee754( const BYTE * ptr ) { int iExp, iSig; UINT32 l1, l2; @@ -225,46 +225,58 @@ double hb_get_ord_ieee754( BYTE * ptr ) * some compilers does not like constraction used by in HB_GET_LE_DOUBLE * macro => d = { ... } */ -double hb_get_rev_double( BYTE * ptr ) +double hb_get_rev_double( const BYTE * ptr ) { - union { - double dbl; - BYTE buffer[ 8 ]; - } u; - HB_TRACE(HB_TR_DEBUG, ("hb_get_rev_double(%p)", ptr)); - u.buffer[ 0 ] = ptr[ 7 ]; - u.buffer[ 1 ] = ptr[ 6 ]; - u.buffer[ 2 ] = ptr[ 5 ]; - u.buffer[ 3 ] = ptr[ 4 ]; - u.buffer[ 4 ] = ptr[ 3 ]; - u.buffer[ 5 ] = ptr[ 2 ]; - u.buffer[ 6 ] = ptr[ 1 ]; - u.buffer[ 7 ] = ptr[ 0 ]; + { +#if defined( __GNUC__ ) + return _hb_get_rev_double( ptr ); +#else + union { + double dbl; + BYTE buffer[ 8 ]; + } u; - return u.dbl; + u.buffer[ 0 ] = ptr[ 7 ]; + u.buffer[ 1 ] = ptr[ 6 ]; + u.buffer[ 2 ] = ptr[ 5 ]; + u.buffer[ 3 ] = ptr[ 4 ]; + u.buffer[ 4 ] = ptr[ 3 ]; + u.buffer[ 5 ] = ptr[ 2 ]; + u.buffer[ 6 ] = ptr[ 1 ]; + u.buffer[ 7 ] = ptr[ 0 ]; + + return u.dbl; +#endif + } } -double hb_get_std_double( BYTE * ptr ) +double hb_get_std_double( const BYTE * ptr ) { - union { - double dbl; - BYTE buffer[ 8 ]; - } u; - HB_TRACE(HB_TR_DEBUG, ("hb_get_std_double(%p)", ptr)); - u.buffer[ 0 ] = ptr[ 0 ]; - u.buffer[ 1 ] = ptr[ 1 ]; - u.buffer[ 2 ] = ptr[ 2 ]; - u.buffer[ 3 ] = ptr[ 3 ]; - u.buffer[ 4 ] = ptr[ 4 ]; - u.buffer[ 5 ] = ptr[ 5 ]; - u.buffer[ 6 ] = ptr[ 6 ]; - u.buffer[ 7 ] = ptr[ 7 ]; + { +#if defined( __GNUC__ ) + return _hb_get_std_double( ptr ); +#else + union { + double dbl; + BYTE buffer[ 8 ]; + } u; - return u.dbl; + u.buffer[ 0 ] = ptr[ 0 ]; + u.buffer[ 1 ] = ptr[ 1 ]; + u.buffer[ 2 ] = ptr[ 2 ]; + u.buffer[ 3 ] = ptr[ 3 ]; + u.buffer[ 4 ] = ptr[ 4 ]; + u.buffer[ 5 ] = ptr[ 5 ]; + u.buffer[ 6 ] = ptr[ 6 ]; + u.buffer[ 7 ] = ptr[ 7 ]; + + return u.dbl; +#endif + } } #if defined( HB_LONG_LONG_OFF ) @@ -275,7 +287,7 @@ double hb_get_std_double( BYTE * ptr ) * values. They are necessary for extracting such number from PCODE, * databases or serialization streams in RPC */ -double hb_get_le_uint64( BYTE * ptr ) +double hb_get_le_uint64( const BYTE * ptr ) { UINT32 l1, l2; @@ -286,7 +298,7 @@ double hb_get_le_uint64( BYTE * ptr ) return ldexp( ( double ) l2, 32 ) + ( double ) l1; } -double hb_get_le_int64( BYTE * ptr ) +double hb_get_le_int64( const BYTE * ptr ) { UINT32 l1; INT32 l2;