00001
00002 #ifndef _GENERAL_H
00003 #define _GENERAL_H
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <string.h>
00016 #include <strings.h>
00017 #include <stdlib.h>
00018 #include <fcntl.h>
00019
00020 #include <unistd.h>
00021 #include <errno.h>
00022 #include <signal.h>
00023
00024 #include <time.h>
00025 #include <stdarg.h>
00026 #include <sys/stat.h>
00027
00028 #include <math.h>
00029
00030
00031
00032
00033
00034
00035 #ifndef M_SQRT2
00036 #define M_SQRT2 (1.41421356237309504880168872420969807856967187537694807317668)
00037 #endif
00038 #ifndef M_SQRT3 //sqrt(3)
00039 #define M_SQRT3 (1.73205080756887729352744634150587236694280525381038062805581)
00040 #endif
00041 #ifndef M_SQRT5
00042 #define M_SQRT5 (2.23606797749978969640917366873127623544061835961152572427090)
00043 #endif
00044 #ifndef M_SQRT7
00045 #define M_SQRT7 (2.64575131106459059050161575363926042571025918308245018036833)
00046 #endif
00047
00048 #ifndef M_CBRT2 //2^(1/3)
00049 #define M_CBRT2 (1.25992104989487316476721060727822835057025146470150798008198)
00050 #endif
00051 #ifndef M_CBRT3
00052 #define M_CBRT3 (1.44224957030740838232163831078010958839186925349935057754642)
00053 #endif
00054 #ifndef M_CBRT5
00055 #define M_CBRT5 (1.70997594667669698935310887254386010986805511054305492438286)
00056 #endif
00057 #ifndef M_CBRT7
00058 #define M_CBRT7 (1.91293118277238910119911683954876028286243905034587576621065)
00059 #endif
00060
00061 #ifndef M_E
00062 #define M_E (2.71828182845904523536028747135266249775724709369995957496697)
00063 #endif
00064 #ifndef M_PI
00065 #define M_PI (3.14159265358979323846264338327950288419716939937510582097494)
00066 #endif
00067 #ifndef M_SQRTPI //sqrt(pi)
00068 #define M_SQRTPI 1.77245385090551602729816748334114518279754945612238712821381
00069 #endif
00070 #ifndef M_CBRTPI
00071 #define M_CBRTPI 1.46459188756152326302014252726379039173859685562793717435726
00072 #endif
00073
00074
00075 #ifndef MIN_DOUBLE
00076 #define MIN_DOUBLE (2.220446e-16)
00077 #endif
00078
00079
00080 #define DOUBLE_PRECISION_INFINITY (1e308)
00081
00082
00083
00084
00085 #define P_C 2.99792458e8 // (m/s) the speed of light (EXACT)
00086 #define P_HBAR 1.0545919e-34 // (kg*m^2/s) hbar plank constant
00087 #define P_KB 1.380662e-23 // (kg*m^2/s^2/K) Boltzmann constant
00088 #define P_E 1.6021892e-19 // (C) electron charge
00089 #define P_ME 9.109558e-31 // (kg) electron mass
00090 #define P_G 6.6732e-11 // (m^3/s^2/kg) Gravitational constant
00091 #define P_NA 6.022169e23 // (1/mol) Avogadro constant
00092 #define P_U 1.660531e-27 // (kg) atomic mass unit
00093 #define P_MU0 (4*M_PI*1e-7) // (C^2*s^4/kg/m^5)
00094 #define P_EPSILON0 (1/P_MU0/P_C/P_C) // (kg*m^3/C^2/s^2)
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 #define ESC "\x1b"
00119
00120
00121
00122 #define BLK ESC"[30m" // Black
00123 #define RED ESC"[31m" // Red
00124 #define GRN ESC"[32m" // Green
00125 #define YEL ESC"[33m" // Yellow
00126 #define BLU ESC"[34m" // Blue
00127 #define MAG ESC"[35m" // Magenta
00128 #define CYN ESC"[36m" // Cyan
00129 #define WHT ESC"[37m" // White
00130
00131
00132
00133 #define HIK ESC"[1;30m" // Black
00134 #define HIR ESC"[1;31m" // Red
00135 #define HIG ESC"[1;32m" // Green
00136 #define HIY ESC"[1;33m" // Yellow
00137 #define HIB ESC"[1;34m" // Blue
00138 #define HIM ESC"[1;35m" // Magenta
00139 #define HIC ESC"[1;36m" // Cyan
00140 #define HIW ESC"[1;37m" // White
00141
00142
00143
00144 #define HBRED ESC"[41;1m" // Red
00145 #define HBGRN ESC"[42;1m" // Green
00146 #define HBYEL ESC"[43;1m" // Yellow
00147 #define HBBLU ESC"[44;1m" // Blue
00148 #define HBMAG ESC"[45;1m" // Magenta
00149 #define HBCYN ESC"[46;1m" // Cyan
00150 #define HBWHT ESC"[47;1m" // White
00151
00152
00153
00154 #define BBLK ESC"[40m" // Black
00155 #define BRED ESC"[41m" // Red
00156 #define BGRN ESC"[42m" // Green
00157 #define BYEL ESC"[43m" // Yellow
00158 #define BBLU ESC"[44m" // Blue
00159 #define BMAG ESC"[45m" // Magenta
00160 #define BCYN ESC"[46m" // Cyan
00161 #define BWHT ESC"[47m" // White
00162
00163 #define NOR ESC"[2;37;0m" // Puts everything back to normal
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 #ifdef __cplusplus
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 #ifdef _DEBUG
00224 #define bad_alloc //What is the REAL standard??
00225
00226
00227 void *operator new[](size_t) throw(bad_alloc);
00228 void *operator new[](size_t, const char *, unsigned) throw(bad_alloc);
00229 void operator delete[](void *) throw();
00230
00231 void *operator new(size_t)throw(bad_alloc);
00232 void *operator new(size_t, const char *, unsigned)throw(bad_alloc);
00233 void operator delete(void *) throw();
00234
00235 #define new new(__FILE__, __LINE__) //How to solve placement new?
00236 #endif
00237
00238
00239
00240
00241 #include <sys/time.h>
00242 #include <sys/resource.h>
00243
00244 inline void udelay(long usec)
00245 {
00246
00247
00248 struct timeval tv;
00249 tv.tv_sec=usec/1000000;
00250 tv.tv_usec=usec%1000000;
00251
00252 select(0,NULL,NULL,NULL,&tv);
00253 }
00254 inline void delay(double sec){ udelay((long)(sec*1e6)); }
00255 inline double CPUTime()
00256 {
00257 struct rusage ru;
00258 getrusage(RUSAGE_SELF,&ru);
00259 return ru.ru_utime.tv_sec+1e-6*ru.ru_utime.tv_usec;
00260 }
00261
00262
00263 unsigned UpdateCRC(unsigned crc, unsigned char *buf, int len);
00264
00265 inline unsigned CRC(unsigned char *buf, int len)
00266 { return UpdateCRC(0, buf, len); }
00267
00268 template <class T>inline T Abs(T a)
00269 { return a>=0?a:-a; }
00270 template <class T>inline T Max(T a, T b)
00271 { return a>b? a:b; }
00272 template <class T>inline T Max(T a, T b, T c)
00273 { return Max(a, Max(b, c)); }
00274 template <class T>inline T Max(T a, T b, T c, T d)
00275 { return Max(Max(a,b),Max(c,d)); }
00276 template <class T>inline T Min(T a, T b)
00277 { return a>b? b:a; }
00278 template <class T>inline T Min(T a, T b, T c)
00279 { return Min(Min(a,b),c); }
00280 template <class T>inline void Swap(T &a, T &b)
00281 { T c;c=a;a=b;b=c; }
00282 template <class T>inline void Swap(T &a, T &b, T &c)
00283 { T d;d=a;a=b;b=c;c=d; }
00284 template <class T>inline T Square(T v)
00285 { return v*v; }
00286 template <class T>inline T Cube(T v)
00287 { return v*v*v; }
00288 template <class T>inline T iMod(T a, T b)
00289 { return a>=0 ? a%b : (b-1)-(-a-1)%b; }
00290
00291 template <class T>inline T Factorial(T n)
00292 {
00293 T nf;
00294 for(nf=1;n>1;nf*=n--);
00295 return nf;
00296 }
00297
00298 inline double drand() { return (rand()+0.5)/(RAND_MAX+1.0); }
00299
00300 inline double randnorm()
00301 {
00302 static double w=0;
00303 double t;
00304 if(w==0) {
00305 double r1, r2;
00306 r1=drand();
00307 r2=drand();
00308 t=sqrt(-log(r1)*2);
00309 w=t*cos(M_PI*2*r2);
00310 return t*sin(M_PI*2*r2);
00311 } else {
00312 t=w; w=0;
00313 return t;
00314 }
00315 }
00316
00317 inline double RandNorm(double xbar, double sigma)
00318 { return randnorm()*sigma+xbar; }
00319
00320 inline double randnorm48()
00321 {
00322 static double w=0;
00323 double t;
00324 if (w==0) {
00325 double r1,r2;
00326 r1=drand48();
00327 r2=drand48();
00328 t=sqrt(-log(r1)*2);
00329 w=t*cos(M_PI*2*r2);
00330 return t*sin(M_PI*2*r2);
00331 } else {
00332 t=w; w=0;
00333 return t;
00334 }
00335 }
00336
00337 inline double RandNorm48(double xbar, double sigma)
00338 { return randnorm48()*sigma+xbar; }
00339
00341
00342
00343
00344
00345
00346
00347
00348
00349 #define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
00350 #define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
00351 template <class T> void QuickSort(T *data, int ndata)
00352 {
00353 const unsigned MaxThresh=4;
00354 static struct TStack { T *lo, *hi; } stack[8*sizeof(int)];
00355
00356 T *base_ptr = data;
00357 T pivot;
00358
00359 if(ndata == 0) return;
00360
00361 if((unsigned)ndata > MaxThresh)
00362 {
00363 T *lo = data;
00364 T *hi = &lo[ndata-1];
00365
00366 TStack *top = stack + 1;
00367
00368 while(stack < top)
00369 {
00370 T *left_ptr;
00371 T *right_ptr;
00372
00373
00374
00375
00376
00377
00378 T *mid = lo + ((hi - lo) >> 1);
00379
00380 if(*mid<*lo) Swap(*mid, *lo);
00381 if(*hi<*mid) Swap(*mid, *hi);
00382 else goto jump_over;
00383 if(*mid<*lo) Swap(*mid, *lo);
00384 jump_over:
00385 pivot=*mid;
00386
00387 left_ptr = lo+1;
00388 right_ptr = hi-1;
00389
00390
00391
00392
00393 do
00394 {
00395 while (*left_ptr<pivot) left_ptr++;
00396
00397 while (pivot<*right_ptr) right_ptr--;
00398
00399 if (left_ptr < right_ptr)
00400 {
00401 Swap(*left_ptr, *right_ptr);
00402 left_ptr++;
00403 right_ptr--;
00404 }
00405 else if (left_ptr == right_ptr)
00406 {
00407 left_ptr ++;
00408 right_ptr --;
00409 break;
00410 }
00411 }
00412 while (left_ptr <= right_ptr);
00413
00414
00415
00416
00417
00418
00419 if ((size_t) (right_ptr - lo) <= MaxThresh)
00420 {
00421 if ((size_t) (hi - left_ptr) <= MaxThresh)
00422
00423 POP(lo, hi);
00424 else
00425
00426 lo = left_ptr;
00427 }
00428 else if ((size_t) (hi - left_ptr) <= MaxThresh)
00429
00430 hi = right_ptr;
00431 else if ((right_ptr - lo) > (hi - left_ptr))
00432 {
00433
00434 PUSH(lo, right_ptr);
00435 lo = left_ptr;
00436 }
00437 else
00438 {
00439
00440 PUSH(left_ptr, hi);
00441 hi = right_ptr;
00442 }
00443 }
00444 }
00445
00446
00447
00448
00449
00450
00451
00452 {
00453 T * const end_ptr = &data[ndata-1];
00454 T *tmp_ptr = base_ptr;
00455 T *thresh = Min(end_ptr, base_ptr + MaxThresh);
00456 register T *run_ptr;
00457
00458
00459
00460
00461
00462 for (run_ptr = tmp_ptr+1; run_ptr <= thresh; run_ptr ++)
00463 if (*run_ptr < *tmp_ptr)
00464 tmp_ptr = run_ptr;
00465
00466 if (tmp_ptr != base_ptr) Swap(*tmp_ptr, *base_ptr);
00467
00468
00469
00470 run_ptr = base_ptr+1;
00471 while (++run_ptr <= end_ptr)
00472 {
00473 tmp_ptr = run_ptr-1;
00474 while (*run_ptr<*tmp_ptr)
00475 tmp_ptr --;
00476
00477 tmp_ptr ++;
00478 if (tmp_ptr != run_ptr)
00479 {
00480 T *trav;
00481
00482 trav = run_ptr+1;
00483 while (--trav >= run_ptr)
00484 {
00485 T c = *trav;
00486 T *hi, *lo;
00487
00488 for (hi = lo = trav; --lo >= tmp_ptr; hi = lo)
00489 *hi = *lo;
00490 *hi = c;
00491 }
00492 }
00493 }
00494 }
00495 }
00496 #undef PUSH
00497 #undef POP
00498 template <class T> void QuickSortTo(T *dest, const T *src, int ndata)
00499 {
00500 memcpy(dest, src, ndata*sizeof(T));
00501 QuickSort(dest, ndata);
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 template <class T>
00531 inline void ReverseTo(T *dest, const T *src, int n)
00532 { for(int i=0;i<n;i++) dest[i]=src[n-i-1]; }
00533
00534 template <class T>
00535 inline void Reverse(T *data, int n)
00536 { for(int i=0;i<n/2;i++) Swap(data[i], data[n-i-1]); }
00537
00538 class LIStream
00539 {
00540 public:
00541 enum { BUFLEN=500 };
00542 private:
00543
00544 public:
00545
00546 virtual int Read(char *buffer, int size)=0;
00547
00548 virtual void Lock() {}
00549
00550 virtual ~LIStream() {}
00551
00552 int ReadLine(char *buffer, int n)
00553 {
00554
00555 int i, nr;
00556 i=0;
00557 do nr=Read(&buffer[i++],1); while(nr==1 && i<n && buffer[i-1]!='\n');
00558 buffer[i-1]=0;
00559 if(nr==0 && i==1) return -1;
00560 return i;
00561 }
00562
00563
00564
00565
00566 int ReadWord(char *buffer, int n, const char *punct=0,
00567 char *pd=0, const char *delim=" \n\t")
00568 {
00569 int i, nr;
00570 char ch;
00571
00572
00573 do nr=Read(&ch,1);
00574 while(nr==1 && delim!=0 && strchr(delim, ch));
00575 if(nr!=1) return -1;
00576
00577 buffer[0]=ch;
00578 i=1;
00579 if(punct!=0 && strchr(punct, ch))
00580 {
00581 if(pd!=0) *pd=ch;
00582 i--;
00583 }
00584 else for(;i<n;i++)
00585 {
00586 nr=Read(buffer+i,1);
00587 if(nr==-1) return -1;
00588 if(nr==0 ||
00589 delim!=0 && strchr(delim, buffer[i]) ||
00590 punct!=0 && strchr(punct, buffer[i]))
00591 {
00592 if(pd!=0) *pd=(nr==0)?0:buffer[i];
00593 break;
00594 }
00595 }
00596 buffer[i]='\0';
00597 return i;
00598 }
00599
00600 LIStream & operator >(unsigned &a)
00601 { Read((char *)&a, sizeof(a)); return *this; }
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 LIStream & operator >(int &a)
00614 { Read((char *)&a, sizeof(a)); return *this; }
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626 LIStream & operator >(double &a)
00627 { Read((char *)&a, sizeof(a)); return *this; }
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 LIStream & operator >(char &a)
00640 { Read((char *)&a, sizeof(a)); return *this; }
00641
00642 LIStream &operator >>(int &a);
00643 LIStream &operator >>(double &a);
00644 LIStream &operator >>(char *a);
00645 };
00646
00647
00648 class LOStream
00649 {
00650 public:
00651
00652 private:
00653
00654 public:
00655
00656 virtual int Write(const char *data, int size)=0;
00657
00658 virtual void Lock() {}
00659 virtual ~LOStream() {}
00660
00661
00662 LOStream & operator <(unsigned a)
00663 { Write((const char *)&a,sizeof(a)); return *this; }
00664 LOStream & operator <(int a)
00665 { Write((const char *)&a,sizeof(a)); return *this; }
00666 LOStream & operator <(double a)
00667 { Write((const char *)&a,sizeof(a)); return *this; }
00668 LOStream & operator <(char a)
00669 { Write((const char *)&a,sizeof(a)); return *this; }
00670 LOStream & operator <(const char *s)
00671 {
00672 int l=strlen(s);
00673 Write(s,l);
00674 return *this;
00675 }
00676
00677
00678
00679 int SafeWrite(const char *data, int size,
00680 int nretry=-1, long udelay=100000000L);
00681
00682 void FmtOutput(long l, unsigned format=0, int radix=10);
00683 void FmtOutput(double d);
00684 public:
00685 enum Formats
00686 {
00687 NoPrefix=1,
00688 ZeroFill=2,
00689 Truncate=4,
00690 Hex=8,
00691 Oct=0x10,
00692 Bin=0x20,
00693 Unsigned=0x40,
00694 FillSign=0x80
00695
00696 };
00697 int Printf(const char *fmt...)
00698 {
00699 int l;
00700 va_list ap;
00701 va_start(ap,fmt);
00702 l=vPrintf(fmt,ap);
00703 va_end(ap);
00704 return l;
00705 }
00706
00707 int vPrintf(const char *fmt, va_list ap);
00708
00709
00710 LOStream & operator <<(bool b)
00711 {
00712 const char strue[]="(true)";
00713 const char sfalse[]="(false)";
00714 if(b) Write(strue, sizeof(strue)-1);
00715 else Write(sfalse, sizeof(sfalse)-1);
00716 return *this;
00717 }
00718
00719 LOStream & operator <<(char c)
00720 {
00721 Write(&c, sizeof(c));
00722 return *this;
00723 }
00724
00725
00726
00727
00728 LOStream & operator <<(unsigned u)
00729 {
00730 FmtOutput((long)u,Unsigned);
00731 return *this;
00732 }
00733 LOStream & operator <<(unsigned long u)
00734 {
00735 FmtOutput((long)u,Unsigned);
00736 return *this;
00737 }
00738
00739
00740 LOStream & operator <<(double d)
00741 {
00742 FmtOutput(d);
00743 return *this;
00744 }
00745 LOStream & operator <<(int i)
00746 {
00747 FmtOutput((long)i);
00748 return *this;
00749 }
00750 LOStream & operator <<(long i)
00751 {
00752 FmtOutput(i);
00753 return *this;
00754 }
00755 LOStream & operator <<(const char *s)
00756 {
00757 if(s)
00758 {
00759 int l=strlen(s);
00760 Write(s, l);
00761 }
00762 return *this;
00763 }
00764 LOStream & operator <<(void *p);
00765 };
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833 class LStream : public LOStream, public LIStream {};
00834
00835 class LFDStream : public LStream
00836 {
00837 int ifd, ofd;
00838 int oldifd, oldofd;
00839 public:
00840 LFDStream():ifd(-1),ofd(-1){}
00841 LFDStream(int If, int Of):ifd(If),ofd(Of){}
00842 virtual int Write(const char *data, int size)
00843 { return ofd < 0?0:write(ofd, data, size); }
00844 virtual int Read(char *buff, int size)
00845 { return ifd < 0?0:read(ifd, buff, size); }
00846 virtual void Lock()
00847 {
00848
00849
00850
00851 }
00852 void Flush(){ fsync(ofd); }
00853 void Redirect(int i, int o){ oldifd=ifd; oldofd=ofd; ifd=i, ofd=o; }
00854 void RedirectOut(int o){ oldofd=ofd; ofd=o; }
00855 void Restore() { ifd=oldifd; ofd=oldofd; }
00856 };
00857
00858 extern LFDStream _IO;
00859 extern LFDStream _Error;
00860 extern LFDStream _Null;
00861
00862
00863 class LSys
00864 {
00865 #ifdef _DEBUG
00866 private:
00867 static int m_Init;
00868 public:
00869 static char *sDebug, *sDebugEnd;
00870 static void sig_handler(int, siginfo_t *sig, void *);
00871 LSys();
00872 ~LSys();
00873 #endif
00874
00875 public:
00876 static char *sInfo, *sWarning, *sError, *sFatal,
00877 *sInfoEnd, *sWarningEnd, *sErrorEnd, *sFatalEnd;
00878 static LOStream *_pSys;
00879
00880 static LOStream *Redirect(LOStream *os)
00881 {
00882 LOStream *p=_pSys;
00883 _pSys=os;
00884 return p;
00885 }
00886 static void Restore()
00887 {
00888 _pSys=&_Error;
00889 sInfo=GRN"[I]"NOR" "; sInfoEnd=GRN"[i]"NOR"\n";
00890 sWarning=YEL"[W]"NOR" "; sWarningEnd=YEL"[w]"NOR"\n";
00891 sError=RED"[E]"NOR" "; sErrorEnd=HIR"[e]"NOR"\n";
00892 sFatal=HIR"[F]"NOR" "; sFatalEnd=HIR"[f]"NOR"\n";
00893 #ifdef _DEBUG
00894 sDebug=HIC"[D]"NOR" "; sDebugEnd=HIC"[d]"NOR"\n";
00895 #endif
00896 }
00897 static void Abort()
00898 {
00899 #ifdef _DEBUG
00900 m_Init=0;
00901 #endif
00902 exit(1);
00903 }
00904 };
00905
00906
00907 #define INFO(d) (void)(*LSys::_pSys << LSys::sInfo << d << LSys::sInfoEnd)
00908 #define INFO_(d) (void)(*LSys::_pSys << LSys::sInfo << d)
00909 #define _INFO_(d) (void)(*LSys::_pSys << d)
00910 #define _INFO(d) (void)(*LSys::_pSys << d << LSys::sInfoEnd)
00911 #define WARNING(d) (void)(*LSys::_pSys<<LSys::sWarning<< d <<LSys::sWarningEnd)
00912 #define WARNING_(d) (void)(*LSys::_pSys << LSys::sWarning << d)
00913 #define _WARNING(d) (void)(*LSys::_pSys << d << LSys::sWarningEnd)
00914 #define ERROR(d) (void)(*LSys::_pSys << LSys::sError << d << LSys::sErrorEnd)
00915 #define ERROR_(d) (void)(*LSys::_pSys << LSys::sError << d <<)
00916 #define _ERROR(d) (void)(*LSys::_pSys << d << LSys::sErrorEnd)
00917 #define FATAL(d) (void)((*LSys::_pSys << LSys::sFatal << d << \
00918 LSys::sFatalEnd), exit(1))
00919 #define SYSERROR(d) (void)(*LSys::_pSys << LSys::sError << d << \
00920 " ("<<strerror(errno)<<")"<<LSys::sErrorEnd)
00921 #define SYSFATAL(d) (void)((*LSys::_pSys << LSys::sError << d << \
00922 " ("<<strerror(errno)<<")"<<LSys::sErrorEnd), exit(1))
00923
00924 inline void INFO_Dump(const char *fmt...)
00925 {
00926 va_list ap;
00927 va_start(ap,fmt);
00928 *LSys::_pSys << LSys::sInfo;
00929 LSys::_pSys->vPrintf(fmt,ap);
00930 *LSys::_pSys << LSys::sInfoEnd;
00931 }
00932 inline void WARNING_Dump(const char *fmt...)
00933 {
00934 va_list ap;
00935 va_start(ap,fmt);
00936 *LSys::_pSys << LSys::sWarning;
00937 LSys::_pSys->vPrintf(fmt,ap);
00938 *LSys::_pSys << LSys::sWarningEnd;
00939 }
00940 inline void ERROR_Dump(const char *fmt...)
00941 {
00942 va_list ap;
00943 va_start(ap,fmt);
00944 *LSys::_pSys << LSys::sError;
00945 LSys::_pSys->vPrintf(fmt,ap);
00946 *LSys::_pSys << LSys::sErrorEnd;
00947 }
00948 inline void FATAL_Dump(const char *fmt...)
00949 {
00950 va_list ap;
00951 va_start(ap,fmt);
00952 *LSys::_pSys << LSys::sFatal;
00953 LSys::_pSys->vPrintf(fmt,ap);
00954 *LSys::_pSys << LSys::sFatalEnd;
00955 LSys::Abort();
00956 }
00957
00958 #define INFO_Printf LSys::_pSys->Printf
00959 #define INFO_Flush LSys::_pSys->Flush
00960
00961 #ifdef _DEBUG
00962
00963 static class LSys _Internal_Debugging_Object;
00964
00965 #define DUMP(d) (void)(*LSys::_pSys << LSys::sDebug << d << LSys::sDebugEnd)
00966 #define DUMP_(d) (void)(*LSys::_pSys << LSys::sDebug << d)
00967 #define _DUMP(d) (void)(*LSys::_pSys << d << LSys::sDebugEnd)
00968 inline void DEBUG_Dump(const char *fmt...)
00969 {
00970 va_list ap;
00971 va_start(ap,fmt);
00972 *LSys::_pSys << LSys::sDebug;
00973 LSys::_pSys->vPrintf(fmt,ap);
00974 *LSys::_pSys << LSys::sDebugEnd;
00975 }
00976
00977 #define ASSERT(p) if(p) ; else DUMP( "Assertion Failed (file " \
00978 << __FILE__ << ", line " << __LINE__ << ')'),LSys::Abort()
00979 #define VERIFY(p) ASSERT(p)
00980 #define ASSERTMSG(p, strm) if(p); else DUMP( "Assertion Failed (file " \
00981 << __FILE__ << ", line "<< __LINE__ << "):" << strm), LSys::Abort()
00982 #define NOTREACHED() DUMP("Illegal branch (file " \
00983 << __FILE__ << ", line "<<__LINE__ << ')'), LSys::Abort()
00984 #define NOTREACHEDMSG(d) DUMP("Illegal branch (file " \
00985 << __FILE__ << ", line "<<__LINE__ << "):" << d), LSys::Abort()
00986
00987 #else //no _DEBUG
00988
00989 #define DUMP(d) ((void)0)
00990 #define DUMP_(d) ((void)0)
00991 #define _DUMP(d) ((void)0)
00992 #define ASSERT(p) ((void)0)
00993 #define ASSERTMSG(p, strm) ((void)0)
00994 #define NOTREACHED() FATAL("Internal error: Illegal branch")
00995 #define NOTREACHEDMSG(d) FATAL("Internal error: " << d)
00996 #define VERIFY(p) (p)
00997
00998 #endif //_DEBUG
00999
01000 #define NOTIMPLEMENTED() NOTREACHEDMSG("Feature not impleneted")
01001
01002
01003
01004 const unsigned _cU=0x0001;
01005 const unsigned _cL=0x0002;
01006 const unsigned _cN=0x0004;
01007 const unsigned _cS=0x0008;
01008 const unsigned _cP=0x0010;
01009 const unsigned _cX=0x0080;
01010
01011 extern const unsigned _CharTable[];
01012
01013 inline bool IsDigit(char ch){ return _CharTable[(unsigned char)ch]&_cN; }
01014 inline bool IsHexDigit(char ch){ return _CharTable[(unsigned char)ch]&_cX; }
01015 inline bool IsSpace(char ch){ return _CharTable[(unsigned char)ch]&_cS; }
01016 inline bool IsUpper(char ch){ return _CharTable[(unsigned char)ch]&_cU; }
01017 inline bool IsLower(char ch){ return _CharTable[(unsigned char)ch]&_cL; }
01018 inline bool IsLetter(char ch){ return _CharTable[(unsigned char)ch]&(_cL|_cU);}
01019 inline bool IsPrintable(char ch){ return _CharTable[(unsigned char)ch]&_cP; }
01020
01021 inline char _ToUpper(char c){ ASSERT(IsLower(c)); return c&0xdf;}
01022 inline char _ToLower(char c){ ASSERT(IsUpper(c)); return c|0x20;}
01023 inline char ToUpper(char c){ return IsLower(c) ? _ToUpper(c):c; }
01024 inline char ToLower(char c){ return IsUpper(c) ? _ToLower(c):c; }
01025
01026 inline char HexToChar(unsigned h)
01027 {
01028 static const char htc[]=
01029 {
01030 '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
01031 };
01032 return htc[h&0x000F];
01033 }
01034
01035 inline unsigned CharToHex(char ch)
01036 {
01037 ASSERT(IsHexDigit(ch));
01038 return (ch>'9')? _ToUpper(ch)-'A'+10 : ch-'0';
01039 }
01040
01041
01042
01043 #ifdef _DEBUG
01044 inline void *StrMemCpy(void *dest, const void *src, unsigned len)
01045 { ASSERT(dest!=0 && src!=0); return memcpy(dest, src, len);}
01046 inline void *StrMemMove(void *dest, const void *src, unsigned len)
01047 { ASSERT(dest!=0 && src!=0); return memmove(dest, src, len);}
01048 inline char *StrCpy(char *dest, const char *src)
01049 { ASSERT(dest!=0 && src!=0); return strcpy(dest, src);}
01050 inline char *StrNCpy(char *dest, const char *src, unsigned len)
01051 { ASSERT(dest!=0 && src!=0); return strncpy(dest, src, len);}
01052 inline char *StrCat(char *dest, const char *src)
01053 { ASSERT(dest!=0 && src!=0); return strcat(dest, src);}
01054 inline char *StrNCat(char *dest, const char *src, unsigned len)
01055 { ASSERT(dest!=0 && src!=0); return strncat(dest, src, len);}
01056 inline int StrMemCmp(const void *m1, const void *m2, unsigned len)
01057 { ASSERT(m1!=0 && m2!=0); return memcmp(m1, m2, len);}
01058 inline int StrCmp(const char *m1, const char *m2)
01059 { ASSERT(m1!=0 && m2!=0); return strcmp(m1, m2);}
01060 inline int StrCaseCmp(const char *m1, const char *m2)
01061 { ASSERT(m1!=0 && m2!=0); return strcasecmp(m1, m2);}
01062 inline int StrNCmp(const char *m1, const char *m2, unsigned len)
01063 { ASSERT(m1!=0 && m2!=0); return strncmp(m1, m2, len);}
01064 inline int StrNCaseCmp(const char *m1, const char *m2, unsigned len)
01065 { ASSERT(m1!=0 && m2!=0); return strncasecmp(m1, m2, len);}
01066 inline void *StrMemChr(const void *s, char c, unsigned l)
01067 { ASSERT(s!=0); return memchr(s, c, l); }
01068 inline char *StrChr(const char *s, char c)
01069 { ASSERT(s!=0); return strchr(s, c); }
01070 inline const char *StrStr(const char *s1, const char *s2)
01071 { ASSERT(s1!=0 && s2!=0); return strstr(s1, s2); }
01072 inline char *StrStr(char *s1, const char *s2)
01073 { ASSERT(s1!=0 && s2!=0); return strstr(s1, s2); }
01074
01075 inline void *StrMemSet(void *s, char b, unsigned l)
01076 { ASSERT(s!=0); return memset(s, b, l); }
01077 inline void StrBZero(void *s, int n)
01078 { ASSERT(s!=0); memset(s,0,n); }
01079 inline unsigned StrLen(const char *s)
01080 { ASSERT(s!=0); return strlen(s); }
01081 #else //Release
01082 #define StrMemCpy(d,s,l) memcpy(d,s,l)
01083 #define StrMemMove(d,s,l) memmove(d,s,l)
01084 #define StrCpy(d,s) strcpy(d,s)
01085 #define StrNCpy(d,s,l) strncpy(d,s,l)
01086 #define StrCat(d,s) strcat(d,s)
01087 #define StrNCat(d,s,l) strncat(d,s,l)
01088 #define StrMemCmp(d,s,l) memcpy(d,s,l)
01089 #define StrCmp(d,s) strcmp(d,s)
01090 #define StrCaseCmp(d,s) strcasecmp(d,s)
01091 #define StrNCmp(d,s,l) strncmp(d,s,l)
01092 #define StrNCaseCmp(d,s,l) strncasecmp(d,s,l)
01093 #define StrMemChr(s,c,l) memchr(s,c,l)
01094 #define StrChr(s,c) strchr(s,c)
01095 #define StrStr(a,b) strstr(a,b)
01096 #define StrMemSet(s,b,l) memset(s,b,l)
01097 #define StrBZero(s,l) ((void)memset(s,0,l))
01098 #define StrLen(s) strlen(s)
01099 #endif //_DEBUG
01100
01101 const char *StrCaseStr(const char *s1, const char *s2);
01102
01103 const char *StrSkipSpaces(const char *str);
01104 inline char *StrSkipSpaces(char *str)
01105 { return (char *)StrSkipSpaces((const char *)str); }
01106
01107 void StrSnipSpaces(char *str);
01108
01109
01110
01111 bool StrScanInt(const char *s, int &i);
01112 bool StrScanLong(const char *s, long &i);
01113 bool StrScanDouble(const char *s, double &d);
01114 int StrPrintf(char *str, const char *fmt...);
01115 int StrNPrintf(char *str, int s, const char *fmt...);
01116
01117
01118
01119
01120 #define StrScanf sscanf
01121
01122
01123 #else //not __cplusplus
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 static void Warning(const char* fmt, ...)
01134 {
01135 va_list ap;
01136 va_start(ap,fmt);
01137 printf(BRED HIW"*Warning*"NOR": ");
01138 vprintf(fmt, ap);
01139 printf("\n");
01140 }
01141
01142 static void Error(const char* fmt, ...)
01143 {
01144 va_list ap;
01145 va_start(ap,fmt);
01146 printf(BRED HIW"*Error*"NOR": ");
01147 vprintf(fmt, ap);
01148 printf("\n");
01149 exit(1);
01150 }
01151
01152 #ifdef _DEBUG
01153
01154 #include <stdarg.h>
01155 static const char* DB_File;
01156 static int DB_Line;
01157 static void DB_RegLocus(const char* file, int line)
01158 {
01159 DB_File=file;
01160 DB_Line=line;
01161 }
01162 static void DB_Assert(int c)
01163 {
01164 if(!c) printf("Assertion Failed at %s:%d\n",DB_File,DB_Line);
01165 }
01166 static void DB_AssertMsg(int c, const char *fmt, ...)
01167 {
01168 if(!c)
01169 {
01170 va_list ap;
01171 va_start(ap,fmt);
01172 printf("Assertion Failed at %s:%d--",DB_File,DB_Line);
01173 vprintf(fmt,ap);
01174 printf("\n");
01175 va_end(ap);
01176 }
01177 }
01178
01179 #define ASSERT(p) DB_RegLocus(__FILE__,__LINE__),DB_Assert(p);
01180 #define VERIFY(p) ASSERT(p)
01181 #define ASSERTMSG DB_RegLocus(__FILE__,__LINE__),DB_AssertMsg
01182 #define NOTREACHED() ASSERTMSG(0,"Not Reachable")
01183
01184 #else //no _DEBUG
01185 #define DUMP(d) ((void)0)
01186 #define ASSERT(p) ((void)0)
01187 #define ASSERTMSG 1?(void)0:(void)
01188 #define NOTREACHED() ((void)0)
01189 #define NOTREACHEDMSG(d) ((void)0)
01190 #define VERIFY(p) ((void)(p))
01191 #endif //_DEBUG
01192
01193
01194 #endif //__cplusplus
01195
01196
01197
01198 #ifndef _DEBUG
01199 inline void *MAlloc(size_t size)
01200 {
01201
01202
01203
01204
01205 return malloc(size);
01206 }
01207 inline void *Realloc(void *ptr, size_t size)
01208 {
01209
01210
01211
01212
01213 return realloc(ptr, size);
01214 }
01215
01216 inline void Free(void *ptr)
01217 {
01218
01219 free(ptr);
01220 }
01221 #else
01222 enum MemType
01223 {
01224 M_Array,
01225 M_Obj,
01226 M_Alloc
01227 };
01228 void *MemAlloc(size_t size, const char *file, unsigned line, enum MemType mt);
01229 void *MemRealloc(void *p,size_t size,
01230 const char *file, unsigned line, enum MemType mt);
01231 void MemFree(void *p, const char *f, unsigned l, enum MemType mt);
01232 void MemDump(const char *f, unsigned l);
01233
01234
01235 #define MAlloc(s) MemAlloc(s,__FILE__,__LINE__, M_Alloc)
01236 #define Realloc(p,s) MemRealloc(p,s,__FILE__,__LINE__, M_Alloc)
01237 #define Free(p) MemFree(p,__FILE__,__LINE__, M_Alloc)
01238 #define DUMP_MEM() MemDump(__FILE__, __LINE__)
01239
01240 #endif //_DEBUG
01241
01242
01243 inline char **ArrAlloc2(unsigned rsize, int dim1, int dim2)
01244 {
01245 int i;
01246 char **p=(char **)MAlloc((sizeof(void *)+rsize*dim2)*dim1);
01247 p[0]=(char *)p+dim1*sizeof(void *);
01248
01249 for(i=1;i<dim1;i++)
01250 p[i]=p[i-1]+rsize;
01251 return p;
01252 }
01253 inline char **ReArrAlloc2(void *ptr, unsigned rsize, int dim1, int dim2)
01254 {
01255 int i;
01256 char **p=(char **)Realloc(ptr, (sizeof(void *)+rsize*dim2)*dim1);
01257 p[0]=(char *)p+dim1*sizeof(void *);
01258
01259 for(i=1;i<dim1;i++)
01260 p[i]=p[i-1]+rsize*dim2;
01261 return p;
01262 }
01263 inline char *StrDup(const char *s)
01264 {
01265
01266 char *p=(char *)MAlloc(StrLen(s)+1);
01267 return StrCpy(p,s);
01268 }
01269
01270 inline bool Equal(double a, double b, double torlerate=1e-13)
01271 {
01272 return Abs(a-b) < torlerate;
01273 }
01274
01275 #endif // _GENERAL_H