2007-03-13 19:40 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/include/hbapi.h
  * harbour/include/hbapiitm.h
  * harbour/source/vm/garbage.c
  * harbour/source/vm/extend.c
  * harbour/source/vm/itemapi.c
    + added hb_gcFunc(), hb_parptrGC(), hb_itemGetPtrGC()
      hb_parptrGC() and hb_itemGetPtrGC() uses GC cleanup function address
      to validate if pointer item points to expected memory block type

  * harbour/source/common/hbhash.c
  * harbour/source/compiler/hbident.c
    * formatting and minor modifications

  * harbour/source/pp/pplib.c
  * harbour/source/pp/pplib2.c
    * use hb_parptrGC() to be sure that given pointer item points
      to PP structure

  + harbour/include/hbregex.h
  + harbour/source/rtl/hbregex.c
  * harbour/source/rtl/Makefile
  * harbour/common.mak
    + added support for regular expressions. Now it's enabled by default
      only in *nixes (POSIX regex) and BCC 5.5 (PCRE regex). Setting
      HB_PCRE_REGEX macro enables Perl-Compatible Regular Expressions
      and HB_POSIX_REGEX - POSIX regular expressions. In xHarbour regex
      support is enabled for all builds because PCRE source code is stored
      in CVS. If you will want we can make the same.
    + the following C functions are available:
      hb_regexCompile(), hb_regexGet(), hb_regexFree(), hb_regexMatch()
    + the following PGR functions are available:
      HB_REGEXCOMP(), HB_ISREGEX(), HB_ATX(), HB_REGEX(), HB_REGEXMATCH(),
      HB_REGEXSPLIT(), HB_REGEXATX(), HB_REGEXALL()
      They are working in similar way to the ones in xHarbour with the
      exception to some bug fixes and form of compiled regular expression.
      In Harbour it's pointer item for which HB_ISREGEX() returns TRUE when
      in xHarbour it's binary string.

  * harbour/source/rdd/dbfcdx/dbfcdx1.c
  * harbour/source/rdd/dbfntx/dbfntx1.c
    * enabled code to seek in index using regular expressions
      (DBOI_SKIPREGEX[BACK])
This commit is contained in:
Przemyslaw Czerpak
2007-03-13 18:40:56 +00:00
parent 9569027809
commit 0ef0f1aab9
16 changed files with 936 additions and 157 deletions

View File

@@ -8,6 +8,50 @@
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
*/
2007-03-13 19:40 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbapi.h
* harbour/include/hbapiitm.h
* harbour/source/vm/garbage.c
* harbour/source/vm/extend.c
* harbour/source/vm/itemapi.c
+ added hb_gcFunc(), hb_parptrGC(), hb_itemGetPtrGC()
hb_parptrGC() and hb_itemGetPtrGC() uses GC cleanup function address
to validate if pointer item points to expected memory block type
* harbour/source/common/hbhash.c
* harbour/source/compiler/hbident.c
* formatting and minor modifications
* harbour/source/pp/pplib.c
* harbour/source/pp/pplib2.c
* use hb_parptrGC() to be sure that given pointer item points
to PP structure
+ harbour/include/hbregex.h
+ harbour/source/rtl/hbregex.c
* harbour/source/rtl/Makefile
* harbour/common.mak
+ added support for regular expressions. Now it's enabled by default
only in *nixes (POSIX regex) and BCC 5.5 (PCRE regex). Setting
HB_PCRE_REGEX macro enables Perl-Compatible Regular Expressions
and HB_POSIX_REGEX - POSIX regular expressions. In xHarbour regex
support is enabled for all builds because PCRE source code is stored
in CVS. If you will want we can make the same.
+ the following C functions are available:
hb_regexCompile(), hb_regexGet(), hb_regexFree(), hb_regexMatch()
+ the following PGR functions are available:
HB_REGEXCOMP(), HB_ISREGEX(), HB_ATX(), HB_REGEX(), HB_REGEXMATCH(),
HB_REGEXSPLIT(), HB_REGEXATX(), HB_REGEXALL()
They are working in similar way to the ones in xHarbour with the
exception to some bug fixes and form of compiled regular expression.
In Harbour it's pointer item for which HB_ISREGEX() returns TRUE when
in xHarbour it's binary string.
* harbour/source/rdd/dbfcdx/dbfcdx1.c
* harbour/source/rdd/dbfntx/dbfntx1.c
* enabled code to seek in index using regular expressions
(DBOI_SKIPREGEX[BACK])
2007-03-12 14:30 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbexpra.c
* emulate xHarbour HB_ENUMINDEX() inside FOR EACH loop when

View File

@@ -379,6 +379,7 @@ RTL_LIB_OBJS = \
$(OBJ_DIR)\hbffind.obj \
$(OBJ_DIR)\hbgtcore.obj \
$(OBJ_DIR)\hbrandom.obj \
$(OBJ_DIR)\hbregex.obj \
$(OBJ_DIR)\idle.obj \
$(OBJ_DIR)\inkey.obj \
$(OBJ_DIR)\is.obj \

View File

