meta, C++




14 Methoden:

/* private: */ void ExecUt ::   read_env
/* private: */ void ExecUt ::   show // hidden by macros
|
/* public: */ BOOL ExecUt ::   ok_At
/* public: */ void ExecUt ::   NewCounters
/* public: */ void ExecUt ::   PutCounters
/* public: */ void ExecUt ::   count_init
/* public: */ void ExecUt ::   count_show



#define static #include exec_ut.h : cpp #include exec_ut.c1 : cpp #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 #include procnestoff #ifdef prot_ #include btree.h : cpp #endif #define m_exut #undef getenv #undef fopen #define retError( e,m ) { errno = e ; set_errDescr( m ); return ; } #include toscreen.h : cpp #ifdef __WINDOWS__ #include <afxwin.h> #include ewinapp.h #include <stdarg.h> int _cdecl printf( const char* szFmt, ... ) { #ifndef __OPTIMIZED__ va_list l; va_start(l, szFmt); char szT[512]; vsprintf(szT, szFmt, l); TRACE("printf: %s\n", szT); #endif return( 0 ); } #endif /* public: */ BOOL ExecUt :: atErr // ----------------------------------------------------------------------------- ( char * mess , char * erro ) LB_("ExecUt.atErr") to_( mess, '[' ) mess += 1 ; skip_space( mess ); LE_ret( At( mess, erro ) ) /* public: */ void ExecUt :: TMPName /* ----------------------------------------------------------------------------- create path name = TMPDir/tmpNr ----------------------------------------------------------------------------- */ ( path & name ) LB_("ExecUt.TMPName") sprintf( name, "%s/%i", TMPDir, ++TMPNr ); if ( TMPNr == 1 ) S_ "mkdir %s", TMPDir _Do LE_ /* public: */ BOOL ExecUt :: ViewStdout( /* ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- */ ) { if no_this return( false ); fflush( stout ); path f ; get_std_file( f, ".sto" ); #ifdef __WINDOWS__ WinExec( f, SW_SHOWNORMAL); #else S_ "type %s", f _Do #endif return( true ); } /* public: */ BOOL ExecUt :: ViewStderr( /* ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- */ ) { if no_this return( false ); fflush( sterr ); path f ; get_std_file( f, ".err" ); #ifdef __WINDOWS__ WinExec( f, SW_SHOWNORMAL); #else S_ "type %s", f _Do #endif return( true ); } /* 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(); ----------------------------------------------------------------------------- */ ) { printf( "this( ExecUt ) = %p\n", this ); } /* public: */ ExecUt :: ~ExecUt /* ----------------------------------------------------------------------------- Der Aufrufer garantiert: - - sein Auftrag: Close stout und sterr, dann gebe auf dem Heap allokierten Speicher frei. Die Funktion garantiert: - ----------------------------------------------------------------------------- :: */ ( ) { // deadlock if temp dir too full !!!! if no_this NO_this #ifdef __TESTCOVER__ { PutCounters(); } #endif #ifndef __OPTIMIZED__ ok_rem_heap( 1 ); #endif #ifdef __DOS_OR_QUICK_WIN__ #ifdef __QUICK_WIN__ printf( "\n\n ok - f e r t i g " ); #else printf( "ok" ); #endif #else // zeige Pop Up Window mit Erfolgsmeldung (oder ...) #endif #ifdef __SPU__ #undef fclose #endif #define f_close( x ) { fflush( x ); fclose( x ); } if ( stout ) f_close( stout ) if ( sterr && sterr != stout ) f_close( sterr ) if ( ef && ef != stout && ef != sterr ) f_close( ef ) #ifndef __MAXIMAL_TRACE__ if ( * err_file && no_error ) unlink( err_file ); #endif #ifdef __SPU__ #endif destroyed = stopped = true ; } /* private: */ void ExecUt :: read_env /* ----------------------------------------------------------------------------- read environment to str ----------------------------------------------------------------------------- */ ( char * str // out: value , char * evar // in : of environment variable ) { if no_this NO_this if ( getenv( evar ) ) strcpy( str, getenv( evar ) ); else *str = 0 ; } /* private: */ void ExecUt :: do_Exit /* ----------------------------------------------------------------------------- fatal error that cannot be handled by exut ----------------------------------------------------------------------------- */ ( int en // in: an EN_... defined in en.h ) { if no_this NO_this #ifdef __WINDOWS__ char mess[ 300 ] ; sprintf( mess, "Function Call %i detected an implementation e r r o r \n" "Documentation not possible\n", call_nr ); PToScreen ps ; ps.message( mess ) ; EWinApp * pApp = ( EWinApp * ) AfxGetApp(); if ( pApp ) pApp -> Exit() ; else AfxAbort() ; #else // printf( "\nS y s t e m E r r o r : %s\n\n", semantics( en ) ); printf( "\nS y s t e m E r r o r in %s.exe: %s\n\n" , this_exe, semantics( en ) ); exit( en ); #endif } /* 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 // out: the path , char * ext // in : extension .err, .ste, or .sto ) { strcpy( fn, std_file ); if ( ! ext ) strcat( fn, ".err" ); esif ( is( ext, ".sto", 4 ) && stout == ef ) strcat( fn, ".err" ); esif ( is( ext, ".ste", 4 ) && sterr == ef ) strcat( fn, ".err" ); esif ( is( ext, ".ste", 4 ) ) strcat( fn, ".ste" ); esif ( is( ext, ".sto", 4 ) ) strcat( fn, ".sto" ); else strcat( fn, ".err" ); } /* public: */ void ExecUt :: throw_error // hidden by macros /* ----------------------------------------------------------------------------- report an unexpected error ----------------------------------------------------------------------------- */ ( int Line , char * File ) { if ( ! *errA ) strcpy( errA, "faulty code" ); printf( "\n\nfatal error %i.%s, call_nr = %u, errno = %i, %s\n[\n\n%s\n\n]" , Line, File, call_nr, errno, checkPoint, errA ); checkPoint = "exec_ut :: throw_error" ; // if ( ! *errA ) strcpy( errA, "faulty code" ); // *errA = 0 ; throw errMess ; } /* public: */ void ExecUt :: set_errDescr // hidden by macros /* ----------------------------------------------------------------------------- describe an error ----------------------------------------------------------------------------- */ ( char * descr // further description of the error ) { if no_this NO_this if ( ! descr ) descr = ( char * )semantics( errno ); char * x1 = errDescr ; char * x2 = errDescr + L_err - 1 ; while ( *descr && x1 < x2 ) *x1++ = *descr++ ; *x1 = 0 ; // Do n o t use strcpy() here - strcpy() as well as strlen() cause // desaster if 'descr is not NULL terminated. } /* public: */ BOOL ExecUt :: IsValid( /* ----------------------------------------------------------------------------- return BOOL( 'this object exists and is ok' ) ----------------------------------------------------------------------------- */ ) { return( ! stopped ); } /* public: */ ExecUt :: ExecUt /* ----------------------------------------------------------------------------- Initialize Mechanismus zur Beobachtung des Programmablaufs ----------------------------------------------------------------------------- */ ( char * app_name // DOS Name of application ) { #undef system rRest = 0 ; sprintf( errme, "\n\nerror --> " ); errst = errme + 12 ; stack_shown = 0 ; counters = "1tc\\counters" ; inproc = "??" ; #ifdef __TESTCOVER__ { int k = 0 ; while ( k < L_wp ) wp[ k++ ] = 0 ; } #endif suggest_trace = step_TR = 100 ; // S_ "del *.err" _Do ABSTURZ !!! strcpy( errDescr, "no exut object" ); sto1 = sto = 0 ; stn = -1 ; app_errors = 0 ; stout = sterr = 0 ; destroyed = stopped = no_error = true ; at1 = at = maxdepth ; char * c ; c = getenv( "SHOW_AT" ); show_at = ( c )? atoi(c) : INT_MAX ; c = getenv( "FROM_PROC" ); trace_from = ( c )? atoi(c) : INT_MAX ; #ifndef __OPTIMIZED__ { FILE * f = fopen( "xtrace", "r" ); if ( f ) then { fscanf( f, "%i", &trace_from ); fclose( f ); } else trace_from = INT_MAX ; } #endif if ( show_at <= 0 ) show_at = 1 ; // darf n i e <= 0 sein !!! if ( show_at < trace_from ) trace_from = show_at - 200 ; comm = comment ; comm_end = comment + L_comment ; exit_type = "ret To" ; int j = 0 ; for ( j = 0 ; j <= maxdepth ; j++ ) // initialize for safety { stack[ j ].proc = "" ; stack[ j ].file = "" ; stack[ j ].comm = "" ; } to_f = ef = stderr ; to_stack = true ; // to_f = ef = stdout ; to_stack = true ; // nicht immer gut !!! c = getenv( "TRACE_DIR" ); if ( c ) then strcpy( err_file, getenv( "trace_DIR" ) ); else strcpy( err_file, "c:\\tmp" ); { // check if TRACE_DIR exists: struct stat st ; stat( err_file, &st ); if ( ! ( st.st_mode & S_IFDIR )) { path comm ; sprintf( comm, "mkdir %s", err_file ); system( comm ); if ( errno ) { strcpy( err_file, "." ); } } } if ( *err_file ) strcat( err_file, "\\" ); // else current directory #ifdef __SPU__ path e_bat ; sprintf( e_bat, "%se.bat", err_file ); #endif if ( *app_name ) then { strcpy( ccc, app_name ); ccc[5] = 0 ; for ( j = 0 ; j < 5 ; j++ ) if ( ccc[j] == '.' ) ccc[j] = 0 ; } else strcpy( ccc, "app" ); strcat( err_file, ccc ); strcat( err_file, "_1.err" ); char * ext = err_file + strlen( err_file ) - 5 ; int n = 100 ; strcpy( TMPDir, err_file ); TMPDir_e = TMPDir + strlen( TMPDir ) - 4 ; *TMPDir_e = 0 ; TMPNr = 0 ; while ( ef == stderr ) { S_ "echo x > x.err " _Do // to avoid 'Could not find *.err': S_ "del *.err > NUL" _Do struct stat B ; ok ; stat( (char *)err_file, &B ); if no_such_file then { #ifdef __OPTIMIZED__ ef = stdout ; // ef = fopen( err_file , "w+" ); // #else ef = stdout ; #endif #ifdef __WINDOWS__ if ( ! ef ) retError( EN_cannot_create_trace_file, 0 ); #else if ( ! ef ) return ; #endif } else { if ( 220 <= n ) ef = stdout ; #ifdef __WINDOWS__ if ( errno ) retError( errno , 0 ); if ( n == 99 ) retError( EN_too_many_error_files, 0 ); #else if ( errno || 220 <= n ) { printf( "\nerror: Too many files in TRACE_DIR," " cannot create %s", err_file ); exit( 1 ); } #endif sprintf( ext, "%i.err", ( n-50 ) % 100 ); unlink( err_file ); ok sprintf( ext, "%i.err", ++n % 100 ); } } strcpy( std_file, err_file ); j = strlen( err_file ) - 4 ; #ifdef __CREATE_STO__ memcpy( std_file + j, ".sto", 5 ); stout = fopen( std_file, "w+" ); #else stout = ef ; #endif #ifdef __CREATE_STE__ memcpy( std_file + j, ".ste", 5 ); sterr = fopen( std_file, "w+" ); #else sterr = ef ; #endif std_file[ j ] = 0 ; to_f = ef ; also_to_f = 0 ; to_stack = true ; errno = 0 ; // fprintf( ef, "trace_from = %ld\n", trace_from ); #ifdef __WINDOWS__ if ( errno ) retError( errno, 0 ); #else if ( errno ) return ; c = getenv( "TRACE_TO_STDOUT" ); if ( c ) { if ( *c == '1' ) ef = stdout ; } #endif std_file[ j ] = 0 ; to_f = ef ; also_to_f = 0 ; to_stack = true ; errno = 0 ; // fprintf( ef, "trace_from = %ld\n", trace_from ); /* #ifdef __SPU__ #undef fclose FILE * f = fopen( e_bat, "w+" ); fprintf( f, "vi %s", err_file ); fclose( f ); errno = 0 ; #define system safe_ut.ok_system #define fclose safe_ut.ok_close #endif */ destroyed = stopped = false ; if ( ef == stdout ) strcpy( err_file, "stdout" ); // printf( "\nok Constructor exec_ut, errno = %i\n", errno ); } /* public: */ char * ExecUt :: get_err_path /* ----------------------------------------------------------------------------- return pointer to name of *.err, *.sto, *.ste without extension ----------------------------------------------------------------------------- */ ( ) { if no_this return( "" ); else return( std_file ); } /* public: */ void ExecUt :: enter_f // hidden by macros /* ----------------------------------------------------------------------------- push function call ----------------------------------------------------------------------------- */ ( char * proc // name of proc , char * file // name of file where the proc is defined , int line // ) { // // , proc, line, file, errno, call_nr ); int merrno = errno ; if no_this { printf( "\n?--> %s", proc ); NO_this } if ( call_nr % 512 == 0 ) then { FILE * f = fopen( "c:\\trace_.bat", "w+" ); ok // muss sein fprintf( f, "call trace %i 1 \n", call_nr - 600 ); fclose( f ); } #define proc_loop stack[ 0 ].call_nr if ( at ) then { at1 = --at ; comm[0] = 0 ; /* if ( stack[ at ].proc == proc ) proc_loop++ ; else proc_loop = 0 ; if ( proc_loop % 2000 == 0 ) { printf( "proc_loop ??: %s %s.%i \n", proc, file, line ); } */ stack[ at ].comm = ++comm ; stack[ at ].call_nr = ++call_nr ; stack[ at ].file = file ; stack[ at ].line = line ; stack[ at ].proc = proc ; stack[ at ].errn = merrno ; stack[ at ].recover = 0 ; // no recovery from SysError } else { stack[1].errn = merrno = EN_stack_too_deep ; at += 8 ; exit(1); } #ifdef __MAXIMAL_TRACE__ if ( sto != sto1 ) errno = EN_storage_corrupted ; if ( trace_from < call_nr ) { /* if ( call_nr < trace_from + 50 ) for ( int k = maxdepth - 1 ; at < k ; k-- ) { fprintf( ef, " %30i %s \n", stack[ k ].line, stack[ k ].proc ); } */ fprintf( ef, "--> %2i %s, call %i\n", maxdepth-at, proc, call_nr ); } #endif if ( merrno ) { errno = merrno ; show(1); } if ( suggest_trace < call_nr ) { suggest_trace = call_nr + step_TR ; S_ "echo trace %li 1 %li > xtrace.bat", call_nr - step_TR , call_nr - step_TR _Do } #undef proc_loop // } /* public: */ BOOL ExecUt :: at_E // hidden by macros /* ----------------------------------------------------------------------------- trace errno at watch point ----------------------------------------------------------------------------- */ ( int line ) { if no_this return( EN_ok ); stack[ at ].line = line ; stack[ at ].errn = errno ; return( errno ); } /* private: */ void ExecUt :: message_fErr /* ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- */ ( char * mess ) { fprintf( ef, mess ); #ifdef __WINDOWS__ #ifdef __MFC__ TRACE( mess ); // into Debugger Window or nowhere #endif #else if ( stderr != ef ) { fprintf( stderr, "%sdescribed in %s\n%s", mess, err_file , stack[ at ].comm ); } #endif } /* public: */ void ExecUt :: AnotherAppErr /* ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- */ ( char * mess ) { app_errors ++ ; #ifdef __WINDOWS__ #ifdef __MFC__ PToScreen ps ; ps.message( mess ) ; #endif #else printf( "\nERROR: %s\n", mess ); #endif fprintf( sterr, "\nERROR: %s\n", mess ); } /* private: */ void ExecUt :: fatal_error_at // hidden by macros /* ----------------------------------------------------------------------------- tell the system you detected a fatal error ----------------------------------------------------------------------------- */ ( int line ) { fatal_error_at( stack[ at ].file, line ); } /* public: */ void ExecUt :: fatal_error_at /* ----------------------------------------------------------------------------- tell the system you detected a fatal error ----------------------------------------------------------------------------- */ ( char * file , int line ) { if no_this NO_this // ?errS "fatal error" ); no_error = false ; printf( "\nfatal error: Last checkpoint: %s", checkPoint ); if ( ! errno ) errno = EN_syserror ; errNo = errno ; stack[ at ].line = line ; putErr( errno, file, line ); exit(1); // unlink( "stopAtErr" ) ok exit(1); show(2); stop( -1 ); } /* public: */ void ExecUt :: to_trace // hidden by macros /* ----------------------------------------------------------------------------- concatenate str to stack[ at ].comm ----------------------------------------------------------------------------- */ ( char * str ) { if no_this NO_this if ( ! str ) str = "( null )" ; int s = strlen( str ); if ( comm_end <= comm + s ) comm = comment + 1 ; memcpy( comm, str, s ); comm += s ; fprintf( ef, "%s", 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 ) { if no_this NO_this to_trace( err_descr ) ; errno = err_code ; } /* public: */ void ExecUt :: end_f // hidden by macros /* ----------------------------------------------------------------------------- pop function call (exit at 'LE_') ----------------------------------------------------------------------------- */ ( int line // of return ) { if no_this NO_this if ( errno ) fatal_error_at( stack[ at ].file, line ); #ifndef __OPTIMIZED__ exit_type = "end " ; exit_f( line ); exit_type = "ret to " ; #endif } /* public: */ void ExecUt :: at_return // hidden by macros /* ----------------------------------------------------------------------------- pop function call (exit at a 'return' point) ----------------------------------------------------------------------------- */ ( int line // of return ) { if no_this NO_this if ( errno ) fatal_error_at( stack[ at ].file, line ); #ifndef __OPTIMIZED__ exit_f( line ); #endif } /* public: */ void ExecUt :: putErr // hidden by macros // ----------------------------------------------------------------------------- ( int err , char * file , int line ) { if no_this NO_this errno = err ; if ( err ) then { path t ; sprintf( t, "\nErrNo( %18s ) at %6i.%s\n", semantics( err ), line, file ); to_trace( t ); } else stack[ at ].comm = "" ; #ifndef __OPTIMIZED__ exit_f( line ); #endif } /* public: */ void ExecUt :: exit_f // hidden by macros /* ----------------------------------------------------------------------------- pop function call (exit at a 'return' point) ----------------------------------------------------------------------------- */ ( int line // of return ) { if no_this NO_this // if ( maxdepth <= at ) return ; // da oft trace nicht von Anfang an // if ( maxdepth <= at ) if ( maxdepth < at ) then { #ifdef LB_tr #else printf( "\nerror: %i = maxdepth <= at = %i\n", maxdepth, at ); #endif if ( at == maxdepth ) return ; printf( "\nerror: exut out of step\n" ); at = maxdepth ; comm = comment ; // re-initialize // at -= 10 ; sprintf( sss, "W a r n i n g : ExecUt out of step \n" ); exit(1); trace( sss ); show(3); *sss = 0 ; } else { comm = stack[ at ].comm - 1 ; /* if ( trace_from < call_nr ) { sprintf( sss, " " "exit %s at %i\n", stack[ at ].proc, line ); trace( sss ); } */ // return out of: // sprintf( sss, "< %s", stack [ at ].proc ); stack[ at ].line = line ; // server's exit stack[ at++ ].errn = errno ; // server's errno at exit } #ifdef __MAXIMAL_TRACE__ if ( trace_from < call_nr ) fprintf( ef, " %2i_%s%i.%s %s\n" , maxdepth - at + 1 , exit_type , stack[ at ].line , stack[ at ].file, sss ); fflush( ef ); #endif } /* public: */ void ExecUt :: count /* ----------------------------------------------------------------------------- Store test coverage for the given code line (= return from a method). ----------------------------------------------------------------------------- */ ( char * file , int line ) LB_("ExecUt.count") #ifdef prot_ sprintf( cName, "%s.%i", file, line ); KVStore st ; counter[ counterNames -> Get( cName, st ) ]++ ; #endif LE_ /* 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 ) LB_("ExecUt.count_init") #ifdef prot_ rBuffer B( file, "" ); Surr s ; while ( B.find( 1, "xut.count(", 0 ) ) { char * c = B.z + B.a + 12 ; if ( c[-1] != '"' ) fErr char * e = c ; to_( e, '"' ) *e++ = '.' ; char * x = e + 1 ; while ( isdigit( *x ) ) *e++ = *x++ ; *e = 0 ; s = counterNames -> StrIns( c ); } if ( e_prot_ <= s ) fErr #endif LE_ /* public: */ void ExecUt :: count_show /* ----------------------------------------------------------------------------- show test coverage ----------------------------------------------------------------------------- */ ( char * file , int line ) LB_("ExecUt.count_show") #ifdef prot_ KVStore st ; Surr s = counterNames -> GetFirst( st ); while ( s ) { fprintf( ef, "%-8i %s", s, st.k ); s = counterNames -> Next( st ); } #endif LE_ /* public: */ void ExecUt :: NewCounters( /* ----------------------------------------------------------------------------- Der Aufrufer sagt: Reinitialize counters for test coverage (i.e. make them 0). ----------------------------------------------------------------------------- */ ) LB_("ExecUt.NewCounters") #ifdef __TESTCOVER__ unlink( counters ); ok for ( int k = 0 ; k < L_wp ; ) wp[ k++ ] = 0 ; PutCounters(); #endif LE_ /* public: */ void ExecUt :: PutCounters( /* ----------------------------------------------------------------------------- Der Aufrufer sagt: Addiere die in diesem Lauf errechnete Testberdeckung zur schon frher erreichten. Die Funktion garantiert: fErr || ok ----------------------------------------------------------------------------- */ ) LB_("ExecUt.PutCounters") #ifdef __TESTCOVER__ int L = sizeof( int ) * L_wp ; int f = _open( counters, O_BINARY | O_RDWR ); if ( errno ) then { ok f = _open( counters, O_BINARY | O_RDWR | O_CREAT, S_IREAD | S_IWRITE ); EE } else { int wp_alt[ L_wp ] ; if ( read( f, wp_alt, L ) != L ) fErr int k = -1 ; while ( ++k < L_wp ) wp[ k ] += wp_alt[ k ] ; } if ( write( f, wp, L ) != L ) fErr close( f ); #endif LE_ /* private: */ void ExecUt :: show // hidden by macros /* ----------------------------------------------------------------------------- stop program because of a fatal error detected show all data in the current execution stack ----------------------------------------------------------------------------- */ ( int Von ) { // // , Von, errno, inproc ); ERRNo = errno ; if ( stack_shown++ ) exit( 1 ); #ifdef __SPU__ /* fprintf( ef, "\n%p %p %p %p %p %p \n" "stdout stderr ef stout sterr to_f \n" , stdout, stderr, ef , stout , sterr , to_f ); */ #endif #ifdef __OPTIMIZED__ fprintf( ef, "\n\nCode version 'minimal checks'" ); #else fprintf( ef, "\n\nCode version 'maximal checks'" ); #endif fprintf( ef, " on %s:\n\nStack is\n\n%s", currentTime( 0 ) , stack[ at ].comm ); stack[ at ].errn = errno ; uint j = maxdepth ; int recover = 0 ; if ( j-1 <= at1 ) then { *comm = 0 ; fprintf( ef, "%s\n", comment ); } if ( at1 < at-3 ) at1 = at-3 ; trace_from = INT_MAX ; while ( at1 <= --j ) { comm[ 0 ] = 0 ; if ( j < at ) stack[ j ].comm = comment ; // no comment char * pr = stack[ j ].proc ; int s = strlen( pr ) - 1 ; while ( isalnum( pr[s] ) || pr[s] == '_' ) s-- ; stack[ j ].proc[ 28 ] = 0 ; #define error(x) stack[ x ].proc \ , semantics( stack[ x ].errn ) \ , stack[ x ].line \ , stack[ x ].file if ( j == at-1 ) then fPrintf( ef, "--> %-28s : %s at %i %s\n", error( j ) ); else { if ( j == at-2 ) fprintf( ef, "\n Last checkpoint before was\n" ); fPrintf( ef, " %-28s : at %i %s\n", stack[ j ].proc , stack[ j ].line , stack[ j ].file ); } #undef error // if ( stack[ j ].recover ) recover = stack[ j ].recover ; } if ( show_at ) then { fflush( ef ); } if ( recover ) then { // throw syserror exception or do the recovery here (e.g. by sending // a signal 'restart me' to a master process and then stopping). printf( "RECOVER not yet implemented\n" ); exit( -1 ); } // else ret_ // else exit( 1 );//exit fhrt komischerweise in einen unendlichen loop !!! } /* 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 ) { #ifndef __OPTIMIZED__ char comm[ 200 ] ; sprintf( comm, "echo %i > xtrace", call_nr - 100 ); #undef system system( comm ); #define system safe_ut.ok_system #endif if ( stopped ) then { printf( "\n stop: %i, stopped = %i\n", en, stopped ); exit(1); } if ( en < 0 ) then { char mess[ 300 ] ; // errno = ERRNo ; // if ( 1 < call_nr ) sprintf( mess, if ( 0 ) sprintf( mess, "S y s t e m E r r o r at call_nr %i, trace in %s, errno = %i\n%s" , call_nr , err_file , errno, stack[ at ].comm ); else sprintf( mess, "%s.exe atLB = %i: " // "S y s t e m E r r o r \"%s\" , see %s\n%s" "S y s t e m E r r o r \"%s\" %s" , this_exe , atLB , semantics( errNo ) // , err_file , stack[ at ].comm ); PToScreen ps ; ps.message( mess ) ; } else ; printf( "\nis errno %i, last LB_ was in %s\n\n", errNo, inproc ); #ifndef __OPTIMIZED__ ok_rem_heap( 0 ); #endif #ifdef __WINDOWS__ printf( "__WINDOWS__" ); EWinApp * pApp = ( EWinApp * ) AfxGetApp(); if ( pApp ) pApp -> Exit() ; else AfxAbort() ; #else exit( en ); #endif stopped = 1 ; } #ifdef __WINDOWS__ #include "en_s1.h" #endif /* public: */ const char * ExecUt :: semantics /* ----------------------------------------------------------------------------- return pointer to semantics of a error code 'code' ----------------------------------------------------------------------------- */ ( int code // in: any value EN_... ) { if no_this return( "" ); if ( 0 < code && code <= 42 ) return( strerror( code ) ); #ifdef MICROSOFT if ( 0 < code ) if ( code < 500 || 16000 < code ) return( strerror( code ) ); #endif switch ( code ) { case 0 : return( "ok" ); #ifdef __WINDOWS__ #include "en_s2.h" // aus "en.h" mittels en_sem.exe erzeugt #else #include "en_sem.h" // aus "en.h" mittels en_sem.exe erzeugt #endif default: { sprintf( nosem, "unspecified errno: %i", errno ); return( nosem ); } } } /* 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 // in: if 0 reset to *.err file , char from // in: if 'e' according to FROM_PROC // else from now on ) { if no_this return ; if ( to_file ) to_f = to_file ; else to_f = ef ; also_to_f = ( to_f && to_f != ef ) ; if ( from == 'e' ) then { char * c = getenv( "FROM_PROC" ); trace_from = ( c )? atoi(c) : 0 ; } else trace_from = call_nr ; if not_path_exists( "xtrace.bat" ) { FILE * f = create( "xtrace.bat" ); fprintf( f, "call trace 9999999 0 9999999" ); close( f ); } S_ "call xtrace.bat" _Do #ifdef __WINDOWS__ if ( to_f == stdout ) to_f = stout ; if ( to_f == stderr ) to_f = sterr ; #endif } /* public: */ void ExecUt :: at_code_position // see mt.h /* ----------------------------------------------------------------------------- trace code position ----------------------------------------------------------------------------- */ ( char * file , int line ) { if no_this return ; if ( trace_from <= call_nr ) { fprintf( ef, " %i\n", line ); } } /* public: */ void ExecUt :: trace_always // hidden by macros /* ----------------------------------------------------------------------------- trace even if call_nr < trace_from ----------------------------------------------------------------------------- */ ( char * str ) { if no_this NO_this fprintf( ef, "%s", str ); if ( also_to_f ) fprintf( to_f, "%s", str ); } /* public: */ void ExecUt :: show_text /* ----------------------------------------------------------------------------- trace the first n_... characters of txt ----------------------------------------------------------------------------- */ ( char * name // any string , char * txt // any text , int n_chars // ) { if no_this NO_this if ( trace_from < call_nr ) { if ( 230 < n_chars ) n_chars = 230 ; if ( L_sss <= n_chars ) n_chars = L_sss - 1 ; memcpy( sss, txt, n_chars ); sss[ n_chars ] = 0 ; for ( int i = 0 ; i < n_chars ; i++ ) if ( !sss[i] ) sss[i] = '?' ; S_ "%s = ...[%s]...\n", name, sss _TR } } /* public: */ void ExecUt :: trace // hidden by macros // ----------------------------------------------------------------------------- ( char * str ) { if no_this NO_this #ifdef __WINDOWS__ #ifdef __MFC__ TRACE( str ); // nimmt Parameter wie printf #endif #endif if ( to_stack ) to_trace( str ); if ( also_to_f ) fprintf( to_f, "\n%s", str ); } /* public: */ void ExecUt :: trace // hidden by macros // ----------------------------------------------------------------------------- ( char * name , char * wert ) { if no_this NO_this if ( ! wert ) wert = "( null )" ; if ( to_stack ) then { sprintf( sss, "\n%s = [", name ); char * c1 = ( char * ) wert ; // Betrug des const in der SS char * c2 = sss + strlen( sss ) ; char * c3 = c1 + 200 ; while ( *c1 && c1 < c3 ) *c2++ = *c1++ ; *c2 = 0 ; if ( c1 == c3 ) strcpy( c2, " ... \n" ); else strcpy( c2, "]\n" ); to_trace( sss ); } if ( also_to_f ) then { const int cs = 80 ; char c[ cs ]; memcpy( c, wert, cs ); c[ cs-1 ] = 0 ; fprintf( to_f, "\n%s = (%s)", name, c ); } } /* public: */ void ExecUt :: trace // hidden by macros // ----------------------------------------------------------------------------- ( BOOL onoff ) { if no_this NO_this if ( onoff ) then trace_from = 0 ; else trace_from = LONG_MAX ; } /* public: */ void ExecUt :: trace // hidden by macros // ----------------------------------------------------------------------------- ( char * name // , pointer wert // ) { if ( to_stack ) then { if no_this return ; sprintf( sss, "\n%s = %p", name, wert ); to_trace( sss ); } if ( also_to_f ) then { fprintf( to_f, "\n%s = (%p)", name, wert ); } } /* public: */ void ExecUt :: trace // hidden by macros // ----------------------------------------------------------------------------- ( char * name , long wert ) { if no_this NO_this char str[ 12 ] ; *str = 0 ; uchar c = abs( wert ) % 256 ; if ( abs( wert ) == c ) then { if ( isprint(( char ) c ) ) sprintf( str, "'%c' = ", ( char ) c ); } if ( to_stack ) then { sprintf( sss, "\n%s = %s%ld", name, str, wert ); to_trace( sss ); } if ( also_to_f ) then { fprintf( to_f, "\n%s = %s(%ld)", name, str, wert ); } } /* public: */ void ExecUt :: xrace // hidden by macros /* ----------------------------------------------------------------------------- PROBLEM -- warum ???????????? ----------------------------------------------------------------------------- */ ( char * name , double wert ) { if no_this NO_this char str[ 40 ] ; s_( str, "%f", wert ); trace( name, str ); } /* public: */ void ExecUt :: trace // hidden by macros /* ----------------------------------------------------------------------------- Klassen K, deren Instanzen als Trace auszugeben sein sollen, mssen 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 ) { if no_this NO_this wert.trace( name, ef ); if ( also_to_f ) wert.trace( name, to_f ); } /* Beispiel eine ausgedruckten Kellers (Diagnosedaten sind stets solche, die die unmittelbar ber ihnen stehende Funktion gesammelt hat): Execution Stack ( error in call 109 ): main program : ok at 89 main.h rB_cpp_ic.cpp_ic : ok at 123 rbcppic.cpp rB_cpp_ic.shift_me : ok at 162 rbcppic.cpp len of e:\tmp\xx_edit = 585216,, 4096 = L, gel = 0 rBuffer.find : ok at 271 rbuffer.cpp --> rBuffer.f_write : not_an_open_file at 448 rbuffer.cpp */ /* public: */ void ExecUt :: ok_new_sto // hidden by macros /* ----------------------------------------------------------------------------- register allocated item ----------------------------------------------------------------------------- */ ( pointer ref // , int line // where allocated in the file , char * file // ) { if no_this NO_this stn = ( ++stn % L_hdescr_page ); if ( ! stn ) then { heap_descr_page * pre = sto ; sto1 = sto = new heap_descr_page ; sto->pre = pre ; } sto -> sto[ stn ].ref = ref ; sto -> sto[ stn ].line = line ; sto -> sto[ stn ].file = file ; // S_ "%p heap - new_sto at %i.%s\n", ref, line, file _TR_a } /* public: */ void ExecUt :: ok_rem_sto // hidden by macros /* ----------------------------------------------------------------------------- unregister heap item ----------------------------------------------------------------------------- */ ( pointer ref // ) { if ( ! ref || no_this ) return ; S_ "Heap %p rem_sto \n", ref _TR int a = stn ; while ( sto ) { while ( 0 <= a ) { if ( sto -> sto[ a ].ref == ref ) then { sto -> sto[ a ].line = 0 ; return ; } a-- ; } sto1 = sto = sto->pre ; a = L_hdescr_page - 1 ; if ( ! sto ) stn = -1 ; // damit ok_new_sto() neu anfangen kann } S_ "W a r n i n g : rem_sto() cannot find the item %p \n", ref _TR show_heap } /* public: */ void ExecUt :: ok_rem_heap // hidden by macros /* ----------------------------------------------------------------------------- search the heap for still allocated items ----------------------------------------------------------------------------- */ ( BOOL check // true, if you expect the heap to be empty ) { if no_this NO_this int a = stn ; long items = 0 ; while ( sto ) { while ( 0 <= a ) { if ( sto -> sto[ a ].line ) then { if ( check ) then { ++ items ; S_ "delete storage allocated at %5ld %s\n" , sto -> sto[ a ].line , sto -> sto[ a ].file _TR } // Das delete hier aber nicht wirklich anwenden - // wir wollen ja nur sehen, was vergessen wurde! } a-- ; } heap_descr_page * pre = sto->pre ; delete( sto ); sto1 = sto = pre ; a = L_hdescr_page - 1 ; } stn = L_hdescr_page - 1 ; if ( items ) errno = EN_still_allocated_items ; // hier ja kein fErr !! } /* public: */ void ExecUt :: ok_show_heap // hidden by macros /* ----------------------------------------------------------------------------- show all items not yet deallocated ----------------------------------------------------------------------------- */ ( char * file , int line ) LB_("ExecUt.ok_show_heap") S_ "Heap at %i in %s: \n----\n", line, file _TR int a = stn ; long items = 0 ; while ( sto ) { while ( 0 <= a ) { if ( sto -> sto[ a ].line ) then { S_ "Heap %p allocated at %5ld %s\n" , sto -> sto[ a ].ref , sto -> sto[ a ].line , sto -> sto[ a ].file _TR items++ ; } a-- ; } sto1 = sto = sto->pre ; a = L_hdescr_page - 1 ; } S_ "Heap items: %ld \n", items _TR LE_ /* public: */ BOOL ExecUt :: ok_At // ----------------------------------------------------------------------------- ( char * c , char * s ) { while ( *s && *s == *c ) { s++ ; c++ ; } return( ! *s ); } /* public: */ BOOL ExecUt :: ok_iAt // ----------------------------------------------------------------------------- ( char * c , char * s ) { while ( *s && upper( *s ) == upper( *c ) ) { s++ ; c++ ; } return( ! *s ); } /* public: */ int ExecUt :: ok_norm /* ----------------------------------------------------------------------------- Ersetze in 'str alle 'fc durch 'tc, return strlen( str ) ----------------------------------------------------------------------------- */ ( char * str , char fc , char tc ) LB_("ExecUt.ok_norm") if ( errno == 2 ) errno = 0 ; // file not found if ( errno ) errno = 0 ; // if ( errno ) fErr1( str ) if ( ! str ) en_fErr( EN_NULL_pointer ) esif ( ! *str ) ret( 0 ) int n = 0 ; while ( *str ) { if ( *str == fc ) { *str = tc ; n++ ; } str++ ; } if ( errno ) fErr3( errno, n, str ); LE_ret( n ) #undef m_exut #define m_exut exut. #define getenv safe_ut.ok_getenv #define fopen safe_ut.ok_fopen #undef __EXEC_UT_CPP__ #undef static #endif
top . C++
Include-structure of
todir / exec_ut.cpp

