From 12880a1b7f1c02e4ec4e8f2eadec1f90754c0eb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Czerpak?= Date: Fri, 5 Jan 2018 14:12:06 +0100 Subject: [PATCH] 2018-01-05 14:12 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * include/hbapiitm.h * src/rtl/hbdef.c * src/vm/itemapi.c * src/harbour.def + added new public C function HB_BOOL hb_itemTypeCmp( PHB_ITEM pItem1, PHB_ITEM pItem2 ); which uses low level item type comparison code taken from hb_default() and hb_defaultValue() PRG functions * include/harbour.hbx * src/harbour.def * src/vm/hashfunc.c + added new PRG function hb_HSetDef( , [, ] ) it checks if exists and if not then adds it to hash array and optionally sets key value to otherwise (the key exists in hash array) and is given then it checks if the type of key's value is compatible with and if not then replaces key's value with . In other words it's combination of hb_HGetDef() and hb_default() and works like this PRG code: FUNCTION hb_HSetDef( hVal, xKey, xDefVal ) IF xKey $ hVal hb_default( @hVal[ xKey ], xDefVal ) ELSE hVal[ xKey ] := xDefVal ENDIF RETURN hVal but much faster. * src/rtl/dirscan.prg * remove READONLY attribute from deleted directories. Be careful. Now this function allows to recursively remove all directories even if they have READONLY attribute. --- ChangeLog.txt | 36 ++++++++++++++++++++++++++ include/harbour.hbx | 1 + include/hbapiitm.h | 3 ++- src/harbour.def | 2 ++ src/rtl/dirscan.prg | 8 ++++-- src/rtl/hbdef.c | 61 ++------------------------------------------- src/vm/hashfunc.c | 29 +++++++++++++++++++++ src/vm/itemapi.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 139 insertions(+), 62 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 67b5093e8a..68d11e865a 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,42 @@ Entries may not always be in chronological/commit order. See license at the end of file. */ +2018-01-05 14:12 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * include/hbapiitm.h + * src/rtl/hbdef.c + * src/vm/itemapi.c + * src/harbour.def + + added new public C function + HB_BOOL hb_itemTypeCmp( PHB_ITEM pItem1, PHB_ITEM pItem2 ); + which uses low level item type comparison code taken from hb_default() + and hb_defaultValue() PRG functions + + * include/harbour.hbx + * src/harbour.def + * src/vm/hashfunc.c + + added new PRG function + hb_HSetDef( , [, ] ) + it checks if exists and if not then adds it to hash array + and optionally sets key value to otherwise (the key + exists in hash array) and is given then it checks if + the type of key's value is compatible with and if not + then replaces key's value with . + In other words it's combination of hb_HGetDef() and hb_default() + and works like this PRG code: + FUNCTION hb_HSetDef( hVal, xKey, xDefVal ) + IF xKey $ hVal + hb_default( @hVal[ xKey ], xDefVal ) + ELSE + hVal[ xKey ] := xDefVal + ENDIF + RETURN hVal + but much faster. + + * src/rtl/dirscan.prg + * remove READONLY attribute from deleted directories. + Be careful. Now this function allows to recursively remove + all directories even if they have READONLY attribute. + 2017-12-20 12:31 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * contrib/hbexpat/3rd/expat/loadlibr.c * contrib/hbexpat/3rd/expat/xmlparse.c diff --git a/include/harbour.hbx b/include/harbour.hbx index 6c38ff7f43..2fff5076fd 100644 --- a/include/harbour.hbx +++ b/include/harbour.hbx @@ -548,6 +548,7 @@ DYNAMIC hb_HSet DYNAMIC hb_HSetAutoAdd DYNAMIC hb_HSetBinary DYNAMIC hb_HSetCaseMatch +DYNAMIC hb_HSetDef DYNAMIC hb_HSetOrder DYNAMIC hb_HSort DYNAMIC hb_HValueAt diff --git a/include/hbapiitm.h b/include/hbapiitm.h index df5361a08f..ddb39da8d3 100644 --- a/include/hbapiitm.h +++ b/include/hbapiitm.h @@ -138,7 +138,8 @@ extern HB_EXPORT PHB_ITEM hb_itemReturnForward( PHB_ITEM pItem ); extern HB_EXPORT void hb_itemReturnRelease( PHB_ITEM pItem ); extern HB_EXPORT HB_SIZE hb_itemSize ( PHB_ITEM pItem ); extern HB_EXPORT HB_TYPE hb_itemType ( PHB_ITEM pItem ); -extern HB_EXPORT const char * hb_itemTypeStr ( PHB_ITEM pItem ); +extern HB_EXPORT const char * hb_itemTypeStr ( PHB_ITEM pItem ); +extern HB_EXPORT HB_BOOL hb_itemTypeCmp ( PHB_ITEM pItem1, PHB_ITEM pItem2 ); #ifndef HB_LONG_LONG_OFF extern HB_EXPORT HB_LONGLONG hb_itemGetNLL ( PHB_ITEM pItem ); extern HB_EXPORT PHB_ITEM hb_itemPutNLL ( PHB_ITEM pItem, HB_LONGLONG lNumber ); diff --git a/src/harbour.def b/src/harbour.def index 559f055e6d..b72fec5edd 100644 --- a/src/harbour.def +++ b/src/harbour.def @@ -644,6 +644,7 @@ HB_FUN_HB_HSET HB_FUN_HB_HSETAUTOADD HB_FUN_HB_HSETBINARY HB_FUN_HB_HSETCASEMATCH +HB_FUN_HB_HSETDEF HB_FUN_HB_HSETORDER HB_FUN_HB_HSORT HB_FUN_HB_HVALUEAT @@ -2860,6 +2861,7 @@ hb_itemStrICmp hb_itemString hb_itemSwap hb_itemType +hb_itemTypeCmp hb_itemTypeStr hb_itemUnRef hb_itemUnRefOnce diff --git a/src/rtl/dirscan.prg b/src/rtl/dirscan.prg index db4705d7df..b3ca224e7b 100644 --- a/src/rtl/dirscan.prg +++ b/src/rtl/dirscan.prg @@ -82,8 +82,12 @@ FUNCTION hb_DirRemoveAll( cDir ) LOCAL aFile, cPath, cFile, nAttr - IF hb_vfDirExists( cDir ) - cPath := hb_DirSepAdd( cDir ) + IF ! Empty( cDir ) .AND. hb_vfDirExists( cDir ) + cPath := hb_DirSepDel( cDir ) + IF hb_vfAttrGet( cPath, @nAttr ) .AND. ! hb_bitAnd( nAttr, HB_FA_READONLY ) == 0 + hb_vfAttrSet( cPath, hb_bitXor( nAttr, HB_FA_READONLY ) ) + ENDIF + cPath := hb_DirSepAdd( cPath ) FOR EACH aFile IN hb_vfDirectory( cPath + hb_osFileMask(), "HSDL" ) IF "D" $ aFile[ F_ATTR ] .AND. ! "L" $ aFile[ F_ATTR ] IF !( aFile[ F_NAME ] == "." .OR. aFile[ F_NAME ] == ".." .OR. aFile[ F_NAME ] == "" ) diff --git a/src/rtl/hbdef.c b/src/rtl/hbdef.c index d2b6650e04..f123d71a59 100644 --- a/src/rtl/hbdef.c +++ b/src/rtl/hbdef.c @@ -47,67 +47,11 @@ #include "hbapi.h" #include "hbapiitm.h" -typedef enum -{ - HB_IT_U, - HB_IT_N, - HB_IT_C, - HB_IT_L, - HB_IT_T, - HB_IT_B, - HB_IT_H, - HB_IT_A, - HB_IT_O, - HB_IT_P, - HB_IT_S -} HB_IT_BASIC; - -static HB_IT_BASIC s_hb_itemTypeBasic( PHB_ITEM pItem ) -{ - switch( HB_ITEM_TYPE( pItem ) ) - { - case HB_IT_ARRAY: - return hb_arrayIsObject( pItem ) ? HB_IT_O : HB_IT_A; - - case HB_IT_BLOCK: - return HB_IT_B; - - case HB_IT_DATE: - case HB_IT_TIMESTAMP: - return HB_IT_T; - - case HB_IT_LOGICAL: - return HB_IT_L; - - case HB_IT_INTEGER: - case HB_IT_LONG: - case HB_IT_DOUBLE: - return HB_IT_N; - - case HB_IT_STRING: - case HB_IT_MEMO: - return HB_IT_C; - - case HB_IT_HASH: - return HB_IT_H; - - case HB_IT_POINTER: - return HB_IT_P; - - case HB_IT_SYMBOL: - return HB_IT_S; - } - - return HB_IT_U; -} - HB_FUNC( HB_DEFAULT ) { PHB_ITEM pDefault = hb_param( 2, HB_IT_ANY ); - if( pDefault && - s_hb_itemTypeBasic( hb_param( 1, HB_IT_ANY ) ) != - s_hb_itemTypeBasic( pDefault ) ) + if( pDefault && ! hb_itemTypeCmp( hb_param( 1, HB_IT_ANY ), pDefault ) ) hb_itemParamStore( 1, pDefault ); } @@ -116,8 +60,7 @@ HB_FUNC( HB_DEFAULTVALUE ) PHB_ITEM pParam = hb_param( 1, HB_IT_ANY ); PHB_ITEM pDefault = hb_param( 2, HB_IT_ANY ); - if( pDefault && - s_hb_itemTypeBasic( pParam ) != s_hb_itemTypeBasic( pDefault ) ) + if( pDefault && ! hb_itemTypeCmp( pParam, pDefault ) ) pParam = pDefault; hb_itemReturn( pParam ); diff --git a/src/vm/hashfunc.c b/src/vm/hashfunc.c index 5e6b5ad632..474e48ccb0 100644 --- a/src/vm/hashfunc.c +++ b/src/vm/hashfunc.c @@ -146,6 +146,35 @@ HB_FUNC( HB_HGETDEF ) hb_errRT_BASE( EG_ARG, 1123, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } +HB_FUNC( HB_HSETDEF ) +{ + PHB_ITEM pHash = hb_param( 1, HB_IT_HASH ); + PHB_ITEM pKey = hb_param( 2, HB_IT_HASHKEY ); + + if( pHash && pKey ) + { + PHB_ITEM pDefault = hb_param( 3, HB_IT_ANY ), pDest; + int iFlags = hb_hashGetFlags( pHash ); + + if( ( iFlags & HB_HASH_AUTOADD_ACCESS ) == 0 ) + hb_hashSetFlags( pHash, HB_HASH_AUTOADD_ACCESS ); + + pDest = hb_hashGetItemPtr( pHash, pKey, HB_HASH_AUTOADD_ACCESS ); + + if( ( iFlags & HB_HASH_AUTOADD_ACCESS ) == 0 ) + hb_hashClearFlags( pHash, HB_HASH_AUTOADD_ACCESS ); + + if( pDest ) + { + if( pDefault && ! hb_itemTypeCmp( pDest, pDefault ) ) + hb_itemCopy( pDest, pDefault ); + hb_itemReturn( pDest ); + } + } + else + hb_errRT_BASE( EG_ARG, 1123, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + HB_FUNC( HB_HGETREF ) { PHB_ITEM pHash = hb_param( 1, HB_IT_HASH ); diff --git a/src/vm/itemapi.c b/src/vm/itemapi.c index 6f2ad55a9a..fba2e2a5fb 100644 --- a/src/vm/itemapi.c +++ b/src/vm/itemapi.c @@ -1506,6 +1506,67 @@ const char * hb_itemTypeStr( PHB_ITEM pItem ) return "U"; } +typedef enum +{ + HB_IT_U, + HB_IT_N, + HB_IT_C, + HB_IT_L, + HB_IT_T, + HB_IT_B, + HB_IT_H, + HB_IT_A, + HB_IT_O, + HB_IT_P, + HB_IT_S +} HB_IT_BASIC; + +static HB_IT_BASIC s_hb_itemTypeBasic( PHB_ITEM pItem ) +{ + switch( HB_ITEM_TYPE( pItem ) ) + { + case HB_IT_ARRAY: + return hb_arrayIsObject( pItem ) ? HB_IT_O : HB_IT_A; + + case HB_IT_BLOCK: + return HB_IT_B; + + case HB_IT_DATE: + case HB_IT_TIMESTAMP: + return HB_IT_T; + + case HB_IT_LOGICAL: + return HB_IT_L; + + case HB_IT_INTEGER: + case HB_IT_LONG: + case HB_IT_DOUBLE: + return HB_IT_N; + + case HB_IT_STRING: + case HB_IT_MEMO: + return HB_IT_C; + + case HB_IT_HASH: + return HB_IT_H; + + case HB_IT_POINTER: + return HB_IT_P; + + case HB_IT_SYMBOL: + return HB_IT_S; + } + + return HB_IT_U; +} + +HB_BOOL hb_itemTypeCmp( PHB_ITEM pItem1, PHB_ITEM pItem2 ) +{ + HB_TRACE( HB_TR_DEBUG, ( "hb_itemTypeCmp(%p, %p)", ( void * ) pItem1, ( void * ) pItem2 ) ); + + return s_hb_itemTypeBasic( pItem1 ) == s_hb_itemTypeBasic( pItem2 ); +} + /* Internal API, not standard Clipper */ void hb_itemInit( PHB_ITEM pItem )