@@ -408,6 +408,101 @@ typedef USHORT ERRCODE;
extern HB_SYMB hb_symEval;
extern HB_EXPORT void hb_xinit( void ); /* Initialize fixed memory subsystem */
extern HB_EXPORT void hb_xexit( void ); /* Deinitialize fixed memory subsystem */
extern HB_EXPORT void * hb_xalloc( ULONG ulSize ); /* allocates memory, returns NULL on failure */
extern HB_EXPORT void * hb_xgrab( ULONG ulSize ); /* allocates memory, exits on failure */
extern HB_EXPORT void hb_xfree( void * pMem ); /* frees memory */
extern HB_EXPORT void * hb_xrealloc( void * pMem, ULONG ulSize ); /* reallocates memory */
extern HB_EXPORT ULONG hb_xsize( void * pMem ); /* returns the size of an allocated memory block */
extern HB_EXPORT ULONG hb_xquery( USHORT uiMode ); /* Query different types of memory information */
#ifdef _HB_API_INTERNAL_
extern void hb_xRefInc( void * pMem ); /* increment reference counter */
extern BOOL hb_xRefDec( void * pMem ); /* decrement reference counter, return TRUE when 0 reached */
extern void hb_xRefFree( void * pMem ); /* decrement reference counter and free the block when 0 reached */
extern HB_COUNTER hb_xRefCount( void * pMem ); /* return number of references */
extern void * hb_xRefResize( void * pMem, ULONG ulSave, ULONG ulSize ); /* reallocates memory, create copy if reference counter greater then 1 */
#if 0
/*
* I used this macros only to test some speed overhead,
* They may not be supported in the future so please do
* not create any code which needs them. [druzus]
*/
#define hb_xRefInc( p ) (++(*HB_COUNTER_PTR( p )))
#define hb_xRefDec( p ) (--(*HB_COUNTER_PTR( p ))==0)
#define hb_xRefFree( p ) do { \
if( hb_xRefDec( p ) ) \
hb_xfree( p ); \
} while( 0 )
#define hb_xRefCount( p ) (*HB_COUNTER_PTR( p ))
#endif
#endif /* _HB_API_INTERNAL_ */
/* #if UINT_MAX == ULONG_MAX */
/* it fails on 64bit platforms where int has 32 bit and long has 64 bit.
we need these functions only when max(size_t) < max(long)
and only on 16bit platforms, so the below condition seems to be
more reasonable. */
#if UINT_MAX > USHRT_MAX
/* NOTE: memcpy/memset can work with ULONG data blocks */
#define hb_xmemcpy memcpy
#define hb_xmemset memset
#else
/* NOTE: otherwise, the hb_xmemcpy and hb_xmemset functions
will be used to copy and/or set ULONG data blocks */
extern HB_EXPORT void * hb_xmemcpy( void * pDestArg, void * pSourceArg, ULONG ulLen ); /* copy more than memcpy() can */
extern HB_EXPORT void * hb_xmemset( void * pDestArg, int iFill, ULONG ulLen ); /* set more than memset() can */
#endif
/* garbage collector */
#define HB_GARBAGE_FUNC( hbfunc ) void hbfunc( void * Cargo ) /* callback function for cleaning garbage memory pointer */
typedef HB_GARBAGE_FUNC( HB_GARBAGE_FUNC_ );
typedef HB_GARBAGE_FUNC_ * HB_GARBAGE_FUNC_PTR;
#define HB_GARBAGE_SWEEPER( hbfunc ) BOOL hbfunc( void * Cargo ) /* callback function for cleaning garbage memory pointer */
typedef HB_GARBAGE_SWEEPER( HB_GARBAGE_SWEEPER_ );
typedef HB_GARBAGE_SWEEPER_ * HB_GARBAGE_SWEEPER_PTR;
extern void hb_gcRegisterSweep( HB_GARBAGE_SWEEPER_PTR pSweep, void * Cargo );
extern PHB_ITEM hb_gcGripGet( HB_ITEM_PTR pItem );
extern void hb_gcGripDrop( HB_ITEM_PTR pItem );
extern HB_EXPORT void *hb_gcAlloc( ULONG ulSize, HB_GARBAGE_FUNC_PTR pFunc ); /* allocates a memory controlled by the garbage collector */
extern void hb_gcFree( void *pAlloc ); /* deallocates a memory allocated by the garbage collector */
extern void * hb_gcLock( void *pAlloc ); /* do not release passed memory block */
extern void * hb_gcUnlock( void *pAlloc ); /* passed block is allowed to be released */
#ifdef _HB_API_INTERNAL_
HB_GARBAGE_FUNC_PTR hb_gcFunc( void *pBlock ); /* return cleanup function pointer */
extern void hb_gcItemRef( HB_ITEM_PTR pItem ); /* checks if passed item refers passed memory block pointer */
extern void hb_vmIsLocalRef( void ); /* hvm.c - mark all local variables as used */
extern void hb_vmIsStaticRef( void ); /* hvm.c - mark all static variables as used */
extern void hb_memvarsIsMemvarRef( void ); /* memvars.c - mark all memvar variables as used */
extern void hb_gcReleaseAll( void ); /* release all memory blocks unconditionally */
extern void hb_gcRefCheck( void * pBlock ); /* Check if block still cannot be access after destructor execution */
extern void hb_gcRefInc( void * pAlloc ); /* increment reference counter */
extern BOOL hb_gcRefDec( void * pAlloc ); /* decrement reference counter, return TRUE when 0 reached */
extern void hb_gcRefFree( void * pAlloc ); /* decrement reference counter and free the block when 0 reached */
extern HB_COUNTER hb_gcRefCount( void * pAlloc ); /* return number of references */
#if 0
#define hb_gcRefInc( p ) hb_xRefInc( HB_GC_PTR( p ) )
#define hb_gcRefDec( p ) hb_xRefDec( HB_GC_PTR( p ) )
#define hb_gcRefCount( p ) hb_xRefCount( HB_GC_PTR( p ) )
#define hb_gcFunc( p ) ( HB_GC_PTR( p )->pFunc )
#endif
#endif /* _HB_API_INTERNAL_ */
extern void hb_gcCollect( void ); /* checks if a single memory block can be released */
extern void hb_gcCollectAll( void ); /* checks if all memory blocks can be released */
/* Extend API */
extern HB_EXPORT char * hb_parc( int iParam, ... ); /* retrieve a string parameter */
extern HB_EXPORT char * hb_parcx( int iParam, ... ); /* retrieve a string parameter */
@@ -424,6 +519,7 @@ extern HB_EXPORT int hb_parni( int iParam, ... ); /* retrieve a numeric p
extern HB_EXPORT long hb_parnl( int iParam, ... ); /* retrieve a numeric parameter as a long */
extern HB_EXPORT HB_LONG hb_parnint( int iParam, ... ); /* retrieve a numeric parameter as a HB_LONG */
extern HB_EXPORT void * hb_parptr( int iParam, ... ); /* retrieve a parameter as a pointer */
extern HB_EXPORT void * hb_parptrGC( HB_GARBAGE_FUNC_PTR pFunc, int iParam, ... ); /* retrieve a parameter as a pointer if it's a pointer to GC allocated block */
extern HB_EXPORT PHB_ITEM hb_param( int iParam, long lMask ); /* retrieve a generic parameter */
extern HB_EXPORT PHB_ITEM hb_paramError( int iParam ); /* Returns either the generic parameter or a NIL item if param not provided */
extern HB_EXPORT BOOL hb_extIsArray( int iParam );
@@ -525,99 +621,6 @@ extern HB_EXPORT int hb_storptrGC( void * pointer, int iParam, ... ); /* stor
extern HB_EXPORT int hb_stornll( LONGLONG lValue, int iParam, ... ); /* stores a long long on a variable by reference */
#endif
extern HB_EXPORT void hb_xinit( void ); /* Initialize fixed memory subsystem */
extern HB_EXPORT void hb_xexit( void ); /* Deinitialize fixed memory subsystem */
extern HB_EXPORT void * hb_xalloc( ULONG ulSize ); /* allocates memory, returns NULL on failure */
extern HB_EXPORT void * hb_xgrab( ULONG ulSize ); /* allocates memory, exits on failure */
extern HB_EXPORT void hb_xfree( void * pMem ); /* frees memory */
extern HB_EXPORT void * hb_xrealloc( void * pMem, ULONG ulSize ); /* reallocates memory */
extern HB_EXPORT ULONG hb_xsize( void * pMem ); /* returns the size of an allocated memory block */
extern HB_EXPORT ULONG hb_xquery( USHORT uiMode ); /* Query different types of memory information */
#ifdef _HB_API_INTERNAL_
extern void hb_xRefInc( void * pMem ); /* increment reference counter */
extern BOOL hb_xRefDec( void * pMem ); /* decrement reference counter, return TRUE when 0 reached */
extern void hb_xRefFree( void * pMem ); /* decrement reference counter and free the block when 0 reached */
extern HB_COUNTER hb_xRefCount( void * pMem ); /* return number of references */
extern void * hb_xRefResize( void * pMem, ULONG ulSave, ULONG ulSize ); /* reallocates memory, create copy if reference counter greater then 1 */
#if 0
/*
* I used this macros only to test some speed overhead,
* They may not be supported in the future so please do
* not create any code which needs them. [druzus]
*/
#define hb_xRefInc( p ) (++(*HB_COUNTER_PTR( p )))
#define hb_xRefDec( p ) (--(*HB_COUNTER_PTR( p ))==0)
#define hb_xRefFree( p ) do { \
if( hb_xRefDec( p ) ) \
hb_xfree( p ); \
} while( 0 )
#define hb_xRefCount( p ) (*HB_COUNTER_PTR( p ))
#endif
#endif /* _HB_API_INTERNAL_ */
/* #if UINT_MAX == ULONG_MAX */
/* it fails on 64bit platforms where int has 32 bit and long has 64 bit.
we need these functions only when max(size_t) < max(long)
and only on 16bit platforms, so the below condition seems to be
more reasonable. */
#if UINT_MAX > USHRT_MAX
/* NOTE: memcpy/memset can work with ULONG data blocks */
#define hb_xmemcpy memcpy
#define hb_xmemset memset
#else
/* NOTE: otherwise, the hb_xmemcpy and hb_xmemset functions
will be used to copy and/or set ULONG data blocks */
extern HB_EXPORT void * hb_xmemcpy( void * pDestArg, void * pSourceArg, ULONG ulLen ); /* copy more than memcpy() can */
extern HB_EXPORT void * hb_xmemset( void * pDestArg, int iFill, ULONG ulLen ); /* set more than memset() can */
#endif
/* garbage collector */
#define HB_GARBAGE_FUNC( hbfunc ) void hbfunc( void * Cargo ) /* callback function for cleaning garbage memory pointer */
typedef HB_GARBAGE_FUNC( HB_GARBAGE_FUNC_ );
typedef HB_GARBAGE_FUNC_ * HB_GARBAGE_FUNC_PTR;
#define HB_GARBAGE_SWEEPER( hbfunc ) BOOL hbfunc( void * Cargo ) /* callback function for cleaning garbage memory pointer */
typedef HB_GARBAGE_SWEEPER( HB_GARBAGE_SWEEPER_ );
typedef HB_GARBAGE_SWEEPER_ * HB_GARBAGE_SWEEPER_PTR;
extern void hb_gcRegisterSweep( HB_GARBAGE_SWEEPER_PTR pSweep, void * Cargo );
extern PHB_ITEM hb_gcGripGet( HB_ITEM_PTR pItem );
extern void hb_gcGripDrop( HB_ITEM_PTR pItem );
extern HB_EXPORT void *hb_gcAlloc( ULONG ulSize, HB_GARBAGE_FUNC_PTR pFunc ); /* allocates a memory controlled by the garbage collector */
extern void hb_gcFree( void *pAlloc ); /* deallocates a memory allocated by the garbage collector */
extern void * hb_gcLock( void *pAlloc ); /* do not release passed memory block */
extern void * hb_gcUnlock( void *pAlloc ); /* passed block is allowed to be released */
#ifdef _HB_API_INTERNAL_
extern void hb_gcItemRef( HB_ITEM_PTR pItem ); /* checks if passed item refers passed memory block pointer */
extern void hb_vmIsLocalRef( void ); /* hvm.c - mark all local variables as used */
extern void hb_vmIsStaticRef( void ); /* hvm.c - mark all static variables as used */
extern void hb_memvarsIsMemvarRef( void ); /* memvars.c - mark all memvar variables as used */
extern void hb_gcReleaseAll( void ); /* release all memory blocks unconditionally */
extern void hb_gcRefCheck( void * pBlock ); /* Check if block still cannot be access after destructor execution */
extern void hb_gcRefInc( void * pAlloc ); /* increment reference counter */
extern BOOL hb_gcRefDec( void * pAlloc ); /* decrement reference counter, return TRUE when 0 reached */
extern void hb_gcRefFree( void * pAlloc ); /* decrement reference counter and free the block when 0 reached */
extern HB_COUNTER hb_gcRefCount( void * pAlloc ); /* return number of references */
#if 0
#define hb_gcRefInc( p ) hb_xRefInc( HB_GC_PTR( p ) )
#define hb_gcRefDec( p ) hb_xRefDec( HB_GC_PTR( p ) )
#define hb_gcRefCount( p ) hb_xRefCount( HB_GC_PTR( p ) )
#endif
#endif /* _HB_API_INTERNAL_ */
extern void hb_gcCollect( void ); /* checks if a single memory block can be released */
extern void hb_gcCollectAll( void ); /* checks if all memory blocks can be released */
/* array management */
extern HB_EXPORT BOOL hb_arrayNew( PHB_ITEM pItem, ULONG ulLen ); /* creates a new array */
extern HB_EXPORT ULONG hb_arrayLen( PHB_ITEM pArray ); /* retrieves the array len */