ewinapp.h
.   .   ewinapp.h3
.   .   exceptns.h
.   .   .   for_all.h
.   .   .   .   exec_ut.h
.   .   .   .   .   exec_ut.h3
.   .   .   .   .   macros_1.h
.   .   .   .   .   traceco.h
.   .   .   .   precomp.h
.   .   .   .   .   basis.h
.   .   .   .   .   .   compiler.h
.   .   .   .   .   .   dmlerr.h
.   .   .   .   .   en.h
.   .   .   .   .   .   en_lec.h
.   .   .   .   .   limits.h
.   .   .   .   .   mt.h
.   .   .   .   .   obsolete.h
.   .   .   .   .   ot.h
.   .   .   .   .   st.h
.   .   .   .   .   trace.h
.   .   .   .   standard.h
.   .   .   .   toscreen.h
.   exec_ut.c1
.   btree.h
.   .   for_spu.h
.   .   .   spu.h
.   .   .   .   help_gen.h
.   .   .   .   .   help_gen.h3
.   .   .   .   rbuffer.h
.   .   .   .   .   rbuffer.h3
.   .   .   .   .   str_set.h
.   .   .   .   .   .   str_set.h3
.   .   .   .   safe_uts.h
.   .   .   .   .   safe_uts.h3
.   .   .   .   ut_repl.h
.   .   btree.h3
.   procnestoff

37 include files
top . is_inc_for . C++