From fe675215149bf1feb86d767f3cd90b40de3221a5 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Thu, 6 Jul 2006 21:07:38 +0000 Subject: [PATCH] 2006-07-06 23:05 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/Makefile + added usrrdd.ch * harbour/include/hbapiitm.h * harbour/source/vm/itemapi.c + added hb_itemPutSymbol() * harbour/source/vm/hvm.c ! fixed HB_P_POPVARIABLE - it should work like HB_P_POPMEMVAR This Ron's code which illustrates it: PROCEDURE Main() USE Test First := First CLOSE ? First RETURN In practice it means that we do not need this PCODE at all and we should replace it in compiler by HB_P_POPMEMVAR and reuse it in the future for differ things. * harbour/source/vm/memvars.c * code cleanup * harbour/source/vm/runner.c ! fixed possible memory leaks when corrupted .hrb file is loaded --- harbour/ChangeLog | 27 ++ harbour/include/Makefile | 1 + harbour/include/hbapiitm.h | 1 + harbour/source/vm/hvm.c | 68 ++-- harbour/source/vm/itemapi.c | 21 + harbour/source/vm/memvars.c | 84 ++-- harbour/source/vm/runner.c | 760 ++++++++++++++++++------------------ 7 files changed, 500 insertions(+), 462 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 724e396871..5020c44ee3 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,33 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ + * harbour/contrib/rdd_ads/ads1.c + * synced with Toninho modifications in xHarbour: + (! Inverted checking for memo data types, verifying binary first, + to prevent freeze in some empty ADT tabes.) + +2006-07-06 23:05 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/Makefile + + added usrrdd.ch + + * harbour/include/hbapiitm.h + * harbour/source/vm/itemapi.c + + added hb_itemPutSymbol() + + * harbour/source/vm/hvm.c + ! fixed HB_P_POPVARIABLE - it should work like HB_P_POPMEMVAR + This Ron's code which illustrates it: + PROCEDURE Main() + USE Test + First := First + CLOSE + ? First + RETURN + In practice it means that we do not need this PCODE at all and + we should replace it in compiler by HB_P_POPMEMVAR and reuse + it in the future for differ things. + + * harbour/source/vm/memvars.c * code cleanup * harbour/source/vm/runner.c diff --git a/harbour/include/Makefile b/harbour/include/Makefile index 04a91eff38..030ba8ad65 100644 --- a/harbour/include/Makefile +++ b/harbour/include/Makefile @@ -95,6 +95,7 @@ PRG_HEADERS=\ simpleio.ch \ std.ch \ tbrowse.ch \ + usrrdd.ch \ API_HEADERS=\ error.api \ diff --git a/harbour/include/hbapiitm.h b/harbour/include/hbapiitm.h index ca19d5b741..56e4a597e8 100644 --- a/harbour/include/hbapiitm.h +++ b/harbour/include/hbapiitm.h @@ -118,6 +118,7 @@ extern HB_EXPORT PHB_ITEM hb_itemPutNLLen ( PHB_ITEM pItem, long lNumber, int extern HB_EXPORT PHB_ITEM hb_itemPutNumType( PHB_ITEM pItem, double dNumber, int iDec, int iType1, int iType2 ); extern HB_EXPORT PHB_ITEM hb_itemPutPtr ( PHB_ITEM pItem, void * pValue ); extern HB_EXPORT PHB_ITEM hb_itemPutPtrGC ( PHB_ITEM pItem, void * pValue ); +extern HB_EXPORT PHB_ITEM hb_itemPutSymbol( PHB_ITEM pItem, PHB_SYMB pSym ); extern HB_EXPORT BOOL hb_itemRelease ( PHB_ITEM pItem ); extern HB_EXPORT PHB_ITEM hb_itemReturn ( PHB_ITEM pItem ); extern HB_EXPORT PHB_ITEM hb_itemReturnForward( PHB_ITEM pItem ); diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index a6e800b2f1..7aac483961 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -1439,7 +1439,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_PUSHVARIABLE: /* Push a value of variable of unknown type onto the eval stack */ - hb_vmPushVariable( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); + hb_vmPushVariable( pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); w += 3; break; @@ -1466,7 +1466,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_POPALIASEDFIELD: - hb_vmPopAliasedField( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); + hb_vmPopAliasedField( pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); w += 3; break; @@ -1476,7 +1476,7 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_POPALIASEDVAR: - hb_vmPopAliasedVar( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); + hb_vmPopAliasedVar( pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); w += 3; break; @@ -1484,14 +1484,14 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) /* Pops a value from the eval stack and uses it to set * a new value of the given field */ - hb_rddPutFieldValue( ( hb_stackItemFromTop(-1) ), pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); + hb_rddPutFieldValue( hb_stackItemFromTop(-1), pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); hb_stackPop(); HB_TRACE(HB_TR_INFO, ("(hb_vmPopField)")); w += 3; break; case HB_P_POPLOCAL: - hb_vmPopLocal( HB_PCODE_MKSHORT( &( pCode[ w + 1 ] ) ) ); + hb_vmPopLocal( HB_PCODE_MKSHORT( &pCode[ w + 1 ] ) ); w += 3; break; @@ -1501,12 +1501,13 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; case HB_P_POPSTATIC: - hb_vmPopStatic( HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) ); + hb_vmPopStatic( HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ) ); w += 3; break; case HB_P_POPMEMVAR: - hb_memvarSetValue( pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ), hb_stackItemFromTop( -1 ) ); + hb_memvarSetValue( pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ), + hb_stackItemFromTop( -1 ) ); hb_stackPop(); HB_TRACE(HB_TR_INFO, ("(hb_vmPopMemvar)")); w += 3; @@ -1514,32 +1515,36 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) case HB_P_POPVARIABLE: { - USHORT uiParams; - PHB_DYNS pDyn; - + /* + 2004-03-19 Ron Pinkas + Test with Clipper shows that for assignment, MEMVAR context + is always used even if MEMVAR does NOT exists, and a FIELD + with this name exists!!! + Here is the Test Ueed - Clipper produced NO R/T Error - + indicating MEMVAR was created. + PROCEDURE Main() + USE Test + First := First + CLOSE + ? First + RETURN + */ +#if 0 /* Pops a value from the eval stack and uses it to set * a new value of a variable of unknown type. */ - uiParams = HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ); - /* First try if passed symbol is a name of field - * in a current workarea - if it is not a field (FAILURE) - * then try the memvar variable (it will create PRIVATE - * variable if this variable doesn't exist) - */ + PHB_SYMB pSymbol = pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ); - /* memvars.c 417 */ - pDyn = ( PHB_DYNS ) ( pSymbols + uiParams )->pDynSym; - if( pDyn && pDyn->hMemvar ) - { + if( pSymbol->pDynSym && pSymbol->pDynSym->hMemvar ) /* If exist a memory symbol with this name use it */ - hb_memvarSetValue( pSymbols + uiParams, hb_stackItemFromTop( -1 ) ); - } - else - { + hb_memvarSetValue( pSymbol, hb_stackItemFromTop(-1) ); + else if( hb_rddFieldPut( hb_stackItemFromTop(-1), pSymbol ) == FAILURE ) /* Try with a field and after create a memvar */ - if( hb_rddFieldPut( hb_stackItemFromTop( -1 ), pSymbols + uiParams ) == FAILURE ) - hb_memvarSetValue( pSymbols + uiParams, hb_stackItemFromTop( -1 ) ); - } + hb_memvarSetValue( pSymbol, hb_stackItemFromTop(-1) ); +#else + hb_memvarSetValue( pSymbols + HB_PCODE_MKUSHORT( &pCode[ w + 1 ] ), + hb_stackItemFromTop( -1 ) ); +#endif hb_stackPop(); HB_TRACE(HB_TR_INFO, ("(hb_vmPopVariable)")); w += 3; @@ -6220,10 +6225,13 @@ HB_EXPORT BOOL hb_xvmPopVariable( PHB_SYMB pSymbol ) { HB_TRACE(HB_TR_INFO, ("hb_xvmPopVariable(%p)", pSymbol)); + /* See the note above in HB_P_POPVARIABLE */ +#if 0 if( pSymbol->pDynSym && pSymbol->pDynSym->hMemvar ) - hb_memvarSetValue( pSymbol, ( hb_stackItemFromTop(-1) ) ); - else if( hb_rddFieldPut( ( hb_stackItemFromTop(-1) ), pSymbol ) == FAILURE ) - hb_memvarSetValue( pSymbol, ( hb_stackItemFromTop(-1) ) ); + hb_memvarSetValue( pSymbol, hb_stackItemFromTop(-1) ); + else if( hb_rddFieldPut( hb_stackItemFromTop(-1), pSymbol ) == FAILURE ) +#endif + hb_memvarSetValue( pSymbol, hb_stackItemFromTop(-1) ); hb_stackPop(); HB_XVM_RETURN diff --git a/harbour/source/vm/itemapi.c b/harbour/source/vm/itemapi.c index 6567f0a15f..2fb17a961a 100644 --- a/harbour/source/vm/itemapi.c +++ b/harbour/source/vm/itemapi.c @@ -1120,6 +1120,27 @@ HB_EXPORT PHB_ITEM hb_itemPutPtrGC( PHB_ITEM pItem, void * pValue ) return pItem; } +HB_EXPORT PHB_ITEM hb_itemPutSymbol( PHB_ITEM pItem, PHB_SYMB pSym ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_itemPutSymbol(%p,%p)", pItem, pSym)); + + if( pItem ) + { + if( HB_IS_COMPLEX( pItem ) ) + hb_itemClear( pItem ); + } + else + pItem = hb_itemNew( NULL ); + + pItem->type = HB_IT_SYMBOL; + pItem->item.asSymbol.stackbase = 0; + pItem->item.asSymbol.lineno = 0; + pItem->item.asSymbol.paramcnt = 0; + pItem->item.asSymbol.value = pSym; + + return pItem; +} + HB_EXPORT void hb_itemGetNLen( PHB_ITEM pItem, int * piWidth, int * piDecimal ) { HB_TRACE(HB_TR_DEBUG, ("hb_itemGetNLen(%p, %p, %p)", pItem, piWidth, piDecimal)); diff --git a/harbour/source/vm/memvars.c b/harbour/source/vm/memvars.c index abdaf1d7d7..154d8cba41 100644 --- a/harbour/source/vm/memvars.c +++ b/harbour/source/vm/memvars.c @@ -511,21 +511,17 @@ void hb_memvarGetValue( HB_ITEM_PTR pItem, PHB_SYMB pMemvarSymb ) /* Generate an error with retry possibility * (user created error handler can create this variable) */ - USHORT uiAction = E_RETRY; HB_ITEM_PTR pError; pError = hb_errRT_New( ES_ERROR, NULL, EG_NOVAR, 1003, NULL, pMemvarSymb->szName, 0, EF_CANRETRY ); - while( uiAction == E_RETRY ) + while( hb_errLaunch( pError ) == E_RETRY ) { - uiAction = hb_errLaunch( pError ); - if( uiAction == E_RETRY ) - { - if( hb_memvarGet( pItem, pMemvarSymb ) == SUCCESS ) - uiAction = E_DEFAULT; - } + if( hb_memvarGet( pItem, pMemvarSymb ) == SUCCESS ) + break; } + hb_errRelease( pError ); } } @@ -554,26 +550,21 @@ void hb_memvarGetRefer( HB_ITEM_PTR pItem, PHB_SYMB pMemvarSymb ) /* Generate an error with retry possibility * (user created error handler can make this variable accessible) */ - USHORT uiAction = E_RETRY; HB_ITEM_PTR pError; pError = hb_errRT_New( ES_ERROR, NULL, EG_NOVAR, 1003, NULL, pMemvarSymb->szName, 0, EF_CANRETRY ); - while( uiAction == E_RETRY ) + while( hb_errLaunch( pError ) == E_RETRY ) { - uiAction = hb_errLaunch( pError ); - if( uiAction == E_RETRY ) + if( pDyn->hMemvar ) { - if( pDyn->hMemvar ) - { - /* value is already created */ - pItem->type = HB_IT_BYREF | HB_IT_MEMVAR; - pItem->item.asMemvar.value = pDyn->hMemvar; - pItem->item.asMemvar.itemsbase = &s_globalTable; - ++s_globalTable[ pDyn->hMemvar ].counter; - uiAction = E_DEFAULT; - } + /* value is already created */ + pItem->type = HB_IT_BYREF | HB_IT_MEMVAR; + pItem->item.asMemvar.value = pDyn->hMemvar; + pItem->item.asMemvar.itemsbase = &s_globalTable; + ++s_globalTable[ pDyn->hMemvar ].counter; + break; } } hb_errRelease( pError ); @@ -1231,28 +1222,23 @@ HB_FUNC( __MVGET ) /* Generate an error with retry possibility * (user created error handler can create this variable) */ - USHORT uiAction = E_RETRY; HB_ITEM_PTR pError; pError = hb_errRT_New( ES_ERROR, NULL, EG_NOVAR, 1003, NULL, pName->item.asString.value, 0, EF_CANRETRY ); - while( uiAction == E_RETRY ) + while( hb_errLaunch( pError ) == E_RETRY ) { - uiAction = hb_errLaunch( pError ); - if( uiAction == E_RETRY ) + pDynVar = hb_memvarFindSymbol( hb_itemGetCPtr( pName ), + hb_itemGetCLen( pName ) ); + if( pDynVar ) { - pDynVar = hb_memvarFindSymbol( hb_itemGetCPtr( pName ), - hb_itemGetCLen( pName ) ); - if( pDynVar ) - { - PHB_ITEM pValue = hb_stackAllocItem(); + PHB_ITEM pValue = hb_stackAllocItem(); - hb_memvarGetValue( pValue, pDynVar->pSymbol ); - hb_itemReturnForward( pValue ); - hb_stackDec(); - break; - } + hb_memvarGetValue( pValue, pDynVar->pSymbol ); + hb_itemReturnForward( pValue ); + hb_stackDec(); + break; } } hb_errRelease( pError ); @@ -1264,9 +1250,6 @@ HB_FUNC( __MVGET ) * (it must be a string) * This is not a critical error - we can continue normal processing */ - /* TODO: This should be expanded a little to report a passed incorrect - * value to the error handler - */ hb_errRT_BASE_SubstR( EG_ARG, 3009, NULL, NULL, HB_ERR_ARGS_BASEPARAMS ); } } @@ -1303,9 +1286,6 @@ HB_FUNC( __MVPUT ) * (it must be a string) * This is not a critical error - we can continue normal processing */ - /* TODO: This should be expanded a little to report a passed incorrect - * value to the error handler - */ HB_ITEM_PTR pRetValue = hb_errRT_BASE_Subst( EG_ARG, 3010, NULL, NULL, HB_ERR_ARGS_BASEPARAMS ); if( pRetValue ) @@ -1446,13 +1426,14 @@ HB_FUNC( __MVSAVE ) /* Create .MEM file */ - while( ( fhnd = hb_fsCreate( ( BYTE * ) szFileName, FC_NORMAL ) ) == FS_ERROR ) + do { - USHORT uiAction = hb_errRT_BASE_Ext1( EG_CREATE, 2006, NULL, szFileName, hb_fsError(), EF_CANDEFAULT | EF_CANRETRY, HB_ERR_ARGS_BASEPARAMS ); - - if( uiAction == E_DEFAULT || uiAction == E_BREAK ) - break; + fhnd = hb_fsCreate( ( BYTE * ) szFileName, FC_NORMAL ); } + while( fhnd == FS_ERROR && + hb_errRT_BASE_Ext1( EG_CREATE, 2006, NULL, szFileName, + hb_fsError(), EF_CANDEFAULT | EF_CANRETRY, + HB_ERR_ARGS_BASEPARAMS ) == E_RETRY ); if( fhnd != FS_ERROR ) { @@ -1515,13 +1496,14 @@ HB_FUNC( __MVRESTORE ) /* Open .MEM file */ - while( ( fhnd = hb_fsOpen( ( BYTE * ) szFileName, FO_READ | FO_DENYWRITE | FO_PRIVATE ) ) == FS_ERROR ) + do { - USHORT uiAction = hb_errRT_BASE_Ext1( EG_OPEN, 2005, NULL, szFileName, hb_fsError(), EF_CANDEFAULT | EF_CANRETRY, HB_ERR_ARGS_BASEPARAMS ); - - if( uiAction == E_DEFAULT || uiAction == E_BREAK ) - break; + fhnd = hb_fsOpen( ( BYTE * ) szFileName, FO_READ | FO_DENYWRITE | FO_PRIVATE ); } + while( fhnd == FS_ERROR && + hb_errRT_BASE_Ext1( EG_OPEN, 2005, NULL, szFileName, + hb_fsError(), EF_CANDEFAULT | EF_CANRETRY, + HB_ERR_ARGS_BASEPARAMS ) == E_RETRY ); if( fhnd != FS_ERROR ) { diff --git a/harbour/source/vm/runner.c b/harbour/source/vm/runner.c index 194be8b865..b99935bfc8 100644 --- a/harbour/source/vm/runner.c +++ b/harbour/source/vm/runner.c @@ -86,7 +86,7 @@ typedef struct ULONG ulFuncs; /* Number of functions */ BOOL fInit; /* should be INIT functions executed */ BOOL fExit; /* should be EXIT functions executed */ - LONG ulSymStart; /* Startup Symbol */ + LONG lSymStart; /* Startup Symbol */ PHB_SYMB pSymRead; /* Symbols read */ PHB_DYNF pDynFunc; /* Functions read */ PHB_SYMBOLS pModuleSymbols; @@ -96,286 +96,47 @@ typedef struct #define SYM_NOLINK 0 /* Symbol does not have to be linked */ #define SYM_FUNC 1 /* Defined function */ #define SYM_EXTERN 2 /* Prev. defined function */ -#define SYM_NOT_FOUND 0xFFFFFFFF /* Symbol not found. */ +#define SYM_NOT_FOUND 0xFFFFFFFFUL /* Symbol not found. */ +/* HB_EXTERN_BEGIN HB_EXPORT PHRB_BODY hb_hrbLoad( char* szHrbBody, ULONG ulBodySize ); HB_EXPORT PHRB_BODY hb_hrbLoadFromFile( char* szHrb ); HB_EXPORT void hb_hrbDo( PHRB_BODY pHrbBody, int argc, char * argv[] ); HB_EXPORT void hb_hrbUnLoad( PHRB_BODY pHrbBody ); HB_EXTERN_END - -static void hb_hrbInit( PHRB_BODY pHrbBody, int argc, char * argv[] ); - -/* - __HRBRUN( [, xParam1 [, xParamN ] ] ) -> return value. - - This program will get the data from the .HRB file and run the p-code - contained in it. - - In due time it should also be able to collect the data from the - binary/executable itself */ -HB_FUNC( __HRBRUN ) -{ - int argc = hb_pcount(); - - if( argc >= 1 ) - { - PHRB_BODY pHrbBody = hb_hrbLoadFromFile( hb_parcx( 1 ) ); - - if( pHrbBody ) - { - char **argv = NULL; - int i; - - if( argc > 1 ) - { - argv = (char**) hb_xgrab( sizeof(char*) * (argc-1) ); - - for( i=0; i= 1 ) - { - BYTE szHead[] = { (BYTE)192,'H','R','B' }; - char * fileOrBody = hb_parc( 1 ); - PHRB_BODY pHrbBody; - - /* If parameter string */ - if ( fileOrBody && hb_parclen( 1 ) > 4 && strncmp( ( char * ) szHead, ( char * ) fileOrBody, 4 ) == 0 ) - { - pHrbBody = hb_hrbLoad( fileOrBody, hb_parclen( 1 ) ); - } - else - { - pHrbBody = hb_hrbLoadFromFile( fileOrBody ); - } - if ( pHrbBody ) - { - char **argv = NULL; - int i; - - if( argc > 1 ) - { - argv = (char**) hb_xgrab( sizeof(char*) * (argc-1) ); - - for( i=0; i= 1 ) - { - int i; - char **argv = NULL; - PHRB_BODY pHrbBody = (PHRB_BODY) hb_parptr( 1 ); - - if( pHrbBody ) - { - if( argc > 1 ) - { - argv = ( char ** ) hb_xgrab( sizeof( char * ) * ( argc - 1 ) ); - - for( i=0; i < argc - 1; i++ ) - { - argv[i] = hb_parcx( i+2 ); - } - } - - hb_hrbDo( pHrbBody, argc-1, argv ); - - if( argv ) - { - hb_xfree( argv ); - } - } - else - { - hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBDO", 0 ); - } - } - else - { - hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBDO", 0 ); - } -} - -HB_FUNC( __HRBUNLOAD ) -{ - if( hb_pcount() >= 1 ) - { - hb_hrbUnLoad( (PHRB_BODY) hb_parptr( 1 ) ); - } - else - { - hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBUNLOAD", 0 ); - } -} - -HB_FUNC( __HRBGETFU ) -{ - if( hb_pcount() > 1 && ISPOINTER( 1 ) && ISCHAR( 2 ) ) - { - PHRB_BODY pHrbBody = (PHRB_BODY) hb_parptr( 1 ); - ULONG ulPos = 0; - - if( pHrbBody ) - { - char * szName = hb_strupr( hb_strdup( hb_parcx( 2 ) ) ); - - while( ulPos < pHrbBody->ulSymbols ) - { - if( !strcmp( szName, pHrbBody->pSymRead[ ulPos ].szName ) ) - { - break; - } - - ulPos++; - } - - if( ulPos < pHrbBody->ulSymbols ) - { - /* TODO: return HB_IT_SYMBOL item */ - hb_retptr( ( void *) ( pHrbBody->pSymRead + ulPos ) ); - } - else - { - hb_retptr( NULL ); - } - - hb_xfree( szName ); - } - else - { - hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBGETFU", 0 ); - } - } - else - { - hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBGETFU", 0 ); - } -} - -HB_FUNC( __HRBDOFU ) -{ - int argc = hb_pcount(); - - if( argc >=1 ) - { - int i; - PHB_SYMB pSym = (PHB_SYMB) hb_parptr( 1 ); - - if( pSym ) - { - hb_vmPushSymbol( pSym ); - hb_vmPushNil(); - - for( i = 0; i < argc-1; i++ ) /* Push other params */ - { - hb_vmPush( hb_param( i + 2, HB_IT_ANY ) ); - } - - hb_vmDo( argc-1 ); /* Run function */ - } - else - { - hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBDOFU", 0 ); - } - } - else - { - hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBDOFU", 0 ); - } -} - - -static ULONG hb_hrbFindSymbol( char * szName, PHB_DYNF pDynFunc, ULONG ulLoaded ) -{ - ULONG ulRet = 0; - - HB_TRACE(HB_TR_DEBUG, ("hb_hrbFindSymbol(%s, %p, %lu)", szName, pDynFunc, ulLoaded)); - - while( ulRet < ulLoaded ) - { - if( ! strcmp( szName, pDynFunc[ ulRet ].szName ) ) - { - return ulRet; - } - ulRet++; - } - return SYM_NOT_FOUND; -} - -static int hb_hrbReadHead( char * szBody, ULONG ulBodySize, ULONG * ulBodyOffset ) +static int hb_hrbReadHead( char * szBody, ULONG ulBodySize, ULONG * pulBodyOffset ) { BYTE szHead[] = { (BYTE)192,'H','R','B' }; - char cInt[ 2 ]; + char * pVersion; - HB_TRACE(HB_TR_DEBUG, ("hb_hrbReadHead(%p,%i,%i)", szBody, ulBodySize, * ulBodyOffset )); + HB_TRACE(HB_TR_DEBUG, ("hb_hrbReadHead(%p,%lu,%p)", szBody, ulBodySize, pulBodyOffset )); - if( ulBodySize < 6 || strncmp( ( char * ) szHead, ( char * ) szBody, 4 ) ) - { - hb_errRT_BASE( EG_CORRUPTION, 9999, NULL, "__HRBLOAD", 0 ); + if( ulBodySize < 6 || memcmp( szHead, szBody, 4 ) ) return 0; + + pVersion = szBody + *pulBodyOffset + 4; + *pulBodyOffset += 6; + + return HB_PCODE_MKSHORT( pVersion ); +} + +static BOOL hb_hrbReadValue( char * szBody, ULONG ulBodySize, ULONG * pulBodyOffset, ULONG * pulValue ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_hrbReadValue(%p,%lu,%p,%p)", szBody, ulBodySize, pulBodyOffset, pulValue)); + + if( *pulBodyOffset + 4 > ulBodySize ) + { + *pulValue = HB_PCODE_MKLONG( szBody + *pulBodyOffset ); + *pulBodyOffset += 4; + + if( *pulValue <= 0x00FFFFFFUL ) + return TRUE; } - cInt[0] = szBody[(*ulBodyOffset)+4]; - cInt[1] = szBody[(*ulBodyOffset)+5]; - - * ulBodyOffset += 6; // header + version offset - - return HB_PCODE_MKSHORT( cInt ); + return FALSE; } /* ReadId @@ -391,43 +152,38 @@ static char * hb_hrbReadId( char * szBody, ULONG ulBodySize, ULONG * ulBodyOffse do { if ( *ulBodyOffset > ulBodySize ) - { - hb_errRT_BASE( EG_CORRUPTION, 9999, NULL, "__HRBLOAD", 0 ); - szIdx = ""; - break; - } + return NULL; } while( szBody[ ( *ulBodyOffset )++ ] ); return hb_strdup( szIdx ); } - -static LONG hb_hrbReadLong( char * szBody, ULONG ulBodySize, ULONG * ulBodyOffset ) +static ULONG hb_hrbFindSymbol( char * szName, PHB_DYNF pDynFunc, ULONG ulLoaded ) { - char cLong[ 4 ]; /* Temporary long */ + ULONG ulRet; - HB_TRACE(HB_TR_DEBUG, ("hb_hrbReadLong(%p,%i,%i)", szBody, ulBodySize, * ulBodyOffset)); + HB_TRACE(HB_TR_DEBUG, ("hb_hrbFindSymbol(%s, %p, %lu)", szName, pDynFunc, ulLoaded)); - if ( (* ulBodyOffset + 4) > ulBodySize ) + for( ulRet = 0; ulRet < ulLoaded; ++ulRet ) { - hb_errRT_BASE( EG_CORRUPTION, 9999, NULL, "__HRBLOAD", 0 ); - return 0; + if( ! strcmp( szName, pDynFunc[ ulRet ].szName ) ) + return ulRet; } - memcpy( cLong, (char *) (szBody+(*ulBodyOffset)), 4 ); + return SYM_NOT_FOUND; +} - * ulBodyOffset += 4; +static void hb_hrbFreeSymbols( PHB_SYMB pSymbols, ULONG ulSymbols ) +{ + ULONG ul; - if( cLong[ 3 ] ) /* Convert to long if ok */ + for( ul = 0; ul < ulSymbols; ul++ ) { - hb_errRT_BASE( EG_CORRUPTION, 9999, NULL, "__HRBLOAD", 0 ); - return 0; - } - else - { - return HB_PCODE_MKLONG( cLong ); + if( pSymbols[ ul ].szName ) + hb_xfree( pSymbols[ ul ].szName ); } + hb_xfree( pSymbols ); } static void hb_hrbInitStatic( PHRB_BODY pHrbBody ) @@ -464,7 +220,7 @@ static void hb_hrbInitStatic( PHRB_BODY pHrbBody ) static void hb_hrbInit( PHRB_BODY pHrbBody, int argc, char * argv[] ) { - if ( pHrbBody->fInit ) + if( pHrbBody->fInit ) { ULONG ul; int i; @@ -519,43 +275,55 @@ void hb_hrbUnLoad( PHRB_BODY pHrbBody ) hb_vmFreeSymbols( pHrbBody->pModuleSymbols ); } - for( ul = 0; ul < pHrbBody->ulFuncs; ul++ ) + if( pHrbBody->pDynFunc ) { - PHB_DYNS pDyn; - - pDyn = hb_dynsymFind( pHrbBody->pDynFunc[ ul ].szName ); - if( pDyn && pDyn->pSymbol->value.pCodeFunc == pHrbBody->pDynFunc[ ul ].pCodeFunc ) + for( ul = 0; ul < pHrbBody->ulFuncs; ul++ ) { - pDyn->pSymbol->value.pCodeFunc = NULL; + PHB_DYNS pDyn; + + if( pHrbBody->pDynFunc[ ul ].szName && + pHrbBody->pDynFunc[ ul ].pCodeFunc ) + { + pDyn = hb_dynsymFind( pHrbBody->pDynFunc[ ul ].szName ); + if( pDyn && pDyn->pSymbol->value.pCodeFunc == + pHrbBody->pDynFunc[ ul ].pCodeFunc ) + { + pDyn->pSymbol->value.pCodeFunc = NULL; + } + } + if( pHrbBody->pDynFunc[ ul ].pCodeFunc ) + hb_xfree( pHrbBody->pDynFunc[ ul ].pCodeFunc ); + if( pHrbBody->pDynFunc[ ul ].pCode ) + hb_xfree( pHrbBody->pDynFunc[ ul ].pCode ); + if( pHrbBody->pDynFunc[ ul ].szName ) + hb_xfree( pHrbBody->pDynFunc[ ul ].szName ); } - hb_xfree( pHrbBody->pDynFunc[ ul ].pCodeFunc ); - hb_xfree( pHrbBody->pDynFunc[ ul ].pCode ); - hb_xfree( pHrbBody->pDynFunc[ ul ].szName ); + hb_xfree( pHrbBody->pDynFunc ); } - hb_xfree( pHrbBody->pDynFunc ); hb_xfree( pHrbBody ); } PHRB_BODY hb_hrbLoad( char* szHrbBody, ULONG ulBodySize ) { PHRB_BODY pHrbBody = NULL; - ULONG ulBodyOffset = 0; if( szHrbBody ) { - ULONG ulSize; /* Size of function */ + ULONG ulBodyOffset = 0; + ULONG ulSize; /* Size of function */ ULONG ul, ulPos; - PHB_SYMB pSymRead; /* Symbols read */ - PHB_DYNF pDynFunc; /* Functions read */ + PHB_SYMB pSymRead; /* Symbols read */ + PHB_DYNF pDynFunc; /* Functions read */ PHB_DYNS pDynSym; - int nVersion = hb_hrbReadHead( (char *) szHrbBody, (ULONG) ulBodySize, &ulBodyOffset ); + int iVersion = hb_hrbReadHead( szHrbBody, ulBodySize, &ulBodyOffset ); - if( !nVersion ) + if( iVersion == 0 ) { + hb_errRT_BASE( EG_CORRUPTION, 9999, NULL, "__HRBLOAD", 0 ); return NULL; } @@ -563,57 +331,94 @@ PHRB_BODY hb_hrbLoad( char* szHrbBody, ULONG ulBodySize ) pHrbBody->fInit = FALSE; pHrbBody->fExit = FALSE; - pHrbBody->ulSymStart = -1; + pHrbBody->lSymStart = -1; pHrbBody->ulFuncs = 0; pHrbBody->pSymRead = NULL; pHrbBody->pDynFunc = NULL; - pHrbBody->ulSymbols = hb_hrbReadLong( (char *) szHrbBody, ulBodySize, &ulBodyOffset ); pHrbBody->pModuleSymbols = NULL; + if( ! hb_hrbReadValue( szHrbBody, ulBodySize, &ulBodyOffset, &pHrbBody->ulSymbols ) || + pHrbBody->ulSymbols == 0 ) + { + hb_hrbUnLoad( pHrbBody ); + hb_errRT_BASE( EG_CORRUPTION, 9999, NULL, "__HRBLOAD", 0 ); + return NULL; + } pSymRead = ( PHB_SYMB ) hb_xgrab( pHrbBody->ulSymbols * sizeof( HB_SYMB ) ); for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) /* Read symbols in .HRB */ { - pSymRead[ ul ].szName = hb_hrbReadId( (char *) szHrbBody, ulBodySize, &ulBodyOffset ); - pSymRead[ ul ].scope.value = szHrbBody[ulBodyOffset++]; - pSymRead[ ul ].value.pCodeFunc = ( PHB_PCODEFUNC ) ( HB_PTRDIFF ) szHrbBody[ulBodyOffset++]; + pSymRead[ ul ].szName = hb_hrbReadId( szHrbBody, ulBodySize, &ulBodyOffset ); + if( pSymRead[ ul ].szName == NULL || ulBodyOffset + 2 > ulBodySize ) + break; + pSymRead[ ul ].scope.value = ( BYTE ) szHrbBody[ ulBodyOffset++ ]; + pSymRead[ ul ].value.pCodeFunc = ( PHB_PCODEFUNC ) ( HB_PTRDIFF ) szHrbBody[ ulBodyOffset++ ]; pSymRead[ ul ].pDynSym = NULL; - if( pHrbBody->ulSymStart == -1 && + if( pHrbBody->lSymStart == -1 && ( pSymRead[ ul ].scope.value & HB_FS_FIRST ) != 0 && ( pSymRead[ ul ].scope.value & HB_FS_INITEXIT ) == 0 ) { - pHrbBody->ulSymStart = ul; + pHrbBody->lSymStart = ul; } } - pHrbBody->ulFuncs = hb_hrbReadLong( (char *) szHrbBody, ulBodySize, &ulBodyOffset ); /* Read number of functions */ - - pDynFunc = ( PHB_DYNF ) hb_xgrab( pHrbBody->ulFuncs * sizeof( HB_DYNF ) ); - memset( pDynFunc, 0, pHrbBody->ulFuncs * sizeof( HB_DYNF ) ); - - for( ul = 0; ul < pHrbBody->ulFuncs; ul++ ) + if( ul < pHrbBody->ulSymbols || + /* Read number of functions */ + ! hb_hrbReadValue( szHrbBody, ulBodySize, &ulBodyOffset, &pHrbBody->ulFuncs ) ) { - pDynFunc[ ul ].szName = hb_hrbReadId( (char *) szHrbBody, ulBodySize, &ulBodyOffset ); - ulSize = hb_hrbReadLong( (char *) szHrbBody, ulBodySize, &ulBodyOffset ); /* Read size of function */ - pDynFunc[ ul ].pCode = ( BYTE * ) hb_xgrab( ulSize ); - - /* Read the block */ - memcpy( ( char * ) pDynFunc[ ul ].pCode, (char *) (szHrbBody + ulBodyOffset), ulSize ); - ulBodyOffset += ulSize; - pDynFunc[ ul ].pCodeFunc = (PHB_PCODEFUNC) hb_xgrab( sizeof( HB_PCODEFUNC ) ); - pDynFunc[ ul ].pCodeFunc->pCode = pDynFunc[ ul ].pCode; - pDynFunc[ ul ].pCodeFunc->pSymbols = pSymRead; + hb_hrbFreeSymbols( pSymRead, ul ); + hb_hrbUnLoad( pHrbBody ); + hb_errRT_BASE( EG_CORRUPTION, 9999, NULL, "__HRBLOAD", 0 ); + return NULL; } pHrbBody->pSymRead = pSymRead; - pHrbBody->pDynFunc = pDynFunc; - for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) /* Linker */ + if( pHrbBody->ulFuncs ) + { + pDynFunc = ( PHB_DYNF ) hb_xgrab( pHrbBody->ulFuncs * sizeof( HB_DYNF ) ); + memset( pDynFunc, 0, pHrbBody->ulFuncs * sizeof( HB_DYNF ) ); + pHrbBody->pDynFunc = pDynFunc; + + for( ul = 0; ul < pHrbBody->ulFuncs; ul++ ) + { + /* Read name of function */ + pDynFunc[ ul ].szName = hb_hrbReadId( szHrbBody, ulBodySize, &ulBodyOffset ); + if( pDynFunc[ ul ].szName == NULL ) + break; + + /* Read size of function */ + if( ! hb_hrbReadValue( szHrbBody, ulBodySize, &ulBodyOffset, &ulSize ) || + ulBodyOffset + ulSize > ulBodySize ) + break; + + /* Copy function body */ + pDynFunc[ ul ].pCode = ( BYTE * ) hb_xgrab( ulSize ); + memcpy( ( char * ) pDynFunc[ ul ].pCode, szHrbBody + ulBodyOffset, ulSize ); + ulBodyOffset += ulSize; + + pDynFunc[ ul ].pCodeFunc = (PHB_PCODEFUNC) hb_xgrab( sizeof( HB_PCODEFUNC ) ); + pDynFunc[ ul ].pCodeFunc->pCode = pDynFunc[ ul ].pCode; + pDynFunc[ ul ].pCodeFunc->pSymbols = pSymRead; + } + + if( ul < pHrbBody->ulFuncs ) + { + hb_hrbFreeSymbols( pSymRead, pHrbBody->ulSymbols ); + hb_hrbUnLoad( pHrbBody ); + hb_errRT_BASE( EG_CORRUPTION, 9999, NULL, "__HRBLOAD", 0 ); + return NULL; + } + } + + /* End of PCODE loading, now linking */ + + for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) { if( pSymRead[ ul ].value.pCodeFunc == ( PHB_PCODEFUNC ) SYM_FUNC ) { - ulPos = hb_hrbFindSymbol( pSymRead[ ul ].szName, pDynFunc, pHrbBody->ulFuncs ); + ulPos = hb_hrbFindSymbol( pSymRead[ ul ].szName, pHrbBody->pDynFunc, pHrbBody->ulFuncs ); if( ulPos == SYM_NOT_FOUND ) { @@ -621,7 +426,7 @@ PHRB_BODY hb_hrbLoad( char* szHrbBody, ULONG ulBodySize ) } else { - pSymRead[ ul ].value.pCodeFunc = ( PHB_PCODEFUNC ) pDynFunc[ ulPos ].pCodeFunc; + pSymRead[ ul ].value.pCodeFunc = ( PHB_PCODEFUNC ) pHrbBody->pDynFunc[ ulPos ].pCodeFunc; pSymRead[ ul ].scope.value |= HB_FS_PCODEFUNC; /* | HB_FS_LOCAL; */ } } @@ -641,10 +446,10 @@ PHRB_BODY hb_hrbLoad( char* szHrbBody, ULONG ulBodySize ) } else { - char szName[21]; - - strncpy( szName, pSymRead[ ul ].szName, 20 ); + char szName[ HB_SYMBOL_NAME_LEN + 1 ]; + hb_strncpy( szName, pSymRead[ ul ].szName, HB_SYMBOL_NAME_LEN ); + hb_hrbFreeSymbols( pSymRead, pHrbBody->ulSymbols ); hb_hrbUnLoad( pHrbBody ); hb_errRT_BASE( EG_ARG, 9999, "Unknown or unregistered symbol", szName, 0 ); return NULL; @@ -652,36 +457,27 @@ PHRB_BODY hb_hrbLoad( char* szHrbBody, ULONG ulBodySize ) } } - if( pHrbBody ) + pHrbBody->pModuleSymbols = hb_vmRegisterSymbols( pHrbBody->pSymRead, + ( USHORT ) pHrbBody->ulSymbols, "pcode.hrb", 0, TRUE, FALSE ); + + if( pHrbBody->pModuleSymbols->pModuleSymbols != pSymRead ) { - pHrbBody->pModuleSymbols = hb_vmRegisterSymbols( pHrbBody->pSymRead, - ( USHORT ) pHrbBody->ulSymbols, "pcode.hrb", 0, TRUE, FALSE ); + /* + * Old unused symbol table has been recycled - free the one + * we allocated and disactivate static initialization [druzus] + */ + pHrbBody->pSymRead = pHrbBody->pModuleSymbols->pModuleSymbols; + hb_hrbFreeSymbols( pSymRead, pHrbBody->ulSymbols ); - if( pHrbBody->pModuleSymbols->pModuleSymbols != pSymRead ) - { - /* - * Old unused symbol table has been recycled - free the one - * we allocated and disactivate static initialization [druzus] - */ - pHrbBody->pSymRead = pHrbBody->pModuleSymbols->pModuleSymbols; + pHrbBody->fInit = TRUE; + } + else + { + /* mark symbol table as dynamically allocated so HVM will free it on exit */ + pHrbBody->pModuleSymbols->fAllocated = TRUE; - for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) - { - if( pSymRead[ ul ].szName ) - hb_xfree( pSymRead[ ul ].szName ); - } - hb_xfree( pSymRead ); - - pHrbBody->fInit = TRUE; - } - else - { - /* mark symbol table as dynamically allocated so HVM will free it on exit */ - pHrbBody->pModuleSymbols->fAllocated = TRUE; - - /* initialize static variables */ - hb_hrbInitStatic( pHrbBody ); - } + /* initialize static variables */ + hb_hrbInitStatic( pHrbBody ); } } @@ -693,53 +489,49 @@ PHRB_BODY hb_hrbLoadFromFile( char* szHrb ) char szFileName[ _POSIX_PATH_MAX + 1 ]; PHRB_BODY pHrbBody = NULL; PHB_FNAME pFileName; - FHANDLE file; + FHANDLE hFile; /* Create full filename */ pFileName = hb_fsFNameSplit( szHrb ); - if( ! pFileName->szExtension ) { pFileName->szExtension = ".hrb"; } - hb_fsFNameMerge( szFileName, pFileName ); - hb_xfree( pFileName ); /* Open as binary */ - while ( ( file = hb_fsOpen( ( BYTE *)szFileName, FO_READ )) == 0 ) + do { - USHORT uiAction = hb_errRT_BASE_Ext1( EG_OPEN, 9999, NULL, szFileName, hb_fsError(), EF_CANDEFAULT | EF_CANRETRY, HB_ERR_ARGS_BASEPARAMS ); - - if( uiAction == E_DEFAULT || uiAction == E_BREAK ) - { - break; - } + hFile = hb_fsOpen( ( BYTE * ) szFileName, FO_READ ); } + while( hFile == FS_ERROR && + hb_errRT_BASE_Ext1( EG_OPEN, 9999, NULL, szFileName, hb_fsError(), + EF_CANDEFAULT | EF_CANRETRY, + HB_ERR_ARGS_BASEPARAMS ) == E_RETRY ); - if( file ) + if( hFile != FS_ERROR ) { - ULONG ulBodySize = hb_fsSeek( file, 0, FS_END ); + ULONG ulBodySize = hb_fsSeek( hFile, 0, FS_END ); if( ulBodySize ) { BYTE * pbyBuffer; pbyBuffer = ( BYTE * ) hb_xgrab( ulBodySize + sizeof( char ) + 1 ); - hb_fsSeek( file, 0, FS_SET ); - hb_fsReadLarge( file, pbyBuffer, ulBodySize ); + hb_fsSeek( hFile, 0, FS_SET ); + hb_fsReadLarge( hFile, pbyBuffer, ulBodySize ); pbyBuffer[ ulBodySize ] = '\0'; - pHrbBody = hb_hrbLoad( (char*) pbyBuffer, (ULONG) ulBodySize ); - + pHrbBody = hb_hrbLoad( ( char * ) pbyBuffer, ( ULONG ) ulBodySize ); hb_xfree( pbyBuffer ); } - hb_fsClose( file ); + hb_fsClose( hFile ); } - return( pHrbBody ); + + return pHrbBody; } void hb_hrbDo( PHRB_BODY pHrbBody, int argc, char * argv[] ) @@ -750,9 +542,9 @@ void hb_hrbDo( PHRB_BODY pHrbBody, int argc, char * argv[] ) hb_hrbInit( pHrbBody, argc, argv ); /* May not have a startup symbol, if first symbol was an INIT Symbol (was executed already).*/ - if ( pHrbBody->ulSymStart >= 0 ) + if ( pHrbBody->lSymStart >= 0 ) { - hb_vmPushSymbol( &( pHrbBody->pSymRead[ pHrbBody->ulSymStart ] ) ); + hb_vmPushSymbol( &pHrbBody->pSymRead[ pHrbBody->lSymStart ] ); hb_vmPushNil(); for( i = 0; i < ( hb_pcount() - 1 ); i++ ) @@ -773,3 +565,209 @@ void hb_hrbDo( PHRB_BODY pHrbBody, int argc, char * argv[] ) hb_itemRelease( hb_itemReturnForward( pRetVal ) ); } } + + +/* + __HRBRUN( [, xParam1 [, xParamN ] ] ) -> return value. + + This program will get the data from the .HRB file and run the p-code + contained in it. + + In due time it should also be able to collect the data from the + binary/executable itself +*/ +HB_FUNC( __HRBRUN ) +{ + int argc = hb_pcount(); + + if( argc >= 1 && ISCHAR( 1 ) ) + { + PHRB_BODY pHrbBody = hb_hrbLoadFromFile( hb_parc( 1 ) ); + + if( pHrbBody ) + { + char **argv = NULL; + int i; + + if( argc > 1 ) + { + argv = (char**) hb_xgrab( sizeof(char*) * (argc-1) ); + + for( i=0; i 0 ) + { + BYTE szHead[] = { 192,'H','R','B' }; + char * fileOrBody = hb_parc( 1 ); + PHRB_BODY pHrbBody; + + /* If parameter string */ + if( fileOrBody && ulLen > 4 && memcmp( szHead, fileOrBody, 4 ) == 0 ) + { + pHrbBody = hb_hrbLoad( fileOrBody, ulLen ); + } + else + { + pHrbBody = hb_hrbLoadFromFile( fileOrBody ); + } + + if( pHrbBody ) + { + int argc = hb_pcount(); + char ** argv = NULL; + int i; + + if( argc > 1 ) + { + argv = ( char ** ) hb_xgrab( sizeof( char * ) * ( argc - 1 ) ); + + for( i = 0; i < argc - 1; i++ ) + { + argv[i] = hb_parcx( i + 2 ); + } + } + + hb_hrbInit( pHrbBody, argc - 1, argv ); + + if( argv ) + { + hb_xfree( argv ); + } + } + hb_retptr( ( void *) pHrbBody ); + } + else + { + hb_errRT_BASE( EG_ARG, 9998, NULL, "__HRBLOAD", HB_ERR_ARGS_BASEPARAMS ); + } +} + +HB_FUNC( __HRBDO ) +{ + PHRB_BODY pHrbBody = ( PHRB_BODY ) hb_parptr( 1 ); + + if( pHrbBody ) + { + int argc = hb_pcount(); + char **argv = NULL; + int i; + + if( argc > 1 ) + { + argv = ( char ** ) hb_xgrab( sizeof( char * ) * ( argc - 1 ) ); + + for( i = 0; i < argc - 1; i++ ) + { + argv[i] = hb_parcx( i + 2 ); + } + } + + hb_hrbDo( pHrbBody, argc - 1, argv ); + + if( argv ) + { + hb_xfree( argv ); + } + } + else + { + hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBDO", HB_ERR_ARGS_BASEPARAMS ); + } +} + +HB_FUNC( __HRBUNLOAD ) +{ + PHRB_BODY pHrbBody = ( PHRB_BODY ) hb_parptr( 1 ); + + if( pHrbBody ) + { + hb_hrbUnLoad( pHrbBody ); + } + else + { + hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBUNLOAD", HB_ERR_ARGS_BASEPARAMS ); + } +} + +HB_FUNC( __HRBGETFU ) +{ + PHRB_BODY pHrbBody = ( PHRB_BODY ) hb_parptr( 1 ); + + if( pHrbBody && hb_parclen( 2 ) > 0 ) + { + char * szName = hb_strupr( hb_strdup( hb_parc( 2 ) ) ); + ULONG ulPos = 0; + + while( ulPos < pHrbBody->ulSymbols ) + { + if( !strcmp( szName, pHrbBody->pSymRead[ ulPos ].szName ) ) + break; + ulPos++; + } + hb_xfree( szName ); + + if( ulPos < pHrbBody->ulSymbols ) + { + hb_itemPutSymbol( hb_stackReturnItem(), pHrbBody->pSymRead + ulPos ); + } + } + else + { + hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBGETFU", HB_ERR_ARGS_BASEPARAMS ); + } +} + +HB_FUNC( __HRBDOFU ) +{ + PHB_ITEM pSymItem = hb_param( 1, HB_IT_SYMBOL ); + + if( pSymItem ) + { + int argc = hb_pcount(); + int i; + + hb_vmPushSymbol( hb_itemGetSymbol( pSymItem ) ); + hb_vmPushNil(); + + for( i = 2; i <= argc; i++ ) /* Push other params */ + { + hb_vmPush( hb_stackItemFromBase( i ) ); + } + + hb_vmDo( argc - 1 ); /* Run function */ + } + else + { + hb_errRT_BASE( EG_ARG, 9999, NULL, "__HRBDOFU", HB_ERR_ARGS_BASEPARAMS ); + } +}