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:
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
132
harbour/include/hbregex.h
Normal 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_ */
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -51,6 +51,7 @@ C_SOURCES=\
|
||||
hbffind.c \
|
||||
hbgtcore.c \
|
||||
hbrandom.c \
|
||||
hbregex.c \
|
||||
idle.c \
|
||||
inkey.c \
|
||||
is.c \
|
||||
|
||||
559
harbour/source/rtl/hbregex.c
Normal file
559
harbour/source/rtl/hbregex.c
Normal 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 );
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user