* contrib/gtqtc/gtqtc1.cpp
* contrib/gtwvg/gtwgud.c
* contrib/gtwvw/wvwdraw.c
* contrib/hbamf/amfdec.c
* contrib/hbamf/amfstdio.c
* contrib/hbbz2io/bz2io.c
* contrib/hbgzio/gzio.c
* contrib/hbhpdf/core.c
* contrib/hbmemio/memio.c
* contrib/hbmisc/irm.c
* contrib/hbmisc/spd.c
* contrib/hbnetio/netiosrv.c
* contrib/hbssl/ssl_sock.c
* contrib/hbwin/olecore.c
* contrib/hbwin/wapi_commctrl.c
* contrib/hbwin/wapi_winuser.c
* contrib/hbwin/win_bmpd.c
* contrib/hbwin/win_misc.c
* contrib/hbzebra/qrcode.c
* contrib/rddads/ads1.c
* contrib/rddads/adsfunc.c
* contrib/rddsql/sqlmix.c
* contrib/sddfb/core.c
* contrib/xhb/cstructc.c
* contrib/xhb/hboutdbg.c
* contrib/xhb/hbserv.c
* include/hbdefs.h
* include/hbexprb.c
* include/hbrddcdx.h
* include/hbthread.h
* include/hbwmain.c
* src/common/hbffind.c
* src/compiler/complex.c
* src/compiler/hbmain.c
* src/compiler/hbopt.c
* src/debug/dbgentry.c
* src/rdd/dbf1.c
* src/rdd/dbfcdx/dbfcdx1.c
* src/rdd/dbffpt/dbffpt1.c
* src/rdd/dbfnsx/dbfnsx1.c
* src/rdd/dbfntx/dbfntx1.c
* src/rdd/hbsix/sxcompr.c
* src/rdd/wacore.c
* src/rdd/workarea.c
* src/rtl/cputime.c
* src/rtl/dates.c
* src/rtl/gtchrmap.c
* src/rtl/gtcrs/gtcrs.c
* src/rtl/gtpca/gtpca.c
* src/rtl/gtsln/gtsln.c
* src/rtl/gtsln/kbsln.c
* src/rtl/gtsln/keytrans.c
* src/rtl/gtstd/gtstd.c
* src/rtl/gttrm/gttrm.c
* src/rtl/gtwvt/gtwvt.c
* src/rtl/gtxwc/gtxwc.c
* src/rtl/hbcom.c
* src/rtl/hbproces.c
* src/rtl/itemseri.c
* src/rtl/langapi.c
* src/rtl/run.c
* src/rtl/sha1.c
* src/rtl/space.c
* src/vm/classes.c
* src/vm/hvm.c
* src/vm/itemapi.c
* src/vm/set.c
* src/vm/thread.c
* convert commented C code to #if 0 blocks, or clean them up in
different ways
2944 lines
79 KiB
C
2944 lines
79 KiB
C
/*
|
|
* The Item API
|
|
*
|
|
* Copyright 1999 Antonio Linares <alinares@fivetech.com>
|
|
* Copyright 1999-2007 Viktor Szakats (vszakats.net/harbour)
|
|
* hb_itemPCount(), hb_itemParamPtr(), hb_itemReturnPtr()
|
|
* hb_itemPutDL(), hb_itemPutNI(), hb_itemGetDL(), hb_itemGetNI(),
|
|
* hb_itemGetCPtr(), hb_itemPutCLPtr(), hb_itemGetCLen(), hb_itemGetNLen()
|
|
* hb_itemPutCConst(), hb_itemPutCLConst()
|
|
* hb_itemPutNLen(), hb_itemPutNDLen(), hb_itemPutNILen(), hb_itemPutNLLen()
|
|
* hb_itemPutD(), hb_itemSetCMemo()
|
|
* Copyright 1999 Eddie Runia <eddie@runia.com> (hb_itemStrCmp())
|
|
* Copyright 1999 David G. Holm <dholm@jsd-llc.com> (hb_itemStr(), hb_itemString(), hb_itemValToStr())
|
|
*
|
|
* 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
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; see the file LICENSE.txt. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301 USA (or visit https://www.gnu.org/licenses/).
|
|
*
|
|
* As a special exception, the Harbour Project gives permission for
|
|
* additional uses of the text contained in its release of Harbour.
|
|
*
|
|
* The exception is that, if you link the Harbour libraries with other
|
|
* files to produce an executable, this does not by itself cause the
|
|
* resulting executable to be covered by the GNU General Public License.
|
|
* Your use of that executable is in no way restricted on account of
|
|
* linking the Harbour library code into it.
|
|
*
|
|
* This exception does not however invalidate any other reasons why
|
|
* the executable file might be covered by the GNU General Public License.
|
|
*
|
|
* This exception applies only to the code released by the Harbour
|
|
* Project under the name Harbour. If you copy code from other
|
|
* Harbour Project or Free Software Foundation releases into a copy of
|
|
* Harbour, as the General Public License permits, the exception does
|
|
* not apply to the code that you add in this way. To avoid misleading
|
|
* anyone as to the status of such modified files, you must delete
|
|
* this exception notice from them.
|
|
*
|
|
* If you write modifications of your own for Harbour, it is your choice
|
|
* whether to permit this exception to apply to your modifications.
|
|
* If you do not wish that, delete this exception notice.
|
|
*
|
|
*/
|
|
|
|
#include "hbvmopt.h"
|
|
/* hbfloat.h have to be included before other header files */
|
|
#include "hbfloat.h"
|
|
|
|
#include "hbvm.h"
|
|
#include "hbstack.h"
|
|
#include "hbapicls.h"
|
|
#include "hbapiitm.h"
|
|
#include "hbapilng.h"
|
|
#include "hbapierr.h"
|
|
#include "hbdate.h"
|
|
#include "hbset.h"
|
|
#include "hbapicdp.h"
|
|
|
|
PHB_ITEM hb_itemNew( PHB_ITEM pNull )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemNew(%p)", ( void * ) pNull ) );
|
|
|
|
return hb_gcGripGet( pNull );
|
|
}
|
|
|
|
PHB_ITEM hb_itemParam( HB_USHORT uiParam )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemParam(%hu)", uiParam ) );
|
|
|
|
return hb_itemNew( hb_param( uiParam, HB_IT_ANY ) );
|
|
}
|
|
|
|
/* Internal Item API. Use this with care. */
|
|
|
|
PHB_ITEM hb_itemParamPtr( HB_USHORT uiParam, long lMask )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemParamPtr(%hu, %ld)", uiParam, lMask ) );
|
|
|
|
return hb_param( ( int ) uiParam, lMask );
|
|
}
|
|
|
|
HB_BOOL hb_itemParamStore( HB_USHORT uiParam, PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemParamStore(%hu, %p)", uiParam, ( void * ) pItem ) );
|
|
|
|
if( hb_param( uiParam, HB_IT_BYREF ) )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
PHB_ITEM pDest = hb_stackItemFromBase( uiParam );
|
|
|
|
if( pItem )
|
|
hb_itemCopyToRef( pDest, pItem );
|
|
else
|
|
hb_itemSetNil( hb_itemUnRef( pDest ) );
|
|
return HB_TRUE;
|
|
}
|
|
|
|
return HB_FALSE;
|
|
}
|
|
|
|
HB_BOOL hb_itemParamStoreForward( HB_USHORT uiParam, PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemParamStoreForward(%hu, %p)", uiParam, ( void * ) pItem ) );
|
|
|
|
if( hb_param( uiParam, HB_IT_BYREF ) )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
PHB_ITEM pDest = hb_stackItemFromBase( uiParam );
|
|
|
|
if( pItem )
|
|
hb_itemMoveToRef( pDest, pItem );
|
|
else
|
|
hb_itemSetNil( hb_itemUnRef( pDest ) );
|
|
return HB_TRUE;
|
|
}
|
|
|
|
return HB_FALSE;
|
|
}
|
|
|
|
HB_BOOL hb_itemParamStoreRelease( HB_USHORT uiParam, PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemParamStoreRelease(%hu, %p)", uiParam, ( void * ) pItem ) );
|
|
|
|
if( hb_param( uiParam, HB_IT_BYREF ) )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
PHB_ITEM pDest = hb_stackItemFromBase( uiParam );
|
|
|
|
if( pItem )
|
|
{
|
|
hb_itemMoveToRef( pDest, pItem );
|
|
hb_itemRelease( pItem );
|
|
}
|
|
else
|
|
hb_itemSetNil( hb_itemUnRef( pDest ) );
|
|
return HB_TRUE;
|
|
}
|
|
|
|
return HB_FALSE;
|
|
}
|
|
|
|
HB_USHORT hb_itemPCount( void )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPCount()" ) );
|
|
|
|
return ( HB_USHORT ) hb_pcount();
|
|
}
|
|
|
|
HB_BOOL hb_itemRelease( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemRelease(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
{
|
|
hb_gcGripDrop( pItem );
|
|
return HB_TRUE;
|
|
}
|
|
else
|
|
return HB_FALSE;
|
|
}
|
|
|
|
PHB_ITEM hb_itemArrayNew( HB_SIZE nLen )
|
|
{
|
|
PHB_ITEM pItem;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemArrayNew(%" HB_PFS "u)", nLen ) );
|
|
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
hb_arrayNew( pItem, nLen );
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemArrayGet( PHB_ITEM pArray, HB_SIZE nIndex )
|
|
{
|
|
PHB_ITEM pItem;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemArrayGet(%p, %" HB_PFS "u)", ( void * ) pArray, nIndex ) );
|
|
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
if( pArray )
|
|
hb_arrayGet( pArray, nIndex, pItem );
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemArrayPut( PHB_ITEM pArray, HB_SIZE nIndex, PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemArrayPut(%p, %" HB_PFS "u, %p)", ( void * ) pArray, nIndex, ( void * ) pItem ) );
|
|
|
|
if( pArray )
|
|
hb_arraySet( pArray, nIndex, pItem );
|
|
|
|
return pArray;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutNil( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutNil(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
hb_itemSetNil( pItem );
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutC( PHB_ITEM pItem, const char * szText )
|
|
{
|
|
HB_SIZE nLen, nAlloc;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutC(%p, %s)", ( void * ) pItem, szText ) );
|
|
|
|
nLen = szText ? strlen( szText ) : 0;
|
|
if( nLen <= 1 )
|
|
{
|
|
nAlloc = 0;
|
|
szText = hb_szAscii[ nLen ? ( unsigned char ) szText[ 0 ] : 0 ];
|
|
}
|
|
else
|
|
{
|
|
nAlloc = nLen + 1;
|
|
szText = ( char * ) hb_xmemcpy( hb_xgrab( nAlloc ), szText, nAlloc );
|
|
}
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_STRING;
|
|
pItem->item.asString.value = ( char * ) HB_UNCONST( szText );
|
|
pItem->item.asString.length = nLen;
|
|
pItem->item.asString.allocated = nAlloc;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutCL( PHB_ITEM pItem, const char * szText, HB_SIZE nLen )
|
|
{
|
|
HB_SIZE nAlloc;
|
|
char * szValue;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutCL(%p, %.*s, %" HB_PFS "u)", ( void * ) pItem, ( int ) nLen, szText, nLen ) );
|
|
|
|
if( nLen <= 1 )
|
|
{
|
|
nAlloc = 0;
|
|
szValue = ( char * ) HB_UNCONST( hb_szAscii[ nLen ? ( unsigned char ) szText[ 0 ] : 0 ] );
|
|
}
|
|
else
|
|
{
|
|
nAlloc = nLen + 1;
|
|
szValue = ( char * ) hb_xmemcpy( hb_xgrab( nAlloc ), szText, nLen );
|
|
szValue[ nLen ] = '\0';
|
|
}
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
/* NOTE: CA-Cl*pper seems to be buggy here, it will return nLen bytes of
|
|
trash if the szText buffer is NULL, at least with hb_retclen().
|
|
[vszakats] */
|
|
|
|
pItem->type = HB_IT_STRING;
|
|
pItem->item.asString.value = szValue;
|
|
pItem->item.asString.length = nLen;
|
|
pItem->item.asString.allocated = nAlloc;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutCConst( PHB_ITEM pItem, const char * szText )
|
|
{
|
|
HB_SIZE nLen;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutCConst(%p, %s)", ( void * ) pItem, szText ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
nLen = szText ? strlen( szText ) : 0;
|
|
|
|
pItem->type = HB_IT_STRING;
|
|
pItem->item.asString.length = nLen;
|
|
pItem->item.asString.allocated = 0;
|
|
pItem->item.asString.value = ( char * ) HB_UNCONST( ( nLen > 1 ? szText :
|
|
hb_szAscii[ nLen ? ( unsigned char ) szText[ 0 ] : 0 ] ) );
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutCLConst( PHB_ITEM pItem, const char * szText, HB_SIZE nLen )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutCLConst(%p, %.*s, %" HB_PFS "u)", ( void * ) pItem, ( int ) nLen, szText, nLen ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_STRING;
|
|
pItem->item.asString.length = nLen;
|
|
pItem->item.asString.allocated = 0;
|
|
|
|
if( nLen <= 1 )
|
|
pItem->item.asString.value = ( char * ) HB_UNCONST( hb_szAscii[ nLen ? ( unsigned char ) szText[ 0 ] : 0 ] );
|
|
else if( szText[ nLen ] == '\0' )
|
|
pItem->item.asString.value = ( char * ) HB_UNCONST( szText );
|
|
else
|
|
hb_errInternal( 6003, "Internal error: hb_itemPutCLConst() missing termination character", NULL, NULL );
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutCPtr( PHB_ITEM pItem, char * szText )
|
|
{
|
|
HB_SIZE nLen;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutCPtr(%p, %s)", ( void * ) pItem, szText ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
nLen = szText ? strlen( szText ) : 0;
|
|
|
|
pItem->type = HB_IT_STRING;
|
|
pItem->item.asString.length = nLen;
|
|
if( nLen <= 1 )
|
|
{
|
|
pItem->item.asString.allocated = 0;
|
|
pItem->item.asString.value = ( char * ) HB_UNCONST( hb_szAscii[ nLen ? ( unsigned char ) szText[ 0 ] : 0 ] );
|
|
if( szText )
|
|
hb_xfree( szText );
|
|
}
|
|
else
|
|
{
|
|
pItem->item.asString.allocated = nLen + 1;
|
|
pItem->item.asString.value = szText;
|
|
}
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutCLPtr( PHB_ITEM pItem, char * szText, HB_SIZE nLen )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutCLPtr(%p, %.*s, %" HB_PFS "u)", ( void * ) pItem, ( int ) nLen, szText, nLen ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_STRING;
|
|
pItem->item.asString.length = nLen;
|
|
if( nLen <= 1 )
|
|
{
|
|
pItem->item.asString.allocated = 0;
|
|
pItem->item.asString.value = ( char * ) HB_UNCONST( hb_szAscii[ nLen ? ( unsigned char ) szText[ 0 ] : 0 ] );
|
|
hb_xfree( szText );
|
|
}
|
|
else
|
|
{
|
|
szText[ nLen ] = '\0';
|
|
pItem->item.asString.allocated = nLen + 1;
|
|
pItem->item.asString.value = szText;
|
|
}
|
|
|
|
return pItem;
|
|
}
|
|
|
|
void hb_itemSetCMemo( PHB_ITEM pItem )
|
|
{
|
|
if( pItem && HB_IS_STRING( pItem ) )
|
|
pItem->type |= HB_IT_MEMOFLAG;
|
|
}
|
|
|
|
/* NOTE: The caller should free the pointer if it's not NULL. [vszakats] */
|
|
|
|
char * hb_itemGetC( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetC(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem && HB_IS_STRING( pItem ) )
|
|
{
|
|
char * szResult = ( char * ) hb_xgrab( pItem->item.asString.length + 1 );
|
|
hb_xmemcpy( szResult, pItem->item.asString.value, pItem->item.asString.length );
|
|
szResult[ pItem->item.asString.length ] = '\0';
|
|
|
|
return szResult;
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
/* NOTE: Caller should not modify the buffer returned by this function.
|
|
[vszakats] */
|
|
|
|
const char * hb_itemGetCPtr( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetCPtr(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem && HB_IS_STRING( pItem ) )
|
|
return pItem->item.asString.value;
|
|
else
|
|
return "";
|
|
}
|
|
|
|
HB_SIZE hb_itemGetCLen( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetCLen(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem && HB_IS_STRING( pItem ) )
|
|
return pItem->item.asString.length;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
HB_SIZE hb_itemCopyC( PHB_ITEM pItem, char * szBuffer, HB_SIZE nLen )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemCopyC(%p, %s, %" HB_PFS "u)", ( void * ) pItem, szBuffer, nLen ) );
|
|
|
|
if( pItem && HB_IS_STRING( pItem ) )
|
|
{
|
|
if( nLen == 0 || nLen > pItem->item.asString.length )
|
|
nLen = pItem->item.asString.length;
|
|
|
|
hb_xmemcpy( szBuffer, pItem->item.asString.value, nLen );
|
|
|
|
return nLen;
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
HB_BOOL hb_itemFreeC( char * szText )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemFreeC(%s)", szText ) );
|
|
|
|
if( szText )
|
|
{
|
|
hb_xfree( szText );
|
|
|
|
return HB_TRUE;
|
|
}
|
|
else
|
|
return HB_FALSE;
|
|
}
|
|
|
|
/* NOTE: Clipper is buggy and will not append a trailing zero, although
|
|
the NG says that it will. Check your buffers, since what may have
|
|
worked with Clipper could overrun the buffer with Harbour.
|
|
The correct buffer size is 9 bytes: char szDate[ 9 ]
|
|
[vszakats] */
|
|
|
|
char * hb_itemGetDS( PHB_ITEM pItem, char * szDate )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetDS(%p, %p)", ( void * ) pItem, ( void * ) szDate ) );
|
|
|
|
if( pItem && HB_IS_DATETIME( pItem ) )
|
|
return hb_dateDecStr( szDate, pItem->item.asDateTime.julian );
|
|
else
|
|
return hb_dateDecStr( szDate, 0 );
|
|
}
|
|
|
|
long hb_itemGetDL( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetDL(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem && HB_IS_DATETIME( pItem ) )
|
|
return pItem->item.asDateTime.julian;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
/* This function always closes the time with a zero byte, so it needs a
|
|
* 18 character long buffer to store time in format "YYYYMMDDhhmmssfff"
|
|
* with trailing 0 byte.
|
|
*/
|
|
char * hb_itemGetTS( PHB_ITEM pItem, char * szDateTime )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetTS(%p, %s)", ( void * ) pItem, szDateTime ) );
|
|
|
|
if( pItem && HB_IS_DATETIME( pItem ) )
|
|
return hb_timeStampStrRawPut( szDateTime, pItem->item.asDateTime.julian,
|
|
pItem->item.asDateTime.time );
|
|
else
|
|
return hb_timeStampStrRawPut( szDateTime, 0, 0 );
|
|
}
|
|
|
|
double hb_itemGetTD( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetTD(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem && HB_IS_DATETIME( pItem ) )
|
|
return hb_timeStampPackDT( pItem->item.asDateTime.julian,
|
|
pItem->item.asDateTime.time );
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
HB_BOOL hb_itemGetTDT( PHB_ITEM pItem, long * plJulian, long * plMilliSec )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetTDT(%p,%p,%p)", ( void * ) pItem, ( void * ) plJulian, ( void * ) plMilliSec ) );
|
|
|
|
if( pItem && HB_IS_DATETIME( pItem ) )
|
|
{
|
|
*plJulian = pItem->item.asDateTime.julian;
|
|
*plMilliSec = pItem->item.asDateTime.time;
|
|
return HB_TRUE;
|
|
}
|
|
else
|
|
{
|
|
*plJulian = *plMilliSec = 0;
|
|
return HB_FALSE;
|
|
}
|
|
}
|
|
|
|
HB_BOOL hb_itemGetL( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetL(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_LOGICAL( pItem ) )
|
|
return pItem->item.asLogical.value;
|
|
|
|
else if( HB_IS_INTEGER( pItem ) )
|
|
return pItem->item.asInteger.value != 0;
|
|
|
|
else if( HB_IS_LONG( pItem ) )
|
|
return pItem->item.asLong.value != 0;
|
|
|
|
else if( HB_IS_DOUBLE( pItem ) )
|
|
return pItem->item.asDouble.value != 0.0;
|
|
}
|
|
|
|
return HB_FALSE;
|
|
}
|
|
|
|
HB_BOOL hb_itemGetLX( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetLX(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_LOGICAL( pItem ) )
|
|
return pItem->item.asLogical.value;
|
|
|
|
else if( HB_IS_INTEGER( pItem ) )
|
|
return pItem->item.asInteger.value != 0;
|
|
|
|
else if( HB_IS_LONG( pItem ) )
|
|
return pItem->item.asLong.value != 0;
|
|
|
|
else if( HB_IS_DOUBLE( pItem ) )
|
|
return pItem->item.asDouble.value != 0.0;
|
|
|
|
else if( HB_IS_DATETIME( pItem ) )
|
|
return pItem->item.asDateTime.julian != 0 ||
|
|
pItem->item.asDateTime.time != 0;
|
|
|
|
else
|
|
return HB_TRUE;
|
|
}
|
|
|
|
return HB_FALSE;
|
|
}
|
|
|
|
double hb_itemGetND( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetND(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_DOUBLE( pItem ) )
|
|
return pItem->item.asDouble.value;
|
|
|
|
else if( HB_IS_INTEGER( pItem ) )
|
|
return ( double ) pItem->item.asInteger.value;
|
|
|
|
else if( HB_IS_LONG( pItem ) )
|
|
return ( double ) pItem->item.asLong.value;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int hb_itemGetNI( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetNI(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_INTEGER( pItem ) )
|
|
return pItem->item.asInteger.value;
|
|
|
|
else if( HB_IS_LONG( pItem ) )
|
|
return ( int ) pItem->item.asLong.value;
|
|
|
|
else if( HB_IS_DOUBLE( pItem ) )
|
|
return HB_CAST_INT( pItem->item.asDouble.value );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
long hb_itemGetNL( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetNL(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_LONG( pItem ) )
|
|
return ( long ) pItem->item.asLong.value;
|
|
|
|
else if( HB_IS_INTEGER( pItem ) )
|
|
return ( long ) pItem->item.asInteger.value;
|
|
|
|
else if( HB_IS_DOUBLE( pItem ) )
|
|
return HB_CAST_LONG( pItem->item.asDouble.value );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
HB_ISIZ hb_itemGetNS( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetNS(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_LONG( pItem ) )
|
|
return ( HB_ISIZ ) pItem->item.asLong.value;
|
|
|
|
else if( HB_IS_INTEGER( pItem ) )
|
|
return ( HB_ISIZ ) pItem->item.asInteger.value;
|
|
|
|
else if( HB_IS_DOUBLE( pItem ) )
|
|
return HB_CAST_ISIZ( pItem->item.asDouble.value );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
HB_MAXINT hb_itemGetNInt( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetNL(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_LONG( pItem ) )
|
|
return ( HB_MAXINT ) pItem->item.asLong.value;
|
|
|
|
else if( HB_IS_INTEGER( pItem ) )
|
|
return ( HB_MAXINT ) pItem->item.asInteger.value;
|
|
|
|
else if( HB_IS_DOUBLE( pItem ) )
|
|
return HB_CAST_MAXINT( pItem->item.asDouble.value );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifndef HB_LONG_LONG_OFF
|
|
HB_LONGLONG hb_itemGetNLL( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetNL(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_LONG( pItem ) )
|
|
return ( HB_LONGLONG ) pItem->item.asLong.value;
|
|
|
|
else if( HB_IS_INTEGER( pItem ) )
|
|
return ( HB_LONGLONG ) pItem->item.asInteger.value;
|
|
|
|
else if( HB_IS_DOUBLE( pItem ) )
|
|
return HB_CAST_LONGLONG( pItem->item.asDouble.value );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
void * hb_itemGetPtr( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetPtr(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem && HB_IS_POINTER( pItem ) )
|
|
return pItem->item.asPointer.value;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
void * hb_itemGetPtrGC( PHB_ITEM pItem, const HB_GC_FUNCS * pFuncs )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetPtrGC(%p,%p)", ( void * ) pItem, ( const void * ) pFuncs ) );
|
|
|
|
if( pItem && HB_IS_POINTER( pItem ) &&
|
|
pItem->item.asPointer.collect &&
|
|
hb_gcFuncs( pItem->item.asPointer.value ) == pFuncs )
|
|
return pItem->item.asPointer.value;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
PHB_SYMB hb_itemGetSymbol( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetSymbol(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem && HB_IS_SYMBOL( pItem ) )
|
|
return pItem->item.asSymbol.value;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
PHB_ITEM hb_itemReturn( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemReturn(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
hb_itemCopy( hb_stackReturnItem(), pItem );
|
|
}
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemReturnForward( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemReturnForward(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
hb_itemMove( hb_stackReturnItem(), pItem );
|
|
}
|
|
|
|
return pItem;
|
|
}
|
|
|
|
void hb_itemReturnRelease( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemReturnRelease(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
hb_itemMove( hb_stackReturnItem(), pItem );
|
|
hb_itemRelease( pItem );
|
|
}
|
|
}
|
|
|
|
|
|
PHB_ITEM hb_itemPutDS( PHB_ITEM pItem, const char * szDate )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutDS(%p, %.8s)", ( void * ) pItem, szDate ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_DATE;
|
|
pItem->item.asDateTime.julian = hb_dateEncStr( szDate );
|
|
pItem->item.asDateTime.time = 0;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutD( PHB_ITEM pItem, int iYear, int iMonth, int iDay )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutD(%p, %04i, %02i, %02i)", ( void * ) pItem, iYear, iMonth, iDay ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_DATE;
|
|
pItem->item.asDateTime.julian = hb_dateEncode( iYear, iMonth, iDay );
|
|
pItem->item.asDateTime.time = 0;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutDL( PHB_ITEM pItem, long lJulian )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutDL(%p, %ld)", ( void * ) pItem, lJulian ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_DATE;
|
|
pItem->item.asDateTime.julian = lJulian;
|
|
pItem->item.asDateTime.time = 0;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutTS( PHB_ITEM pItem, const char * szDateTime )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutTS(%p, %s)", ( void * ) pItem, szDateTime ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_TIMESTAMP;
|
|
hb_timeStampStrRawGet( szDateTime, &pItem->item.asDateTime.julian,
|
|
&pItem->item.asDateTime.time );
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutTD( PHB_ITEM pItem, double dTimeStamp )
|
|
{
|
|
long lJulian, lMilliSec;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutTD(%p, %lf)", ( void * ) pItem, dTimeStamp ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
hb_timeStampUnpackDT( dTimeStamp, &lJulian, &lMilliSec );
|
|
pItem->type = HB_IT_TIMESTAMP;
|
|
pItem->item.asDateTime.julian = lJulian;
|
|
pItem->item.asDateTime.time = lMilliSec;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutTDT( PHB_ITEM pItem, long lJulian, long lMilliSec )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutTDT(%p, %ld, %ld)", ( void * ) pItem, lJulian, lMilliSec ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_TIMESTAMP;
|
|
pItem->item.asDateTime.julian = lJulian;
|
|
pItem->item.asDateTime.time = lMilliSec;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutL( PHB_ITEM pItem, HB_BOOL bValue )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutL(%p, %d)", ( void * ) pItem, ( int ) bValue ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_LOGICAL;
|
|
pItem->item.asLogical.value = bValue;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutND( PHB_ITEM pItem, double dNumber )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutND(%p, %lf)", ( void * ) pItem, dNumber ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_DOUBLE;
|
|
pItem->item.asDouble.length = HB_DBL_LENGTH( dNumber );
|
|
pItem->item.asDouble.decimal = ( HB_USHORT ) hb_stackSetStruct()->HB_SET_DECIMALS;
|
|
pItem->item.asDouble.value = dNumber;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutNI( PHB_ITEM pItem, int iNumber )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutNI(%p, %d)", ( void * ) pItem, iNumber ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_INTEGER;
|
|
pItem->item.asInteger.value = iNumber;
|
|
pItem->item.asInteger.length = HB_INT_LENGTH( iNumber );
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutNL( PHB_ITEM pItem, long lNumber )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutNL(%p, %ld)", ( void * ) pItem, lNumber ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
HB_ITEM_PUT_LONGRAW( pItem, lNumber );
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutNS( PHB_ITEM pItem, HB_ISIZ nNumber )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutNS(%p, %" HB_PFS "d)", ( void * ) pItem, nNumber ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
#if HB_SIZE_MAX <= HB_VMUINT_MAX
|
|
pItem->type = HB_IT_INTEGER;
|
|
pItem->item.asInteger.value = nNumber;
|
|
/* EXP limit used intentionally */
|
|
pItem->item.asInteger.length = HB_INT_EXPLENGTH( nNumber );
|
|
#else
|
|
if( HB_LIM_INT( nNumber ) )
|
|
{
|
|
pItem->type = HB_IT_INTEGER;
|
|
pItem->item.asInteger.value = ( int ) nNumber;
|
|
/* EXP limit used intentionally */
|
|
pItem->item.asInteger.length = HB_INT_EXPLENGTH( nNumber );
|
|
}
|
|
else
|
|
{
|
|
pItem->type = HB_IT_LONG;
|
|
pItem->item.asLong.value = nNumber;
|
|
pItem->item.asLong.length = HB_LONG_LENGTH( nNumber );
|
|
}
|
|
#endif
|
|
|
|
return pItem;
|
|
}
|
|
|
|
#ifndef HB_LONG_LONG_OFF
|
|
PHB_ITEM hb_itemPutNLL( PHB_ITEM pItem, HB_LONGLONG llNumber )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutNL(%p, %" PFLL "d)", ( void * ) pItem, llNumber ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
#if HB_VMLONG_MAX >= LONGLONG_MAX
|
|
pItem->type = HB_IT_LONG;
|
|
pItem->item.asLong.value = ( HB_MAXINT ) llNumber;
|
|
pItem->item.asLong.length = HB_LONG_LENGTH( llNumber );
|
|
#else
|
|
pItem->type = HB_IT_DOUBLE;
|
|
pItem->item.asDouble.value = ( double ) llNumber;
|
|
pItem->item.asDouble.length = HB_DBL_LENGTH( pItem->item.asDouble.value );
|
|
pItem->item.asDouble.decimal = 0;
|
|
#endif
|
|
return pItem;
|
|
}
|
|
#endif
|
|
|
|
PHB_ITEM hb_itemPutNInt( PHB_ITEM pItem, HB_MAXINT nNumber )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutNInt(%p, %" PFHL "d)", ( void * ) pItem, nNumber ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
if( HB_LIM_INT( nNumber ) )
|
|
{
|
|
pItem->type = HB_IT_INTEGER;
|
|
pItem->item.asInteger.value = ( int ) nNumber;
|
|
/* EXP limit used intentionally */
|
|
pItem->item.asInteger.length = HB_INT_EXPLENGTH( nNumber );
|
|
}
|
|
else
|
|
{
|
|
pItem->type = HB_IT_LONG;
|
|
pItem->item.asLong.value = nNumber;
|
|
pItem->item.asLong.length = HB_LONG_LENGTH( nNumber );
|
|
}
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutNIntLen( PHB_ITEM pItem, HB_MAXINT nNumber, int iWidth )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutNIntLen(%p, %" PFHL "d, %d)", ( void * ) pItem, nNumber, iWidth ) );
|
|
|
|
if( HB_LIM_INT( nNumber ) )
|
|
{
|
|
return hb_itemPutNILen( pItem, ( int ) nNumber, iWidth );
|
|
}
|
|
else
|
|
{
|
|
#ifdef HB_LONG_LONG_OFF
|
|
return hb_itemPutNLLen( pItem, ( long ) nNumber, iWidth );
|
|
#else
|
|
return hb_itemPutNLLLen( pItem, ( HB_LONGLONG ) nNumber, iWidth );
|
|
#endif
|
|
}
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutNLen( PHB_ITEM pItem, double dNumber, int iWidth, int iDec )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutNLen(%p, %lf, %d, %d)", ( void * ) pItem, dNumber, iWidth, iDec ) );
|
|
|
|
if( iDec < 0 )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
iDec = hb_stackSetStruct()->HB_SET_DECIMALS;
|
|
}
|
|
|
|
if( iDec == 0 )
|
|
{
|
|
HB_MAXINT nNumber = ( HB_MAXINT ) dNumber;
|
|
|
|
if( ( double ) nNumber == dNumber )
|
|
{
|
|
if( iWidth <= 0 || iWidth >= HB_DEFAULT_WIDTH )
|
|
iWidth = HB_DBL_LENGTH( dNumber );
|
|
|
|
return hb_itemPutNIntLen( pItem, nNumber, iWidth );
|
|
}
|
|
}
|
|
|
|
return hb_itemPutNDLen( pItem, dNumber, iWidth, iDec );
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutNDLen( PHB_ITEM pItem, double dNumber, int iWidth, int iDec )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutNDLen(%p, %lf, %d, %d)", ( void * ) pItem, dNumber, iWidth, iDec ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
if( iWidth <= 0 || iWidth >= HB_DEFAULT_WIDTH )
|
|
iWidth = HB_DBL_LENGTH( dNumber );
|
|
|
|
if( iDec < 0 )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
iDec = hb_stackSetStruct()->HB_SET_DECIMALS;
|
|
}
|
|
|
|
pItem->type = HB_IT_DOUBLE;
|
|
pItem->item.asDouble.length = ( HB_USHORT ) iWidth;
|
|
pItem->item.asDouble.decimal = ( HB_USHORT ) iDec;
|
|
pItem->item.asDouble.value = dNumber;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutNDDec( PHB_ITEM pItem, double dNumber, int iDec )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutNDDec(%p, %lf, %i)", ( void * ) pItem, dNumber, iDec ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_DOUBLE;
|
|
pItem->item.asDouble.length = HB_DBL_LENGTH( dNumber );
|
|
|
|
if( iDec == HB_DEFAULT_DECIMALS )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
pItem->item.asDouble.decimal = ( HB_USHORT ) hb_stackSetStruct()->HB_SET_DECIMALS;
|
|
}
|
|
else
|
|
{
|
|
pItem->item.asDouble.decimal = ( HB_USHORT ) iDec;
|
|
}
|
|
|
|
pItem->item.asDouble.value = dNumber;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
double hb_itemGetNDDec( PHB_ITEM pItem, int * piDec )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetNDDec(%p,%p)", ( void * ) pItem, ( void * ) piDec ) );
|
|
|
|
if( HB_IS_INTEGER( pItem ) )
|
|
{
|
|
*piDec = 0;
|
|
return ( double ) pItem->item.asInteger.value;
|
|
}
|
|
else if( HB_IS_LONG( pItem ) )
|
|
{
|
|
*piDec = 0;
|
|
return ( double ) pItem->item.asLong.value;
|
|
}
|
|
else if( HB_IS_DOUBLE( pItem ) )
|
|
{
|
|
*piDec = pItem->item.asDouble.decimal;
|
|
return pItem->item.asDouble.value;
|
|
}
|
|
|
|
*piDec = 0;
|
|
return 0.0;
|
|
}
|
|
|
|
|
|
PHB_ITEM hb_itemPutNILen( PHB_ITEM pItem, int iNumber, int iWidth )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutNILen(%p, %d, %d)", ( void * ) pItem, iNumber, iWidth ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
if( iWidth <= 0 || iWidth >= HB_DEFAULT_WIDTH )
|
|
iWidth = HB_INT_LENGTH( iNumber );
|
|
|
|
pItem->type = HB_IT_INTEGER;
|
|
pItem->item.asInteger.length = ( HB_USHORT ) iWidth;
|
|
pItem->item.asInteger.value = iNumber;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutNLLen( PHB_ITEM pItem, long lNumber, int iWidth )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutNLLen(%p, %ld, %d)", ( void * ) pItem, lNumber, iWidth ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
#if HB_VMINT_MAX == LONG_MAX
|
|
if( iWidth <= 0 || iWidth >= HB_DEFAULT_WIDTH )
|
|
iWidth = HB_INT_LENGTH( lNumber );
|
|
|
|
pItem->type = HB_IT_INTEGER;
|
|
pItem->item.asInteger.value = ( int ) lNumber;
|
|
pItem->item.asInteger.length = ( HB_USHORT ) iWidth;
|
|
#else
|
|
if( iWidth <= 0 || iWidth >= HB_DEFAULT_WIDTH )
|
|
iWidth = HB_LONG_LENGTH( lNumber );
|
|
|
|
pItem->type = HB_IT_LONG;
|
|
pItem->item.asLong.value = ( HB_MAXINT ) lNumber;
|
|
pItem->item.asLong.length = iWidth;
|
|
#endif
|
|
|
|
return pItem;
|
|
}
|
|
|
|
#ifndef HB_LONG_LONG_OFF
|
|
PHB_ITEM hb_itemPutNLLLen( PHB_ITEM pItem, HB_LONGLONG llNumber, int iWidth )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutNLLLen(%p, %" PFLL "d, %d)", ( void * ) pItem, llNumber, iWidth ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
#if HB_VMLONG_MAX >= LONGLONG_MAX
|
|
if( iWidth <= 0 || iWidth >= HB_DEFAULT_WIDTH )
|
|
iWidth = HB_LONG_LENGTH( llNumber );
|
|
|
|
pItem->type = HB_IT_LONG;
|
|
pItem->item.asLong.value = ( HB_MAXINT ) llNumber;
|
|
pItem->item.asLong.length = ( HB_USHORT ) iWidth;
|
|
#else
|
|
pItem->type = HB_IT_DOUBLE;
|
|
pItem->item.asDouble.value = ( double ) llNumber;
|
|
if( iWidth <= 0 || iWidth >= HB_DEFAULT_WIDTH )
|
|
iWidth = HB_LONG_LENGTH( pItem->item.asDouble.value );
|
|
pItem->item.asDouble.length = iWidth;
|
|
pItem->item.asDouble.decimal = 0;
|
|
#endif
|
|
|
|
return pItem;
|
|
}
|
|
#endif
|
|
|
|
PHB_ITEM hb_itemPutNumType( PHB_ITEM pItem, double dNumber, int iDec, int iType1, int iType2 )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutNumType( %p, %lf, %d, %i, %i)", ( void * ) pItem, dNumber, iDec, iType1, iType2 ) );
|
|
|
|
if( iDec || iType1 & HB_IT_DOUBLE || iType2 & HB_IT_DOUBLE )
|
|
{
|
|
return hb_itemPutNDDec( pItem, dNumber, iDec );
|
|
}
|
|
else if( HB_DBL_LIM_INT( dNumber ) )
|
|
{
|
|
return hb_itemPutNI( pItem, ( int ) dNumber );
|
|
}
|
|
else if( HB_DBL_LIM_LONG( dNumber ) )
|
|
{
|
|
#ifdef HB_LONG_LONG_OFF
|
|
return hb_itemPutNL( pItem, ( long ) ( unsigned long ) dNumber );
|
|
#else
|
|
return hb_itemPutNLL( pItem, ( HB_LONGLONG ) dNumber );
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
return hb_itemPutND( pItem, dNumber );
|
|
}
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutPtr( PHB_ITEM pItem, void * pValue )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutPtr(%p, %p)", ( void * ) pItem, pValue ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_POINTER;
|
|
pItem->item.asPointer.value = pValue;
|
|
pItem->item.asPointer.collect =
|
|
pItem->item.asPointer.single = HB_FALSE;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutPtrGC( PHB_ITEM pItem, void * pValue )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutPtrGC(%p, %p)", ( void * ) pItem, pValue ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_POINTER;
|
|
pItem->item.asPointer.value = pValue;
|
|
pItem->item.asPointer.collect = HB_TRUE;
|
|
pItem->item.asPointer.single = HB_FALSE;
|
|
|
|
hb_gcAttach( pValue );
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutPtrRawGC( PHB_ITEM pItem, void * pValue )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutPtrRawGC(%p, %p)", ( void * ) pItem, pValue ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_POINTER;
|
|
pItem->item.asPointer.value = pValue;
|
|
pItem->item.asPointer.collect = HB_TRUE;
|
|
pItem->item.asPointer.single = HB_FALSE;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemPutSymbol( PHB_ITEM pItem, PHB_SYMB pSym )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPutSymbol(%p,%p)", ( void * ) pItem, ( void * ) pSym ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_COMPLEX( pItem ) )
|
|
hb_itemClear( pItem );
|
|
}
|
|
else
|
|
pItem = hb_itemNew( NULL );
|
|
|
|
pItem->type = HB_IT_SYMBOL;
|
|
pItem->item.asSymbol.value = pSym;
|
|
pItem->item.asSymbol.stackstate = NULL;
|
|
pItem->item.asSymbol.paramcnt =
|
|
pItem->item.asSymbol.paramdeclcnt = 0;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
void hb_itemGetNLen( PHB_ITEM pItem, int * piWidth, int * piDecimal )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetNLen(%p, %p, %p)", ( void * ) pItem, ( void * ) piWidth, ( void * ) piDecimal ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_DOUBLE( pItem ) )
|
|
{
|
|
if( piWidth ) *piWidth = ( int ) pItem->item.asDouble.length;
|
|
if( piDecimal ) *piDecimal = ( int ) pItem->item.asDouble.decimal;
|
|
}
|
|
else if( HB_IS_INTEGER( pItem ) )
|
|
{
|
|
if( piWidth ) *piWidth = ( int ) pItem->item.asInteger.length;
|
|
if( piDecimal ) *piDecimal = 0;
|
|
}
|
|
else if( HB_IS_LONG( pItem ) )
|
|
{
|
|
if( piWidth ) *piWidth = ( int ) pItem->item.asLong.length;
|
|
if( piDecimal ) *piDecimal = 0;
|
|
}
|
|
else
|
|
{
|
|
if( piWidth ) *piWidth = 0;
|
|
if( piDecimal ) *piDecimal = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
HB_SIZE hb_itemSize( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemSize(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_STRING( pItem ) )
|
|
return pItem->item.asString.length;
|
|
else if( HB_IS_ARRAY( pItem ) )
|
|
return hb_arrayLen( pItem );
|
|
else if( HB_IS_HASH( pItem ) )
|
|
return hb_hashLen( pItem );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
HB_TYPE hb_itemType( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemType(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
return ( HB_TYPE ) HB_ITEM_TYPE( pItem );
|
|
else
|
|
return HB_IT_NIL;
|
|
}
|
|
|
|
const char * hb_itemTypeStr( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemTypeStr(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
{
|
|
switch( HB_ITEM_TYPE( pItem ) )
|
|
{
|
|
case HB_IT_ARRAY:
|
|
return hb_arrayIsObject( pItem ) ? "O" : "A";
|
|
|
|
case HB_IT_BLOCK:
|
|
return "B";
|
|
|
|
case HB_IT_DATE:
|
|
return "D";
|
|
|
|
case HB_IT_TIMESTAMP:
|
|
return "T";
|
|
|
|
case HB_IT_LOGICAL:
|
|
return "L";
|
|
|
|
case HB_IT_INTEGER:
|
|
case HB_IT_LONG:
|
|
case HB_IT_DOUBLE:
|
|
return "N";
|
|
|
|
case HB_IT_STRING:
|
|
return "C";
|
|
|
|
case HB_IT_MEMO:
|
|
return "M";
|
|
|
|
case HB_IT_HASH:
|
|
return "H";
|
|
|
|
case HB_IT_POINTER:
|
|
return "P";
|
|
|
|
case HB_IT_SYMBOL:
|
|
return "S";
|
|
}
|
|
}
|
|
|
|
return "U";
|
|
}
|
|
|
|
/* Internal API, not standard Clipper */
|
|
|
|
void hb_itemInit( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemInit(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem )
|
|
pItem->type = HB_IT_NIL;
|
|
}
|
|
|
|
void hb_itemClear( PHB_ITEM pItem )
|
|
{
|
|
HB_TYPE type;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemClear(%p)", ( void * ) pItem ) );
|
|
|
|
type = HB_ITEM_TYPERAW( pItem );
|
|
pItem->type = HB_IT_NIL;
|
|
|
|
/* GCLOCK enter */
|
|
if( type & HB_IT_STRING )
|
|
{
|
|
if( pItem->item.asString.allocated )
|
|
hb_xRefFree( pItem->item.asString.value );
|
|
}
|
|
else if( type & HB_IT_ARRAY )
|
|
hb_gcRefFree( pItem->item.asArray.value );
|
|
|
|
else if( type & HB_IT_BLOCK )
|
|
hb_gcRefFree( pItem->item.asBlock.value );
|
|
|
|
else if( type & HB_IT_HASH )
|
|
hb_gcRefFree( pItem->item.asHash.value );
|
|
|
|
else if( type & HB_IT_BYREF )
|
|
{
|
|
if( type & HB_IT_MEMVAR )
|
|
hb_memvarValueDecRef( pItem->item.asMemvar.value );
|
|
|
|
else if( type & HB_IT_ENUM ) /* FOR EACH control variable */
|
|
hb_vmEnumRelease( pItem->item.asEnum.basePtr,
|
|
pItem->item.asEnum.valuePtr );
|
|
|
|
else if( type & HB_IT_EXTREF )
|
|
pItem->item.asExtRef.func->clear( pItem->item.asExtRef.value );
|
|
|
|
else if( pItem->item.asRefer.offset == 0 && pItem->item.asRefer.value >= 0 )
|
|
hb_gcRefFree( pItem->item.asRefer.BasePtr.array );
|
|
}
|
|
else if( type & HB_IT_POINTER )
|
|
{
|
|
if( pItem->item.asPointer.collect )
|
|
hb_gcRefFree( pItem->item.asPointer.value );
|
|
}
|
|
/* GCLOCK leave */
|
|
}
|
|
|
|
/* Internal API, not standard Clipper */
|
|
|
|
void hb_itemCopy( PHB_ITEM pDest, PHB_ITEM pSource )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemCopy(%p, %p)", ( void * ) pDest, ( void * ) pSource ) );
|
|
|
|
if( pDest == pSource )
|
|
hb_errInternal( HB_EI_ITEMBADCOPY, NULL, "hb_itemCopy()", NULL );
|
|
|
|
if( HB_IS_COMPLEX( pDest ) )
|
|
hb_itemClear( pDest );
|
|
|
|
hb_itemRawCpy( pDest, pSource );
|
|
pDest->type &= ~HB_IT_DEFAULT;
|
|
|
|
if( HB_IS_COMPLEX( pSource ) )
|
|
{
|
|
/* GCLOCK enter */
|
|
if( HB_IS_STRING( pSource ) )
|
|
{
|
|
if( pSource->item.asString.allocated )
|
|
hb_xRefInc( pSource->item.asString.value );
|
|
}
|
|
else if( HB_IS_ARRAY( pSource ) )
|
|
hb_gcRefInc( pSource->item.asArray.value );
|
|
|
|
else if( HB_IS_BLOCK( pSource ) )
|
|
hb_gcRefInc( pSource->item.asBlock.value );
|
|
|
|
else if( HB_IS_HASH( pSource ) )
|
|
hb_gcRefInc( pSource->item.asHash.value );
|
|
|
|
else if( HB_IS_BYREF( pSource ) )
|
|
{
|
|
if( HB_IS_MEMVAR( pSource ) )
|
|
hb_memvarValueIncRef( pSource->item.asMemvar.value );
|
|
|
|
else if( HB_IS_ENUM( pSource ) ) /* enumerators cannot be copied */
|
|
pDest->type = HB_IT_NIL;
|
|
|
|
else if( HB_IS_EXTREF( pSource ) )
|
|
pSource->item.asExtRef.func->copy( pDest );
|
|
|
|
else if( pSource->item.asRefer.offset == 0 && pSource->item.asRefer.value >= 0 )
|
|
hb_gcRefInc( pSource->item.asRefer.BasePtr.array );
|
|
}
|
|
else if( HB_IS_POINTER( pSource ) )
|
|
{
|
|
if( pSource->item.asPointer.collect )
|
|
{
|
|
if( pSource->item.asPointer.single )
|
|
pDest->item.asPointer.collect = HB_FALSE;
|
|
else
|
|
hb_gcRefInc( pSource->item.asPointer.value );
|
|
}
|
|
}
|
|
/* GCLOCK leave */
|
|
}
|
|
}
|
|
|
|
/* Internal API, not standard Clipper */
|
|
|
|
void hb_itemCopyToRef( PHB_ITEM pDest, PHB_ITEM pSource )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemCopyToRef(%p, %p)", ( void * ) pDest, ( void * ) pSource ) );
|
|
|
|
if( HB_IS_BYREF( pDest ) )
|
|
{
|
|
pDest = hb_itemUnRefWrite( pDest, pSource );
|
|
if( ! pDest || pDest == pSource )
|
|
/* extended reference or pDest is a reference to pSource
|
|
- do not copy */
|
|
return;
|
|
}
|
|
|
|
if( HB_IS_BYREF( pSource ) )
|
|
{
|
|
if( hb_itemUnRef( pSource ) == pDest )
|
|
/*
|
|
* assign will create cyclic reference
|
|
* pSource and pDest reference to the same item
|
|
* we can simply drop coping
|
|
*/
|
|
return;
|
|
}
|
|
|
|
if( HB_IS_OBJECT( pDest ) &&
|
|
hb_objOperatorCall( HB_OO_OP_ASSIGN, pDest, pDest, pSource, NULL ) )
|
|
return;
|
|
|
|
hb_itemCopy( pDest, pSource );
|
|
}
|
|
|
|
/* Internal API, not standard Clipper */
|
|
|
|
void hb_itemCopyFromRef( PHB_ITEM pDest, PHB_ITEM pSource )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemCopyFromRef(%p, %p)", ( void * ) pDest, ( void * ) pSource ) );
|
|
|
|
if( HB_IS_BYREF( pSource ) )
|
|
{
|
|
pSource = hb_itemUnRef( pSource );
|
|
if( pDest == pSource )
|
|
/* pSource is a reference to pDest - do not copy */
|
|
return;
|
|
}
|
|
|
|
hb_itemCopy( pDest, pSource );
|
|
}
|
|
|
|
/*
|
|
* copy (transfer) the value of item without increasing
|
|
* a reference counters, the pSource item is cleared
|
|
*/
|
|
void hb_itemMove( PHB_ITEM pDest, PHB_ITEM pSource )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemMove(%p, %p)", ( void * ) pDest, ( void * ) pSource ) );
|
|
|
|
if( pDest == pSource )
|
|
hb_errInternal( HB_EI_ITEMBADCOPY, NULL, "hb_itemMove()", NULL );
|
|
|
|
if( HB_IS_COMPLEX( pDest ) )
|
|
hb_itemClear( pDest );
|
|
|
|
/* GCLOCK enter */
|
|
hb_itemRawCpy( pDest, pSource );
|
|
pDest->type &= ~HB_IT_DEFAULT;
|
|
pSource->type = HB_IT_NIL;
|
|
/* GCLOCK leave */
|
|
}
|
|
|
|
/* Internal API, not standard Clipper */
|
|
|
|
void hb_itemMoveRef( PHB_ITEM pDest, PHB_ITEM pSource )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemMoveRef(%p, %p)", ( void * ) pDest, ( void * ) pSource ) );
|
|
|
|
if( HB_IS_BYREF( pSource ) )
|
|
{
|
|
if( hb_itemUnRef( pSource ) == ( HB_IS_BYREF( pDest ) ?
|
|
hb_itemUnRef( pDest ) : pDest ) )
|
|
{
|
|
/*
|
|
* assign will create cyclic reference
|
|
* pSource is a reference to pDest
|
|
* we can simply drop coping
|
|
*/
|
|
hb_itemSetNil( pSource );
|
|
return;
|
|
}
|
|
}
|
|
|
|
if( HB_IS_COMPLEX( pDest ) )
|
|
hb_itemClear( pDest );
|
|
|
|
/* GCLOCK enter */
|
|
hb_itemRawCpy( pDest, pSource );
|
|
pDest->type &= ~HB_IT_DEFAULT;
|
|
pSource->type = HB_IT_NIL;
|
|
/* GCLOCK leave */
|
|
}
|
|
|
|
/* Internal API, not standard Clipper */
|
|
|
|
void hb_itemMoveToRef( PHB_ITEM pDest, PHB_ITEM pSource )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemMoveToRef(%p, %p)", ( void * ) pDest, ( void * ) pSource ) );
|
|
|
|
if( HB_IS_BYREF( pDest ) )
|
|
{
|
|
pDest = hb_itemUnRefWrite( pDest, pSource );
|
|
if( ! pDest || pDest == pSource )
|
|
{
|
|
/* extended reference or pDest is a reference to pSource
|
|
- do not copy */
|
|
hb_itemSetNil( pSource );
|
|
return;
|
|
}
|
|
}
|
|
|
|
if( HB_IS_BYREF( pSource ) )
|
|
{
|
|
if( hb_itemUnRef( pSource ) == pDest )
|
|
{
|
|
/*
|
|
* assign will create cyclic reference
|
|
* pSource and pDest reference to the same item
|
|
* we can simply drop coping
|
|
*/
|
|
hb_itemSetNil( pSource );
|
|
return;
|
|
}
|
|
}
|
|
|
|
if( HB_IS_OBJECT( pDest ) &&
|
|
hb_objOperatorCall( HB_OO_OP_ASSIGN, pDest, pDest, pSource, NULL ) )
|
|
{
|
|
hb_itemSetNil( pSource );
|
|
return;
|
|
}
|
|
|
|
if( HB_IS_COMPLEX( pDest ) )
|
|
hb_itemClear( pDest );
|
|
|
|
/* GCLOCK enter */
|
|
hb_itemRawCpy( pDest, pSource );
|
|
pDest->type &= ~HB_IT_DEFAULT;
|
|
pSource->type = HB_IT_NIL;
|
|
/* GCLOCK leave */
|
|
}
|
|
|
|
void hb_itemMoveFromRef( PHB_ITEM pDest, PHB_ITEM pSource )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemMoveFromRef(%p, %p)", ( void * ) pDest, ( void * ) pSource ) );
|
|
|
|
if( HB_IS_BYREF( pSource ) )
|
|
{
|
|
PHB_ITEM pUnRef = hb_itemUnRef( pSource );
|
|
if( pDest != pUnRef )
|
|
/* pSource is not a reference to pDest - make copy */
|
|
hb_itemCopy( pDest, pUnRef );
|
|
hb_itemClear( pSource );
|
|
}
|
|
else
|
|
hb_itemMove( pDest, pSource );
|
|
}
|
|
|
|
/* Internal API, not standard Clipper */
|
|
|
|
void hb_itemSwap( PHB_ITEM pItem1, PHB_ITEM pItem2 )
|
|
{
|
|
HB_ITEM temp;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemSwap(%p, %p)", ( void * ) pItem1, ( void * ) pItem2 ) );
|
|
|
|
/*
|
|
* It's safe to use this version because our GC cannot be
|
|
* activated inside memcpy()
|
|
*/
|
|
/* GCLOCK enter */
|
|
hb_itemRawCpy( &temp, pItem2 );
|
|
hb_itemRawCpy( pItem2, pItem1 );
|
|
hb_itemRawCpy( pItem1, &temp );
|
|
pItem1->type &= ~HB_IT_DEFAULT;
|
|
pItem2->type &= ~HB_IT_DEFAULT;
|
|
/* GCLOCK leave */
|
|
}
|
|
|
|
/* Internal API, not standard Clipper */
|
|
/* De-references item passed by the reference */
|
|
|
|
PHB_ITEM hb_itemUnRefOnce( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemUnRefOnce(%p)", ( void * ) pItem ) );
|
|
|
|
if( HB_IS_BYREF( pItem ) )
|
|
{
|
|
if( HB_IS_MEMVAR( pItem ) )
|
|
{
|
|
pItem = pItem->item.asMemvar.value;
|
|
}
|
|
else if( HB_IS_ENUM( pItem ) ) /* FOR EACH control variable */
|
|
{
|
|
/* enumerator variable */
|
|
if( pItem->item.asEnum.valuePtr )
|
|
return pItem->item.asEnum.valuePtr;
|
|
else
|
|
{
|
|
PHB_ITEM pBase = HB_IS_BYREF( pItem->item.asEnum.basePtr ) ?
|
|
hb_itemUnRef( pItem->item.asEnum.basePtr ) :
|
|
pItem->item.asEnum.basePtr;
|
|
if( HB_IS_ARRAY( pBase ) )
|
|
{
|
|
pBase = hb_arrayGetItemPtr( pBase, pItem->item.asEnum.offset );
|
|
if( pBase )
|
|
return pBase;
|
|
}
|
|
else if( HB_IS_HASH( pBase ) )
|
|
{
|
|
pBase = hb_hashGetValueAt( pBase, pItem->item.asEnum.offset );
|
|
if( pBase )
|
|
return pBase;
|
|
}
|
|
else if( HB_IS_STRING( pBase ) )
|
|
{
|
|
if( pItem->item.asEnum.offset > 0 &&
|
|
( HB_SIZE ) pItem->item.asEnum.offset <= pBase->item.asString.length )
|
|
{
|
|
pItem->item.asEnum.valuePtr = hb_itemPutCL( NULL,
|
|
pBase->item.asString.value + pItem->item.asEnum.offset - 1, 1 );
|
|
return pItem->item.asEnum.valuePtr;
|
|
}
|
|
}
|
|
|
|
/* put it here to avoid recursive RT error generation */
|
|
pItem->item.asEnum.valuePtr = hb_itemNew( NULL );
|
|
|
|
if( hb_vmRequestQuery() == 0 )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
hb_itemPutNS( hb_stackAllocItem(), pItem->item.asEnum.offset );
|
|
hb_errRT_BASE( EG_BOUND, 1132, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ),
|
|
2, pItem->item.asEnum.basePtr, hb_stackItemFromTop( -1 ) );
|
|
hb_stackPop();
|
|
}
|
|
return pItem->item.asEnum.valuePtr;
|
|
}
|
|
}
|
|
else if( HB_IS_EXTREF( pItem ) )
|
|
{
|
|
pItem = pItem->item.asExtRef.func->read( pItem );
|
|
}
|
|
else
|
|
{
|
|
if( pItem->item.asRefer.value >= 0 )
|
|
{
|
|
if( pItem->item.asRefer.offset == 0 )
|
|
{
|
|
/* a reference to a static variable or array item */
|
|
if( ( HB_SIZE ) pItem->item.asRefer.value <
|
|
pItem->item.asRefer.BasePtr.array->nLen )
|
|
{
|
|
pItem = pItem->item.asRefer.BasePtr.array->pItems +
|
|
pItem->item.asRefer.value;
|
|
}
|
|
else if( hb_vmRequestQuery() == 0 )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
hb_arrayPushBase( pItem->item.asRefer.BasePtr.array );
|
|
hb_itemPutNS( hb_stackAllocItem(), pItem->item.asRefer.value + 1 );
|
|
hb_errRT_BASE( EG_BOUND, 1132, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ),
|
|
2, hb_stackItemFromTop( -2 ), hb_stackItemFromTop( -1 ) );
|
|
hb_stackPop();
|
|
hb_stackPop();
|
|
|
|
/* check it again - user error handler can resize the array */
|
|
if( ( HB_SIZE ) pItem->item.asRefer.value <
|
|
pItem->item.asRefer.BasePtr.array->nLen )
|
|
{
|
|
pItem = pItem->item.asRefer.BasePtr.array->pItems +
|
|
pItem->item.asRefer.value;
|
|
}
|
|
else
|
|
/* It's safe to clear the item - if we are here then
|
|
the reference chain to this item does not start in
|
|
one of the pItem->item.asRefer.BasePtr.array items
|
|
or more then one reference to this array exists
|
|
so it will not be freed [druzus] */
|
|
hb_itemClear( pItem );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* a reference to a local variable */
|
|
PHB_ITEM * pLocal;
|
|
|
|
pLocal = *( pItem->item.asRefer.BasePtr.itemsbasePtr ) +
|
|
pItem->item.asRefer.offset + pItem->item.asRefer.value;
|
|
pItem = *pLocal;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* local variable referenced in a codeblock */
|
|
pItem = hb_codeblockGetRef( pItem->item.asRefer.BasePtr.block,
|
|
( int ) pItem->item.asRefer.value );
|
|
}
|
|
}
|
|
}
|
|
|
|
return pItem;
|
|
}
|
|
|
|
/* Internal API, not standard Clipper */
|
|
/* De-references item passed by the reference */
|
|
|
|
PHB_ITEM hb_itemUnRef( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemUnRef(%p)", ( void * ) pItem ) );
|
|
|
|
do
|
|
{
|
|
pItem = hb_itemUnRefOnce( pItem );
|
|
}
|
|
while( HB_IS_BYREF( pItem ) );
|
|
|
|
return pItem;
|
|
}
|
|
|
|
/* Unreference passed variable for writing
|
|
* Do not unreference string enumerators
|
|
*/
|
|
PHB_ITEM hb_itemUnRefWrite( PHB_ITEM pItem, PHB_ITEM pSource )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemUnRefWrite(%p,%p)", ( void * ) pItem, ( void * ) pSource ) );
|
|
|
|
if( HB_IS_EXTREF( pItem ) )
|
|
{
|
|
pItem = pItem->item.asExtRef.func->write( pItem, pSource );
|
|
}
|
|
else if( HB_IS_STRING( pSource ) &&
|
|
pSource->item.asString.length == 1 )
|
|
{
|
|
do
|
|
{
|
|
if( HB_IS_ENUM( pItem ) && HB_IS_BYREF( pItem->item.asEnum.basePtr ) &&
|
|
pItem->item.asEnum.offset >= 1 )
|
|
{
|
|
PHB_ITEM pBase = hb_itemUnRef( pItem->item.asEnum.basePtr );
|
|
if( HB_IS_STRING( pBase ) &&
|
|
( HB_SIZE ) pItem->item.asEnum.offset <= pBase->item.asString.length )
|
|
{
|
|
hb_itemUnShareString( pBase );
|
|
pBase->item.asString.value[ pItem->item.asEnum.offset - 1 ] =
|
|
pSource->item.asString.value[ 0 ];
|
|
return pItem->item.asEnum.valuePtr;
|
|
}
|
|
}
|
|
pItem = hb_itemUnRefOnce( pItem );
|
|
}
|
|
while( HB_IS_BYREF( pItem ) );
|
|
}
|
|
else
|
|
pItem = hb_itemUnRef( pItem );
|
|
|
|
return pItem;
|
|
}
|
|
|
|
/* Unreference passed variable
|
|
* Do not unreference the last reference stored
|
|
*/
|
|
PHB_ITEM hb_itemUnRefRefer( PHB_ITEM pItem )
|
|
{
|
|
PHB_ITEM pLast;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemUnRefRefer(%p)", ( void * ) pItem ) );
|
|
|
|
do
|
|
{
|
|
pLast = pItem;
|
|
pItem = hb_itemUnRefOnce( pItem );
|
|
}
|
|
while( HB_IS_BYREF( pItem ) );
|
|
|
|
return pLast;
|
|
}
|
|
|
|
/* Internal API, not standard Clipper */
|
|
/* Resize string buffer of given string item */
|
|
|
|
PHB_ITEM hb_itemReSizeString( PHB_ITEM pItem, HB_SIZE nSize )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemReSizeString(%p,%" HB_PFS "u)", ( void * ) pItem, nSize ) );
|
|
|
|
if( pItem->item.asString.allocated == 0 )
|
|
{
|
|
char * szText = ( char * ) hb_xgrab( nSize + 1 );
|
|
hb_xmemcpy( szText, pItem->item.asString.value,
|
|
pItem->item.asString.length );
|
|
szText[ nSize ] = '\0';
|
|
pItem->item.asString.value = szText;
|
|
pItem->item.asString.length = nSize;
|
|
pItem->item.asString.allocated = nSize + 1;
|
|
}
|
|
else
|
|
{
|
|
HB_SIZE nAlloc = nSize + 1 +
|
|
( pItem->item.asString.allocated <= nSize ? nSize : 0 );
|
|
pItem->item.asString.value = ( char * )
|
|
hb_xRefResize( pItem->item.asString.value,
|
|
pItem->item.asString.length,
|
|
nAlloc, &pItem->item.asString.allocated );
|
|
pItem->item.asString.length = nSize;
|
|
pItem->item.asString.value[ nSize ] = '\0';
|
|
}
|
|
pItem->type &= ~HB_IT_DEFAULT;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
/* Internal API, not standard Clipper */
|
|
/* UnShare string buffer of given string item */
|
|
|
|
PHB_ITEM hb_itemUnShareString( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemUnShareString(%p)", ( void * ) pItem ) );
|
|
|
|
if( pItem->item.asString.allocated == 0 ||
|
|
hb_xRefCount( pItem->item.asString.value ) > 1 )
|
|
{
|
|
HB_SIZE nLen = pItem->item.asString.length + 1;
|
|
char * szText = ( char * ) hb_xmemcpy( hb_xgrab( nLen ),
|
|
pItem->item.asString.value, nLen );
|
|
if( pItem->item.asString.allocated )
|
|
{
|
|
/* GCLOCK enter */
|
|
hb_xRefFree( pItem->item.asString.value );
|
|
/* GCLOCK leave */
|
|
}
|
|
pItem->item.asString.value = szText;
|
|
pItem->item.asString.allocated = nLen;
|
|
}
|
|
pItem->type &= ~HB_IT_DEFAULT;
|
|
|
|
return pItem;
|
|
}
|
|
|
|
PHB_ITEM hb_itemUnShare( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemUnShare(%p)", ( void * ) pItem ) );
|
|
|
|
if( HB_IS_BYREF( pItem ) )
|
|
pItem = hb_itemUnRef( pItem );
|
|
|
|
if( HB_IS_STRING( pItem ) )
|
|
return hb_itemUnShareString( pItem );
|
|
else
|
|
return pItem;
|
|
}
|
|
|
|
HB_BOOL hb_itemGetWriteCL( PHB_ITEM pItem, char ** pszValue, HB_SIZE * pnLen )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetWriteCL(%p,%p,%p)", ( void * ) pItem, ( void * ) pszValue, ( void * ) pnLen ) );
|
|
|
|
if( pItem )
|
|
{
|
|
if( HB_IS_BYREF( pItem ) )
|
|
pItem = hb_itemUnRef( pItem );
|
|
|
|
if( HB_IS_STRING( pItem ) )
|
|
{
|
|
hb_itemUnShareString( pItem );
|
|
*pnLen = pItem->item.asString.length;
|
|
*pszValue = pItem->item.asString.value;
|
|
return HB_TRUE;
|
|
}
|
|
}
|
|
return HB_FALSE;
|
|
}
|
|
|
|
/* Internal API, not standard Clipper */
|
|
/* clone the given item */
|
|
PHB_ITEM hb_itemClone( PHB_ITEM pItem )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemClone(%p)", ( void * ) pItem ) );
|
|
|
|
if( HB_IS_ARRAY( pItem ) )
|
|
{
|
|
if( HB_IS_OBJECT( pItem ) )
|
|
return hb_objCloneTo( hb_itemNew( NULL ), pItem );
|
|
else
|
|
return hb_arrayClone( pItem );
|
|
}
|
|
else if( HB_IS_HASH( pItem ) )
|
|
return hb_hashClone( pItem );
|
|
else
|
|
return hb_itemNew( pItem );
|
|
}
|
|
|
|
void hb_itemCloneTo( PHB_ITEM pDest, PHB_ITEM pSource )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemCloneTo(%p,%p)", ( void * ) pDest, ( void * ) pSource ) );
|
|
|
|
if( HB_IS_ARRAY( pSource ) )
|
|
{
|
|
if( HB_IS_OBJECT( pSource ) )
|
|
hb_objCloneTo( pDest, pSource );
|
|
else
|
|
hb_arrayCloneTo( pDest, pSource );
|
|
}
|
|
else if( HB_IS_HASH( pSource ) )
|
|
hb_hashCloneTo( pDest, pSource );
|
|
else
|
|
hb_itemCopy( pDest, pSource );
|
|
}
|
|
|
|
|
|
/* Check whether two items are exactly equal */
|
|
HB_BOOL hb_itemEqual( PHB_ITEM pItem1, PHB_ITEM pItem2 )
|
|
{
|
|
HB_BOOL fResult = HB_FALSE;
|
|
|
|
if( HB_IS_NUMERIC( pItem1 ) )
|
|
{
|
|
if( HB_IS_NUMINT( pItem1 ) && HB_IS_NUMINT( pItem2 ) )
|
|
fResult = HB_ITEM_GET_NUMINTRAW( pItem1 ) == HB_ITEM_GET_NUMINTRAW( pItem2 );
|
|
else
|
|
fResult = HB_IS_NUMERIC( pItem2 ) &&
|
|
hb_itemGetND( pItem1 ) == hb_itemGetND( pItem2 );
|
|
}
|
|
else if( HB_IS_STRING( pItem1 ) )
|
|
fResult = HB_IS_STRING( pItem2 ) &&
|
|
pItem1->item.asString.length == pItem2->item.asString.length &&
|
|
memcmp( pItem1->item.asString.value,
|
|
pItem2->item.asString.value,
|
|
pItem1->item.asString.length ) == 0;
|
|
|
|
else if( HB_IS_NIL( pItem1 ) )
|
|
fResult = HB_IS_NIL( pItem2 );
|
|
|
|
else if( HB_IS_DATETIME( pItem1 ) )
|
|
fResult = HB_IS_DATETIME( pItem2 ) &&
|
|
pItem1->item.asDateTime.julian == pItem2->item.asDateTime.julian &&
|
|
pItem1->item.asDateTime.time == pItem2->item.asDateTime.time;
|
|
|
|
else if( HB_IS_LOGICAL( pItem1 ) )
|
|
fResult = HB_IS_LOGICAL( pItem2 ) && ( pItem1->item.asLogical.value ?
|
|
pItem2->item.asLogical.value : ! pItem2->item.asLogical.value );
|
|
|
|
else if( HB_IS_ARRAY( pItem1 ) )
|
|
fResult = HB_IS_ARRAY( pItem2 ) &&
|
|
pItem1->item.asArray.value == pItem2->item.asArray.value;
|
|
|
|
else if( HB_IS_HASH( pItem1 ) )
|
|
fResult = HB_IS_HASH( pItem2 ) &&
|
|
pItem1->item.asHash.value == pItem2->item.asHash.value;
|
|
|
|
else if( HB_IS_POINTER( pItem1 ) )
|
|
fResult = HB_IS_POINTER( pItem2 ) &&
|
|
pItem1->item.asPointer.value == pItem2->item.asPointer.value;
|
|
|
|
else if( HB_IS_BLOCK( pItem1 ) )
|
|
fResult = HB_IS_BLOCK( pItem2 ) &&
|
|
pItem1->item.asBlock.value == pItem2->item.asBlock.value;
|
|
|
|
else if( HB_IS_SYMBOL( pItem1 ) )
|
|
fResult = HB_IS_SYMBOL( pItem2 ) &&
|
|
( pItem1->item.asSymbol.value == pItem2->item.asSymbol.value ||
|
|
( pItem1->item.asSymbol.value->pDynSym != NULL &&
|
|
pItem1->item.asSymbol.value->pDynSym ==
|
|
pItem2->item.asSymbol.value->pDynSym ) );
|
|
|
|
return fResult;
|
|
}
|
|
|
|
/* For compatible types compare pItem1 with pItem2 setting piResult
|
|
to -1, 0 or 1 if pItem1 is <, == or > then pItem2 and return true
|
|
otherwise return false.
|
|
*/
|
|
HB_BOOL hb_itemCompare( PHB_ITEM pItem1, PHB_ITEM pItem2, HB_BOOL bForceExact, int * piResult )
|
|
{
|
|
HB_BOOL fResult = HB_FALSE;
|
|
|
|
if( HB_IS_NUMERIC( pItem1 ) )
|
|
{
|
|
if( HB_IS_NUMINT( pItem1 ) && HB_IS_NUMINT( pItem2 ) )
|
|
{
|
|
HB_MAXINT n1 = HB_ITEM_GET_NUMINTRAW( pItem1 ),
|
|
n2 = HB_ITEM_GET_NUMINTRAW( pItem2 );
|
|
*piResult = n1 < n2 ? -1 : ( n1 > n2 ? 1 : 0 );
|
|
fResult = HB_TRUE;
|
|
}
|
|
else if( HB_IS_NUMERIC( pItem2 ) )
|
|
{
|
|
double d1 = hb_itemGetND( pItem1 ),
|
|
d2 = hb_itemGetND( pItem2 );
|
|
*piResult = d1 < d2 ? -1 : ( d1 > d2 ? 1 : 0 );
|
|
fResult = HB_TRUE;
|
|
}
|
|
}
|
|
else if( HB_IS_STRING( pItem1 ) )
|
|
{
|
|
if( HB_IS_STRING( pItem2 ) )
|
|
{
|
|
*piResult = hb_itemStrCmp( pItem1, pItem2, bForceExact );
|
|
fResult = HB_TRUE;
|
|
}
|
|
}
|
|
else if( HB_IS_NIL( pItem1 ) )
|
|
{
|
|
if( HB_IS_NIL( pItem2 ) )
|
|
{
|
|
*piResult = 0;
|
|
fResult = HB_TRUE;
|
|
}
|
|
}
|
|
else if( HB_IS_DATETIME( pItem1 ) )
|
|
{
|
|
if( HB_IS_DATETIME( pItem2 ) )
|
|
{
|
|
*piResult = pItem1->item.asDateTime.julian < pItem2->item.asDateTime.julian ? -1 :
|
|
( pItem1->item.asDateTime.julian > pItem2->item.asDateTime.julian ? 1 :
|
|
( pItem1->item.asDateTime.time < pItem2->item.asDateTime.time ? -1 :
|
|
( pItem1->item.asDateTime.time > pItem2->item.asDateTime.time ? 1 : 0 ) ) );
|
|
fResult = HB_TRUE;
|
|
}
|
|
}
|
|
else if( HB_IS_LOGICAL( pItem1 ) )
|
|
{
|
|
if( HB_IS_LOGICAL( pItem2 ) )
|
|
{
|
|
*piResult = pItem1->item.asLogical.value ?
|
|
( pItem2->item.asLogical.value ? 0 : 1 ) :
|
|
( pItem2->item.asLogical.value ? -1 : 0 );
|
|
fResult = HB_TRUE;
|
|
}
|
|
}
|
|
else if( HB_IS_ARRAY( pItem1 ) )
|
|
{
|
|
if( HB_IS_ARRAY( pItem2 ) )
|
|
{
|
|
*piResult = pItem1->item.asArray.value < pItem2->item.asArray.value ? -1 :
|
|
( pItem1->item.asArray.value > pItem2->item.asArray.value ? 1 : 0 );
|
|
fResult = HB_TRUE;
|
|
}
|
|
}
|
|
else if( HB_IS_HASH( pItem1 ) )
|
|
{
|
|
if( HB_IS_HASH( pItem2 ) )
|
|
{
|
|
*piResult = pItem1->item.asHash.value < pItem2->item.asHash.value ? -1 :
|
|
( pItem1->item.asHash.value > pItem2->item.asHash.value ? 1 : 0 );
|
|
fResult = HB_TRUE;
|
|
}
|
|
}
|
|
else if( HB_IS_POINTER( pItem1 ) )
|
|
{
|
|
if( HB_IS_POINTER( pItem2 ) )
|
|
{
|
|
*piResult = pItem1->item.asPointer.value < pItem2->item.asPointer.value ? -1 :
|
|
( pItem1->item.asPointer.value > pItem2->item.asPointer.value ? 1 : 0 );
|
|
fResult = HB_TRUE;
|
|
}
|
|
}
|
|
else if( HB_IS_BLOCK( pItem1 ) )
|
|
{
|
|
if( HB_IS_BLOCK( pItem2 ) )
|
|
{
|
|
*piResult = pItem1->item.asBlock.value < pItem2->item.asBlock.value ? -1 :
|
|
( pItem1->item.asBlock.value > pItem2->item.asBlock.value ? 1 : 0 );
|
|
fResult = HB_TRUE;
|
|
}
|
|
}
|
|
else if( HB_IS_SYMBOL( pItem1 ) )
|
|
{
|
|
if( HB_IS_SYMBOL( pItem2 ) )
|
|
{
|
|
*piResult = ( pItem1->item.asSymbol.value == pItem2->item.asSymbol.value ||
|
|
( pItem1->item.asSymbol.value->pDynSym != NULL &&
|
|
pItem1->item.asSymbol.value->pDynSym ==
|
|
pItem2->item.asSymbol.value->pDynSym ) ) ? 0 :
|
|
( pItem1->item.asSymbol.value < pItem2->item.asSymbol.value ? -1 : 1 );
|
|
fResult = HB_TRUE;
|
|
}
|
|
}
|
|
return fResult;
|
|
}
|
|
|
|
/* Internal API, not standard Clipper */
|
|
|
|
/* Check whether two strings are equal (0), smaller (-1), or greater (1) */
|
|
int hb_itemStrCmp( PHB_ITEM pFirst, PHB_ITEM pSecond, HB_BOOL bForceExact )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
const char * szFirst;
|
|
const char * szSecond;
|
|
HB_SIZE nLenFirst;
|
|
HB_SIZE nLenSecond;
|
|
HB_SIZE nMinLen;
|
|
int iRet = 0; /* Current status */
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemStrCmp(%p, %p, %d)", ( void * ) pFirst, ( void * ) pSecond, ( int ) bForceExact ) );
|
|
|
|
szFirst = pFirst->item.asString.value;
|
|
szSecond = pSecond->item.asString.value;
|
|
nLenFirst = pFirst->item.asString.length;
|
|
nLenSecond = pSecond->item.asString.length;
|
|
|
|
if( szFirst == szSecond && nLenFirst == nLenSecond )
|
|
return 0;
|
|
|
|
|
|
if( ! bForceExact && hb_stackSetStruct()->HB_SET_EXACT )
|
|
{
|
|
/* SET EXACT ON and not using == */
|
|
/* Don't include trailing spaces */
|
|
while( nLenFirst > nLenSecond && szFirst[ nLenFirst - 1 ] == ' ' )
|
|
nLenFirst--;
|
|
while( nLenSecond > nLenFirst && szSecond[ nLenSecond - 1 ] == ' ' )
|
|
nLenSecond--;
|
|
bForceExact = HB_TRUE;
|
|
}
|
|
|
|
nMinLen = nLenFirst < nLenSecond ? nLenFirst : nLenSecond;
|
|
|
|
/* Both strings not empty */
|
|
if( nMinLen )
|
|
{
|
|
PHB_CODEPAGE cdp = hb_vmCDP();
|
|
if( cdp && ! HB_CDP_ISBINSORT( cdp ) )
|
|
iRet = hb_cdpcmp( szFirst, nLenFirst, szSecond, nLenSecond,
|
|
cdp, bForceExact );
|
|
else
|
|
{
|
|
do
|
|
{
|
|
if( *szFirst != *szSecond )
|
|
{
|
|
iRet = ( ( HB_UCHAR ) *szFirst < ( HB_UCHAR ) *szSecond ) ? -1 : 1;
|
|
break;
|
|
}
|
|
szFirst++;
|
|
szSecond++;
|
|
}
|
|
while( --nMinLen );
|
|
|
|
/* If equal and length is different ! */
|
|
if( ! iRet && nLenFirst != nLenSecond )
|
|
{
|
|
/* Force an exact comparison? */
|
|
if( bForceExact || nLenSecond > nLenFirst )
|
|
iRet = ( nLenFirst < nLenSecond ) ? -1 : 1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Both empty ? */
|
|
if( nLenFirst != nLenSecond )
|
|
{
|
|
if( bForceExact )
|
|
iRet = ( nLenFirst < nLenSecond ) ? -1 : 1;
|
|
else
|
|
iRet = ( nLenSecond == 0 ) ? 0 : -1;
|
|
}
|
|
else
|
|
/* Both empty => Equal ! */
|
|
iRet = 0;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
/* Check whether two strings are equal (0), smaller (-1), or greater (1), ignore case */
|
|
int hb_itemStrICmp( PHB_ITEM pFirst, PHB_ITEM pSecond, HB_BOOL bForceExact )
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
const char * szFirst;
|
|
const char * szSecond;
|
|
HB_SIZE nLenFirst;
|
|
HB_SIZE nLenSecond;
|
|
HB_SIZE nMinLen;
|
|
int iRet = 0; /* Current status */
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemStrICmp(%p, %p, %d)", ( void * ) pFirst, ( void * ) pSecond, ( int ) bForceExact ) );
|
|
|
|
szFirst = pFirst->item.asString.value;
|
|
szSecond = pSecond->item.asString.value;
|
|
nLenFirst = pFirst->item.asString.length;
|
|
nLenSecond = pSecond->item.asString.length;
|
|
|
|
if( ! bForceExact && hb_stackSetStruct()->HB_SET_EXACT )
|
|
{
|
|
/* SET EXACT ON and not using == */
|
|
/* Don't include trailing spaces */
|
|
while( nLenFirst > nLenSecond && szFirst[ nLenFirst - 1 ] == ' ' )
|
|
nLenFirst--;
|
|
while( nLenSecond > nLenFirst && szSecond[ nLenSecond - 1 ] == ' ' )
|
|
nLenSecond--;
|
|
bForceExact = HB_TRUE;
|
|
}
|
|
|
|
nMinLen = nLenFirst < nLenSecond ? nLenFirst : nLenSecond;
|
|
|
|
/* Both strings not empty */
|
|
if( nMinLen )
|
|
{
|
|
PHB_CODEPAGE cdp = hb_vmCDP();
|
|
if( cdp && ! HB_CDP_ISBINSORT( cdp ) )
|
|
iRet = hb_cdpicmp( szFirst, nLenFirst, szSecond, nLenSecond,
|
|
cdp, bForceExact );
|
|
else
|
|
{
|
|
do
|
|
{
|
|
int i1 = HB_TOUPPER( ( HB_UCHAR ) *szFirst );
|
|
int i2 = HB_TOUPPER( ( HB_UCHAR ) *szSecond );
|
|
if( i1 != i2 )
|
|
{
|
|
iRet = ( i1 < i2 ) ? -1 : 1;
|
|
break;
|
|
}
|
|
szFirst++;
|
|
szSecond++;
|
|
}
|
|
while( --nMinLen );
|
|
|
|
/* If equal and length is different ! */
|
|
if( ! iRet && nLenFirst != nLenSecond )
|
|
{
|
|
/* Force an exact comparison? */
|
|
if( bForceExact || nLenSecond > nLenFirst )
|
|
iRet = ( nLenFirst < nLenSecond ) ? -1 : 1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Both empty ? */
|
|
if( nLenFirst != nLenSecond )
|
|
{
|
|
if( bForceExact )
|
|
iRet = ( nLenFirst < nLenSecond ) ? -1 : 1;
|
|
else
|
|
iRet = ( nLenSecond == 0 ) ? 0 : -1;
|
|
}
|
|
else
|
|
/* Both empty => Equal ! */
|
|
iRet = 0;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
/* converts a numeric to a string with optional width & precision. */
|
|
|
|
HB_BOOL hb_itemStrBuf( char * szResult, PHB_ITEM pNumber, int iSize, int iDec )
|
|
{
|
|
int iPos, iDot;
|
|
HB_BOOL fNeg;
|
|
|
|
if( iDec < 0 )
|
|
iDec = 0;
|
|
|
|
if( iDec > 0 )
|
|
iPos = iDot = iSize - iDec - 1;
|
|
else
|
|
{
|
|
iPos = iSize;
|
|
iDot = 0;
|
|
}
|
|
|
|
if( HB_IS_DOUBLE( pNumber ) )
|
|
{
|
|
double dNumber = hb_itemGetND( pNumber );
|
|
|
|
if( ! hb_isfinite( dNumber ) )
|
|
{
|
|
/* Numeric overflow */
|
|
iPos = -1;
|
|
}
|
|
else
|
|
{
|
|
double dInt, dFract, dDig, doBase = 10.0;
|
|
int iPrec, iFirst = -1;
|
|
|
|
#if 0
|
|
dNumber = hb_numRound( dNumber, iDec );
|
|
#endif
|
|
|
|
#ifdef HB_NUM_PRECISION
|
|
iPrec = HB_NUM_PRECISION;
|
|
#else
|
|
iPrec = 16;
|
|
#endif
|
|
|
|
if( dNumber < 0 )
|
|
{
|
|
fNeg = HB_TRUE;
|
|
dFract = modf( -dNumber, &dInt );
|
|
}
|
|
else
|
|
{
|
|
fNeg = HB_FALSE;
|
|
dFract = modf( dNumber, &dInt );
|
|
}
|
|
|
|
while( iPos-- > 0 )
|
|
{
|
|
dDig = modf( dInt / doBase + 0.01, &dInt ) * doBase;
|
|
szResult[ iPos ] = '0' + ( char ) ( dDig + 0.01 );
|
|
if( szResult[ iPos ] != '0' )
|
|
iFirst = iPos;
|
|
if( dInt < 1 )
|
|
break;
|
|
}
|
|
|
|
if( iPos > 0 )
|
|
memset( szResult, ' ', iPos );
|
|
|
|
if( iDec > 0 && iPos >= 0 )
|
|
{
|
|
for( iPos = iDot + 1; iPos < iSize; iPos++ )
|
|
{
|
|
dFract = modf( dFract * doBase, &dDig );
|
|
szResult[ iPos ] = '0' + ( char ) ( dDig + 0.01 );
|
|
if( iFirst < 0 )
|
|
{
|
|
if( szResult[ iPos ] != '0' )
|
|
iFirst = iPos - 1;
|
|
}
|
|
else if( iPos - iFirst >= iPrec )
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* now try to round the results and set 0 in places over defined
|
|
precision, the same is done by Clipper */
|
|
if( iPos >= 0 )
|
|
{
|
|
int iZer, iLast;
|
|
|
|
if( iFirst < 0 )
|
|
iZer = 0;
|
|
else
|
|
iZer = iSize - iFirst - iPrec - ( iDec > 0 ? 1 : 0 );
|
|
|
|
dFract = modf( dFract * doBase, &dDig );
|
|
iLast = ( int ) ( dDig + 0.01 );
|
|
|
|
/* hack for x.xxxx4999999999, f.e. 8.995 ~FL 8.994999999999999218.. */
|
|
if( iLast == 4 && iZer < 0 )
|
|
{
|
|
for( iPos = -iZer; iPos > 0; --iPos )
|
|
{
|
|
dFract = modf( dFract * doBase, &dDig );
|
|
if( dDig + 0.01 < 9 && ( iPos != 1 || dDig < 2 ) )
|
|
break;
|
|
}
|
|
if( iPos == 0 )
|
|
iLast = 5;
|
|
}
|
|
iLast = iLast >= 5 ? 1 : 0;
|
|
|
|
iPos = iSize;
|
|
while( iPos-- > 0 )
|
|
{
|
|
if( iDec == 0 || iPos != iDot )
|
|
{
|
|
if( iZer > 0 )
|
|
{
|
|
if( iDec == 0 || iPos <= iDot + 1 )
|
|
iLast = szResult[ iPos ] >= '5' ? 1 : 0;
|
|
|
|
szResult[ iPos ] = '0';
|
|
--iZer;
|
|
}
|
|
else if( iLast > 0 )
|
|
{
|
|
if( szResult[ iPos ] == '9' )
|
|
szResult[ iPos ] = '0';
|
|
else
|
|
{
|
|
if( szResult[ iPos ] < '0' ) /* '-' or ' ' */
|
|
{
|
|
szResult[ iPos ] = '1';
|
|
iFirst = iPos;
|
|
}
|
|
else
|
|
{
|
|
szResult[ iPos ]++;
|
|
if( iFirst < 0 )
|
|
iFirst = iPos;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( fNeg && iFirst >= 0 && iPos >= 0 )
|
|
{
|
|
iPos = ( iDot > 0 && iFirst >= iDot ) ? iDot - 2 : iFirst - 1;
|
|
if( iPos >= 0 )
|
|
szResult[ iPos ] = '-';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
HB_MAXINT nNumber;
|
|
|
|
if( HB_IS_INTEGER( pNumber ) )
|
|
nNumber = pNumber->item.asInteger.value;
|
|
|
|
else if( HB_IS_LONG( pNumber ) )
|
|
nNumber = pNumber->item.asLong.value;
|
|
|
|
else
|
|
{
|
|
nNumber = 0;
|
|
iPos = -1;
|
|
}
|
|
|
|
fNeg = ( nNumber < 0 );
|
|
while( iPos-- > 0 )
|
|
{
|
|
szResult[ iPos ] = '0' + ( char ) ( fNeg ? -( nNumber % 10 ) : ( nNumber % 10 ) );
|
|
nNumber /= 10;
|
|
if( nNumber == 0 )
|
|
break;
|
|
}
|
|
if( fNeg && iPos-- > 0 )
|
|
szResult[ iPos ] = '-';
|
|
|
|
if( iPos > 0 )
|
|
memset( szResult, ' ', iPos );
|
|
|
|
if( iDec > 0 && iPos >= 0 )
|
|
memset( &szResult[ iSize - iDec ], '0', iDec );
|
|
}
|
|
|
|
szResult[ iSize ] = '\0';
|
|
/* Set to asterisks in case of overflow */
|
|
if( iPos < 0 )
|
|
{
|
|
memset( szResult, '*', iSize );
|
|
return HB_FALSE;
|
|
}
|
|
else if( iDot > 0 )
|
|
szResult[ iDot ] = '.';
|
|
|
|
return HB_TRUE;
|
|
}
|
|
|
|
/* converts a numeric to a string with optional width & precision.
|
|
This function should be used by any function that wants to format numeric
|
|
data for displaying, printing, or putting in a database.
|
|
|
|
Note: The caller is responsible for calling hb_xfree() to free the results
|
|
buffer, but ONLY if the return value is not a NULL pointer! (If a NULL
|
|
pointer is returned, then there was a conversion error.)
|
|
*/
|
|
char * hb_itemStr( PHB_ITEM pNumber, PHB_ITEM pWidth, PHB_ITEM pDec )
|
|
{
|
|
char * szResult = NULL;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemStr(%p, %p, %p)", ( void * ) pNumber, ( void * ) pWidth, ( void * ) pDec ) );
|
|
|
|
if( pNumber )
|
|
{
|
|
/* Default to the width and number of decimals specified by the item,
|
|
with a limit of 90 integer places, plus one space for the sign. */
|
|
int iWidth, iDec, iSize;
|
|
|
|
hb_itemGetNLen( pNumber, &iWidth, &iDec );
|
|
|
|
if( iWidth > 90 )
|
|
iWidth = 90;
|
|
|
|
if( pWidth && HB_IS_NUMERIC( pWidth ) )
|
|
{
|
|
/* If the width parameter is specified, override the default value
|
|
and set the number of decimals to zero */
|
|
iWidth = hb_itemGetNI( pWidth );
|
|
|
|
if( iWidth < 1 )
|
|
iWidth = 10; /* If 0 or negative, use default */
|
|
iDec = 0;
|
|
}
|
|
|
|
/* Clipper ignores decimal places when iWidth is 1 */
|
|
if( iWidth > 1 && pDec && HB_IS_NUMERIC( pDec ) )
|
|
{
|
|
/* This function does not include the decimal places in the width,
|
|
so the width must be adjusted downwards, if the decimal places
|
|
parameter is greater than 0 */
|
|
iDec = hb_itemGetNI( pDec );
|
|
|
|
if( iDec <= 0 )
|
|
iDec = 0;
|
|
else if( pWidth )
|
|
iWidth -= ( iDec + 1 );
|
|
}
|
|
|
|
iSize = ( iDec > 0 ? iWidth + 1 + iDec : iWidth );
|
|
|
|
if( iSize > 0 )
|
|
{
|
|
szResult = ( char * ) hb_xgrab( iSize + 1 );
|
|
hb_itemStrBuf( szResult, pNumber, iSize, iDec );
|
|
}
|
|
}
|
|
|
|
return szResult;
|
|
}
|
|
|
|
/* NOTE: The caller must free the pointer if the bFreeReq param gets set to
|
|
HB_TRUE, this trick is required to stay thread safe, while minimize
|
|
memory allocation and buffer copying.
|
|
As a side effect the caller should never modify the returned buffer
|
|
since it may point to a constant value. [vszakats] */
|
|
|
|
char * hb_itemString( PHB_ITEM pItem, HB_SIZE * nLen, HB_BOOL * bFreeReq )
|
|
{
|
|
char * buffer;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemString(%p, %p, %p)", ( void * ) pItem, ( void * ) nLen, ( void * ) bFreeReq ) );
|
|
|
|
switch( HB_ITEM_TYPE( pItem ) )
|
|
{
|
|
case HB_IT_STRING:
|
|
case HB_IT_MEMO:
|
|
buffer = ( char * ) HB_UNCONST( hb_itemGetCPtr( pItem ) );
|
|
* nLen = hb_itemGetCLen( pItem );
|
|
* bFreeReq = HB_FALSE;
|
|
break;
|
|
|
|
case HB_IT_DATE:
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
char szDate[ 9 ];
|
|
|
|
hb_dateDecStr( szDate, pItem->item.asDateTime.julian );
|
|
|
|
buffer = ( char * ) hb_xgrab( 11 );
|
|
hb_dateFormat( szDate, buffer, hb_stackSetStruct()->HB_SET_DATEFORMAT );
|
|
* nLen = strlen( buffer );
|
|
* bFreeReq = HB_TRUE;
|
|
break;
|
|
}
|
|
|
|
case HB_IT_TIMESTAMP:
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
char szDateTime[ 27 ];
|
|
|
|
hb_timeStampFormat( szDateTime,
|
|
hb_stackSetStruct()->HB_SET_DATEFORMAT,
|
|
hb_stackSetStruct()->HB_SET_TIMEFORMAT,
|
|
pItem->item.asDateTime.julian,
|
|
pItem->item.asDateTime.time );
|
|
|
|
buffer = hb_strdup( szDateTime );
|
|
* nLen = strlen( buffer );
|
|
* bFreeReq = HB_TRUE;
|
|
break;
|
|
}
|
|
|
|
case HB_IT_DOUBLE:
|
|
case HB_IT_INTEGER:
|
|
case HB_IT_LONG:
|
|
{
|
|
HB_STACK_TLS_PRELOAD
|
|
if( hb_stackSetStruct()->HB_SET_FIXED )
|
|
{
|
|
/* If fixed mode is enabled, use the default number of decimal places. */
|
|
hb_itemPutNI( hb_stackAllocItem(), hb_stackSetStruct()->HB_SET_DECIMALS );
|
|
buffer = hb_itemStr( pItem, NULL, hb_stackItemFromTop( -1 ) );
|
|
hb_stackPop();
|
|
}
|
|
else
|
|
buffer = hb_itemStr( pItem, NULL, NULL );
|
|
if( buffer )
|
|
{
|
|
*nLen = strlen( buffer );
|
|
*bFreeReq = HB_TRUE;
|
|
}
|
|
else
|
|
{
|
|
buffer = ( char * ) "";
|
|
*nLen = 0;
|
|
*bFreeReq = HB_FALSE;
|
|
}
|
|
break;
|
|
}
|
|
case HB_IT_NIL:
|
|
buffer = ( char * ) "NIL";
|
|
*nLen = 3;
|
|
*bFreeReq = HB_FALSE;
|
|
break;
|
|
|
|
case HB_IT_LOGICAL:
|
|
buffer = ( char * ) ( hb_itemGetL( pItem ) ? ".T." : ".F." );
|
|
*nLen = 3;
|
|
*bFreeReq = HB_FALSE;
|
|
break;
|
|
|
|
case HB_IT_SYMBOL:
|
|
*bFreeReq = HB_TRUE;
|
|
*nLen = strlen( hb_itemGetSymbol( pItem )->szName ) + 3;
|
|
buffer = ( char * ) hb_xgrab( *nLen + 1 );
|
|
buffer[ 0 ] = '@';
|
|
memcpy( buffer + 1, hb_itemGetSymbol( pItem )->szName, *nLen - 3 );
|
|
buffer[ *nLen - 2 ] = '(';
|
|
buffer[ *nLen - 1 ] = ')';
|
|
buffer[ *nLen ] = '\0';
|
|
break;
|
|
|
|
case HB_IT_POINTER:
|
|
{
|
|
int size = ( sizeof( void * ) << 1 ) + 3; /* n bytes for address + 0x + \0 */
|
|
HB_PTRUINT addr = ( HB_PTRUINT ) hb_itemGetPtr( pItem );
|
|
|
|
*nLen = size - 1;
|
|
*bFreeReq = HB_TRUE;
|
|
buffer = ( char * ) hb_xgrab( size );
|
|
buffer[ 0 ] = '0';
|
|
buffer[ 1 ] = 'x';
|
|
buffer[ --size ] = '\0';
|
|
do
|
|
{
|
|
HB_UCHAR uc = ( HB_UCHAR ) ( addr & 0xf );
|
|
buffer[ --size ] = ( char ) ( uc + ( uc < 10 ? '0' : 'A' - 10 ) );
|
|
addr >>= 4;
|
|
}
|
|
while( size > 2 );
|
|
break;
|
|
}
|
|
default:
|
|
buffer = ( char * ) "";
|
|
*nLen = 0;
|
|
*bFreeReq = HB_FALSE;
|
|
}
|
|
|
|
return buffer;
|
|
}
|
|
|
|
/* This function is used by all of the PAD functions to prepare the argument
|
|
being padded. If date, convert to string using hb_dateFormat(). If numeric,
|
|
convert to unpadded string. Return pointer to string and set string length */
|
|
|
|
char * hb_itemPadConv( PHB_ITEM pItem, HB_SIZE * pnSize, HB_BOOL * bFreeReq )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemPadConv(%p, %p, %p)", ( void * ) pItem, ( void * ) pnSize, ( void * ) bFreeReq ) );
|
|
|
|
if( pItem )
|
|
{
|
|
switch( HB_ITEM_TYPE( pItem ) )
|
|
{
|
|
case HB_IT_STRING:
|
|
case HB_IT_MEMO:
|
|
case HB_IT_DATE:
|
|
case HB_IT_TIMESTAMP:
|
|
return hb_itemString( pItem, pnSize, bFreeReq );
|
|
|
|
case HB_IT_DOUBLE:
|
|
case HB_IT_INTEGER:
|
|
case HB_IT_LONG:
|
|
{
|
|
int i;
|
|
char * buffer = hb_itemString( pItem, pnSize, bFreeReq );
|
|
|
|
/* remove leading spaces if any, a little bit redundant but
|
|
* I don't want to complicate the API interface more. Druzus
|
|
*/
|
|
for( i = 0; buffer[ i ] == ' '; i++ )
|
|
;
|
|
|
|
if( i > 0 )
|
|
{
|
|
int j = 0;
|
|
*pnSize -= i;
|
|
do
|
|
{
|
|
buffer[ j++ ] = buffer[ i ];
|
|
}
|
|
while( buffer[ i++ ] );
|
|
}
|
|
return buffer;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
PHB_ITEM hb_itemValToStr( PHB_ITEM pItem )
|
|
{
|
|
PHB_ITEM pResult;
|
|
char * buffer;
|
|
HB_SIZE nLen;
|
|
HB_BOOL bFreeReq;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_itemValToStr(%p)", ( void * ) pItem ) );
|
|
|
|
buffer = hb_itemString( pItem, &nLen, &bFreeReq );
|
|
if( bFreeReq )
|
|
pResult = hb_itemPutCLPtr( NULL, buffer, nLen );
|
|
else
|
|
pResult = hb_itemPutCL( NULL, buffer, nLen );
|
|
|
|
return pResult;
|
|
}
|