/* Module ut/exec_ut exec_ut.ic
*****************************************************************************
Authors GRT
Zweck: Trace-Hilfen und Macros
- zum Hochmelden von mglicher Applikationsfehler 'errno != 0',
- zur Behandelung nicht erwarteter Situationen (Systemfehler),
- zum schnellen Lokalisieren solcher Fehler
- und auch zum Messen von Testberdeckung
Neue Werte fr 'errno' (= Error Codes, die das Anwendungssystem
definiert), sind grundstzlich in Datei 'en.h' einzutragen.
Wertzuweisungen an errno haben stets die Form 'errno = EN_...'
mit einem in Datei 'en.h' definierten Identifier 'EN_...' (er ist
sprechender als die durchs Basissystem definierten Namen fr die
Error Codes).
Note: Trace-Umfang wird gesteuert durch Kopieren einer der Dateien
ot.h , st.h , mt.h nach trace.h
unmittelbar vor Aufruf des Compilers. Die Produktionsversion
des Systems erfordert trace.h == ot.h (optimized version).
Note: Die Trace Datei ist prozeáspezifisch. Jeder Prozeá sollte sie
selbst noch zerstren, wenn er ohne Fehler zu Ende kommt. Zu
diesem Zweck sei ok_exit(r) sein letzter Befehl, r der exit
code des Prozesses.
Note: Jede MFC-Applikation muá das Datenelement CWinApp::m_pMainWnd
initialisieren. Dies passiert automatisch, wenn die Programm-
Vorlage "Applikationshauptfenster" benutzt wird.
Status: Noch nicht ganz fertig: exec_ut :: show() ffnet noch kein
Fenster, in dem es den durch Diagnosedaten kommentierten Auf-
rufkeller zeigt.
Docum: VERTKON/doc/on_error Einfhrung - bitte unbedingt lesen
VERTKON/doc/cod_rl Codier-Richtlinien (lese Kap. 2 )
-----------------------------------------------------------------------------
*/
#include for_all.h
predeclare Btree ;
// Als 'hidden by macros' gekennzeichnete Funktionen drfen Clients der
#define dos_me( s ) exut.ok_norm( s, '/', '\\' )
#define unix_me( s ) exut.ok_norm( s, '\\', '/' )
#define At( c,x ) ( exut.ok_At( c,x ) )
#define not_At( c,x ) ( ! exut.ok_At( c,x ) )
#define iAt( c,x ) ( exut.ok_iAt( c,x ) )
#define not_iAt( c,x ) ( ! exut.ok_iAt( c,x ) )
#define tmpName exut.TMPName
#define tmpDir exut.TMPDir
#define tmpDir_e exut.TMPDir_e
#undef DELETE
#define Delete( x )
{
delete x ; x = 0 ;
}
#define DELETE( x )
{
delete[] x ; x = 0 ;
}
// Wichtig: K e i n fErr, wenn x == 0 . // Es kann sonst dead locks geben. // // Die C++ Semantik: delete(0) hat leere // Wirkung. Den Pointer auf 0 abzufragen
#define WW_
{
fread( &exut.www, 1, 1, stdin );
}
#define no_this ( destroyed )
#define NO_this
{
printf( "\nerror: No exut !! %i %s", \
__LINE__, __FILE__ ); exit(1);
}
#define trace_to( x ) exut.trace_config( x, 'n' );
#define ok errno = 0 ;
#define no_such_file ( errno == ENOENT || errno == ENOTDIR )
#define ErrDescr errDescr
#define SetError( x, s ) exut.set_errDescr( s )
#define en_fErr( e )
{
errno = e ; fErr
}
#ifdef __WINDOWS__
#define ret_WinAppExit return( EWinApp :: ExitInstance() );
// Dieses Makro hindert pretty.exe daran, hier das return() // durch ret() zu ersetzen: ret() kann nicht mehr arbeiten, // da ExitInstance() ein Objekt vernichtet, dessen Methoden
#define EXIT( x ) EWinApp :: Exit();
// AfxAbort tut's nicht, da der Benutzer hier // n i c h t mehr die Wahl haben soll, den
#else
#define EXIT( x ) exit( x );
#endif
#ifdef no_trace__
#define _x( x )
#define LP_( n,x )
#else
#define _x( x ) exut.trace( #x, x );
#define LP_( n,x ) exut.trace( n, x );
// Zur Ausgabe von Diagnosedaten in den Aufrufkeller verwende man
#endif
#define L1_( x1 )
{
_ _x(x1)
}
#define L2_( x1, x2 )
{
_ _x(x1) _x(x2)
}
#define L3_( x1, x2, x3 )
{
_ _x(x1) _x(x2) _x(x3)
}
#define L4_( x1, x2, x3, x4 )
{
_ _x(x1) _x(x2) _x(x3) _x(x4)
}
#define L5_( x1, x2, x3, x4, x5 )
{
_ _x(x1) _x(x2) _x(x3) _x(x4) _x(x5)
}
// Zur Ausgabe frei formatierbarer Diagnosedaten im Fehlerfall
#define S_
{
sprintf( exut.ccc,
// #define _fErr ); exut.trace_always ( exut.ccc ); fErr }
#define _fErr ); exut.AnotherAppErr( exut.ccc ); fErr
}
#define _exit(m) ); exut.trace( exut.ccc ); EXIT(m);
#define _TR ); exut.trace( exut.ccc );
#define _TR_a ); exut.trace_always( exut.ccc );
#define _sto ); fprintf( stout, exut.ccc );
#define _ste ); fprintf( stout, exut.ccc );
#define _appErr ); exut.AnotherAppErr( exut.ccc );
#define APP_ERRORS ( exut.app_errors )
// Mit _fErr ausgegebener Text sollte stets mit einem // Zeilenvorschub enden (er steht ja auch im Fehlerkeller und
#ifdef __WIN_OR_QUICK_WIN__
#define _Do ); WinExec( exut.ccc, SW_SHOWNORMAL );
#else
#define _Do ); system( exut.ccc );
#endif
// Beispiel: S_ "%i.entry = %s\n", n, str _TR // // Die spezielle Form der Macros garantiert Abschaltbarkeit solcher
#undef _
#ifdef __MAXIMAL_TRACE__
// Use the following macros in order to be able to trace your
#define then
#define then_
{
_
#define else_
}
else
#define esif_
else if
#define esif else if
#define while_
while
#define do_ do
{
_
#define trace_off exut.trace( false );
#define trace_on exut.trace( true );
#define _ exut.at_code_position( __FILE__, __LINE__ );
#else
#define then
#define then_
#define else_ else
#define esif else if
#define do_ do
#define while_ while
#define _
#define trace_off
#define trace_on
#endif
// for_all.h includes a file "trace.h" which is a copy of either // mt.h or ot.h (in these two files - and nowhere else - you should // define or undefine __MAXIMAL_TRACE__ and __OPTIMIZED__). // // Lese 'ot.h' als 'ohne Trace' (= Produktionsversion). // Lese 'mt.h' als 'mit Trace' (= zum Test instrumentierte Version). // // Man wird von Fall zu Fall nur __MAXIMAL_TRACE__ in mt.h entweder
#define ErrNo errno
#define putErrNo( e ) exut.putErr( e, __FILE__,__LINE__ )
// Damit die ''errno bei Bedarf thread save gemacht werden kann, // sollte man zum Zugriff aus sie nur ''ErrNo und ''putErrNo()
#define retIfErr( r ) if ( errno ) Ret( e,r )
#define retIfErr_ if ( errno ) Ret_( e )
#define Ret(e,r)
{
exut.putErr( e, __FILE__, __LINE__ ); return( r );
}
#define Ret_(e)
{
exut.putErr( e, __FILE__, __LINE__ ); return ;
}
#undef LB_
#undef LE_
#undef ret_
#undef ret
#ifdef __OPTIMIZED__
#ifdef __TESTCOVER__
#define _ x1tc( __FILE__, __LINE__ );
char * fileint line
{
}
#else
#define _
#endif
#define LB_(x)
{
inproc = x ;
#define LE_ if ( errno ) fErr else
{
_
}
}
#define E ;
#define EE
{
if ( errno ) fErr
}
// to be used instead of E in order to stay in the // optimized version of the program - please use it // at least in constructors as well as in destructors
#define ret(x)
{
if ( errno ) fErr ; _ return( x ) ;
}
#define ret_
{
if ( errno ) fErr ; _ return ;
}
// Call 'Ret( errno, r )' instead of 'ret( r )' where // you think the error might be an application error,
#undef fErr
#define fErr exut.fatal_error_at( __FILE__, __LINE__ );
#define ffErr
#else
#ifndef __EXEC_UT_CPP__
#ifdef xICROSOFT
#define LB_(x)
{
static char BASED_CODE PROC_x[] = x ; \
exut.enter_f( PROC_x, __FILE__, __LINE__ );
#else
#define LB_(x)
{
exut.enter_f( x, __FILE__, __LINE__ ); \
if ( errno ) fErr
#endif
#define LE_ exut.end_f( __LINE__ );
}
#define E ;
{
_ if ( exut.at_E( __LINE__ ) ) fErr
}
// this ensures that functions detecting errors will
#define EE
{
_ if ( exut.at_E( __LINE__ ) ) fErr
}
// to be used instead of E in order to stay in the // optimized version of the program - please use it // at least in constructors as well as in destructors
#define ret(x)
{
_ exut.at_return( __LINE__ ); return(x);
}
#define ret_
{
_ exut.at_return( __LINE__ ); return ;
}
// Call 'Ret( errno, r )' instead of 'ret( r )' where // you think the error might be an application error,
#define Ret(e,r)
{
_ errno = e ; exut.exit_f(__LINE__); return(r);
}
#define Ret_(e)
{
_ errno = e ; exut.exit_f(__LINE__); return ;
}
#define fErr exut.fatal_error_at( __FILE__, __LINE__ );
#define ffErr fErr
/*
Zwischen LB_ und LE_ (aber auch nur dort) ist statt 'return' stets
ret_ , ret( r ), Ret_( e ), oder Ret( e, r )
zu verwenden. Wo unmittelbar auf ret_ bzw. ret(r) ein LE_ folgen wrde,
ziehe man beides zusammen zu
LE_ bzw. LE_ret( r )
Ein SPU-Werkzeug wird die Einhaltung dieser Regeln kontrollieren, um so zu
garantieren, daá hier nicht Code entsteht, der niemals durchlaufen wrde.
*/
#else
#define LB_(x)
{
#define LB_(x)
{
inproc = x ;
#define LE_
}
#define E ;
#define EE if ( errno ) fErr
#define fErr
{
_ exit_f( __LINE__ ); show();
}
#endif
#endif
#ifndef _DEBUG
#undef ASSERT
#define ASSERT(x) if ( ! x ) fErr
#undef TRACE
#define TRACE(x)
#endif
#define _1( x1 )
{
_x(x1)
}
#define _2( x1, x2 )
{
_x(x1) _x(x2)
}
#define _3( x1, x2, x3 )
{
_x(x1) _x(x2) _x(x3)
}
#define _4( x1, x2, x3, x4 )
{
_x(x1) _x(x2) _x(x3) _x(x4)
}
#define _5( x1, x2, x3, x4, x5 )
{
_x(x1) _4( x2, x3, x4, x5 )
}
#define _6( x1, x2, x3, x4, x5 )
{
_x(x1) _5( x2, x3, x4, x5, x6 )
}
#define _7( x1, x2, x3, x4, x5 )
{
_x(x1) _6( x2, x3, x4, x5, x6, x7 )
}
#define fErr1( x1 )
{
_x(x1) fErr
}
#define fErr2( x1, x2 )
{
_x(x1) _x(x2) fErr
}
#define fErr3( x1, x2, x3 )
{
_x(x1) _x(x2) _x(x3) fErr
}
#define fErr4( x1, x2, x3, x4 )
{
_x(x1) _x(x2) _x(x3) _x(x4) fErr
}
#define fErr5( x1, x2, x3, x4, x5 )
{
\
_x(x1) _x(x2) _x(x3) _x(x4) _x(x5) fErr
}
#define fErr6( x1, x2, x3, x4, x5, x6 )
{
\
_x(x1) _x(x2) _x(x3) _x(x4) _x(x5) _x(x6) fErr
}
#define fErr7( x1, x2, x3, x4, x5, x6, x7 )
{
\
_x(x1) _x(x2) _x(x3) _x(x4) _x(x5) _x(x6) _x(x7) fErr
}
#define fErr8( x1, x2, x3, x4, x5, x6, x7, x8 )
{
\
_x(x1) _x(x2) _x(x3) _x(x4) _x(x5) _x(x6) _x(x7) _x(x8) fErr
}
#define fErr9( x1, x2, x3, x4, x5, x6, x7, x8, x9 )
{
\
_x(x1) _x(x2) _x(x3) _x(x4) _x(x5) _x(x6) _x(x7) _x(x8) _x(x9) fErr
}
#undef fErr
#undef LE_ret
#define LE_fErr fErr
}
#define LE_ret( x ) ret(x)
}
#define LE_Ret(e,r) Ret(e,r)
}
#define LE_Ret_(e) Ret_(e)
// In order to avoid unreachable code, please use // // 'LE_fErr ' instead of 'fErr LE_' // 'LE_ret(x) ' instead of 'ret(x) LE_' // 'LE_Ret(e,r) ' instead of 'Ret(e,r) LE_' // 'LE_Ret_(e) ' instead of 'Ret_(e) LE_'
#define ok_exit( ec )
{
if ( exut ) delete exut ; EXIT( ec );
}
#ifdef __OPTIMIZED__
#define show_heap
#define ass_heap_empty
#define new_sto( a,t ) a = new t ;
#define rem_sto( a )
{
delete a ; a = 0 ;
}
#define REM_sto( a )
{
delete[] a ; a = 0 ;
}
// REM_sto is hidden in other macros - // forget it.
// Statt 'delete' stets 'delete[]' zu // schreiben funktioniert nicht (warum
#else
#define show_heap exut.ok_show_heap( __FILE__, __LINE__ );
#define ass_heap_empty exut.ok_rem_heap( 1 );
// this is an assertion - if the heap // still contains items allocated via
#define new_sto( a,t )
{
a = new t ; exut.ok_new_sto( \
a, __LINE__, __FILE__ );
}
#define rem_sto( a )
{
if ( ! a ) fErr \
exut.ok_rem_sto( a ); \
if ( a )
{
delete a ; a = 0 ;
}
}
#define REM_sto( a )
{
if ( ! a ) fErr \
exut.ok_rem_sto( a ); \
if ( a )
{
delete[] a ; a = 0 ;
}
}
// delete in rem_sto() aufzurufen // geht nicht, da dort der Datentyp // nicht mehr bekannt ist ( // // Welche Auswirkung hat delete angewandt
#endif
#ifdef GNU
#define far
#define Rem_sto rem_sto
#define path_ref char *
#else
#define Rem_sto REM_sto
#define path_ref path &
#endif
#define def_sto( x, t ) t *x ; new_sto( x, t );
#define rem_next( x, t )
{
t *n = x->next ; rem_sto(x); x = n ;
}
#define rem_pre ( x, t )
{
t *n = x->pre ; rem_sto(x); x = n ;
}
typedef void *   pointer
; #ifdef __TESTCOVER__ #endif #define AppErr( s ) { printf( "\n\nUser's Error: %s\n", s ); exit(1); } #include traceco.h
class ExecUt
/* _____________________________________________________________________________ R e u s e . f o r . ALL A framework to enable trace, error handling, and test coverage documentation. Zusammen mit ot.bat und mt.bat ist diese Klasse ein Werkzeug zum Einsehen des Aufrufkellers sowie zur gut konfigurierbaren Ausgabe beleibig umfang- reicher Diagnosedaten. _ P r e C o n d i t i o n : - Die Umgebungsvariable TRACE_DIR sollte definiert sein und als Wert den Pfad zu einem Directory enthalten, in dem die Standard-Dateien app_x.err (= Diagnosedaten) app_x.ste (= Meldungen zu Anwendungsfehlern) app_x.sto (= Standard-Ausgabekanal der Anwendung) erzeugt werden sollen. Hierbei wird ein passendes x mit 1 <= x <= 99 ausgesucht. Es muá sichergestellt sein, daá bislang noch nicht mehr als 98 Dateien app_x.err existieren. Stets die gleiche Silbe x zu nehmen geht nicht, da sonst nicht mehrere Programme gleichzeitig arbeiten knnten. - Die Dateien *.sto und/oder *.ste (zu schreiben mit S_ ... _sto/_ste) sind nur dann n i c h t mit *.err identisch, wenn define __CREATE_STO__ bzw. define __CREATE_STE__ gesetzt wurde. B e a c h t e : - Mit 'ot compiliert, existiert keinerlei Overhead. Leider ist damm im Fehlerfall der Aufrufkeller nicht bekannt. - Mit 'mt compiliert (aber ohne Ausgabe von Durchlauftrace) ist der Code um etwa den Faktor 2 langsamer. - Mit 'mt compiliert und TRACE 1 1 1 (= kompletter Durchlauftrace) ist der Code um etwa den Faktor 8 langsamer. _____________________________________________________________________________ */ { public:
void count() { } #define nr_of_counters 1 int testCover[ nr_of_counters ] ; #define L_ccc 6000 #define L_wp 6000 #define AtErr( m ) ( exut.atErr( errMess, m ) ) #define errA exut.errst #define errMess exut.errme #define M_ sprintf( errA + strlen( errA ), // #define m_errMess sprintf( errA + strlen( errA ), "\n%i %s\n[\n\n" #define m_errMess M_ #define m_errout "\nfatal error at %i %s\n[\n\n" // #define m_errMess sprintf( errA + strlen( errA ), m_errout // #define m_errMess sprintf( errA + strlen( errA ), "%i %s\n[\n\n" // #define m_ "\n\n]",__LINE__,__FILE__, #define m_ "", #define seeMessages { if ( *errA ) throw "see messages" ; } #define seeProblems { if ( *errA ) throw "s: see problems described" ; } // #define ret_error "\n] in %s\n\n", inproc ); throw errMess ; // #define ret_error "\n]" ); throw errMess ; falsch !!! #define ret_error "" ); fErr // #define ret_error "\n]" ); fErr // #define ret_error "\n]" ); printf( errA ); throw errMess ; #define fErr exut.throw_error( __LF__ ); #define NoErrMess *errA = 0 ; #define AppErrors *errA long rRest ; char www ; char * errst ; // errMess ohne "error -->" char errme [ L_ccc ] ; // errMess char ccc [ L_ccc ] ; int app_errors ; // Number of application errors // documented to *.ste so far path TMPDir ; char * TMPDir_e ; int TMPNr ; // #ifdef __TESTCOVER__ int wp[ L_wp ] ; // counter at watchpoints // #endif protected: #include macros_1.h #ifdef prot_ #define e_prot_ 2000 Btree * counterNames ; uint counter[ e_prot_ ] ; char cName [ 800 ] ; #endif FILE * to_f ; FILE * ef ; // default for to_f BOOL to_stack ; BOOL stack_shown ; private: #define L_hdescr_page 400
struct  heap_sto
{ heap_sto :: heap_sto(); pointer ref ; // int line ; // where allocated char * file ; // where allocated } ;
struct  heap_descr_page
{ heap_descr_page :: heap_descr_page(); heap_sto sto[ L_hdescr_page ] ; // heap_descr_page * pre ; // previous page } ; heap_descr_page * sto1 ; #define L_sss L_ccc char sss[ L_sss ] ; char std_file[ 200 ] ; char err_file[ 200 ] ; BOOL also_to_f ; // see config_trace() BOOL stopped ; // see stop() and constructor BOOL destroyed ; // int ERRNo ;
struct  call_descr
top . is_inc_for . C++
{ call_descr :: call_descr(); char * proc ; // name of proc char * file ; // file from where the call came int line ; // line from where the call came unsigned long call_nr ; // char * comm ; // start of comment string #undef BB #undef BBStr #undef bb #undef bbStr #define BB #define BBStr( x,y,z ) ; #define bb #define bbStr( x,y,z ) ; # ifndef procNestOn #undef LB_ #undef LE_ #undef LE_ret #undef ret #undef ret_ #undef __ #undef ___ #define LB_( x ) { #define LE_ } #define ret_ return ; #define LE_ret( x ) return( x ); } #define ret( x ) return( x ); #define __ #define ___ #endif int errn ; // errno the call finished with int recover ; // see ... } ; #define maxdepth 100 #define L_comment 20000 #define L_nosem 100 char comment[ L_comment ] ; char nosem [ L_nosem ] ; char * counters ; char * comm ; char * comm_end ; call_descr stack[ maxdepth + 2 ] ; int errNo ; uint at ; uint at1 ; char * exit_type ; BOOL no_error ; long show_at ; long suggest_trace ; long step_TR ; heap_descr_page * sto ; int stn ; #define L_err 400 char errDescr[ L_err ] ; // exported methods: public: BOOL ExecUt :: atErr // ----------------------------------------------------------------------------- ( char * mess , char * erro ) ; public: void ExecUt :: TMPName /* ----------------------------------------------------------------------------- create path name = TMPDir/tmpNr ----------------------------------------------------------------------------- */ ( path & name ) ; public: BOOL ExecUt :: ViewStdout( /* ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- */ ) ; public: BOOL ExecUt :: ViewStderr( /* ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- */ ) ; public: void ExecUt :: trace_yourself( /* ----------------------------------------------------------------------------- Diese Methode dient dem Nachweis: delete( exut ) macht den this pointer n i c h t zu 0 , Folgender Code etwa druckt 3 Mal dieselbe Adresse: ExecUt * xxx //new ExecUt( "" ); xxx -> trace_yourself(); printf( "xxx = %p\n", exut ); delete( xxx ); xxx -> trace_yourself(); ----------------------------------------------------------------------------- */ ) ; public: ~ExecUt /* ----------------------------------------------------------------------------- Der Aufrufer garantiert: - - sein Auftrag: Close stout und sterr, dann gebe auf dem Heap allokierten Speicher frei. Die Funktion garantiert: - ----------------------------------------------------------------------------- */ ( ) ; public: void ExecUt :: get_std_file /* ----------------------------------------------------------------------------- Der Aufrufer garantiert: 'fn zeigt auf ein char[n] mit L_path <= n - sein Auftrag: Schreibe dort hinein den Pfad zur vom Prozess erzeugten Datei *.ext ( 'ext = .err, .ste, oder .sto ). Die Funktion garantiert: - ----------------------------------------------------------------------------- */ ( char * fn , char * ext // in : extension .err, .ste, or .sto ) ; public: void ExecUt :: throw_error // hidden by macros/* ----------------------------------------------------------------------------- report an unexpected error ----------------------------------------------------------------------------- */ ( int Line , char * File ) ; public: void ExecUt :: set_errDescr // hidden by macros/* ----------------------------------------------------------------------------- describe an error ----------------------------------------------------------------------------- */ ( char * descr ) ; public: BOOL ExecUt :: IsValid( /* ----------------------------------------------------------------------------- return BOOL( 'this object exists and is ok' ) ----------------------------------------------------------------------------- */ ) ; public: ExecUt :: ExecUt /* ----------------------------------------------------------------------------- Initialize Mechanismus zur Beobachtung des Programmablaufs ----------------------------------------------------------------------------- */ ( char * app_name ) ; public: char * ExecUt :: get_err_path /* ----------------------------------------------------------------------------- return pointer to name of *.err, *.sto, *.ste without extension ----------------------------------------------------------------------------- */ ( ) ; public: void ExecUt :: enter_f // hidden by macros/* ----------------------------------------------------------------------------- push function call ----------------------------------------------------------------------------- */ ( char * proc , char * file // name of file where the proc is defined, int line // ) ; public: BOOL ExecUt :: at_E // hidden by macros/* ----------------------------------------------------------------------------- trace errno at watch point ----------------------------------------------------------------------------- */ ( int line ) ; public: void ExecUt :: AnotherAppErr /* ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- */ ( char * mess ) ; public: void ExecUt :: fatal_error_at /* ----------------------------------------------------------------------------- tell the system you detected a fatal error ----------------------------------------------------------------------------- */ ( char * file , int line ) ; public: void ExecUt :: to_trace // hidden by macros/* ----------------------------------------------------------------------------- concatenate str to stack[ at ].comm ----------------------------------------------------------------------------- */ ( char * str ) ; public: void ExecUt :: set_errno // hidden by macros/* ----------------------------------------------------------------------------- set errno a n d description of error err_descr is pointing to some string produced via 'sprintf(...)' - it may contain arbitrarily long comment describing the situation in which the error was found. ----------------------------------------------------------------------------- */ ( int err_code , char * err_descr ) ; public: void ExecUt :: end_f // hidden by macros/* ----------------------------------------------------------------------------- pop function call (exit at 'LE_') ----------------------------------------------------------------------------- */ ( int line // of return ) ; public: void ExecUt :: at_return // hidden by macros/* ----------------------------------------------------------------------------- pop function call (exit at a 'return' point) ----------------------------------------------------------------------------- */ ( int line // of return ) ; public: void ExecUt :: putErr // hidden by macros// ----------------------------------------------------------------------------- ( int err , char * file , int line ) ; public: void ExecUt :: exit_f // hidden by macros/* ----------------------------------------------------------------------------- pop function call (exit at a 'return' point) ----------------------------------------------------------------------------- */ ( int line // of return ) ; public: void ExecUt :: count /* ----------------------------------------------------------------------------- Store test coverage for the given code line (= return from a method). ----------------------------------------------------------------------------- */ ( char * file , int line ) ; public: void ExecUt :: count_init /* ----------------------------------------------------------------------------- Create all counter names The given file has to be a concatenation of all already preprocessed compilation units. ----------------------------------------------------------------------------- */ ( char * file ) ; public: void ExecUt :: count_show /* ----------------------------------------------------------------------------- show test coverage ----------------------------------------------------------------------------- */ ( char * file , int line ) ; public: void ExecUt :: NewCounters( /* ----------------------------------------------------------------------------- Der Aufrufer sagt: Reinitialize counters for test coverage (i.e. make them 0). ----------------------------------------------------------------------------- */ ) ; public: void ExecUt :: PutCounters( /* ----------------------------------------------------------------------------- Der Aufrufer sagt: Addiere die in diesem Lauf errechnete Testberdeckung zur schon frher erreichten. Die Funktion garantiert: fErr || ok ----------------------------------------------------------------------------- */ ) ; public: virtual void ExecUt :: stop /* ----------------------------------------------------------------------------- show a window telling the user that an error occurred ----------------------------------------------------------------------------- */ ( int en // if ( en <= 0 ): error is a system error // if ( en > 0 ): error is an application error ) ; public: const char * ExecUt :: semantics /* ----------------------------------------------------------------------------- return pointer to semantics of a error code 'code' ----------------------------------------------------------------------------- */ ( int code // in: any value EN_... ) ; public: void ExecUt :: trace_config /* ----------------------------------------------------------------------------- Der Aufrufer garantiert: - - sein Auftrag: set trace destination to_f and redefine trace_from Die Funktion garantiert: - Diese Prozedur wird vor allem dann aufzurufen sein, wenn Trace direkt auf den Bildschirm (als stderr) gegeben werden soll - etwa deswegen, weil der Prozess vor seinem Absturz kein flush auf die Diagnosedatei mehr machen kann (DOS und QUICK_WIN Programme). ----------------------------------------------------------------------------- */ ( FILE * to_file , char from // in: if 'e' according to FROM_PROC // else from now on ) ; public: void ExecUt :: at_code_position // see mt.h/* ----------------------------------------------------------------------------- trace code position ----------------------------------------------------------------------------- */ ( char * file , int line ) ; public: void ExecUt :: trace_always // hidden by macros/* ----------------------------------------------------------------------------- trace even if call_nr < trace_from ----------------------------------------------------------------------------- */ ( char * str ) ; public: void ExecUt :: show_text /* ----------------------------------------------------------------------------- trace the first n_... characters of txt ----------------------------------------------------------------------------- */ ( char * name , char * txt // any text, int n_chars // ) ; public: void ExecUt :: trace // hidden by macros// ----------------------------------------------------------------------------- ( char * str ) ; public: void ExecUt :: trace // hidden by macros// ----------------------------------------------------------------------------- ( char * name , char * wert ) ; public: void ExecUt :: trace // hidden by macros// ----------------------------------------------------------------------------- ( BOOL onoff ) ; public: void ExecUt :: trace // hidden by macros// ----------------------------------------------------------------------------- ( char * name , pointer wert // ) ; public: void ExecUt :: trace // hidden by macros// ----------------------------------------------------------------------------- ( char * name , long wert ) ; public: void ExecUt :: xrace // hidden by macros/* ----------------------------------------------------------------------------- PROBLEM -- warum ???????????? ----------------------------------------------------------------------------- */ ( char * name , double wert ) ; public: void ExecUt :: trace // hidden by macros/* ----------------------------------------------------------------------------- Klassen K, deren Instanzen als Trace auszugeben sein sollen, mssen eine Methode K :: trace() bereitstellen, mit der sich jede Instanz selbst per ExecUt :: trace drucken kann. Sie tun das dann, wenn sie Spezialisierung der Klasse 'EStandardServices' sind. Aufruf solcher Trace-Befehle nur per Macro L1_ (damit in der optimierten Version des Systems garantiert kein Trace-Kommando mehr steht). ----------------------------------------------------------------------------- */ ( char * name , EStandardServices & wert // the object to be traced ) ; public: void ExecUt :: ok_new_sto // hidden by macros/* ----------------------------------------------------------------------------- register allocated item ----------------------------------------------------------------------------- */ ( pointer ref , int line // where allocated in the file, char * file // ) ; public: void ExecUt :: ok_rem_sto // hidden by macros/* ----------------------------------------------------------------------------- unregister heap item ----------------------------------------------------------------------------- */ ( pointer ref ) ; public: void ExecUt :: ok_rem_heap // hidden by macros/* ----------------------------------------------------------------------------- search the heap for still allocated items ----------------------------------------------------------------------------- */ ( BOOL check ) ; public: void ExecUt :: ok_show_heap // hidden by macros/* ----------------------------------------------------------------------------- show all items not yet deallocated ----------------------------------------------------------------------------- */ ( char * file , int line ) ; public: BOOL ExecUt :: ok_At // ----------------------------------------------------------------------------- ( char * c , char * s ) ; public: BOOL ExecUt :: ok_iAt // ----------------------------------------------------------------------------- ( char * c , char * s ) ; public: int ExecUt :: ok_norm /* ----------------------------------------------------------------------------- Ersetze in 'str alle 'fc durch 'tc, return strlen( str ) ----------------------------------------------------------------------------- */ ( char * str , char fc , char tc ) ; #include exec_ut.h3 : cpp } ; #endif