2007-04-03 14:10 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbapi.h
* harbour/source/vm/arrays.c
+ added hb_arrayRevScan()
* harbour/source/vm/arrayshb.c
+ added RASCAN() covered by HB_COMPAT_XHB macro
This commit is contained in:
@@ -8,6 +8,14 @@
|
||||
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
|
||||
*/
|
||||
|
||||
2007-04-03 14:10 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
|
||||
* harbour/include/hbapi.h
|
||||
* harbour/source/vm/arrays.c
|
||||
+ added hb_arrayRevScan()
|
||||
|
||||
* harbour/source/vm/arrayshb.c
|
||||
+ added RASCAN() covered by HB_COMPAT_XHB macro
|
||||
|
||||
2007-04-03 13:00 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
|
||||
* harbour/source/compiler/harbour.y
|
||||
* harbour/source/compiler/harbour.yyc
|
||||
|
||||
@@ -677,6 +677,7 @@ extern HB_EXPORT long hb_arrayGetDL( PHB_ITEM pArray, ULONG ulIndex ); /* r
|
||||
extern HB_EXPORT HB_TYPE hb_arrayGetType( PHB_ITEM pArray, ULONG ulIndex ); /* retrieves the type of an array item */
|
||||
extern HB_EXPORT BOOL hb_arrayFill( PHB_ITEM pArray, PHB_ITEM pValue, ULONG * pulStart, ULONG * pulCount ); /* fill an array with a given item */
|
||||
extern HB_EXPORT ULONG hb_arrayScan( PHB_ITEM pArray, PHB_ITEM pValue, ULONG * pulStart, ULONG * pulCount, BOOL fExact ); /* scan an array for a given item, or until code-block item returns TRUE */
|
||||
extern HB_EXPORT ULONG hb_arrayRevScan( PHB_ITEM pArray, PHB_ITEM pValue, ULONG * pulStart, ULONG * pulCount, BOOL fExact ); /* scan an array for a given item, or until code-block item returns TRUE in reverted order */
|
||||
extern HB_EXPORT BOOL hb_arrayEval( PHB_ITEM pArray, PHB_ITEM bBlock, ULONG * pulStart, ULONG * pulCount ); /* execute a code-block for every element of an array item */
|
||||
extern HB_EXPORT BOOL hb_arrayCopy( PHB_ITEM pSrcArray, PHB_ITEM pDstArray, ULONG * pulStart, ULONG * pulCount, ULONG * pulTarget ); /* copy items from one array to another */
|
||||
extern HB_EXPORT PHB_ITEM hb_arrayClone( PHB_ITEM pArray ); /* returns a duplicate of an existing array, including all nested items */
|
||||
|
||||
@@ -799,6 +799,154 @@ ULONG hb_arrayScan( PHB_ITEM pArray, PHB_ITEM pValue, ULONG * pulStart, ULONG *
|
||||
return 0;
|
||||
}
|
||||
|
||||
ULONG hb_arrayRevScan( PHB_ITEM pArray, PHB_ITEM pValue, ULONG * pulStart, ULONG * pulCount, BOOL fExact )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_arrayRevScan(%p, %p, %p, %p, %d)", pArray, pValue, pulStart, pulCount, (int) fExact));
|
||||
|
||||
if( HB_IS_ARRAY( pArray ) )
|
||||
{
|
||||
PHB_BASEARRAY pBaseArray = pArray->item.asArray.value;
|
||||
ULONG ulLen = pBaseArray->ulLen;
|
||||
ULONG ulStart;
|
||||
ULONG ulCount;
|
||||
|
||||
if( pulStart && *pulStart )
|
||||
ulStart = *pulStart - 1;
|
||||
else
|
||||
ulStart = ulLen - 1;
|
||||
|
||||
if( ulStart < ulLen )
|
||||
{
|
||||
ulCount = ulStart + 1;
|
||||
if( pulCount && *pulCount < ulCount )
|
||||
ulCount = *pulCount;
|
||||
|
||||
if( ulCount > 0 )
|
||||
{
|
||||
/* Make separate search loops for different types to find, so that
|
||||
the loop can be faster. */
|
||||
|
||||
if( HB_IS_BLOCK( pValue ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
hb_vmPushSymbol( &hb_symEval );
|
||||
hb_vmPush( pValue );
|
||||
hb_vmPush( pBaseArray->pItems + ulStart );
|
||||
hb_vmPushLong( ulStart + 1 );
|
||||
hb_vmDo( 2 );
|
||||
|
||||
if( HB_IS_LOGICAL( hb_stackReturnItem() ) && hb_stackReturnItem()->item.asLogical.value )
|
||||
return ulStart;
|
||||
}
|
||||
while( --ulCount && ulStart-- );
|
||||
}
|
||||
else if( HB_IS_STRING( pValue ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
PHB_ITEM pItem = pBaseArray->pItems + ulStart;
|
||||
|
||||
/* NOTE: The order of the pItem and pValue parameters passed to
|
||||
hb_itemStrCmp() is significant, please don't change it. [vszakats] */
|
||||
if( HB_IS_STRING( pItem ) && hb_itemStrCmp( pItem, pValue, fExact ) == 0 )
|
||||
return ulStart + 1;
|
||||
}
|
||||
while( --ulCount && ulStart-- );
|
||||
}
|
||||
else if( HB_IS_NUMERIC( pValue ) )
|
||||
{
|
||||
double dValue = hb_itemGetND( pValue );
|
||||
|
||||
do
|
||||
{
|
||||
PHB_ITEM pItem = pBaseArray->pItems + ulStart;
|
||||
|
||||
if( HB_IS_NUMERIC( pItem ) && hb_itemGetND( pItem ) == dValue )
|
||||
return ulStart + 1;
|
||||
}
|
||||
while( --ulCount && ulStart-- );
|
||||
}
|
||||
else if( HB_IS_DATE( pValue ) )
|
||||
{
|
||||
long lValue = hb_itemGetDL( pValue ); /* NOTE: This is correct: Get the date as a long value. [vszakats] */
|
||||
|
||||
do
|
||||
{
|
||||
PHB_ITEM pItem = pBaseArray->pItems + ulStart;
|
||||
|
||||
if( HB_IS_DATE( pItem ) && hb_itemGetDL( pItem ) == lValue )
|
||||
return ulStart + 1;
|
||||
}
|
||||
while( --ulCount && ulStart-- );
|
||||
}
|
||||
else if( HB_IS_LOGICAL( pValue ) )
|
||||
{
|
||||
BOOL bValue = hb_itemGetL( pValue );
|
||||
|
||||
do
|
||||
{
|
||||
PHB_ITEM pItem = pBaseArray->pItems + ulStart;
|
||||
|
||||
if( HB_IS_LOGICAL( pItem ) && hb_itemGetL( pItem ) == bValue )
|
||||
return ulStart + 1;
|
||||
}
|
||||
while( --ulCount && ulStart-- );
|
||||
}
|
||||
else if( HB_IS_NIL( pValue ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
PHB_ITEM pItem = pBaseArray->pItems + ulStart;
|
||||
|
||||
if( HB_IS_NIL( pItem ) )
|
||||
return ulStart + 1;
|
||||
}
|
||||
while( --ulCount && ulStart-- );
|
||||
}
|
||||
else if( HB_IS_POINTER( pValue ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
PHB_ITEM pItem = pBaseArray->pItems + ulStart;
|
||||
|
||||
if( HB_IS_POINTER( pItem ) &&
|
||||
pItem->item.asPointer.value == pValue->item.asPointer.value )
|
||||
return ulStart + 1;
|
||||
}
|
||||
while( --ulCount && ulStart-- );
|
||||
}
|
||||
else if( fExact && HB_IS_ARRAY( pValue ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
PHB_ITEM pItem = pBaseArray->pItems + ulStart;
|
||||
|
||||
if( HB_IS_ARRAY( pItem ) &&
|
||||
pItem->item.asArray.value == pValue->item.asArray.value )
|
||||
return ulStart + 1;
|
||||
}
|
||||
while( --ulCount && ulStart-- );
|
||||
}
|
||||
else if( fExact && HB_IS_HASH( pValue ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
PHB_ITEM pItem = pBaseArray->pItems + ulStart;
|
||||
|
||||
if( HB_IS_HASH( pItem ) &&
|
||||
pItem->item.asHash.value == pValue->item.asHash.value )
|
||||
return ulStart + 1;
|
||||
}
|
||||
while( --ulCount && ulStart-- );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL hb_arrayEval( PHB_ITEM pArray, PHB_ITEM bBlock, ULONG * pulStart, ULONG * pulCount )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_arrayEval(%p, %p, %p, %p)", pArray, bBlock, pulStart, pulCount));
|
||||
|
||||
@@ -286,21 +286,41 @@ HB_FUNC( ASCAN )
|
||||
ULONG ulCount = hb_parnl( 4 );
|
||||
|
||||
#if defined( HB_COMPAT_XHB )
|
||||
hb_retnl( hb_arrayScan( pArray, pValue,
|
||||
ISNUM( 3 ) ? &ulStart : NULL,
|
||||
ISNUM( 4 ) ? &ulCount : NULL,
|
||||
hb_parl( 5 ) ) );
|
||||
hb_retnint( hb_arrayScan( pArray, pValue,
|
||||
ISNUM( 3 ) ? &ulStart : NULL,
|
||||
ISNUM( 4 ) ? &ulCount : NULL,
|
||||
hb_parl( 5 ) ) );
|
||||
#else
|
||||
hb_retnl( hb_arrayScan( pArray, pValue,
|
||||
ISNUM( 3 ) ? &ulStart : NULL,
|
||||
ISNUM( 4 ) ? &ulCount : NULL,
|
||||
FALSE ) );
|
||||
hb_retnint( hb_arrayScan( pArray, pValue,
|
||||
ISNUM( 3 ) ? &ulStart : NULL,
|
||||
ISNUM( 4 ) ? &ulCount : NULL,
|
||||
FALSE ) );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
hb_retnl( 0 );
|
||||
hb_retni( 0 );
|
||||
}
|
||||
|
||||
#if defined( HB_COMPAT_XHB )
|
||||
HB_FUNC( RASCAN )
|
||||
{
|
||||
PHB_ITEM pArray = hb_param( 1, HB_IT_ARRAY );
|
||||
PHB_ITEM pValue = hb_param( 2, HB_IT_ANY );
|
||||
|
||||
if( pArray && pValue )
|
||||
{
|
||||
ULONG ulStart = hb_parnl( 3 );
|
||||
ULONG ulCount = hb_parnl( 4 );
|
||||
hb_retnint( hb_arrayRevScan( pArray, pValue,
|
||||
ISNUM( 3 ) ? &ulStart : NULL,
|
||||
ISNUM( 4 ) ? &ulCount : NULL,
|
||||
hb_parl( 5 ) ) );
|
||||
}
|
||||
else
|
||||
hb_retni( 0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* TODO: In Xbase++ fifth parameter determines whether array elements
|
||||
are passed by reference to the code block. [vszakats] */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user