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

Reply via email to