View File

@@ -95,6 +95,7 @@ extern HB_EXPORT long hb_itemGetNL ( PHB_ITEM pItem );
extern HB_EXPORT HB_LONG hb_itemGetNInt ( PHB_ITEM pItem );
extern HB_EXPORT void hb_itemGetNLen ( PHB_ITEM pItem, int * piWidth, int * piDec );
extern HB_EXPORT void * hb_itemGetPtr ( PHB_ITEM pItem );
extern HB_EXPORT void * hb_itemGetPtrGC ( PHB_ITEM pItem, HB_GARBAGE_FUNC_PTR pFunc );
extern HB_EXPORT PHB_SYMB hb_itemGetSymbol( PHB_ITEM pItem );
extern HB_EXPORT PHB_ITEM hb_itemNew ( PHB_ITEM pNull );
extern HB_EXPORT void hb_itemInit ( PHB_ITEM pItem );

132
harbour/include/hbregex.h Normal file
View File

@@ -0,0 +1,132 @@
/*
* $Id$
*/
/*
* Harbour Project source code:
*
*
* Copyright 2007 Przemyslaw Czerpak <druzus / at / priv.onet.pl>
* www - http://www.harbour-project.org
*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
*
* 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.
*
*/
#ifndef HB_REGEX_H_
#define HB_REGEX_H_
#include "hbapi.h"
#if defined( _HB_REGEX_INTERNAL_ )
#if defined( __BORLANDC__ )
# if __BORLANDC__ >= 0x550 && !defined( HB_PCRE_REGEX_BCC )
# define HB_PCRE_REGEX_BCC
# endif
#elif defined( OS_UNIX_COMPATIBLE ) && !defined( __WATCOMC__ )
# if !defined( HB_POSIX_REGEX )
# define HB_POSIX_REGEX
# endif
#endif
#if defined( HB_PCRE_REGEX_BCC )
# include <pcre.h>
# include <pcreposi.h>
# if !defined( HB_PCRE_REGEX )
# define HB_PCRE_REGEX
# endif
#elif defined( HB_PCRE_REGEX )
# include <pcre/pcre.h>
# include <pcre/pcreposix.h>
#elif defined( HB_POSIX_REGEX )
# include <regex.h>
#else
# undef _HB_REGEX_INTERNAL_
#endif
#endif /* _HB_REGEX_INTERNAL_ */
#if defined( _HB_REGEX_INTERNAL_ )
typedef struct
{
regex_t reg;
regmatch_t aMatches[1];
BOOL fFree;
int iCFlags;
int iEFlags;
} HB_REGEX;
typedef HB_REGEX * PHB_REGEX;
#ifndef REG_EXTENDED
# define REG_EXTENDED 0x00
#endif
#ifndef REG_NOSUB
# define REG_NOSUB 0x00
#endif
#else
typedef void * PHB_REGEX;
#endif /* _HB_REGEX_INTERNAL_ */
#define HBREG_ICASE 0x01
#define HBREG_NEWLINE 0x02
#define HBREG_NOTBOL 0x04
#define HBREG_NOTEOL 0x08
#define HBREG_EXTENDED 0x10
#define HBREG_NOSUB 0x20
#ifndef REGEX_MAX_GROUPS
# define REGEX_MAX_GROUPS 16
#endif
HB_EXTERN_BEGIN
extern HB_EXPORT PHB_REGEX hb_regexCompile( const char *szRegEx, ULONG ulLen, int iFlags );
extern HB_EXPORT PHB_REGEX hb_regexGet( PHB_ITEM pRegExItm, int iFlags );
extern HB_EXPORT void hb_regexFree( PHB_REGEX pRegEx );
extern HB_EXPORT BOOL hb_regexMatch( PHB_REGEX pRegEx, const char *szString, BOOL fFull );
HB_EXTERN_END
#endif /* HB_REGEX_H_ */

View File

@@ -55,7 +55,7 @@
static HB_HASH_ITEM_PTR hb_hashItemNew( ULONG ulKey, void *pKey, void * pValue )
{
HB_HASH_ITEM_PTR pItem = (HB_HASH_ITEM_PTR) hb_xgrab( sizeof( HB_HASH_ITEM ) );
pItem->key = ulKey;
pItem->KeyPtr = pKey;
pItem->ValPtr = pValue;
@@ -64,8 +64,10 @@ static HB_HASH_ITEM_PTR hb_hashItemNew( ULONG ulKey, void *pKey, void * pValue )
return pItem;
}
static void hb_hashItemDelete( HB_HASH_ITEM_PTR pItem )
static void hb_hashItemDelete( HB_HASH_TABLE_PTR pTable, HB_HASH_ITEM_PTR pItem )
{
if( pTable->pDeleteItemFunc )
( pTable->pDeleteItemFunc )( pTable, pItem->KeyPtr, pItem->ValPtr );
hb_xfree( (void *) pItem );
}
@@ -85,16 +87,16 @@ HB_HASH_TABLE_PTR hb_hashTableCreate( ULONG ulSize,
HB_HASH_FUNC_PTR pComp )
{
HB_HASH_TABLE_PTR pTable = ( HB_HASH_TABLE_PTR ) hb_xgrab( sizeof( HB_HASH_TABLE ) );
pTable->ulTableSize = ulSize;
pTable->pKeyFunc = pHashFunc;
pTable->pDeleteItemFunc = pDelete;
pTable->pCompFunc = pComp;
pTable->ulCount = pTable->ulUsed = 0;
pTable->pItems = ( HB_HASH_ITEM_PTR * ) hb_xgrab( sizeof( HB_HASH_ITEM_PTR ) * ulSize );
memset( pTable->pItems, 0, sizeof( HB_HASH_ITEM_PTR ) * ulSize );
return pTable;
}
@@ -108,16 +110,13 @@ void hb_hashTableKill( HB_HASH_TABLE_PTR pTable )
{
if( pTable->pItems[ ulSize ] )
{
HB_HASH_ITEM_PTR pItem;
HB_HASH_ITEM_PTR pNext;
HB_HASH_ITEM_PTR pItem, pFree;
pItem = pTable->pItems[ ulSize ];
while( pItem )
{
if( pTable->pDeleteItemFunc )
( pTable->pDeleteItemFunc )( pTable, pItem->KeyPtr, pItem->ValPtr );
pNext = pItem->next;
hb_xfree( ( void * ) pItem );
pItem = pNext;
pFree = pItem;
pItem = pItem->next;
hb_hashItemDelete( pTable, pFree );
}
}
++ulSize;
@@ -131,26 +130,26 @@ HB_HASH_TABLE_PTR hb_hashTableResize( HB_HASH_TABLE_PTR pTable, ULONG ulNewSize
{
HB_HASH_TABLE_PTR pNew;
ULONG ulSize = 0;
if( ulNewSize == 0 )
ulNewSize = 2 * pTable->ulTableSize + 1;
pNew = hb_hashTableCreate( ulNewSize,
pTable->pKeyFunc,
pTable->pDeleteItemFunc,
pTable->pCompFunc );
pTable->pKeyFunc,
pTable->pDeleteItemFunc,
pTable->pCompFunc );
while( ulSize < pTable->ulTableSize )
{
if( pTable->pItems[ ulSize ] )
{
HB_HASH_ITEM_PTR pItem;
pItem = pTable->pItems[ ulSize ];
while( pItem )
{
ULONG ulKey;
HB_HASH_ITEM_PTR pNewItem, pNext;
pNext = pItem->next;
ulKey = ( pTable->pKeyFunc )( pNew, pItem->KeyPtr, pItem->ValPtr );
pNewItem = pNew->pItems[ ulKey ];
@@ -184,7 +183,7 @@ BOOL hb_hashTableAdd( HB_HASH_TABLE_PTR pTable, void *pKey, void *pValue )
{
ULONG ulKey;
HB_HASH_ITEM_PTR pItem;
ulKey = ( pTable->pKeyFunc )( pTable, pKey, pValue );
pItem = pTable->pItems[ ulKey ];
if( pItem )
@@ -199,7 +198,7 @@ BOOL hb_hashTableAdd( HB_HASH_TABLE_PTR pTable, void *pKey, void *pValue )
++pTable->ulUsed;
}
++pTable->ulCount;
return TRUE;
}
@@ -210,14 +209,14 @@ void * hb_hashTableFind( HB_HASH_TABLE_PTR pTable, void *pKey )
ULONG ulKey;
HB_HASH_ITEM_PTR pItem;
void * pFound = NULL;
ulKey = ( pTable->pKeyFunc )( pTable, pKey, NULL );
pItem = pTable->pItems[ ulKey ];
if( pItem )
{
while( pItem && (( pTable->pCompFunc )( pTable, pItem->KeyPtr, pKey ) != 0) )
pItem = pItem->next;
if( pItem )
pFound = pItem->ValPtr;
}
@@ -235,11 +234,11 @@ BOOL hb_hashTableDel( HB_HASH_TABLE_PTR pTable, void *pKey )
HB_HASH_ITEM_PTR pItem;
HB_HASH_ITEM_PTR pPrev = NULL;
BOOL bFound = FALSE;
ulKey = ( pTable->pKeyFunc )( pTable, pKey, NULL );
if( ulKey > pTable->ulTableSize )
return FALSE;
pItem = pTable->pItems[ ulKey ];
while( pItem && !bFound )
{
@@ -258,12 +257,9 @@ BOOL hb_hashTableDel( HB_HASH_TABLE_PTR pTable, void *pKey )
pTable->pItems[ ulKey ] = NULL;
}
}
if( pTable->pDeleteItemFunc )
( pTable->pDeleteItemFunc )( pTable, pItem->KeyPtr, pItem->ValPtr );
hb_hashItemDelete( pItem );
bFound = TRUE;
--pTable->ulCount;
hb_hashItemDelete( pTable, pItem );
bFound = TRUE;
}
else
{

View File

@@ -72,7 +72,7 @@ static HB_HASH_FUNC( hb_comp_IdentKey ) /* ULONG func (void *Value, void *Car
HB_SYMBOL_UNUSED( HashPtr );
HB_SYMBOL_UNUSED( Cargo );
return ulSum % HB_IDENT_TABLE_SIZE;
}

View File

@@ -119,9 +119,10 @@ static void hb_pp_StdRules( PHB_PP_STATE pState )
}
}
static PHB_PP_STATE hb_pp_Param( int iParam )
PHB_PP_STATE hb_pp_Param( int iParam )
{
PHB_PP_STATE * pStatePtr = ( PHB_PP_STATE * ) hb_parptr( iParam );
PHB_PP_STATE * pStatePtr =
( PHB_PP_STATE * ) hb_parptrGC( hb_pp_Destructor, iParam );
if( pStatePtr )
return * pStatePtr;

View File

@@ -56,12 +56,12 @@
#include "hbpp.h"
#include "hbapi.h"
extern PHB_PP_STATE hb_pp_Param( int iParam );
HB_FUNC( __PP_STDRULES )
{
PHB_PP_STATE * pStatePtr = ( PHB_PP_STATE * ) hb_parptr( 1 );
PHB_PP_STATE pState = hb_pp_Param( 1 );
if( pStatePtr && * pStatePtr )
{
hb_pp_setStdRules( * pStatePtr );
}
if( pState )
hb_pp_setStdRules( pState );
}

View File

@@ -80,9 +80,7 @@
#include "hbrddcdx.h"
#include "hbmath.h"
#include "rddsys.ch"
#ifdef __XHARBOUR__
#include "hbregex.h"
#endif
#ifndef HB_CDP_SUPPORT_OFF
/* for nation sorting support */
@@ -5508,8 +5506,6 @@ static BOOL hb_cdxDBOISkipWild( CDXAREAP pArea, LPCDXTAG pTag, BOOL fForward,
return fFound;
}
#if defined(__XHARBOUR__)
static BOOL hb_cdxRegexMatch( CDXAREAP pArea, PHB_REGEX pRegEx, LPCDXKEY pKey )
{
char * szKey = ( char * ) pKey->val;
@@ -5535,14 +5531,14 @@ static BOOL hb_cdxDBOISkipRegEx( CDXAREAP pArea, LPCDXTAG pTag, BOOL fForward,
PHB_ITEM pRegExItm )
{
BOOL fFound = FALSE, fFirst = TRUE;
HB_REGEX RegEx;
PHB_REGEX pRegEx;
HB_TRACE(HB_TR_DEBUG, ("hb_cdxDBOISkipRegEx(%p, %p, %i, %p)", pArea, pTag, fForward, pRegExItm));
if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE )
return FALSE;
if( !pTag || pTag->uiType != 'C' || !hb_regexGet( &RegEx, pRegExItm, 0, 0 ) )
if( !pTag || pTag->uiType != 'C' || ( pRegEx = hb_regexGet( pRegExItm, 0 ) ) == NULL )
{
if ( SELF_SKIP( ( AREAP ) pArea, fForward ? 1 : -1 ) == FAILURE )
return FALSE;
@@ -5569,12 +5565,12 @@ static BOOL hb_cdxDBOISkipRegEx( CDXAREAP pArea, LPCDXTAG pTag, BOOL fForward,
hb_cdxTagSkipNext( pTag );
while ( !pTag->TagEOF )
{
if( hb_cdxRegexMatch( pArea, &RegEx, pTag->CurKey ) )
if( hb_cdxRegexMatch( pArea, pRegEx, pTag->CurKey ) )
{
ULONG ulRecNo = pArea->ulRecNo;
SELF_SKIPFILTER( ( AREAP ) pArea, 1 );
if ( pArea->ulRecNo == ulRecNo ||
hb_cdxRegexMatch( pArea, &RegEx, pTag->CurKey ) )
hb_cdxRegexMatch( pArea, pRegEx, pTag->CurKey ) )
{
fFound = TRUE;
break;
@@ -5590,12 +5586,12 @@ static BOOL hb_cdxDBOISkipRegEx( CDXAREAP pArea, LPCDXTAG pTag, BOOL fForward,
hb_cdxTagSkipPrev( pTag );
while ( !pTag->TagBOF )
{
if( hb_cdxRegexMatch( pArea, &RegEx, pTag->CurKey ) )
if( hb_cdxRegexMatch( pArea, pRegEx, pTag->CurKey ) )
{
ULONG ulRecNo = pArea->ulRecNo;
SELF_SKIPFILTER( ( AREAP ) pArea, -1 );
if ( pArea->ulRecNo == ulRecNo ||
hb_cdxRegexMatch( pArea, &RegEx, pTag->CurKey ) )
hb_cdxRegexMatch( pArea, pRegEx, pTag->CurKey ) )
{
fFound = TRUE;
break;
@@ -5619,11 +5615,10 @@ static BOOL hb_cdxDBOISkipRegEx( CDXAREAP pArea, LPCDXTAG pTag, BOOL fForward,
else
pArea->fEof = FALSE;
hb_regexFree( &RegEx );
hb_regexFree( pRegEx );
return fFound;
}
#endif
/*
* evaluate given C function in given scope
@@ -7953,7 +7948,6 @@ static ERRCODE hb_cdxOrderInfo( CDXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pO
hb_cdxDBOISkipWild( pArea, pTag, FALSE, pOrderInfo->itmNewVal ) );
break;
#if defined(__XHARBOUR__)
case DBOI_SKIPREGEX:
pOrderInfo->itmResult = hb_itemPutL( pOrderInfo->itmResult,
hb_cdxDBOISkipRegEx( pArea, pTag, TRUE, pOrderInfo->itmNewVal ) );
@@ -7963,7 +7957,6 @@ static ERRCODE hb_cdxOrderInfo( CDXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pO
pOrderInfo->itmResult = hb_itemPutL( pOrderInfo->itmResult,
hb_cdxDBOISkipRegEx( pArea, pTag, FALSE, pOrderInfo->itmNewVal ) );
break;
#endif
case DBOI_SCOPEEVAL:
if ( pTag && pOrderInfo->itmNewVal &&

View File

@@ -143,9 +143,7 @@
#include "hbmath.h"
#include "hbrddntx.h"
#include "rddsys.ch"
#ifdef __XHARBOUR__
#include "hbregex.h"
#endif
#ifndef HB_CDP_SUPPORT_OFF
#include "hbapicdp.h"
#endif
@@ -4281,8 +4279,6 @@ static BOOL hb_ntxOrdSkipWild( LPTAGINFO pTag, BOOL fForward, PHB_ITEM pWildItm
return fFound;
}
#if defined(__XHARBOUR__)
static BOOL hb_ntxRegexMatch( LPTAGINFO pTag, PHB_REGEX pRegEx, char * szKey )
{
#ifndef HB_CDP_SUPPORT_OFF
@@ -4307,11 +4303,11 @@ static BOOL hb_ntxOrdSkipRegEx( LPTAGINFO pTag, BOOL fForward, PHB_ITEM pRegExIt
{
NTXAREAP pArea = pTag->Owner->Owner;
BOOL fFound = FALSE;
HB_REGEX RegEx;
PHB_REGEX pRegEx;
HB_TRACE(HB_TR_DEBUG, ("hb_ntxOrdSkipRegEx(%p, %d, %p)", pTag, fForward, pRegExItm));
if( pTag->KeyType != 'C' || !hb_regexGet( &RegEx, pRegExItm, 0, 0 ) )
if( pTag->KeyType != 'C' || ( pRegEx = hb_regexGet( pRegExItm, 0 ) ) == NULL )
{
if( SELF_SKIP( ( AREAP ) pArea, fForward ? 1 : -1 ) != SUCCESS )
return FALSE;
@@ -4341,12 +4337,12 @@ static BOOL hb_ntxOrdSkipRegEx( LPTAGINFO pTag, BOOL fForward, PHB_ITEM pRegExIt
if( SELF_GOTO( ( AREAP ) pArea, pTag->CurKeyInfo->Xtra ) != SUCCESS )
break;
if( hb_ntxRegexMatch( pTag, &RegEx, ( char * ) pTag->CurKeyInfo->key ) )
if( hb_ntxRegexMatch( pTag, pRegEx, ( char * ) pTag->CurKeyInfo->key ) )
{
ULONG ulRecNo = pArea->ulRecNo;
if( SELF_SKIPFILTER( ( AREAP ) pArea, fForward ? 1 : -1 ) != SUCCESS ||
pArea->ulRecNo == ulRecNo ||
hb_ntxRegexMatch( pTag, &RegEx, ( char * ) pTag->CurKeyInfo->key ) )
hb_ntxRegexMatch( pTag, pRegEx, ( char * ) pTag->CurKeyInfo->key ) )
{
fFound = TRUE;
break;
@@ -4378,11 +4374,10 @@ static BOOL hb_ntxOrdSkipRegEx( LPTAGINFO pTag, BOOL fForward, PHB_ITEM pRegExIt
else
pArea->fEof = FALSE;
hb_regexFree( &RegEx );
hb_regexFree( pRegEx );
return fFound;
}
#endif
/*
* add key to custom tag (ordKeyAdd())
@@ -6945,13 +6940,11 @@ static ERRCODE ntxOrderInfo( NTXAREAP pArea, USHORT uiIndex, LPDBORDERINFO pInfo
hb_itemPutL( pInfo->itmResult, hb_ntxOrdSkipWild( pTag,
uiIndex == DBOI_SKIPWILD, pInfo->itmNewVal ) );
break;
#if defined(__XHARBOUR__)
case DBOI_SKIPREGEX:
case DBOI_SKIPREGEXBACK:
hb_itemPutL( pInfo->itmResult, hb_ntxOrdSkipRegEx( pTag,
uiIndex == DBOI_SKIPREGEX, pInfo->itmNewVal ) );
break;
#endif
case DBOI_FINDREC:
case DBOI_FINDRECCONT:
hb_itemPutL( pInfo->itmResult, hb_ntxOrdFindRec( pTag,

View File

@@ -51,6 +51,7 @@ C_SOURCES=\
hbffind.c \
hbgtcore.c \
hbrandom.c \
hbregex.c \
idle.c \
inkey.c \
is.c \

View File

@@ -0,0 +1,559 @@
/*
* $Id$
*/
/*
* Harbour Project source code:
*
*
* Copyright 2007 Przemyslaw Czerpak <druzus / at / priv.onet.pl>
* www - http://www.harbour-project.org
*
* 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 software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
*
* 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.
*
*/
/* #define HB_PCRE_REGEX */
#define _HB_REGEX_INTERNAL_
#include "hbregex.h"
#include "hbapiitm.h"
#include "hbapierr.h"
/* This releases regex when called from the garbage collector */
static HB_GARBAGE_FUNC( hb_regexRelease )
{
#ifdef _HB_REGEX_INTERNAL_
PHB_REGEX pRegEx = ( PHB_REGEX ) Cargo;
regfree( &pRegEx->reg );
#else
HB_SYMBOL_UNUSED( Cargo );
#endif
}
PHB_REGEX hb_regexCompile( const char *szRegEx, ULONG ulLen, int iFlags )
{
#ifdef _HB_REGEX_INTERNAL_
PHB_REGEX pRegEx;
HB_SYMBOL_UNUSED( ulLen );
pRegEx = ( PHB_REGEX ) hb_gcAlloc( sizeof( HB_REGEX ), hb_regexRelease );
hb_gcLock( pRegEx );
memset( pRegEx, 0, sizeof( HB_REGEX ) );
pRegEx->fFree = TRUE;
pRegEx->iCFlags = REG_EXTENDED |
( ( iFlags & HBREG_ICASE ) ? REG_ICASE : 0 ) |
( ( iFlags & HBREG_NEWLINE ) ? REG_NEWLINE : 0 ) |
( ( iFlags & HBREG_NOSUB ) ? REG_NOSUB : 0 );
pRegEx->iEFlags = ( ( iFlags & HBREG_NOTBOL ) ? REG_NOTBOL : 0 ) |
( ( iFlags & HBREG_NOTEOL ) ? REG_NOTBOL : 0 );
if( regcomp( &pRegEx->reg, szRegEx, pRegEx->iCFlags ) != 0 )
{
hb_gcFree( pRegEx );
pRegEx = NULL;
}
return pRegEx;
#else
HB_SYMBOL_UNUSED( szRegEx );
HB_SYMBOL_UNUSED( ulLen );
HB_SYMBOL_UNUSED( iFlags );
return NULL;
#endif
}
PHB_REGEX hb_regexGet( PHB_ITEM pRegExItm, int iFlags )
{
PHB_REGEX pRegEx = NULL;
if( pRegExItm )
{
if( HB_IS_POINTER( pRegExItm ) )
{
pRegEx = ( PHB_REGEX ) hb_itemGetPtrGC( pRegExItm, hb_regexRelease );
}
else if( HB_IS_STRING( pRegExItm ) )
{
ULONG ulLen = hb_itemGetCLen( pRegExItm );
char * szRegEx = hb_itemGetCPtr( pRegExItm );
if( ulLen > 0 )
pRegEx = hb_regexCompile( szRegEx, ulLen, iFlags );
}
}
if( !pRegEx )
hb_errRT_BASE_SubstR( EG_ARG, 3012, "Invalid Regular expression", &hb_errFuncName, 1, pRegExItm );
return pRegEx;
}
void hb_regexFree( PHB_REGEX pRegEx )
{
#ifdef _HB_REGEX_INTERNAL_
if( pRegEx && pRegEx->fFree )
{
regfree( &pRegEx->reg );
hb_gcFree( pRegEx );
}
#else
HB_SYMBOL_UNUSED( pRegEx );
#endif
}
BOOL hb_regexMatch( PHB_REGEX pRegEx, const char *szString, BOOL fFull )
{
#ifdef _HB_REGEX_INTERNAL_
BOOL fMatch;
fMatch = regexec( &pRegEx->reg, szString, 1, pRegEx->aMatches, pRegEx->iEFlags ) == 0;
return fMatch && ( !fFull ||
( pRegEx->aMatches[0].rm_so == 0 &&
pRegEx->aMatches[0].rm_eo == (int) strlen( szString ) ) );
#else
HB_SYMBOL_UNUSED( pRegEx );
HB_SYMBOL_UNUSED( szString );
HB_SYMBOL_UNUSED( fFull );
return FALSE;
#endif
}
HB_FUNC( HB_REGEXCOMP )
{
#ifdef _HB_REGEX_INTERNAL_
ULONG ulLen = hb_parclen( 1 );
if( ulLen == 0 )
hb_errRT_BASE_SubstR( EG_ARG, 3012, "Wrong parameter count/type",
&hb_errFuncName, HB_ERR_ARGS_BASEPARAMS );
else
{
int iFlags = HBREG_EXTENDED;
PHB_REGEX pRegEx;
if( ISLOG( 2 ) && !hb_parl( 2 ) )
iFlags |= HBREG_ICASE;
if( hb_parl( 3 ) )
iFlags |= HBREG_NEWLINE;
pRegEx = hb_regexCompile( hb_parc( 1 ), ulLen, iFlags );
if( pRegEx )
{
pRegEx->fFree = FALSE;
hb_retptrGC( pRegEx );
hb_gcUnlock( pRegEx );
}
}
#endif
}
HB_FUNC( HB_ISREGEX )
{
hb_retl( hb_parptrGC( hb_regexRelease, 1 ) != NULL );
}
HB_FUNC( HB_ATX )
{
#ifdef _HB_REGEX_INTERNAL_
char * pszString, * pszCopy = NULL;
ULONG ulLen, ulStart, ulEnd;
regmatch_t aMatches[ 1 ];
PHB_REGEX pRegEx;
PHB_ITEM pString;
int iPCount = hb_pcount();
pString = hb_param( 2, HB_IT_STRING );
if( !pString )
{
hb_errRT_BASE_SubstR( EG_ARG, 3012, "Wrong parameters",
&hb_errFuncName, HB_ERR_ARGS_BASEPARAMS );
return;
}
pszString = hb_itemGetCPtr( pString );
ulLen = hb_itemGetCLen( pString );
pRegEx = hb_regexGet( hb_param( 1, HB_IT_ANY ),
ISLOG( 3 ) && !hb_parl( 3 ) ? HBREG_ICASE : 0 );
if( !pRegEx )
return;
ulStart = hb_parnl( 4 );
ulEnd = hb_parnl( 5 );
if( ulLen && ulStart <= ulLen && ulStart <= ulEnd )
{
if( ulEnd > 0 && ulEnd < ulLen && pszString[ ulEnd ] != 0 )
{
if( ulStart > 1 )
{
pszString += ulStart - 1;
ulEnd -= ulStart - 1;
}
pszCopy = ( char * ) hb_xgrab( ulEnd + 1 );
memcpy( pszCopy, pszString, ulEnd );
pszCopy[ ulEnd ] = '\0';
pszString = pszCopy;
}
if( regexec( &pRegEx->reg, pszString, 1, aMatches, 0 ) == 0 )
{
ulStart = aMatches[0].rm_so + 1;
ulLen = aMatches[0].rm_eo - aMatches[0].rm_so;
hb_retclen( pszString + aMatches[0].rm_so, ulLen );
}
else
ulStart = ulLen = 0;
}
else
ulStart = ulLen = 0;
hb_regexFree( pRegEx );
if( pszCopy )
hb_xfree( pszCopy );
if( iPCount > 3 )
{
hb_stornl( ulStart, 4 );
if( iPCount > 4 )
hb_stornl( ulLen, 5 );
}
#endif
}
static BOOL hb_regex( int iRequest )
{
#ifdef _HB_REGEX_INTERNAL_
regmatch_t aMatches[ REGEX_MAX_GROUPS ];
PHB_ITEM pRetArray, pMatch, pString;
int i, iMatches, iMaxMatch;
BOOL fResult = FALSE;
PHB_REGEX pRegEx;
char * pszString;
ULONG ulLen;
pString = hb_param( 2, HB_IT_STRING );
if( !pString )
{
hb_errRT_BASE_SubstR( EG_ARG, 3012, "Wrong parameters",
&hb_errFuncName, HB_ERR_ARGS_BASEPARAMS );
return FALSE;
}
pRegEx = hb_regexGet( hb_param( 1, HB_IT_ANY ),
( ISLOG( 3 ) && !hb_parl( 3 ) ? HBREG_ICASE : 0 ) |
( hb_parl( 4 ) ? HBREG_NEWLINE : 0 ) );
if( !pRegEx )
return FALSE;
pszString = hb_itemGetCPtr( pString );
ulLen = hb_itemGetCLen( pString );
iMatches = 0;
iMaxMatch = iRequest == 0 || iRequest == 4 || iRequest == 5 ?
REGEX_MAX_GROUPS : 1;
aMatches[0].rm_so = 0;
aMatches[0].rm_eo = ulLen;
if( regexec( &pRegEx->reg, pszString, iMaxMatch, aMatches, 0 ) == 0 )
{
switch ( iRequest )
{
case 0:
/* Count sucessful matches */
for( i = 0; i < iMaxMatch; i++ )
{
if( aMatches[i].rm_eo != -1 )
iMatches = i;
}
iMatches++;
pRetArray = hb_itemArrayNew( iMatches );
for( i = 0; i < iMatches; i++ )
{
if( aMatches[i].rm_eo > -1 )
hb_itemPutCL( hb_arrayGetItemPtr( pRetArray, i + 1 ),
pszString + aMatches[i].rm_so,
aMatches[i].rm_eo - aMatches[i].rm_so );
else
hb_itemPutCL( hb_arrayGetItemPtr( pRetArray, i + 1 ), "", 0 );
}
hb_itemRelease( hb_itemReturnForward( pRetArray ) );
fResult = TRUE;
break;
case 1: /* LIKE */
fResult = aMatches[0].rm_so == 0 &&
( ULONG ) aMatches[0].rm_eo == ulLen;
break;
case 2: /* MATCH */
fResult = TRUE;
break;
case 3: /* SPLIT */
iMaxMatch = hb_parni( 5 );
pRetArray = hb_itemArrayNew( 0 );
pMatch = hb_itemNew( NULL );
do
{
hb_itemPutCL( pMatch, pszString, aMatches[0].rm_so );
hb_arrayAddForward( pRetArray, pMatch );
ulLen -= aMatches[0].rm_eo;
pszString += aMatches[ 0 ].rm_eo;
iMatches++;
}
while( aMatches[0].rm_eo && ulLen && ( iMaxMatch == 0 || iMatches < iMaxMatch ) &&
regexec( &pRegEx->reg, pszString, 1, aMatches, 0 ) == 0 );
/* last match must be done also in case that pszString is empty;
this would mean an empty split field at the end of the string */
/* if( ulLen ) */
{
hb_itemPutCL( pMatch, pszString, ulLen );
hb_arrayAddForward( pRetArray, pMatch );
}
hb_itemRelease( pMatch );
hb_itemRelease( hb_itemReturnForward( pRetArray ) );
fResult = TRUE;
break;
case 4: /* results AND positions */
/* Count sucessful matches */
for( i = 0; i < iMaxMatch; i++ )
{
if( aMatches[i].rm_eo != -1 )
iMatches = i;
}
iMatches++;
pRetArray = hb_itemArrayNew( iMatches );
for( i = 0; i < iMatches; i++ )
{
pMatch = hb_arrayGetItemPtr( pRetArray, i + 1 );
hb_arrayNew( pMatch, 3 );
if ( aMatches[i].rm_eo != -1 )
{
/* matched string */
hb_itemPutCL( hb_arrayGetItemPtr( pMatch, 1 ), pszString + aMatches[i].rm_so, aMatches[i].rm_eo - aMatches[i].rm_so );
/* begin of match */
hb_itemPutNI( hb_arrayGetItemPtr( pMatch, 2 ), aMatches[i].rm_so + 1 );
/* End of match */
hb_itemPutNI( hb_arrayGetItemPtr( pMatch, 3 ), aMatches[i].rm_eo );
}
else
{
hb_itemPutCL( hb_arrayGetItemPtr( pMatch, 1 ), "", 0 );
hb_itemPutNI( hb_arrayGetItemPtr( pMatch, 2 ), 0 );
hb_itemPutNI( hb_arrayGetItemPtr( pMatch, 3 ), 0 );
}
}
hb_itemRelease( hb_itemReturnForward( pRetArray ) );
fResult = TRUE;
break;
case 5: /* _ALL_ results AND positions */
{
PHB_ITEM pAtxArray;
int iMax = hb_parni( 5 ); /* max nuber of matches I want, 0 = unlimited */
int iGetMatch = hb_parni( 6 ); /* Gets if want only one single match or a sub-match */
BOOL fOnlyMatch = !ISLOG( 7 ) || hb_parl( 7 ); /* if TRUE returns only matches and sub-matches, not positions */
ULONG ulOffSet = 0;
int iCount = 0;
/* Set new array */
pRetArray = hb_itemArrayNew( 0 );
do
{
/* Count sucessful matches */
for( i = 0; i < iMaxMatch; i++ )
{
if( aMatches[i].rm_eo != -1 )
iMatches = i;
}
iMatches++;
/* If I want all matches */
if( iGetMatch == 0 || // Check boundaries
( iGetMatch < 0 || iGetMatch > iMatches ) )
{
pAtxArray = hb_itemArrayNew( iMatches );
for( i = 0; i < iMatches; i++ )
{
pMatch = hb_arrayGetItemPtr( pAtxArray, i + 1 );
if( !fOnlyMatch )
{
hb_arrayNew( pMatch, 3 );
if ( aMatches[i].rm_eo != -1 )
{
/* matched string */
hb_itemPutCL( hb_arrayGetItemPtr( pMatch, 1 ), pszString + aMatches[i].rm_so, aMatches[i].rm_eo - aMatches[i].rm_so );
/* begin of match */
hb_itemPutNI( hb_arrayGetItemPtr( pMatch, 2 ), ulOffSet + aMatches[i].rm_so + 1 );
/* End of match */
hb_itemPutNI( hb_arrayGetItemPtr( pMatch, 3 ), ulOffSet + aMatches[i].rm_eo );
}
else
{
hb_itemPutCL( hb_arrayGetItemPtr( pMatch, 1 ), "", 0 );
hb_itemPutNI( hb_arrayGetItemPtr( pMatch, 2 ), 0 );
hb_itemPutNI( hb_arrayGetItemPtr( pMatch, 3 ), 0 );
}
}
else
{
if( aMatches[i].rm_eo != -1 )
/* matched string */
hb_itemPutCL( pMatch, pszString + aMatches[i].rm_so, aMatches[i].rm_eo - aMatches[i].rm_so );
else
hb_itemPutCL( pMatch, "", 0 );
}
}
hb_arrayAddForward( pRetArray, pAtxArray );
hb_itemRelease( pAtxArray );
}
else /* Here I get only single matches */
{
i = iGetMatch - 1;
pMatch = hb_itemNew( NULL );
if( !fOnlyMatch )
{
hb_arrayNew( pMatch, 3 );
if( aMatches[i].rm_eo != -1 )
{
/* matched string */
hb_itemPutCL( hb_arrayGetItemPtr( pMatch, 1 ), pszString + aMatches[i].rm_so, aMatches[i].rm_eo - aMatches[i].rm_so );
/* begin of match */
hb_itemPutNI( hb_arrayGetItemPtr( pMatch, 2 ), ulOffSet + aMatches[i].rm_so + 1 );
/* End of match */
hb_itemPutNI( hb_arrayGetItemPtr( pMatch, 3 ), ulOffSet + aMatches[i].rm_eo );
}
else
{
hb_itemPutCL( hb_arrayGetItemPtr( pMatch, 1 ), "", 0 );
hb_itemPutNI( hb_arrayGetItemPtr( pMatch, 2 ), 0 );
hb_itemPutNI( hb_arrayGetItemPtr( pMatch, 3 ), 0 );
}
}
else
{
if( aMatches[i].rm_eo != -1 )
/* matched string */
hb_itemPutCL( pMatch, pszString + aMatches[i].rm_so, aMatches[i].rm_eo - aMatches[i].rm_so );
else
hb_itemPutCL( pMatch, "", 0 );
}
hb_arrayAddForward( pRetArray, pMatch );
hb_itemRelease( pMatch );
}
ulLen -= aMatches[0].rm_eo;
pszString += aMatches[ 0 ].rm_eo;
ulOffSet += aMatches[0].rm_eo;
iCount++;
}
while( aMatches[0].rm_eo && ulLen && ( iMax == 0 || iCount < iMax ) &&
regexec( &pRegEx->reg, pszString, iMaxMatch, aMatches, 0 ) == 0 );
hb_itemRelease( hb_itemReturnForward( pRetArray ) );
fResult = TRUE;
break;
}
}
}
else if( iRequest == 3 )
{
pRetArray = hb_itemArrayNew( 1 );
hb_arraySet( pRetArray, 1, pString );
hb_itemRelease( hb_itemReturnForward( pRetArray ) );
fResult = TRUE;
}
hb_regexFree( pRegEx );
return fResult;
#else
HB_SYMBOL_UNUSED( iRequest );
return FALSE;
#endif
}
/* Returns array of Match + Sub-Matches. */
HB_FUNC( HB_REGEX )
{
hb_regex( 0 );
}
/* Returns just .T. if match found or .F. otherwise. */
HB_FUNC( HB_REGEXMATCH )
{
hb_retl( hb_regex( hb_parl( 3 ) ? 1 : 2 ) );
}
/* Splits the string in an array of matched expressions */
HB_FUNC( HB_REGEXSPLIT )
{
hb_regex( 3 );
}
/* Returns array of { Match, start, end }, { Sub-Matches, start, end } */
HB_FUNC( HB_REGEXATX )
{
hb_regex( 4 );
}
/* 2005-12-16 - Francesco Saverio Giudice
HB_RegExAll( cRegex, cString, lCaseSensitive, lNewLine, nMaxMatches, nGetMatch, lOnlyMatch ) -> aAllRegexMatches
This function return all matches from a Regex search.
It is a mix from hb_RegEx() and hb_RegExAtX()
PARAMETERS:
cRegex - Regex pattern string or precompiled Regex
cString - The string you want to search
lCaseSensitive - default = FALSE
lNewLine - default = FALSE
nMaxMatches - default = unlimited, this limit number of matches that have to return
nGetMatch - default = unlimited, this returns only one from Match + Sub-Matches
lOnlyMatch - default = TRUE, if TRUE returns Matches, otherwise it returns also start and end positions
*/
HB_FUNC( HB_REGEXALL )
{
hb_regex( 5 );
}

View File

@@ -621,6 +621,43 @@ HB_EXPORT void * hb_parptr( int iParam, ... )
return NULL;
}
HB_EXPORT void * hb_parptrGC( HB_GARBAGE_FUNC_PTR pFunc, int iParam, ... )
{
HB_TRACE(HB_TR_DEBUG, ("hb_parptrGC(%p,%d, ...)", pFunc, iParam));
if( ( iParam >= 0 && iParam <= hb_pcount() ) || ( iParam == -1 ) )
{
PHB_ITEM pItem = ( iParam == -1 ) ? hb_stackReturnItem() : hb_stackItemFromBase( iParam );
if( HB_IS_BYREF( pItem ) )
pItem = hb_itemUnRef( pItem );
if( HB_IS_POINTER( pItem ) )
{
if( pItem->item.asPointer.collect &&
hb_gcFunc( pItem->item.asPointer.value ) == pFunc )
return pItem->item.asPointer.value;
}
else if( HB_IS_ARRAY( pItem ) )
{
va_list va;
ULONG ulArrayIndex;
va_start( va, iParam );
ulArrayIndex = va_arg( va, ULONG );
va_end( va );
pItem = hb_arrayGetItemPtr( pItem, ulArrayIndex );
if( pItem && HB_IS_POINTER( pItem ) &&
pItem->item.asPointer.collect &&
hb_gcFunc( pItem->item.asPointer.value ) == pFunc )
return pItem->item.asPointer.value;
}
}
return NULL;
}
HB_EXPORT ULONG hb_parinfa( int iParamNum, ULONG uiArrayIndex )
{
PHB_ITEM pArray;

View File

@@ -206,6 +206,12 @@ void hb_gcFree( void *pBlock )
}
}
/* return cleanup function pointer */
HB_GARBAGE_FUNC_PTR hb_gcFunc( void *pBlock )
{
return HB_GC_PTR( pBlock )->pFunc;
}
/* increment reference counter */
#undef hb_gcRefInc
void hb_gcRefInc( void * pBlock )

View File

@@ -603,6 +603,18 @@ HB_EXPORT void * hb_itemGetPtr( PHB_ITEM pItem )
return NULL;
}
HB_EXPORT void * hb_itemGetPtrGC( PHB_ITEM pItem, HB_GARBAGE_FUNC_PTR pFunc )
{
HB_TRACE(HB_TR_DEBUG, ("hb_itemGetPtrGC(%p,%p)", pItem, pFunc));
if( pItem && HB_IS_POINTER( pItem ) &&
pItem->item.asPointer.collect &&
hb_gcFunc( pItem->item.asPointer.value ) == pFunc )
return pItem->item.asPointer.value;
else
return NULL;
}
HB_EXPORT PHB_SYMB hb_itemGetSymbol( PHB_ITEM pItem )
{
HB_TRACE(HB_TR_DEBUG, ("hb_itemGetSymbol(%p)", pItem));