2006-07-13 14:00 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/common.mak
  * harbour/source/rtl/Makefile
  + harbour/source/rtl/dbjoin.prg
    + added __dbJoin() - code by Pavel Tsarenko borrowed from xHarbour

  * harbour/source/rdd/dbtotal.prg
    + added __dbTransRec() and updated to use it like in Clipper
      Can someone tell me why we have Set( _SET_CANCEL, .f. ) in this
      function?

  * harbour/source/rtl/dummy.prg
    - removed __dbJoin() and __dbTransRec()
      Now only one function is defined here: __dbFList()
      I have no idea what it does - if someone knows then please
      implement it.

  * harbour/include/hbvm.h
  * harbour/source/vm/hvm.c
    * formatting

  * harbour/source/rdd/dbcmd.c
    * keep strict Clipper compatibility in DBCREATE() parameters

  * harbour/source/rdd/dbsort.prg
  * harbour/source/rdd/dbstrux.prg
  * harbour/source/rtl/dbdelim.prg
    * updated for strict Clipper DBCREATE() parameters
This commit is contained in:
Przemyslaw Czerpak
2006-07-13 12:10:54 +00:00
parent c944577d58
commit 90caeffb84
12 changed files with 340 additions and 195 deletions

View File

@@ -8,6 +8,35 @@
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
*/
Memo fields only.
! Fixed error when passing xFor parameter as a string.
! Set(_SET_CANCEL...) calls removed.
+ Formatting, added few comments, CA-Cl*pper differences.
2006-07-13 14:00 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/common.mak
* harbour/source/rtl/Makefile
+ harbour/source/rtl/dbjoin.prg
+ added __dbJoin() - code by Pavel Tsarenko borrowed from xHarbour
* harbour/source/rdd/dbtotal.prg
+ added __dbTransRec() and updated to use it like in Clipper
Can someone tell me why we have Set( _SET_CANCEL, .f. ) in this
function?
* harbour/source/rtl/dummy.prg
- removed __dbJoin() and __dbTransRec()
Now only one function is defined here: __dbFList()
I have no idea what it does - if someone knows then please
implement it.
* harbour/include/hbvm.h
* harbour/source/vm/hvm.c
* formatting
* harbour/source/rdd/dbcmd.c
* keep strict Clipper compatibility in DBCREATE() parameters
* harbour/source/rdd/dbsort.prg
* harbour/source/rdd/dbstrux.prg
* harbour/source/rtl/dbdelim.prg

View File

@@ -413,6 +413,7 @@ RTL_LIB_OBJS = \
$(OBJ_DIR)\dbedit.obj \
$(OBJ_DIR)\dbdelim.obj \
$(OBJ_DIR)\dbsdf.obj \
$(OBJ_DIR)\dbjoin.obj \
$(OBJ_DIR)\devoutp.obj \
$(OBJ_DIR)\dircmd.obj \
$(OBJ_DIR)\dummy.obj \

View File

