diff --git a/ChangeLog.txt b/ChangeLog.txt index f45c5a2b02..03f18ffd77 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,51 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2016-06-20 21:59 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * doc/cmpopt.txt + * enumeration + ! typos + + * src/codepage/uckam.c + + added info about Kamenicky codepage number: CP895 + + * include/hbapi.h + * src/common/hbstr.c + + added new C function: + char * hb_dblToStr( char * szBuf, HB_SIZE nSize, + double dNumber, int iMaxDec ); + it converts numeric value to string trying to keep all significant + digits in double numbers + + * include/harbour.hbx + * src/rtl/hbntos.c + + added new PRG function: + hb_ntoc( ) -> cValue + it converts numeric value to string trying to keep all significant + digits in double numbers + + * src/rtl/hbsocket.c + + added support for error codes returned by + getaddrinfo() / getnameinfo() and gethostbyname() / gethostbyaddr() + + * src/rtl/hbinet.c + + set HB_SOCKET_ERR_WRONGADDR error code if hb_socketResolveAddr() + returns NULL without setting error code + + * src/vm/arrays.c + * src/vm/hashfunc.c + ! fix hb_HScan(), AScan(), hb_AScan() and hb_RAScan() for very large + integers with more then 53 significant bits. Such bits were lost + after conversion to double value used in scan process + + * src/vm/itemapi.c + * formatting + + * src/rtl/gtwvt/gtwvt.c + ! do not convert characters received with ALTGR or ALT+CTRL flags to + extended keycodes - some national keyboards may use such combination + for national characters and even pure ASCII ones + 2016-05-04 15:50 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * src/rtl/hbsocket.c ! fixed very bad typo which caused buffer overflow on 32bit diff --git a/doc/cmpopt.txt b/doc/cmpopt.txt index 862bf95add..20b2157051 100644 --- a/doc/cmpopt.txt +++ b/doc/cmpopt.txt @@ -75,7 +75,7 @@ arguments are well known and can be calculated at compile time: // switch which disables macro substitution // is used * => - / => // Clipper optimize only integers + / => // Clipper optimizes only integers % => $ => // Clipper wrongly calculates @@ -206,7 +206,7 @@ to intialize static variables, f.e.: static s_var := ( 1 + 2 / 3 ) Clipper does not optimize expression used in LOCAL, PRIVATE and -PUBLIC variables declarations but it optimize expressions for STATIC +PUBLIC variables declarations but it optimizes expressions for STATIC declarations. This code illustrates it: proc main() @@ -219,7 +219,9 @@ declarations. This code illustrates it: return This behavior is not replicated in Harbour even if -kc switch is used -and Harbour optimize expressions in all declarations. +and Harbour optimizes expressions in all declarations. + +3. Macro expansion: Harbour supports macro expansion for expressions with declared symbols. This functionality can be enabled by -kd compiler switch: @@ -240,6 +242,8 @@ code to Harbour because some compilers just like xHarbour accepted in some limited way officially unsupported syntax with macros using declared symbols. +4. PCODE optimization: + Harbour has additional optimization phase which operates on generated PCODE. It can also reduce expressions, joins jumps, removes death or meaningless code which can appear after all other optimizations and were not optimized diff --git a/include/harbour.hbx b/include/harbour.hbx index a2586e4c6e..cee0dd59c3 100644 --- a/include/harbour.hbx +++ b/include/harbour.hbx @@ -709,6 +709,7 @@ DYNAMIC hb_mutexSubscribeNow DYNAMIC hb_mutexUnlock DYNAMIC hb_mvRestore DYNAMIC hb_mvSave +DYNAMIC hb_ntoc DYNAMIC hb_NToColor DYNAMIC hb_ntos DYNAMIC hb_NToT diff --git a/include/hbapi.h b/include/hbapi.h index b7e4eadd10..e15e903565 100644 --- a/include/hbapi.h +++ b/include/hbapi.h @@ -993,6 +993,7 @@ extern HB_EXPORT double hb_strVal( const char * szText, HB_SIZE nLen ); /* re extern HB_EXPORT HB_MAXINT hb_strValInt( const char * szText, int * iOverflow ); extern HB_EXPORT char * hb_strRemEscSeq( char * szText, HB_SIZE * nLen ); /* remove C ESC sequences and converts them to Clipper chars */ extern HB_EXPORT char * hb_numToStr( char * szBuf, HB_SIZE nSize, HB_MAXINT nNumber ); +extern HB_EXPORT char * hb_dblToStr( char * szBuf, HB_SIZE nSize, double dNumber, int iMaxDec ); extern HB_EXPORT double hb_numRound( double dResult, int iDec ); /* round a number to a specific number of digits */ extern HB_EXPORT double hb_numInt( double dNum ); /* take the integer part of the number */ extern HB_EXPORT void hb_random_seed( HB_I32 seed ); diff --git a/src/codepage/uckam.c b/src/codepage/uckam.c index 9724d82924..e3e9ea5e72 100644 --- a/src/codepage/uckam.c +++ b/src/codepage/uckam.c @@ -1,5 +1,5 @@ /* - * Czech and Slovak Kamenicky <-> Unicode conversion table + * Czech and Slovak Kamenicky (CP895) <-> Unicode conversion table * * Copyright 2006 Vojtech Obrdlik * adapted from David Kozub - http://linux.fjfi.cvut.cz/%7Ezub/cp895/ diff --git a/src/common/hbstr.c b/src/common/hbstr.c index aace79278b..106043c316 100644 --- a/src/common/hbstr.c +++ b/src/common/hbstr.c @@ -819,6 +819,124 @@ char * hb_numToStr( char * szBuf, HB_SIZE nSize, HB_MAXINT lNumber ) return &szBuf[ iPos ]; } +/* if you want to be sure that size of buffer is enough to hold each + double number with '\0' terminating character then it should have + at least HB_MAX_DOUBLE_LENGTH bytes. If buffer is not large enough + then NULL is returned */ +char * hb_dblToStr( char * szBuf, HB_SIZE nSize, double dNumber, int iMaxDec ) +{ + double dInt, dFract, dDig, doBase = 10.0; + int iLen, iPos, iPrec; + char * szResult; + HB_BOOL fFirst; + + HB_TRACE( HB_TR_DEBUG, ( "hb_dblToStr(%p, %" HB_PFS "u, %f, %d)", szBuf, nSize, dNumber, iMaxDec ) ); + + iLen = ( int ) ( nSize - 1 ); + if( iLen <= 0 ) + return NULL; +#ifdef HB_NUM_PRECISION + iPrec = HB_NUM_PRECISION; +#else + iPrec = 16; +#endif + szResult = szBuf; + if( dNumber < 0 ) + { + if( --iLen == 0 ) + return NULL; + *szBuf++ = '-'; + dFract = modf( -dNumber, &dInt ); + } + else + dFract = modf( dNumber, &dInt ); + + iPos = iLen; + do + { + dDig = modf( dInt / doBase + 0.01, &dInt ) * doBase; + szBuf[ --iPos ] = '0' + ( char ) ( dDig + 0.01 ); + if( iPos == 0 ) + { + if( dInt >= 1 ) + return NULL; + break; + } + } + while( dInt >= 1 ); + if( iPos > 0 ) + memmove( szBuf, szBuf + iPos, HB_MIN( iLen - iPos, iPrec ) ); + iPos = iLen - iPos; + + fFirst = iPos > 1 || szBuf[ 0 ] != '0'; + if( fFirst ) + { + if( iPos >= iPrec ) + { + while( iPrec < iPos ) + szBuf[ iPrec++ ] = '0'; + iPrec = 0; + } + else + iPrec -= iPos; + } + + while( dInt >= 1 ) + { + if( iPos >= iLen ) + return NULL; + dDig = modf( dInt / doBase + 0.01, &dInt ) * doBase; + szBuf[ iPos++ ] = iPrec-- > 0 ? '0' + ( char ) ( dDig + 0.01 ) : '0'; + } + + if( iPrec > 0 && iLen - iPos > 1 && iMaxDec != 0 && dFract > 0 ) + { + int iDec = iPos; + + szBuf[ iPos ] = '.'; + while( ++iPos < iLen && iPrec > 0 && iMaxDec-- != 0 ) + { + dFract = modf( dFract * doBase, &dDig ); + szBuf[ iPos ] = '0' + ( char ) ( dDig + 0.01 ); + if( szBuf[ iPos ] != '0' ) + fFirst = HB_TRUE; + if( fFirst ) + --iPrec; + } + if( dFract > ( iPrec > 0 ? 0.5 - hb_numPow10( -iPrec ) : 0.2 ) ) + { + iPrec = iPos; + for( ;; ) + { + if( --iPrec < 0 ) + { + memmove( szBuf + 1, szBuf, iPos ); + *szBuf = '1'; + if( iPos < iLen ) + ++iPos; + ++iDec; + break; + } + if( iPrec == iDec ) + --iPrec; + if( szBuf[ iPrec ] != '9' ) + { + ++szBuf[ iPrec ]; + break; + } + szBuf[ iPrec ] = '0'; + } + } + while( iPos > iDec && szBuf[ iPos - 1 ] == '0' ) + --iPos; + if( szBuf[ iPos - 1 ] == '.' ) + --iPos; + } + + szBuf[ iPos ] = '\0'; + return iPos == 1 && *szResult == '-' && *szBuf == '0' ? szBuf : szResult; +} + /* * This function copies szText to destination buffer. * NOTE: Unlike the documentation for strncpy, this routine will always append diff --git a/src/rtl/gtwvt/gtwvt.c b/src/rtl/gtwvt/gtwvt.c index 791fc63663..14957a1b3d 100644 --- a/src/rtl/gtwvt/gtwvt.c +++ b/src/rtl/gtwvt/gtwvt.c @@ -140,6 +140,8 @@ static HB_CRITICAL_NEW( s_wvtMtx ); #endif #endif +#define HB_KF_ALTGR 0x10 + static PHB_GTWVT s_wvtWindows[ WVT_MAX_WINDOWS ]; static int s_wvtCount = 0; @@ -2133,8 +2135,21 @@ static int hb_gt_wvt_GetKeyFlags( void ) iFlags |= HB_KF_SHIFT; if( GetKeyState( VK_CONTROL ) & 0x8000 ) iFlags |= HB_KF_CTRL; - if( GetKeyState( VK_MENU ) & 0x8000 ) + if( GetKeyState( VK_RMENU ) & 0x8000 ) iFlags |= HB_KF_ALT; + if( GetKeyState( VK_LMENU ) & 0x8000 ) + iFlags |= HB_KF_ALTGR; + + return iFlags; +} + +static int hb_gt_wvt_UpdateKeyFlags( int iFlags ) +{ + if( iFlags & HB_KF_ALTGR ) + { + iFlags |= HB_KF_ALT; + iFlags &= ~HB_KF_ALTGR; + } return iFlags; } @@ -2384,7 +2399,8 @@ static void hb_gt_wvt_MouseEvent( PHB_GTWVT pWVT, UINT message, WPARAM wParam, L if( keyCode != 0 ) hb_gt_wvt_AddCharToInputQueue( pWVT, - HB_INKEY_NEW_MKEY( keyCode, hb_gt_wvt_GetKeyFlags() ) ); + HB_INKEY_NEW_MKEY( keyCode, + hb_gt_wvt_UpdateKeyFlags( hb_gt_wvt_GetKeyFlags() ) ) ); } static HB_BOOL hb_gt_wvt_KeyEvent( PHB_GTWVT pWVT, UINT message, WPARAM wParam, LPARAM lParam ) @@ -2524,7 +2540,7 @@ static HB_BOOL hb_gt_wvt_KeyEvent( PHB_GTWVT pWVT, UINT message, WPARAM wParam, pWVT->IgnoreWM_SYSCHAR = HB_TRUE; iKey = ( int ) wParam - VK_NUMPAD0 + '0'; } - else if( iFlags == HB_KF_ALT ) + else if( iFlags == HB_KF_ALT || iFlags == HB_KF_ALTGR ) iFlags = 0; /* for ALT + */ iFlags |= HB_KF_KEYPAD; break; @@ -2575,7 +2591,7 @@ static HB_BOOL hb_gt_wvt_KeyEvent( PHB_GTWVT pWVT, UINT message, WPARAM wParam, iKey = iKeyPad; if( ( lParam & WVT_EXTKEY_FLAG ) == 0 ) { - if( iFlags == HB_KF_ALT ) + if( iFlags == HB_KF_ALT || iFlags == HB_KF_ALTGR ) iFlags = iKey = 0; /* for ALT + */ else iFlags |= HB_KF_KEYPAD; @@ -2583,13 +2599,16 @@ static HB_BOOL hb_gt_wvt_KeyEvent( PHB_GTWVT pWVT, UINT message, WPARAM wParam, } pWVT->keyFlags = iFlags; if( iKey != 0 ) - iKey = HB_INKEY_NEW_KEY( iKey, iFlags ); + iKey = HB_INKEY_NEW_KEY( iKey, hb_gt_wvt_UpdateKeyFlags( iFlags ) ); break; case WM_CHAR: - if( ( iFlags & HB_KF_CTRL ) != 0 && ( iFlags & HB_KF_ALT ) != 0 ) + if( ( iFlags & HB_KF_CTRL ) != 0 ? ( iFlags & HB_KF_ALT ) != 0 : + ( ( iFlags & HB_KF_ALTGR ) != 0 ) ) /* workaround for AltGR and German keyboard */ - iFlags &= ~( HB_KF_CTRL | HB_KF_ALT ); + iFlags &= ~( HB_KF_CTRL | HB_KF_ALT | HB_KF_ALTGR ); + else + iFlags = hb_gt_wvt_UpdateKeyFlags( iFlags ); case WM_SYSCHAR: if( ! pWVT->IgnoreWM_SYSCHAR ) { diff --git a/src/rtl/hbinet.c b/src/rtl/hbinet.c index a59881146d..a65bc35036 100644 --- a/src/rtl/hbinet.c +++ b/src/rtl/hbinet.c @@ -1272,7 +1272,11 @@ static void hb_inetConnectInternal( HB_BOOL fResolve ) szHost = szAddr = hb_socketResolveAddr( szHost, HB_SOCKET_AF_INET ); if( fResolve && ! szAddr ) + { hb_inetGetError( socket ); + if( socket->iError == 0 ) + socket->iError = HB_SOCKET_ERR_WRONGADDR; + } else { /* Creates comm socket */ diff --git a/src/rtl/hbntos.c b/src/rtl/hbntos.c index 0fb94290e1..9982d8644b 100644 --- a/src/rtl/hbntos.c +++ b/src/rtl/hbntos.c @@ -2,6 +2,7 @@ * hb_ntos() function * * Copyright 2008 Viktor Szakats (vszakats.net/harbour) + * Copyright 2016 Przemyslaw Czerpak * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -72,3 +73,37 @@ HB_FUNC( HB_NTOS ) hb_retc_null(); } + +HB_FUNC( HB_NTOC ) +{ + PHB_ITEM pNumber = hb_param( 1, HB_IT_NUMERIC ); + + if( pNumber ) + { + char szBuffer[ HB_MAX_DOUBLE_LENGTH ]; + + if( ! HB_IS_DOUBLE( pNumber ) ) + { + HB_MAXINT nNumber = hb_itemGetNInt( pNumber ); + int iPos = sizeof( szBuffer ); + HB_BOOL fNeg = nNumber < 0; + + if( fNeg ) + nNumber = -nNumber; + szBuffer[ --iPos ] = '\0'; + do + { + szBuffer[ --iPos ] = '0' + ( char ) ( nNumber % 10 ); + nNumber /= 10; + } + while( nNumber != 0 ); + + hb_retc( szBuffer + iPos ); + } + else + hb_retc( hb_dblToStr( szBuffer, sizeof( szBuffer ), + hb_itemGetND( pNumber ), hb_parnidef( 2, 20 ) ) ); + } + else + hb_retc_null(); +} diff --git a/src/rtl/hbsocket.c b/src/rtl/hbsocket.c index d0ed123b11..9428ac5eec 100644 --- a/src/rtl/hbsocket.c +++ b/src/rtl/hbsocket.c @@ -183,6 +183,7 @@ # endif # define HB_IS_INET_NTOA_MT_SAFE # define HB_HAS_GETHOSTBYADDR +# define hb_socketSetResolveError( err ) hb_socketSetOsError( err ) #elif defined( HB_OS_OS2 ) # if defined( __WATCOMC__ ) # define HB_HAS_INET_PTON @@ -209,6 +210,10 @@ /* # define HB_HAS_INET6 */ #endif +#if defined( HB_HAS_NAMEINFO ) && ! defined( HB_HAS_ADDRINFO ) +# undef HB_HAS_NAMEINFO +#endif + #if defined( HB_OS_WIN ) # include @@ -812,14 +817,17 @@ PHB_ITEM hb_socketGetIFaces( int af, HB_BOOL fNoAliases ) #if defined( HB_OS_WIN ) # define HB_SOCK_GETERROR() WSAGetLastError() +# define HB_SOCK_GETHERROR() WSAGetLastError() # define HB_SOCK_IS_EINTR( err ) ( (err) == WSAEINTR ) # define HB_SOCK_IS_EINPROGRES( err ) ( (err) == WSAEWOULDBLOCK ) #elif defined( HB_OS_OS2 ) && defined( __WATCOMC__ ) # define HB_SOCK_GETERROR() sock_errno() +# define HB_SOCK_GETHERROR() h_errno # define HB_SOCK_IS_EINTR( err ) ( (err) == EINTR ) # define HB_SOCK_IS_EINPROGRES( err ) ( (err) == EINPROGRESS ) #else # define HB_SOCK_GETERROR() errno +# define HB_SOCK_GETHERROR() h_errno # define HB_SOCK_IS_EINTR( err ) ( (err) == EINTR ) # define HB_SOCK_IS_EINPROGRES( err ) ( (err) == EINPROGRESS ) #endif @@ -1088,6 +1096,9 @@ static void hb_socketSetOsError( int err ) case WSA_E_CANCELLED: uiErr = HB_SOCKET_ERR_CANCELLED; break; + case WSA_NOT_ENOUGH_MEMORY: + uiErr = HB_SOCKET_ERR_NOMEM; + break; default: uiErr = HB_SOCKET_ERR_OTHER; break; @@ -1323,7 +1334,93 @@ static void hb_socketSetOsError( int err ) break; # endif #endif -/* + default: + uiErr = HB_SOCKET_ERR_OTHER; + break; + } +#endif + + pError->uiSocketError = uiErr; + pError->iSocketOsError = err; +} + +#if ! defined( HB_OS_WIN ) +static void hb_socketSetResolveError( int err ) +{ + PHB_IOERRORS pError = hb_stackIOErrors(); + HB_ERRCODE uiErr; + + switch( err ) + { + case 0: + uiErr = 0; + break; + +#if defined( HB_HAS_ADDRINFO ) || defined( HB_HAS_NAMEINFO ) + + /* getaddrinfo() / getnameinfo() */ +#if defined( EAI_AGAIN ) + case EAI_AGAIN: + uiErr = HB_SOCKET_ERR_TRYAGAIN; + break; +#endif +#if defined( EAI_BADFLAGS ) + case EAI_BADFLAGS: + uiErr = HB_SOCKET_ERR_INVAL; + break; +#endif +#if defined( EAI_FAIL ) + case EAI_FAIL: + uiErr = HB_SOCKET_ERR_NORECOVERY; + break; +#endif +#if defined( EAI_ADDRFAMILY ) + case EAI_ADDRFAMILY: +#endif +#if defined( EAI_FAMILY ) + case EAI_FAMILY: + uiErr = HB_SOCKET_ERR_AFNOSUPPORT; + break; +#endif +#if defined( EAI_MEMORY ) + case EAI_MEMORY: + uiErr = HB_SOCKET_ERR_NOMEM; + break; +#endif +#if defined( EAI_NODATA ) + case EAI_NODATA: + uiErr = HB_SOCKET_ERR_NODATA; + break; +#endif +#if defined( EAI_NONAME ) + case EAI_NONAME: + uiErr = HB_SOCKET_ERR_HOSTNOTFOUND; + break; +#endif +#if defined( EAI_OVERFLOW ) + case EAI_OVERFLOW: + uiErr = HB_SOCKET_ERR_NAMETOOLONG; + break; +#endif +#if defined( EAI_SERVICE ) + case EAI_SERVICE: + uiErr = HB_SOCKET_ERR_TYPENOTFOUND; + break; +#endif +#if defined( EAI_SOCKTYPE ) + case EAI_SOCKTYPE: + uiErr = HB_SOCKET_ERR_NOSUPPORT; + break; +#endif +#if defined( EAI_SYSTEM ) + case EAI_SYSTEM: + uiErr = HB_SOCKET_ERR_SYSCALLFAILURE; + break; +#endif + +#else /* ! HB_HAS_ADDRINFO && ! HB_HAS_NAMEINFO */ + + /* gethostbyname() / gethostbyaddr() */ #if defined( TRY_AGAIN ) case TRY_AGAIN: uiErr = HB_SOCKET_ERR_TRYAGAIN; @@ -1350,16 +1447,17 @@ static void hb_socketSetOsError( int err ) uiErr = HB_SOCKET_ERR_NODATA; break; #endif -*/ + +#endif /* ! HB_HAS_ADDRINFO && ! HB_HAS_NAMEINFO */ default: - uiErr = HB_SOCKET_ERR_OTHER; + uiErr = HB_SOCKET_ERR_WRONGADDR; break; } -#endif pError->uiSocketError = uiErr; pError->iSocketOsError = err; } +#endif #if defined( HB_SOCKET_TRANSLATE_DOMAIN ) static int hb_socketTransDomain( int domain, int *err ) @@ -3267,11 +3365,14 @@ HB_BOOL hb_socketResolveInetAddr( void ** pSockAddr, unsigned * puiLen, const ch { #if defined( HB_HAS_ADDRINFO ) struct addrinfo hints, * res = NULL; + int iError; hb_vmUnlock(); memset( &hints, 0, sizeof( hints ) ); hints.ai_family = AF_INET; - if( getaddrinfo( szAddr, NULL, &hints, &res ) == 0 ) + iError = getaddrinfo( szAddr, NULL, &hints, &res ); + hb_socketSetResolveError( iError ); + if( iError == 0 ) { if( ( int ) res->ai_addrlen >= ( int ) sizeof( struct sockaddr_in ) && hb_socketGetAddrFamily( res->ai_addr, ( unsigned ) res->ai_addrlen ) == AF_INET ) @@ -3287,6 +3388,7 @@ HB_BOOL hb_socketResolveInetAddr( void ** pSockAddr, unsigned * puiLen, const ch hb_vmUnlock(); he = gethostbyname( szAddr ); + hb_socketSetResolveError( he == NULL ? HB_SOCK_GETHERROR() : 0 ); if( he && he->h_addr_list[ 0 ] ) { sa.sin_addr.s_addr = ( ( struct in_addr * ) he->h_addr_list[ 0 ] )->s_addr; @@ -3316,6 +3418,7 @@ char * hb_socketResolveAddr( const char * szAddr, int af ) { char * szResult = NULL; HB_BOOL fTrans = HB_FALSE; + int iError = 0; if( ! szAddr || ! *szAddr ) return NULL; @@ -3345,6 +3448,8 @@ char * hb_socketResolveAddr( const char * szAddr, int af ) sin.s_addr = ( ( struct in_addr * ) he->h_addr_list[ 0 ] )->s_addr; fTrans = HB_TRUE; } + else + iError = HB_SOCK_GETHERROR(); hb_vmLock(); } #endif @@ -3397,7 +3502,8 @@ char * hb_socketResolveAddr( const char * szAddr, int af ) # endif memset( &hints, 0, sizeof( hints ) ); hints.ai_family = af; - if( getaddrinfo( szAddr, NULL, &hints, &res ) == 0 ) + iError = getaddrinfo( szAddr, NULL, &hints, &res ); + if( iError == 0 ) { szResult = hb_socketAddrGetName( res->ai_addr, ( unsigned ) res->ai_addrlen ); freeaddrinfo( res ); @@ -3405,6 +3511,7 @@ char * hb_socketResolveAddr( const char * szAddr, int af ) hb_vmLock(); #endif } + hb_socketSetResolveError( iError ); return szResult; } @@ -3424,6 +3531,7 @@ PHB_ITEM hb_socketGetHosts( const char * szAddr, int af ) memset( &hints, 0, sizeof( hints ) ); hints.ai_family = af; iResult = getaddrinfo( szAddr, NULL, &hints, &res ); + hb_socketSetResolveError( iResult ); hb_vmLock(); if( iResult == 0 ) @@ -3467,7 +3575,7 @@ PHB_ITEM hb_socketGetHosts( const char * szAddr, int af ) } freeaddrinfo( res ); } -#else +#else /* ! HB_HAS_ADDRINFO */ if( af == HB_SOCKET_AF_INET ) { @@ -3501,6 +3609,8 @@ PHB_ITEM hb_socketGetHosts( const char * szAddr, int af ) if( he == NULL ) he = gethostbyname( szAddr ); + hb_socketSetResolveError( he == NULL ? HB_SOCK_GETHERROR() : 0 ); + hb_vmLock(); if( he ) @@ -3565,20 +3675,24 @@ char * hb_socketGetHostName( const void * pSockAddr, unsigned len ) hb_vmUnlock(); iResult = getnameinfo( ( const struct sockaddr * ) pSockAddr, len, szHost, NI_MAXHOST, NULL, 0, 0 ); + hb_socketSetResolveError( iResult ); hb_vmLock(); if( iResult == 0 ) szResult = hb_strdup( szHost ); -#elif defined( HB_HAS_ADDRINFO ) && ! defined( HB_HAS_GETHOSTBYADDR ) +#elif defined( HB_HAS_ADDRINFO ) char * szAddr = hb_socketAddrGetName( pSockAddr, len ); if( szAddr ) { struct addrinfo hints, * res = NULL; + int iError; hb_vmUnlock(); memset( &hints, 0, sizeof( hints ) ); hints.ai_family = af; hints.ai_flags = AI_CANONNAME; - if( getaddrinfo( szAddr, NULL, &hints, &res ) == 0 ) + iError = getaddrinfo( szAddr, NULL, &hints, &res ); + hb_socketSetResolveError( iError ); + if( iError == 0 ) { if( res->ai_canonname ) szResult = hb_strdup( res->ai_canonname ); @@ -3586,7 +3700,7 @@ char * hb_socketGetHostName( const void * pSockAddr, unsigned len ) } hb_vmLock(); } -#else +#else /* ! HB_HAS_ADDRINFO */ struct hostent * he = NULL; if( af == AF_INET ) @@ -3595,6 +3709,7 @@ char * hb_socketGetHostName( const void * pSockAddr, unsigned len ) const struct sockaddr_in * sa = ( const struct sockaddr_in * ) pSockAddr; hb_vmUnlock(); he = gethostbyaddr( ( const char * ) &sa->sin_addr, sizeof( sa->sin_addr ), af ); + hb_socketSetResolveError( he == NULL ? HB_SOCK_GETHERROR() : 0 ); hb_vmLock(); #else char * szAddr = hb_socketAddrGetName( pSockAddr, len ); @@ -3602,6 +3717,7 @@ char * hb_socketGetHostName( const void * pSockAddr, unsigned len ) { hb_vmUnlock(); he = gethostbyname( szAddr ); + hb_socketSetResolveError( he == NULL ? HB_SOCK_GETHERROR() : 0 ); hb_vmLock(); } #endif @@ -3612,12 +3728,13 @@ char * hb_socketGetHostName( const void * pSockAddr, unsigned len ) const struct sockaddr_in6 * sa = ( const struct sockaddr_in6 * ) pSockAddr; hb_vmUnlock(); he = gethostbyaddr( ( const char * ) &sa->sin6_addr, sizeof( sa->sin6_addr ), af ); + hb_socketSetResolveError( he == NULL ? HB_SOCK_GETHERROR() : 0 ); hb_vmLock(); } #endif if( he && he->h_name ) szResult = hb_strdup( he->h_name ); -#endif +#endif /* ! HB_HAS_ADDRINFO */ } return szResult; } diff --git a/src/vm/arrays.c b/src/vm/arrays.c index 2606deffa9..8d3461d74e 100644 --- a/src/vm/arrays.c +++ b/src/vm/arrays.c @@ -1075,6 +1075,20 @@ HB_SIZE hb_arrayScan( PHB_ITEM pArray, PHB_ITEM pValue, HB_SIZE * pnStart, HB_SI } while( --nCount > 0 ); } + else if( HB_IS_NUMINT( pValue ) ) + { + HB_MAXINT nValue = hb_itemGetNInt( pValue ); + + do + { + PHB_ITEM pItem = pBaseArray->pItems + nStart++; + + if( HB_IS_NUMERIC( pItem ) && hb_itemGetNInt( pItem ) == nValue && + hb_itemGetND( pItem ) == ( double ) nValue ) + return nStart; + } + while( --nCount > 0 ); + } else if( HB_IS_NUMERIC( pValue ) ) { double dValue = hb_itemGetND( pValue ); @@ -1242,6 +1256,20 @@ HB_SIZE hb_arrayRevScan( PHB_ITEM pArray, PHB_ITEM pValue, HB_SIZE * pnStart, HB } while( --nCount && nStart-- ); } + else if( HB_IS_NUMINT( pValue ) ) + { + HB_MAXINT nValue = hb_itemGetNInt( pValue ); + + do + { + PHB_ITEM pItem = pBaseArray->pItems + nStart; + + if( HB_IS_NUMERIC( pItem ) && hb_itemGetNInt( pItem ) == nValue && + hb_itemGetND( pItem ) == ( double ) nValue ) + return nStart + 1; + } + while( --nCount && nStart-- ); + } else if( HB_IS_NUMERIC( pValue ) ) { double dValue = hb_itemGetND( pValue ); diff --git a/src/vm/hashfunc.c b/src/vm/hashfunc.c index 94229ce65b..1ef9311277 100644 --- a/src/vm/hashfunc.c +++ b/src/vm/hashfunc.c @@ -514,6 +514,26 @@ HB_FUNC( HB_HSCAN ) ++nStart; } } + else if( HB_IS_NUMINT( pValue ) ) + { + HB_MAXINT nValue = hb_itemGetNInt( pValue ); + while( nCount-- ) + { + PHB_ITEM pItem = hb_hashGetValueAt( pHash, nStart ); + if( pItem ) + { + if( HB_IS_NUMERIC( pItem ) && hb_itemGetNInt( pItem ) == nValue && + hb_itemGetND( pItem ) == ( double ) nValue ) + { + fFound = HB_TRUE; + break; + } + } + else + break; + ++nStart; + } + } else if( HB_IS_NUMERIC( pValue ) ) { double dValue = hb_itemGetND( pValue ); diff --git a/src/vm/itemapi.c b/src/vm/itemapi.c index 8fea415bba..c3dbe0342e 100644 --- a/src/vm/itemapi.c +++ b/src/vm/itemapi.c @@ -2060,7 +2060,7 @@ PHB_ITEM hb_itemReSizeString( PHB_ITEM pItem, HB_SIZE nSize ) { HB_SIZE nAlloc = nSize + 1 + ( pItem->item.asString.allocated <= nSize ? nSize : 0 ); - pItem->item.asString.value = ( char* ) + pItem->item.asString.value = ( char * ) hb_xRefResize( pItem->item.asString.value, pItem->item.asString.length, nAlloc, &pItem->item.asString.allocated );