/*---------------------------------------------------------------------------*\
** $Author: antanas $
** $Date: 2021-08-25 14:49:05 +0300 (Wed, 25 Aug 2021) $
** $Revision: 8871 $
** $URL: svn+ssh://www.crystallography.net/home/coder/svn-repositories/cod-tools/tags/v3.8.1/src/externals/cexceptions/tests/programs/tfinaly.c $
\*---------------------------------------------------------------------------*/

#include <stdio.h>
#include <cxprintf.h>
#include <cexceptions.h>
#include <allocx.h>

void f( cexception_t * );
void g( cexception_t * );
void h( cexception_t * );

int main()
{
    cexception_t ex;
    cexception_guard(ex) {
       puts("Guarded statement");
       g(&ex);
       f(&ex);
       g(&ex);
       f(&ex);
       puts("End of guarded statements");
    }
    cexception_finally3(
       { puts( "before cleanup" ); },
       { puts( "cleanup" ); },
       { puts( cexception_message( &ex )); }
    )
    return 0;
}

void g( cexception_t *ex )
{
    puts("------g() enters ---------");
    puts("------g() leaves ---------");
}

void f( cexception_t *ex )
{
    cexception_t f_ex;

    puts("------f() enters ---------");
    cexception_guard(f_ex) {
        h( &f_ex );
    }
    cexception_catch {
        printf("Exception caught in f() from ");
    if( cexception_subsystem_tag( &f_ex ) == 0 ) {
        puts("default (main) subsystem");
    } else if( cexception_subsystem_tag( &f_ex ) == allocx_subsystem ) {
        puts("allocx subsystem"); 
    } else {
        puts("some unknown subsystem");
    }
    cexception_reraise( f_ex, ex );
    }

    cexception_raise( ex, -2, "cexception in f()" );
    puts("------f() leaves ---------");
}

void h( cexception_t *ex )
{
    puts("------h() enters ---------");
    cexception_raise( ex, -3,
              cxprintf( "cexception generated in h(), "
                "code = %d", -3 ));
    puts("------h() leaves ---------");
}
