#include "stdutil.h" #include #include #include #include using namespace std; #ifdef MEMDEBUG struct Mem{ Mem *next,*prev; const char *file; int line,size,tag; }; static bool track; static Mem head,tail; static Mem x_head,x_tail; static void remove( Mem *m ){ m->next->prev=m->prev; m->prev->next=m->next; } static void insert( Mem *m,Mem *next ){ m->next=next; m->prev=next->prev; next->prev->next=m; next->prev=m; } static void init(){ if( head.next ) return; head.next=head.prev=&tail;head.tag='HEAD'; tail.next=tail.prev=&head;tail.tag='TAIL'; x_head.next=x_head.prev=&x_tail;x_head.tag='HEAD'; x_tail.next=x_tail.prev=&x_head;x_tail.tag='TAIL'; } static void check( Mem *m ){ if( m->tag!='DNEW' ){ MessageBox( GetDesktopWindow(),"mem_check: pre_tag!='DNEW'","Memory error",MB_OK|MB_ICONWARNING ); if( m->tag=='NDWE' ){ string t="Probable double delete"; t+="- d_new file: "+string(m->file)+" line:"+itoa(m->line); MessageBox( GetDesktopWindow(),t.c_str(),"Memory error",MB_OK|MB_ICONWARNING ); } ExitProcess( 0 ); } int *t=(int*)( (char*)(m+1)+m->size ); if( *t!='dnew' ){ MessageBox( GetDesktopWindow(),"mem_check: post_tag!='dnew'","Memory error",MB_OK|MB_ICONWARNING ); string t="Probable memory overwrite - d_new file: "+string(m->file)+" line:"+itoa(m->line); MessageBox( GetDesktopWindow(),t.c_str(),"Memory error",MB_OK|MB_ICONWARNING ); ExitProcess( 0 ); } } static void *op_new( size_t size,const char *file="",int line=0 ){ init(); Mem *m=(Mem*)malloc( sizeof(Mem)+size+sizeof(int) ); memset( m+1,0xcc,size ); m->file=file;m->line=line;m->size=size;m->tag='DNEW'; int *t=(int*)( (char*)(m+1)+size );*t='dnew'; if( track ) insert( m,head.next ); else insert( m,x_head.next ); return m+1; } static void op_delete( void *q ){ init(); if( !q ) return; Mem *m=(Mem*)q-1; check( m ); remove( m ); m->tag='NDWE'; *(int*)( (char*)(m+1)+m->size )='ndwe'; free( m ); } void trackmem( bool enable ){ init(); if( track==enable ) return; track=enable; Mem *m; while( (m=head.next)!=&tail ){ remove( m );insert( m,x_head.next ); } } void checkmem( ostream &out ){ init(); Mem *m,*next; int sum=0,usum=0,xsum=0; for( m=head.next;m!=&tail;m=next ){ check( m ); next=m->next; if( m->line ){ out<file<<" line:"<line<<" "<size<<" bytes"<size; }else{ usum+=m->size; } } for( m=x_head.next;m!=&x_tail;m=m->next ){ check( m ); xsum+=m->size; } out<<"Tracked blitz mem in use:"<> 20 ) & eMax; return e != eMax; } static int _isnan( double n ){ // definition: exponent 2047, nonzero fraction. int e; // 11 bit exponent const int eMax = 2047; // 0x7ff, all bits = 1 int *pn = (int *) &n; e = *++pn; // Intel order! e = ( e >> 20 ) & eMax; if ( e != 2047 ) return 0; // almost always return here int fHi, fLo; // 52 bit fraction fHi = ( *pn ) & 0xfffff; // first 20 bits fLo = *--pn; // last 32 bits return ( fHi | fLo ) != 0; // returns 0,1 not just 0,nonzero } ///////////// //By FLOYD!// ///////////// string ftoa( float n ){ static const int digits=6; int eNeg = -4, ePos = 8; // limits for e notation. char buffer[50]; // from MSDN example, 25 would probably suffice string t; int dec, sign; if ( _finite( n ) ){ // if ( digits < 1 ) digits = 1; // less than one digit is nonsense // if ( digits > 8 ) digits = 8; // practical maximum for float t = _ecvt( n, digits, &dec, &sign ); if ( dec <= eNeg + 1 || dec > ePos ){ _gcvt( n, digits, buffer ); t = buffer; return t; } // Here is the tricky case. We want a nicely formatted // number with no e-notation or multiple trailing zeroes. if ( dec <= 0 ){ t = "0." + string( -dec, '0' ) + t; dec = 1; // new location for decimal point } else if( dec < digits ){ t = t.substr( 0, dec ) + "." + t.substr( dec ); } else{ t = t + string( dec - digits, '0' ) + ".0"; dec += dec - digits; } // Finally, trim off excess zeroes. int dp1 = dec + 1, p = t.length(); while( --p > dp1 && t[p] == '0' ); t = string( t, 0, ++p ); return sign ? "-" + t : t; } // end of finite case if ( _isnan( n ) ) return "NaN"; if ( n > 0.0 ) return "Infinity"; if ( n < 0.0 ) return "-Infinity"; abort(); } /* string ftoa( float n ){ static const float min=.000001f,max=9999999.0f; int i=*(int*)&n; int e=(i>>23)&0xff; int f=i&0x007fffff; if( e==0xff && f ) return "NAN"; string t; int s=(i>>31)&0x01; if( e==0xff ){ t="INFINITY"; }else if( !e && !f ){ t="0.000000"; }else if( n>=min && n<=max ){ int dec,sgn; t=_fcvt( fabs(n),6,&dec,&sgn ); if( dec<=0 ){ t="0."+string( -dec,'0' )+t; }else if( dec