stdutil.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. #include "stdutil.h"
  2. #include <set>
  3. #include <math.h>
  4. #include <stdlib.h>
  5. #include <windows.h>
  6. using namespace std;
  7. #ifdef MEMDEBUG
  8. struct Mem{
  9. Mem *next,*prev;
  10. const char *file;
  11. int line,size,tag;
  12. };
  13. static bool track;
  14. static Mem head,tail;
  15. static Mem x_head,x_tail;
  16. static void remove( Mem *m ){
  17. m->next->prev=m->prev;
  18. m->prev->next=m->next;
  19. }
  20. static void insert( Mem *m,Mem *next ){
  21. m->next=next;
  22. m->prev=next->prev;
  23. next->prev->next=m;
  24. next->prev=m;
  25. }
  26. static void init(){
  27. if( head.next ) return;
  28. head.next=head.prev=&tail;head.tag='HEAD';
  29. tail.next=tail.prev=&head;tail.tag='TAIL';
  30. x_head.next=x_head.prev=&x_tail;x_head.tag='HEAD';
  31. x_tail.next=x_tail.prev=&x_head;x_tail.tag='TAIL';
  32. }
  33. static void check( Mem *m ){
  34. if( m->tag!='DNEW' ){
  35. MessageBox( GetDesktopWindow(),"mem_check: pre_tag!='DNEW'","Memory error",MB_OK|MB_ICONWARNING );
  36. if( m->tag=='NDWE' ){
  37. string t="Probable double delete";
  38. t+="- d_new file: "+string(m->file)+" line:"+itoa(m->line);
  39. MessageBox( GetDesktopWindow(),t.c_str(),"Memory error",MB_OK|MB_ICONWARNING );
  40. }
  41. ExitProcess( 0 );
  42. }
  43. int *t=(int*)( (char*)(m+1)+m->size );
  44. if( *t!='dnew' ){
  45. MessageBox( GetDesktopWindow(),"mem_check: post_tag!='dnew'","Memory error",MB_OK|MB_ICONWARNING );
  46. string t="Probable memory overwrite - d_new file: "+string(m->file)+" line:"+itoa(m->line);
  47. MessageBox( GetDesktopWindow(),t.c_str(),"Memory error",MB_OK|MB_ICONWARNING );
  48. ExitProcess( 0 );
  49. }
  50. }
  51. static void *op_new( size_t size,const char *file="<unknown>",int line=0 ){
  52. init();
  53. Mem *m=(Mem*)malloc( sizeof(Mem)+size+sizeof(int) );
  54. memset( m+1,0xcc,size );
  55. m->file=file;m->line=line;m->size=size;m->tag='DNEW';
  56. int *t=(int*)( (char*)(m+1)+size );*t='dnew';
  57. if( track ) insert( m,head.next );
  58. else insert( m,x_head.next );
  59. return m+1;
  60. }
  61. static void op_delete( void *q ){
  62. init();
  63. if( !q ) return;
  64. Mem *m=(Mem*)q-1;
  65. check( m );
  66. remove( m );
  67. m->tag='NDWE';
  68. *(int*)( (char*)(m+1)+m->size )='ndwe';
  69. free( m );
  70. }
  71. void trackmem( bool enable ){
  72. init();
  73. if( track==enable ) return;
  74. track=enable;
  75. Mem *m;
  76. while( (m=head.next)!=&tail ){
  77. remove( m );insert( m,x_head.next );
  78. }
  79. }
  80. void checkmem( ostream &out ){
  81. init();
  82. Mem *m,*next;
  83. int sum=0,usum=0,xsum=0;
  84. for( m=head.next;m!=&tail;m=next ){
  85. check( m );
  86. next=m->next;
  87. if( m->line ){
  88. out<<m->file<<" line:"<<m->line<<" "<<m->size<<" bytes"<<endl;
  89. sum+=m->size;
  90. }else{
  91. usum+=m->size;
  92. }
  93. }
  94. for( m=x_head.next;m!=&x_tail;m=m->next ){
  95. check( m );
  96. xsum+=m->size;
  97. }
  98. out<<"Tracked blitz mem in use:"<<sum<<endl;
  99. out<<"Tracked other mem in use:"<<usum<<endl;
  100. out<<"Untracked mem in use:"<<xsum<<endl;
  101. out<<"Total mem in use:"<<(sum+usum+xsum)<<endl;
  102. }
  103. void * _cdecl operator new( size_t size ){ return op_new( size ); }
  104. void * _cdecl operator new[]( size_t size ){ return op_new( size ); }
  105. void * _cdecl operator new( size_t size,const char *file,int line ){ return op_new( size,file,line ); }
  106. void * _cdecl operator new[]( size_t size,const char *file,int line ){ return op_new( size,file,line ); }
  107. void _cdecl operator delete( void *q ){ op_delete( q ); }
  108. void _cdecl operator delete[]( void *q ){ op_delete( q ); }
  109. void _cdecl operator delete( void *q,const char *file,int line ){ op_delete( q ); }
  110. void _cdecl operator delete[]( void *q,const char *file,int line ){ op_delete( q ); }
  111. #else
  112. void trackmem( bool enable ){
  113. }
  114. void checkmem( ostream &out ){
  115. }
  116. #endif
  117. int atoi( const string &s ){
  118. return atoi( s.c_str() );
  119. }
  120. double atof( const string &s ){
  121. return atof( s.c_str() );
  122. }
  123. string itoa( int n ){
  124. char buff[32];itoa( n,buff,10 );
  125. return string( buff );
  126. }
  127. static int _finite( double n ){ // definition: exponent anything but 2047.
  128. int e; // 11 bit exponent
  129. const int eMax = 2047; // 0x7ff, all bits = 1
  130. int *pn = (int *) &n;
  131. e = *++pn; // Intel order!
  132. e = ( e >> 20 ) & eMax;
  133. return e != eMax;
  134. }
  135. static int _isnan( double n ){ // definition: exponent 2047, nonzero fraction.
  136. int e; // 11 bit exponent
  137. const int eMax = 2047; // 0x7ff, all bits = 1
  138. int *pn = (int *) &n;
  139. e = *++pn; // Intel order!
  140. e = ( e >> 20 ) & eMax;
  141. if ( e != 2047 ) return 0; // almost always return here
  142. int fHi, fLo; // 52 bit fraction
  143. fHi = ( *pn ) & 0xfffff; // first 20 bits
  144. fLo = *--pn; // last 32 bits
  145. return ( fHi | fLo ) != 0; // returns 0,1 not just 0,nonzero
  146. }
  147. /////////////
  148. //By FLOYD!//
  149. /////////////
  150. string ftoa( float n ){
  151. static const int digits=6;
  152. int eNeg = -4, ePos = 8; // limits for e notation.
  153. char buffer[50]; // from MSDN example, 25 would probably suffice
  154. string t;
  155. int dec, sign;
  156. if ( _finite( n ) ){
  157. // if ( digits < 1 ) digits = 1; // less than one digit is nonsense
  158. // if ( digits > 8 ) digits = 8; // practical maximum for float
  159. t = _ecvt( n, digits, &dec, &sign );
  160. if ( dec <= eNeg + 1 || dec > ePos ){
  161. _gcvt( n, digits, buffer );
  162. t = buffer;
  163. return t;
  164. }
  165. // Here is the tricky case. We want a nicely formatted
  166. // number with no e-notation or multiple trailing zeroes.
  167. if ( dec <= 0 ){
  168. t = "0." + string( -dec, '0' ) + t;
  169. dec = 1; // new location for decimal point
  170. }
  171. else if( dec < digits ){
  172. t = t.substr( 0, dec ) + "." + t.substr( dec );
  173. }
  174. else{
  175. t = t + string( dec - digits, '0' ) + ".0";
  176. dec += dec - digits;
  177. }
  178. // Finally, trim off excess zeroes.
  179. int dp1 = dec + 1, p = t.length();
  180. while( --p > dp1 && t[p] == '0' );
  181. t = string( t, 0, ++p );
  182. return sign ? "-" + t : t;
  183. } // end of finite case
  184. if ( _isnan( n ) ) return "NaN";
  185. if ( n > 0.0 ) return "Infinity";
  186. if ( n < 0.0 ) return "-Infinity";
  187. abort();
  188. }
  189. /*
  190. string ftoa( float n ){
  191. static const float min=.000001f,max=9999999.0f;
  192. int i=*(int*)&n;
  193. int e=(i>>23)&0xff;
  194. int f=i&0x007fffff;
  195. if( e==0xff && f ) return "NAN";
  196. string t;
  197. int s=(i>>31)&0x01;
  198. if( e==0xff ){
  199. t="INFINITY";
  200. }else if( !e && !f ){
  201. t="0.000000";
  202. }else if( n>=min && n<=max ){
  203. int dec,sgn;
  204. t=_fcvt( fabs(n),6,&dec,&sgn );
  205. if( dec<=0 ){
  206. t="0."+string( -dec,'0' )+t;
  207. }else if( dec<t.size() ){
  208. t=t.substr( 0,dec )+"."+t.substr( dec );
  209. }else{
  210. t=t+string( '0',dec-t.size() )+".000000";
  211. }
  212. }else{
  213. char buff[32];
  214. _gcvt( fabs(n),7,buff );
  215. t=buff;
  216. }
  217. return s ? "-"+t : t;
  218. }
  219. */
  220. string tolower( const string &s ){
  221. string t=s;
  222. for( int k=0;k<t.size();++k ) t[k]=tolower(t[k]);
  223. return t;
  224. }
  225. string toupper( const string &s ){
  226. string t=s;
  227. for( int k=0;k<t.size();++k ) t[k]=toupper(t[k]);
  228. return t;
  229. }
  230. string fullfilename( const string &t ){
  231. char buff[MAX_PATH+1],*p;
  232. GetFullPathName( t.c_str(),MAX_PATH,buff,&p );
  233. return string(buff);
  234. }
  235. string filenamepath( const string &t ){
  236. char buff[MAX_PATH+1],*p;
  237. GetFullPathName( t.c_str(),MAX_PATH,buff,&p );
  238. if( !p ) return "";
  239. *p=0;return string(buff);
  240. }
  241. string filenamefile( const string &t ){
  242. char buff[MAX_PATH+1],*p;
  243. GetFullPathName( t.c_str(),MAX_PATH,buff,&p );
  244. if( !p ) return "";
  245. return string( p );
  246. }
  247. const int MIN_SIZE=256;
  248. qstreambuf::qstreambuf(){
  249. buf=d_new char[MIN_SIZE];
  250. setg( buf,buf,buf );
  251. setp( buf,buf,buf+MIN_SIZE );
  252. }
  253. qstreambuf::~qstreambuf(){
  254. delete buf;
  255. }
  256. int qstreambuf::size(){
  257. return pptr()-gptr();
  258. }
  259. char *qstreambuf::data(){
  260. return gptr();
  261. }
  262. qstreambuf::int_type qstreambuf::underflow(){
  263. if( gptr()==egptr() ){
  264. if( gptr()==pptr() ) return traits_type::eof();
  265. setg( gptr(),gptr(),pptr() );
  266. }
  267. return traits_type::to_int_type( *gptr() );
  268. }
  269. qstreambuf::int_type qstreambuf::overflow( qstreambuf::int_type c ){
  270. if( c==traits_type::eof() ) return c;
  271. if( pptr()==epptr() ){
  272. int sz=size();
  273. int n_sz=sz*2;if( n_sz<MIN_SIZE ) n_sz=MIN_SIZE;
  274. char *n_buf=d_new char[ n_sz ];
  275. memcpy( n_buf,gptr(),sz );
  276. delete buf;buf=n_buf;
  277. setg( buf,buf,buf+sz );
  278. setp( buf+sz,buf+sz,buf+n_sz );
  279. }
  280. *pptr()=traits_type::to_char_type( c );
  281. pbump( 1 );return traits_type::not_eof( c );
  282. }