On Fri, 15 Feb 2008, Alexander S.Kresin wrote:
Hi All,
have we a C level error api ? In other words, are there C level
functions to catch up errors, which on prg level we handle with BEGIN
SEQUENCE ... END SEQUENCE ?
1. Please remember that Harbour always returns from RT error handler.
Even when QUIT is executed to allow final cleanup so at C level
you will always be able to execute your code after RT error.
Such functionality do not exist in xHarbour and QUIT interrupts
application immediately. Anyhow you always have to write code
which is ready for returning from error handler because it can
be executed inside user BEGIN SEQUENCE / END which set {|e|break(e)}
as error block for both compilers. After executing user code
you can test if pending exception exist in HVM stack by
hb_vmRequestQuery() != 0
If you do not need recover value (error object) then it will be
enough for you to reset the query flag when it has HB_BREAK_REQUESTED
but we do not have hb_vmRequestReset() like in xHarbour - I haven't
added it intentionally so far.
2. If you want to create real BEGIN SEQUENCE / END envelope on
HVM stack then we do not have any direct API functions for it
but you can use hb_xmv*() functions desigend for -gc3 compilation
(-gc3 generates real C code instead of PCODE encapsulated in .c files)
hb_xvmSeqBegin() - push BEGIN SEQUENCE / END envelope on HVM stack
hb_xvmSeqEnd()- pop BEGIN SEQUENCE / END envelope from HVM stack
discarding recover value. Return TRUE if other
exception (QUIT) are still active
hb_xvmSeqRecover()- pop BEGIN SEQUENCE / END envelope from HVM stack
leave recover value on top of HVM stack (it will
have to be poped by your code. Return TRUE if
other exception (QUIT) are still active
Examples.
1. Pure BEGIN SEQUENCE / END:
hb_xvmSeqBegin();
hb_itemDo( pItem );
if( hb_xvmSeqEnd() )
return; /* QUIT executed */
2. BEGIN SEQUENCE / END with RECOVER code - the error object stored in
pError should be released later by hb_itemRelease()
hb_xvmSeqBegin();
hb_itemDo( pItem );
if( hb_vmRequestQuery() != 0 )
{
if( hb_xvmSeqRecover() )
return; /* QUIT executed */
pError = hb_itemNew( hb_stackItemFromTop( -1 ) );
hb_stackPop();
}
else
{
if( hb_xvmSeqEnd() )
return; /* QUIT executed */
pError = NULL;
}
or the same in a little bit simpler version using hb_xvmSeqEndTest()
function:
hb_xvmSeqBegin();
hb_itemDo( pItem );
if( hb_xvmSeqEndTest() )
{
if( hb_xvmSeqRecover() )
return; /* QUIT executed */
pError = hb_itemNew( hb_stackItemFromTop( -1 ) );
hb_stackPop();
}
else
pError = NULL;
Best regards,
Przemek
___
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour