| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- #include "stdutil.h"
- #include <set>
- #include <math.h>
- #include <stdlib.h>
- #include <windows.h>
- 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="<unknown>",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<<m->file<<" line:"<<m->line<<" "<<m->size<<" bytes"<<endl;
- sum+=m->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:"<<sum<<endl;
- out<<"Tracked other mem in use:"<<usum<<endl;
- out<<"Untracked mem in use:"<<xsum<<endl;
- out<<"Total mem in use:"<<(sum+usum+xsum)<<endl;
- }
- void * _cdecl operator new( size_t size ){ return op_new( size ); }
- void * _cdecl operator new[]( size_t size ){ return op_new( size ); }
- void * _cdecl operator new( size_t size,const char *file,int line ){ return op_new( size,file,line ); }
- void * _cdecl operator new[]( size_t size,const char *file,int line ){ return op_new( size,file,line ); }
- void _cdecl operator delete( void *q ){ op_delete( q ); }
- void _cdecl operator delete[]( void *q ){ op_delete( q ); }
- void _cdecl operator delete( void *q,const char *file,int line ){ op_delete( q ); }
- void _cdecl operator delete[]( void *q,const char *file,int line ){ op_delete( q ); }
- #else
- void trackmem( bool enable ){
- }
- void checkmem( ostream &out ){
- }
- #endif
- int atoi( const string &s ){
- return atoi( s.c_str() );
- }
- double atof( const string &s ){
- return atof( s.c_str() );
- }
- string itoa( int n ){
- char buff[32];itoa( n,buff,10 );
- return string( buff );
- }
- static int _finite( double n ){ // definition: exponent anything but 2047.
- 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;
- 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<t.size() ){
- t=t.substr( 0,dec )+"."+t.substr( dec );
- }else{
- t=t+string( '0',dec-t.size() )+".000000";
- }
- }else{
- char buff[32];
- _gcvt( fabs(n),7,buff );
- t=buff;
- }
- return s ? "-"+t : t;
- }
- */
- string tolower( const string &s ){
- string t=s;
- for( int k=0;k<t.size();++k ) t[k]=tolower(t[k]);
- return t;
- }
- string toupper( const string &s ){
- string t=s;
- for( int k=0;k<t.size();++k ) t[k]=toupper(t[k]);
- return t;
- }
- string fullfilename( const string &t ){
- char buff[MAX_PATH+1],*p;
- GetFullPathName( t.c_str(),MAX_PATH,buff,&p );
- return string(buff);
- }
- string filenamepath( const string &t ){
- char buff[MAX_PATH+1],*p;
- GetFullPathName( t.c_str(),MAX_PATH,buff,&p );
- if( !p ) return "";
- *p=0;return string(buff);
- }
- string filenamefile( const string &t ){
- char buff[MAX_PATH+1],*p;
- GetFullPathName( t.c_str(),MAX_PATH,buff,&p );
- if( !p ) return "";
- return string( p );
- }
- const int MIN_SIZE=256;
- qstreambuf::qstreambuf(){
- buf=d_new char[MIN_SIZE];
- setg( buf,buf,buf );
- setp( buf,buf,buf+MIN_SIZE );
- }
- qstreambuf::~qstreambuf(){
- delete buf;
- }
- int qstreambuf::size(){
- return pptr()-gptr();
- }
- char *qstreambuf::data(){
- return gptr();
- }
- qstreambuf::int_type qstreambuf::underflow(){
- if( gptr()==egptr() ){
- if( gptr()==pptr() ) return traits_type::eof();
- setg( gptr(),gptr(),pptr() );
- }
- return traits_type::to_int_type( *gptr() );
- }
- qstreambuf::int_type qstreambuf::overflow( qstreambuf::int_type c ){
- if( c==traits_type::eof() ) return c;
- if( pptr()==epptr() ){
- int sz=size();
- int n_sz=sz*2;if( n_sz<MIN_SIZE ) n_sz=MIN_SIZE;
- char *n_buf=d_new char[ n_sz ];
- memcpy( n_buf,gptr(),sz );
- delete buf;buf=n_buf;
- setg( buf,buf,buf+sz );
- setp( buf+sz,buf+sz,buf+n_sz );
- }
- *pptr()=traits_type::to_char_type( c );
- pbump( 1 );return traits_type::not_eof( c );
- }
|