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 )