@@ -99,12 +99,12 @@ extern HB_EXPORT PHB_SYMB hb_vmProcessSymbolsEx( PHB_SYMB pSymbols, USHORT uiSym
extern HB_EXPORT void hb_vmSymbolInit_RT( void ); /* initialization of runtime support symbols */
/* Harbour virtual machine escaping API */
extern HB_EXPORT void hb_vmRequestDebug( void );
extern HB_EXPORT void hb_vmRequestBreak( PHB_ITEM pItem );
extern HB_EXPORT void hb_vmRequestCancel( void );
extern HB_EXPORT void hb_vmRequestDebug( void );
extern HB_EXPORT void hb_vmRequestQuit( void );
extern HB_EXPORT void hb_vmRequestEndProc( void );
extern HB_EXPORT USHORT hb_vmRequestQuery( void );
extern HB_EXPORT void hb_vmRequestQuit( void );
/* Return values of hb_vmRequestQuery() */
#define HB_QUIT_REQUESTED 1 /* immediately quit the application */

View File

@@ -1775,7 +1775,7 @@ static ERRCODE hb_rddCreateTable( char * szFileName, PHB_ITEM pStruct,
* In Clipper the arguments are:
* dbCreate( cFile, aStruct, cRDD, lKeepOpen, cAlias, cDelimArg )
* In Harbour:
* dbCreate( cFile, aStruct, cRDD, lKeepOpen, cAlias, cCodePage, nConnection, cDelimArg )
* dbCreate( cFile, aStruct, cRDD, lKeepOpen, cAlias, cDelimArg, cCodePage, nConnection )
*/
HB_FUNC( DBCREATE )
{
@@ -1786,9 +1786,10 @@ HB_FUNC( DBCREATE )
ULONG ulConnection;
/*
* NOTE: 4-th and 5-th parameters are undocumented Clipper ones
* 4-th is boolean flag indicating if file should stay open and
* NOTE: 4-th, 5-th and 6-th parameters are undocumented Clipper ones
* 4-th is boolean flag indicating if file should stay open
* 5-th is alias - if not given then WA is open without alias
* 6-th is optional DELIMITED value used by some RDDs like DELIM
*/
szFileName = hb_parc( 1 );
@@ -1797,9 +1798,9 @@ HB_FUNC( DBCREATE )
fKeepOpen = ISLOG( 4 );
fCurrArea = fKeepOpen && !hb_parl( 4 );
szAlias = hb_parc( 5 );
szCpId = hb_parc( 6 );
ulConnection = hb_parnl( 7 );
pDelim = hb_param( 8, HB_IT_ANY );
pDelim = hb_param( 6, HB_IT_ANY );
szCpId = hb_parc( 7 );
ulConnection = hb_parnl( 8 );
/*
* Clipper allows to use empty struct array for RDDs which does not
@@ -4716,20 +4717,26 @@ HB_FUNC( DBSKIPPER )
nRecs = hb_parnl( 1 ) ;
}
SELF_EOF( pArea, &bBEof );
if( SELF_EOF( pArea, &bBEof ) != SUCCESS )
return;
if( nRecs == 0 )
{
SELF_SKIP( pArea, 0 );
if( SELF_SKIP( pArea, 0 ) != SUCCESS )
return;
}
else if( nRecs > 0 && !bBEof )
{
while( nSkipped < nRecs )
{
SELF_SKIP( pArea, 1 );
SELF_EOF( pArea, &bBEof );
if( SELF_SKIP( pArea, 1 ) != SUCCESS )
return;
if( SELF_EOF( pArea, &bBEof ) != SUCCESS )
return;
if( bBEof )
{
SELF_SKIP( pArea, -1 );
if( SELF_SKIP( pArea, -1 ) != SUCCESS )
return;
nRecs = nSkipped ;
}
else
@@ -4742,8 +4749,10 @@ HB_FUNC( DBSKIPPER )
{
while( nSkipped > nRecs )
{
SELF_SKIP( pArea, -1 );
SELF_BOF( pArea, &bBEof );
if( SELF_SKIP( pArea, -1 ) != SUCCESS )
return;
if( SELF_BOF( pArea, &bBEof ) != SUCCESS )
return;
if( bBEof )
{
nRecs = nSkipped ;

View File

@@ -66,7 +66,7 @@ FUNCTION __dbSort( cToFileName, aFields, bFor, bWhile, nNext, nRecord, lRest,;
BEGIN SEQUENCE
dbCreate( cToFileName, aStruct, cRddName, .T., "", cdpID, nConnection )
dbCreate( cToFileName, aStruct, cRddName, .T., "", , cdpID, nConnection )
nToArea := Select()
dbSelectArea( nArea )
__dbArrange( nToArea, aStruct, bFor, bWhile, nNext, nRecord, lRest, aFields )

View File

@@ -115,11 +115,11 @@ FUNCTION __dbCreate( cFileName, cFileFrom, cRDDName, lNew, cAlias, cdpId, nConne
IF Empty( cFileFrom )
dbCreate( cFileName, {;
{ "FIELD_NAME", "C", 10, 0 },;
{ "FIELD_TYPE", "C", 1, 0 },;
{ "FIELD_LEN" , "N", 3, 0 },;
{ "FIELD_DEC" , "N", 3, 0 } }, cRDDName,,, cdpId, nConnection )
dbCreate( cFileName, { { "FIELD_NAME", "C", 10, 0 },;
{ "FIELD_TYPE", "C", 1, 0 },;
{ "FIELD_LEN" , "N", 3, 0 },;
{ "FIELD_DEC" , "N", 3, 0 } },;
cRDDName,,,, cdpId, nConnection )
dbUseArea( .F., cRDDName, cFileName, cAlias,,, cdpId, nConnection )
ELSE
@@ -140,7 +140,7 @@ FUNCTION __dbCreate( cFileName, cFileFrom, cRDDName, lNew, cAlias, cdpId, nConne
( aField[ DBS_LEN ] += aField[ DBS_DEC ] * 256, ;
aField[ DBS_DEC ] := 0 ), NIL ) } )
dbCreate( cFileName, aStruct, cRDDName,,, cdpId, nConnection )
dbCreate( cFileName, aStruct, cRDDName,,,, cdpId, nConnection )
dbUseArea( lNew, cRDDName, cFileName, cAlias,,, cdpId, nConnection )
ENDIF

View File

@@ -55,171 +55,154 @@
#include "error.ch"
FUNCTION __DBTOTAL( cFile, xKey, aFields, ;
xFor, xWhile, nNext, nRec, lRest, rdd, ;
nConnection, cdpId)
xFor, xWhile, nNext, nRec, lRest, rdd, ;
nConnection, cdpId )
LOCAL CurSelect
LOCAL NewSelect
LOCAL aNewDbStruct
LOCAL aGetField
LOCAL aFieldsSum
LOCAL lDbTransRecord
LOCAL xCurKey
LOCAL bKeyBlock
LOCAL bForBlock
LOCAL bWhileBlock
LOCAL cset
LOCAL flag_err
LOCAL err_block
LOCAL wRec
LOCAL err
LOCAL CurSelect
LOCAL NewSelect
LOCAL aNewDbStruct
LOCAL aGetField
LOCAL aFieldsSum
LOCAL lDbTransRecord
LOCAL xCurKey
LOCAL bKeyBlock
LOCAL bForBlock
LOCAL bWhileBlock
LOCAL cset
LOCAL flag_err
LOCAL err_block
LOCAL wRec
LOCAL err
err_block := Errorblock( { | x | Break( x ) } )
flag_err := .F.
cset := Set( _SET_CANCEL, .f. )
err_block := Errorblock( { | x | Break( x ) } )
flag_err := .F.
cset := Set( _SET_CANCEL, .f. )
IF ( Valtype( xWhile ) == "C" )
bWhileBlock := "{||" + xWhile + "}"
bWhileBlock := &bWhileBlock
ELSEIF ( Valtype( xWhile ) != "B" )
bWhileBlock := { || .t. }
ELSE
bWhileBlock := xWhile
lRest := .T.
ENDIF
IF ( Valtype( xWhile ) == "C" )
bWhileBlock := "{||" + xWhile + "}"
bWhileBlock := &bWhileBlock
ELSE
IF ( Valtype( xWhile ) != "B" )
bWhileBlock := { || .t. }
ELSE
bWhileBlock := xWhile
lRest := .T.
ENDIF
IF ( Valtype( xFor ) == "C" )
bForBlock := "{||" + xFor + "}"
bForBlock := &xFor
ELSEIF ( Valtype( xFor ) != "B" )
bForBlock := { || .t. }
ELSE
bForBlock := xFor
ENDIF
ENDIF
IF ( Valtype( xFor ) == "C" )
bForBlock := "{||" + xFor + "}"
bForBlock := &xFor
ELSE
IF ( Valtype( xFor ) != "B" )
bForBlock := { || .t. }
ELSE
bForBlock := xFor
ENDIF
ENDIF
Iif( lRest == NIL, .F., lRest )
IF ( nRec != NIL )
GOTO nRec
nNext := 1
ELSE
IF ( nNext == NIL )
nNext := - 1
ELSE
lRest := .T.
ENDIF
IF ( !lRest )
IF ( lRest == NIL )
lRest := .F.
ENDIF
IF ( nRec != NIL )
GOTO nRec
nNext := 1
ELSE
IF ( nNext == NIL )
nNext := - 1
IF ( !lRest )
GOTO TOP
ENDIF
ENDIF
ELSE
lRest := .T.
ENDIF
ENDIF
ENDIF
CurSelect := SELECT()
aNewDbStruct := {}
Aeval( Dbstruct(), { | _1 | IIF( _1[ 2 ] == "M", NIL, Aadd( aNewDbStruct, _1 ) ) } )
IF ( Empty( aNewDbStruct ) )
RETURN .F.
ENDIF
CurSelect := SELECT()
aNewDbStruct := {}
Aeval( Dbstruct(), { | _1 | Iif( _1[ 2 ] == "M", NIL, Aadd( aNewDbStruct, _1 ) ) } )
IF ( Empty( aNewDbStruct ) )
RETURN ( .F. )
ENDIF
BEGIN SEQUENCE
BEGIN SEQUENCE
IF ( Empty( xKey ) )
xKey := Indexkey()
ENDIF
IF ( Empty( xKey ) )
xKey := Indexkey()
ENDIF
IF ( Empty( xKey ) )
Set( _SET_CANCEL, cset )
err := errorNew()
err:description := "invalid argument"
err:genCode := EG_ARG
Eval( Errorblock(), err )
ENDIF
IF ( Empty( xKey ) )
Set( _SET_CANCEL, cset )
err := errorNew()
err:description := "invalid argument"
err:genCode := EG_ARG
Eval( Errorblock(), err )
ENDIF
IF ( Valtype( xKey ) == "C" )
bKeyBlock := "{||" + xKey + "}"
bKeyBlock := &bKeyBlock
ELSEIF ( Valtype( xKey ) != "B" )
bKeyBlock := { || .t. }
ELSE
bKeyBlock := xKey
ENDIF
IF ( Valtype( xKey ) == "C" )
bKeyBlock := "{||" + xKey + "}"
bKeyBlock := &bKeyBlock
ELSE
IF ( Valtype( xKey ) != "B" )
bKeyBlock := { || .t. }
ELSE
bKeyBlock := xKey
aGetField := {}
Aeval( aFields, { | _1 | Aadd( aGetField, getfield( _1 ) ) } )
aFieldsSum := Array( Len( aGetField ) )
dbCreate( cFile, aNewDbStruct, rdd, .T., "", , cdpId, nConnection )
NewSelect := SELECT()
SELECT( CurSelect )
WHILE ( !Eof() .and. nNext != 0 .and. Eval( bWhileBlock ) )
lDbTransRecord := .F.
Afill( aFieldsSum, 0 )
xCurKey := Eval( bKeyBlock )
WHILE ( !Eof() .and. nNext -- != 0 .and. Eval( bWhileBlock ) .and. ;
xCurKey == Eval( bKeyBlock ) )
IF ( Eval( bForBlock ) )
IF ( !lDbTransRecord )
__dbTransRec( NewSelect, aNewDbStruct )
SELECT( CurSelect )
lDbTransRecord := .T.
ENDIF
Aeval( aGetField, { | _1, _2 | ;
aFieldsSum[ _2 ] := aFieldsSum[ _2 ] + Eval( _1 ) } )
ENDIF
ENDIF
SKIP
ENDDO
aGetField := {}
Aeval( aFields, { | _1 | Aadd( aGetField, getfield( _1 ) ) } )
aFieldsSum := Array( Len( aGetField ) )
IF ( lDbTransRecord )
SELECT( NewSelect )
Aeval( aGetField, { | _1, _2 | Eval( _1, aFieldsSum[ _2 ] ) } )
SELECT( CurSelect )
ENDIF
dbCreate( cFile, aNewDbStruct, rdd, .T., "", cdpId, nConnection )
NewSelect := SELECT()
SELECT( CurSelect )
ENDDO
WHILE ( !Eof() .and. nNext != 0 .and. Eval( bWhileBlock ) )
lDbTransRecord := .F.
Afill( aFieldsSum, 0 )
xCurKey := Eval( bKeyBlock )
WHILE ( !Eof() .and. nNext -- != 0 .and. Eval( bWhileBlock ) .and. ;
xCurKey == Eval( bKeyBlock ) ;
)
IF ( Eval( bForBlock ) )
IF ( !lDbTransRecord )
RECOVER USING err
flag_err := .t.
wRec := dbRead()
SELECT( NewSelect )
Dbappend()
dbwrite( wRec )
ENDSEQUENCE
SELECT( CurSelect )
IF ( NewSelect != NIL )
SELECT( NewSelect )
CLOSE
ENDIF
lDbTransRecord := .T.
ENDIF
SELECT( CurSelect )
Set( _SET_CANCEL, cset )
Errorblock( err_block )
Aeval( aGetField, { | _1, _2 | aFieldsSum[ _2 ] := aFieldsSum[ _2 ] + ;
Eval( _1 ) ;
} ;
)
ENDIF
IF ( flag_err )
IF ( ValType( err:operation ) == "C" )
err:operation += "/__DBTOTAL"
ELSE
err:operation := "__DBTOTAL"
ENDIF
Eval( Errorblock(), err )
ENDIF
SKIP
ENDDO
IF ( lDbTransRecord )
SELECT( NewSelect )
Aeval( aGetField, { | _1, _2 | Eval( _1, aFieldsSum[ _2 ] ) } )
SELECT( CurSelect )
ENDIF
ENDDO
RECOVER USING err
flag_err := .t.
ENDSEQUENCE
IF ( NewSelect != NIL )
SELECT( NewSelect )
CLOSE
ENDIF
SELECT( CurSelect )
Set( _SET_CANCEL, cset )
Errorblock( err_block )
IF ( flag_err )
err:operation += "/__DBTOTAL"
Eval( Errorblock(), err )
ENDIF
RETURN ( .t. )
RETURN .T.
STATIC FUNCTION GETFIELD( cField )
@@ -240,8 +223,9 @@ STATIC FUNCTION GETFIELD( cField )
err:candefaul := .T.
err:operation := cField
err:subcode := 1101
lErr := Eval( Errorblock(), err )
lErr := Eval( Errorblock(), err )
IF ( Valtype( lErr ) != "L" .or. lErr )
__errInHandler()
ENDIF
BREAK( err )
@@ -250,27 +234,7 @@ STATIC FUNCTION GETFIELD( cField )
cField := Substr( cField, nPos + 2 )
ENDIF
RETURN ( Fieldblock( cField ) )
RETURN Fieldblock( cField )
STATIC FUNCTION DbWrite( w )
LOCAL ncount
FOR ncount := 1 TO Len( w )
Fieldput( ncount, w[ ncount ] )
NEXT
RETURN nil
STATIC FUNCTION DbRead()
LOCAL aRec := {}
LOCAL nCount
FOR nCount := 1 TO FCount()
IF ( FieldType( nCount ) != "M" )
AAdd( aRec, Fieldget( nCount ) )
ENDIF
NEXT
RETURN aRec
FUNCTION __dbTransRec( nDstArea, aFieldsStru )
Return __dbTrans( nDstArea, aFieldsStru, , , 1 )

View File

@@ -138,6 +138,7 @@ PRG_SOURCES=\
color53.prg \
dbdelim.prg \
dbedit.prg \
dbjoin.prg \
dbsdf.prg \
devoutp.prg \
dircmd.prg \

View File

@@ -84,7 +84,7 @@ local nSrcArea, nDstArea, aStruct, cRDD := "DELIM"
endif
if lExport
dbcreate( cFile, aStruct, cRDD, .T., "", , , cDelimArg )
dbcreate( cFile, aStruct, cRDD, .T., "", cDelimArg )
nDstArea := Select()
if nDstArea == nSrcArea
nDstArea := Nil

View File

@@ -0,0 +1,144 @@
/*
* $Id$
*/
/*
* Harbour Project source code:
* __DBJOIN() function
*
* Copyright 2005 Pavel Tsarenko <tpe2@mail.ru>
* 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.
*
*/
Function __dbJoin( cAlias, cFile, aFields, bFor, cRdd, nConnection, cdpId )
Local nMaster := Select()
Local nDetail := Select(cAlias)
Local nResult, aStruct, aJoinList, oError, lError := .F.
Select(nMaster)
if ( Empty(aStruct := FieldTwo(cAlias, aFields)) )
return .F.
endif
begin sequence
dbCreate(cFile, aStruct, cRdd, .T., "", , cdpId, nConnection)
nResult := Select()
aJoinList := __JoinList(nMaster, nDetail, nResult, aStruct)
Select(nMaster)
go top
do while ! Eof()
Select(nDetail)
go top
do while ! Eof()
Select(nMaster)
if Eval(bFor)
__doJoinList(aJoinList)
endif
Select(nDetail)
skip
enddo
Select(nMaster)
Skip
enddo
recover using oError
lError := .T.
end sequence
if nResult != nil
Select(nResult)
close
endif
Select(nMaster)
if lError
break( oError )
endif
return .T.
static function FieldTwo( cAlias, aFields )
Local aFldTemp, bFind, cField, aStruct
if Empty(aFields)
return dbStruct()
endif
aFldTemp := {}
AEval(aFields, { |cFld| AAdd(aFldTemp, Trim(Upper(cFld))) })
aFields := aFldTemp
aStruct := {}
bFind := { |c| c == cField }
AEval(dbStruct(), { |a| ( cField := a[1], iif( ascan(aFields, bFind) == 0,;
nil, AAdd(aStruct, a) ) ) })
select(cAlias)
bFind := { |cFld| "->" $ cFld .AND. SubStr(cFld, At("->", cFld) + 2) == ;
cField }
AEval(dbStruct(), { |a| ( cField := a[ 1 ], iif( AScan(aFields, bFind) == 0,;
nil, AAdd(aStruct, a) ) ) })
return aStruct
static function __JoinList(nMaster, nDetail, nResult, aStruct)
Local i, aList := {}, nPos
for i := 1 to len(aStruct)
if ( nPos := (nMaster)->(FieldPos(aStruct[i][1])) ) # 0
AAdd(aList, {nResult, nMaster, nPos, i})
elseif ( nPos := (nDetail)->(FieldPos(aStruct[i][1])) ) # 0
AAdd(aList, {nResult, nDetail, nPos, i})
endif
next
Return aList
static function __doJoinList(aList)
local i, aJoin
if len(aList) > 0
( aList[1][1] )->( dbAppend() )
for each aJoin in aList
( aJoin[1] )->(FieldPut( aJoin[4], ( aJoin[2] )->(FieldGet( aJoin[3] )) ))
next
endif
return nil

View File

@@ -54,8 +54,5 @@
/* TODO: Dummy functions, should be removed when implemented. */
FUNCTION __dbJoin() ; RETURN NIL
/* NOTE: Internal functions */
FUNCTION __dbFList() ; RETURN {}
FUNCTION __dbTransRec() ; RETURN NIL

View File

@@ -545,8 +545,8 @@ HB_EXPORT void hb_vmQuit( void )
hb_pp_Free();
#endif
s_uiActionRequest = 0; /* EXIT procedures should be processed */
hb_vmDoExitFunctions(); /* process defined EXIT functions */
s_uiActionRequest = 0; /* EXIT procedures should be processed */
hb_vmDoExitFunctions(); /* process defined EXIT functions */
/* process AtExit registered functions */
hb_vmDoModuleExitFunctions();