X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=myutils.cpp;h=226b0f63560b04348ea425290c98b48b1abc4de6;hb=8dd3c225255d7084e3aff8740aa4f1f1cabb367a;hp=ea983eb9e229a8549e1231aaaf75625d12135274;hpb=a150db3c2bfd7b76420048a1e94ebe397f2c6045;p=mothur.git diff --git a/myutils.cpp b/myutils.cpp index ea983eb..226b0f6 100755 --- a/myutils.cpp +++ b/myutils.cpp @@ -11,19 +11,19 @@ #include #include -#ifdef _MSC_VER -#include -#include -#include -#include -#include -#else +#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) #include #include #include #include #include #include +#else +//#include +#include +#include +#include +#include #endif #include "myutils.h" @@ -46,11 +46,11 @@ static double g_PeakMemUseBytes; #if TEST_UTILS void TestUtils() - { +{ const int C = 100000000; for (int i = 0; i < C; ++i) ProgressStep(i, C, "something or other"); - + Progress("\n"); Progress("Longer message\r"); Sleep(1000); @@ -63,30 +63,30 @@ void TestUtils() const unsigned N = 10; unsigned M = 10; for (unsigned i = 0; i < N; ++i) - { + { ProgressStep(i, N, "Allocating 1MB blocks"); for (unsigned j = 0; j < M; ++j) - { + { ProgressStep(j, M, "Inner loop"); malloc(100000); Sleep(500); - } } } +} #endif // TEST_UTILS static void AllocBuffer(FILE *f) - { +{ int fd = fileno(f); if (fd < 0 || fd >= 256) return; if (g_IOBuffers[fd] == 0) g_IOBuffers[fd] = myalloc(char, MY_IO_BUFSIZ); setvbuf(f, g_IOBuffers[fd], _IOFBF, MY_IO_BUFSIZ); - } +} static void FreeBuffer(FILE *f) - { +{ int fd = fileno(f); if (fd < 0 || fd >= 256) return; @@ -94,12 +94,12 @@ static void FreeBuffer(FILE *f) return; myfree(g_IOBuffers[fd]); g_IOBuffers[fd] = 0; - } +} unsigned GetElapsedSecs() - { +{ return (unsigned) (time(0) - g_StartTime); - } +} static unsigned g_NewCalls; static unsigned g_FreeCalls; @@ -110,7 +110,7 @@ static double g_NetBytes; static double g_MaxNetBytes; void LogAllocStats() - { +{ Log("\n"); Log(" Allocs %u\n", g_NewCalls); Log(" Frees %u\n", g_FreeCalls); @@ -120,37 +120,47 @@ void LogAllocStats() Log(" Net bytes %s\n", MemBytesToStr(g_NetBytes)); Log("Max net bytes %s\n", MemBytesToStr(g_MaxNetBytes)); Log(" Peak total %s\n", MemBytesToStr(g_MaxNetBytes + g_InitialMemUseBytes)); - } +} bool StdioFileExists(const string &FileName) - { +{ struct stat SD; int i = stat(FileName.c_str(), &SD); return i == 0; - } +} void myassertfail(const char *Exp, const char *File, unsigned Line) - { +{ Die("%s(%u) assert failed: %s", File, Line, Exp); - } +} bool myisatty(int fd) - { +{ return isatty(fd) != 0; - } +} -#ifdef _MSC_VER -#include +#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) +#else +//#ifdef BIT_VERSION +//#include +//int fseeko(FILE *stream, off_t offset, int whence) +//// { +// off_t FilePos = _fseeki64(stream, offset, whence); +// return (FilePos == -1L) ? -1 : 0; +// } +//#define ftello(fm) (off_t) _ftelli64(fm) +//#else int fseeko(FILE *stream, off_t offset, int whence) - { - off_t FilePos = _fseeki64(stream, offset, whence); +{ + off_t FilePos = fseek(stream, offset, whence); return (FilePos == -1L) ? -1 : 0; - } -#define ftello(fm) (off_t) _ftelli64(fm) +} +#define ftello(fm) (off_t) ftell(fm) +//#endif #endif void LogStdioFileState(FILE *f) - { +{ unsigned long tellpos = (unsigned long) ftello(f); long fseek_pos = fseek(f, 0, SEEK_CUR); int fd = fileno(f); @@ -164,95 +174,102 @@ void LogStdioFileState(FILE *f) fpos_t fpos; int fgetpos_retval = fgetpos(f, &fpos); Log("fpos %ld (retval %d)\n", (long) fpos, fgetpos_retval); -// Log("eof %d\n", _eof(fd)); + // Log("eof %d\n", _eof(fd)); #endif -#ifdef _MSC_VER +#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) +#else +#ifdef BIT_VERSION __int64 pos64 = _ftelli64(f); Log("_ftelli64 %lld\n", pos64); +#else + __int32 pos32 = ftell(f); + Log("ftell %lld\n", pos32); + #endif - } +#endif +} FILE *OpenStdioFile(const string &FileName) - { +{ const char *Mode = "rb"; FILE *f = fopen(FileName.c_str(), Mode); if (f == 0) - { + { if (errno == EFBIG) - { + { if (sizeof(off_t) == 4) Die("File too big, off_t is 32 bits, recompile needed"); else Die("Cannot open '%s', file too big (off_t=%u bits)", - FileName.c_str(), sizeof(off_t)*8); - } - Die("Cannot open %s, errno=%d %s", - FileName.c_str(), errno, strerror(errno)); + FileName.c_str(), sizeof(off_t)*8); } + Die("Cannot open %s, errno=%d %s", + FileName.c_str(), errno, strerror(errno)); + } AllocBuffer(f); return f; - } +} FILE *CreateStdioFile(const string &FileName) - { +{ FILE *f = fopen(FileName.c_str(), "wb+"); if (0 == f) Die("Cannot create %s, errno=%d %s", - FileName.c_str(), errno, strerror(errno)); + FileName.c_str(), errno, strerror(errno)); AllocBuffer(f); return f; - } +} void SetStdioFilePos(FILE *f, off_t Pos) - { +{ if (0 == f) Die("SetStdioFilePos failed, f=NULL"); int Ok = fseeko(f, Pos, SEEK_SET); off_t NewPos = ftello(f); if (Ok != 0 || Pos != NewPos) - { + { LogStdioFileState(f); Die("SetStdioFilePos(%d) failed, Ok=%d NewPos=%d", - (int) Pos, Ok, (int) NewPos); - } + (int) Pos, Ok, (int) NewPos); } +} void ReadStdioFile(FILE *f, off_t Pos, void *Buffer, unsigned Bytes) - { +{ if (0 == f) Die("ReadStdioFile failed, f=NULL"); SetStdioFilePos(f, Pos); unsigned BytesRead = fread(Buffer, 1, Bytes, f); if (BytesRead != Bytes) - { + { LogStdioFileState(f); Die("ReadStdioFile failed, attempted %d bytes, read %d bytes, errno=%d", - (int) Bytes, (int) BytesRead, errno); - } + (int) Bytes, (int) BytesRead, errno); } +} void ReadStdioFile(FILE *f, void *Buffer, unsigned Bytes) - { +{ if (0 == f) Die("ReadStdioFile failed, f=NULL"); unsigned BytesRead = fread(Buffer, 1, Bytes, f); if (BytesRead != Bytes) - { + { LogStdioFileState(f); Die("ReadStdioFile failed, attempted %d bytes, read %d bytes, errno=%d", - (int) Bytes, (int) BytesRead, errno); - } + (int) Bytes, (int) BytesRead, errno); } +} // Return values from functions like lseek, ftell, fgetpos are // "undefined" for files that cannot seek. Attempt to detect // whether a file can seek by checking for error returns. bool CanSetStdioFilePos(FILE *f) - { -// Common special cases +{ + // Common special cases if (f == stdin || f == stdout || f == stderr) return false; - + fpos_t CurrPos; int ok1 = fgetpos(f, &CurrPos); if (ok1 < 0) @@ -266,14 +283,14 @@ bool CanSetStdioFilePos(FILE *f) if (!ok3 || !ok4) return false; return true; - } +} byte *ReadAllStdioFile(FILE *f, unsigned &FileSize) - { +{ const unsigned BUFF_SIZE = 1024*1024; - + if (CanSetStdioFilePos(f)) - { + { off_t Pos = GetStdioFilePos(f); off_t FileSize = GetStdioFileSize(f); if (FileSize > UINT_MAX) @@ -284,51 +301,51 @@ byte *ReadAllStdioFile(FILE *f, unsigned &FileSize) SetStdioFilePos(f, Pos); FileSize = unsigned(FileSize); return Buffer; - } - -// Can't seek, read one buffer at a time. + } + + // Can't seek, read one buffer at a time. FileSize = 0; - -// Just to initialize so that first call to realloc works. + + // Just to initialize so that first call to realloc works. byte *Buffer = (byte *) malloc(4); if (Buffer == 0) Die("ReadAllStdioFile, out of memory"); for (;;) - { + { Buffer = (byte *) realloc(Buffer, FileSize + BUFF_SIZE); unsigned BytesRead = fread(Buffer + FileSize, 1, BUFF_SIZE, f); FileSize += BytesRead; if (BytesRead < BUFF_SIZE) - { + { Buffer = (byte *) realloc(Buffer, FileSize); return Buffer; - } } } +} byte *ReadAllStdioFile(const std::string &FileName, off_t &FileSize) - { +{ #if WIN32 FILE *f = OpenStdioFile(FileName); FileSize = GetStdioFileSize(f); CloseStdioFile(f); - + HANDLE h = CreateFile(FileName.c_str(), GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (h == INVALID_HANDLE_VALUE) Die("ReadAllStdioFile:Open(%s) failed", FileName.c_str()); - + unsigned uFileSize = (unsigned) FileSize; if ((off_t) uFileSize != FileSize) Die("File too big (%.1f Gb): %s", double(FileSize)/1e9, FileName.c_str()); - + byte *Buffer = myalloc(byte, uFileSize); DWORD BytesRead; ReadFile(h, Buffer, uFileSize, &BytesRead, NULL); if (FileSize != BytesRead) Die("ReadAllStdioFile:Error reading %s, attempted %u got %u", - FileName.c_str(), FileSize, (unsigned) BytesRead); - + FileName.c_str(), FileSize, (unsigned) BytesRead); + CloseHandle(h); return Buffer; #else @@ -349,56 +366,56 @@ byte *ReadAllStdioFile(const std::string &FileName, off_t &FileSize) size_t n = read(h, Buffer, stBytes); if (n != FileSize) Die("ReadAllStdioFile, Error reading %s, attempted %g got %g", - FileName.c_str(), (double) FileSize, (double) n); + FileName.c_str(), (double) FileSize, (double) n); close(h); return Buffer; #endif - } +} void WriteStdioFile(FILE *f, off_t Pos, const void *Buffer, unsigned Bytes) - { +{ if (0 == f) Die("WriteStdioFile failed, f=NULL"); SetStdioFilePos(f, Pos); unsigned BytesWritten = fwrite(Buffer, 1, Bytes, f); if (BytesWritten != Bytes) - { + { LogStdioFileState(f); Die("WriteStdioFile failed, attempted %d bytes, wrote %d bytes, errno=%d", - (int) Bytes, (int) BytesWritten, errno); - } + (int) Bytes, (int) BytesWritten, errno); } +} void WriteStdioFile(FILE *f, const void *Buffer, unsigned Bytes) - { +{ if (0 == f) Die("WriteStdioFile failed, f=NULL"); unsigned BytesWritten = fwrite(Buffer, 1, Bytes, f); if (BytesWritten != Bytes) - { + { LogStdioFileState(f); Die("WriteStdioFile failed, attempted %d bytes, wrote %d bytes, errno=%d", - (int) Bytes, (int) BytesWritten, errno); - } + (int) Bytes, (int) BytesWritten, errno); } +} // Return false on EOF, true if line successfully read. bool ReadLineStdioFile(FILE *f, char *Line, unsigned Bytes) - { +{ if (feof(f)) return false; if ((int) Bytes < 0) Die("ReadLineStdioFile: Bytes < 0"); char *RetVal = fgets(Line, (int) Bytes, f); if (NULL == RetVal) - { + { if (feof(f)) return false; if (ferror(f)) Die("ReadLineStdioFile: errno=%d", errno); Die("ReadLineStdioFile: fgets=0, feof=0, ferror=0"); - } - + } + if (RetVal != Line) Die("ReadLineStdioFile: fgets != Buffer"); unsigned n = strlen(Line); @@ -409,37 +426,37 @@ bool ReadLineStdioFile(FILE *f, char *Line, unsigned Bytes) if (n > 1 && (Line[n-2] == '\r' || Line[n-2] == '\n')) Line[n-2] = 0; return true; - } +} // Return false on EOF, true if line successfully read. bool ReadLineStdioFile(FILE *f, string &Line) - { +{ Line.clear(); for (;;) - { + { int c = fgetc(f); if (c == -1) - { + { if (feof(f)) - { + { if (!Line.empty()) return true; return false; - } - Die("ReadLineStdioFile, errno=%d", errno); } + Die("ReadLineStdioFile, errno=%d", errno); + } if (c == '\r') continue; if (c == '\n') return true; Line.push_back((char) c); - } } +} // Copies all of fFrom regardless of current // file position, appends to fTo. void AppendStdioFileToFile(FILE *fFrom, FILE *fTo) - { +{ off_t SavedFromPos = GetStdioFilePos(fFrom); off_t FileSize = GetStdioFileSize(fFrom); const off_t BUFF_SIZE = 1024*1024; @@ -447,108 +464,109 @@ void AppendStdioFileToFile(FILE *fFrom, FILE *fTo) SetStdioFilePos(fFrom, 0); off_t BytesRemaining = FileSize; while (BytesRemaining > 0) - { + { off_t BytesToRead = BytesRemaining; if (BytesToRead > BUFF_SIZE) BytesToRead = BUFF_SIZE; ReadStdioFile(fFrom, Buffer, (unsigned) BytesToRead); WriteStdioFile(fTo, Buffer, (unsigned) BytesToRead); BytesRemaining -= BytesToRead; - } - SetStdioFilePos(fFrom, SavedFromPos); } + SetStdioFilePos(fFrom, SavedFromPos); +} void RenameStdioFile(const string &FileNameFrom, const string &FileNameTo) - { +{ int Ok = rename(FileNameFrom.c_str(), FileNameTo.c_str()); if (Ok != 0) Die("RenameStdioFile(%s,%s) failed, errno=%d %s", - FileNameFrom.c_str(), FileNameTo.c_str(), errno, strerror(errno)); - } + FileNameFrom.c_str(), FileNameTo.c_str(), errno, strerror(errno)); +} void FlushStdioFile(FILE *f) - { +{ int Ok = fflush(f); if (Ok != 0) Die("fflush(%p)=%d,", f, Ok); - } +} void CloseStdioFile(FILE *f) - { +{ if (f == 0) return; int Ok = fclose(f); if (Ok != 0) Die("fclose(%p)=%d", f, Ok); FreeBuffer(f); - } +} off_t GetStdioFilePos(FILE *f) - { +{ off_t FilePos = ftello(f); if (FilePos < 0) Die("ftello=%d", (int) FilePos); return FilePos; - } +} off_t GetStdioFileSize(FILE *f) - { +{ off_t CurrentPos = GetStdioFilePos(f); - int Ok = fseeko(f, 0, SEEK_END); + off_t zeroPos = 0; + int Ok = fseeko(f, zeroPos, SEEK_END); if (Ok < 0) Die("fseek in GetFileSize"); - + off_t Length = ftello(f); if (Length < 0) Die("ftello in GetFileSize"); SetStdioFilePos(f, CurrentPos); return Length; - } +} void DeleteStdioFile(const string &FileName) - { +{ int Ok = remove(FileName.c_str()); if (Ok != 0) Die("remove(%s) failed, errno=%d %s", FileName.c_str(), errno, strerror(errno)); - } +} void myvstrprintf(string &Str, const char *Format, va_list ArgList) - { +{ static char szStr[MAX_FORMATTED_STRING_LENGTH]; vsnprintf(szStr, MAX_FORMATTED_STRING_LENGTH-1, Format, ArgList); szStr[MAX_FORMATTED_STRING_LENGTH - 1] = '\0'; Str.assign(szStr); - } +} void myvstrprintf(string &Str, const char *Format, ...) - { +{ va_list ArgList; va_start(ArgList, Format); myvstrprintf(Str, Format, ArgList); va_end(ArgList); - } +} FILE *g_fLog = 0; void SetLogFileName(const string &FileName) - { +{ if (g_fLog != 0) CloseStdioFile(g_fLog); g_fLog = 0; if (FileName.empty()) return; g_fLog = CreateStdioFile(FileName); - } +} void Log(const char *Format, ...) - { +{ if (g_fLog == 0) return; - + static bool InLog = false; if (InLog) return; - + InLog = true; va_list ArgList; va_start(ArgList, Format); @@ -556,97 +574,85 @@ void Log(const char *Format, ...) va_end(ArgList); fflush(g_fLog); InLog = false; - } +} void Die(const char *Format, ...) - { +{ static bool InDie = false; if (InDie) exit(1); InDie = true; string Msg; - + if (g_fLog != 0) setbuf(g_fLog, 0); va_list ArgList; va_start(ArgList, Format); myvstrprintf(Msg, Format, ArgList); va_end(ArgList); - + fprintf(stderr, "\n\n"); Log("\n"); time_t t = time(0); Log("%s", asctime(localtime(&t))); for (unsigned i = 0; i < g_Argv.size(); i++) - { + { fprintf(stderr, (i == 0) ? "%s" : " %s", g_Argv[i].c_str()); Log((i == 0) ? "%s" : " %s", g_Argv[i].c_str()); - } + } fprintf(stderr, "\n"); Log("\n"); - + time_t CurrentTime = time(0); unsigned ElapsedSeconds = unsigned(CurrentTime - g_StartTime); const char *sstr = SecsToStr(ElapsedSeconds); Log("Elapsed time: %s\n", sstr); - + const char *szStr = Msg.c_str(); fprintf(stderr, "\n---Fatal error---\n%s\n", szStr); Log("\n---Fatal error---\n%s\n", szStr); - -#ifdef _MSC_VER - if (IsDebuggerPresent()) - __debugbreak(); - _CrtSetDbgFlag(0); + +#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) +#else + //if (IsDebuggerPresent()) + // __debugbreak(); + //_CrtSetDbgFlag(0); #endif - + exit(1); - } +} void Warning(const char *Format, ...) - { +{ string Msg; - + va_list ArgList; va_start(ArgList, Format); myvstrprintf(Msg, Format, ArgList); va_end(ArgList); - + const char *szStr = Msg.c_str(); - + fprintf(stderr, "\nWARNING: %s\n", szStr); if (g_fLog != stdout) - { + { Log("\nWARNING: %s\n", szStr); fflush(g_fLog); - } } +} -#ifdef _MSC_VER -double GetMemUseBytes() - { - HANDLE hProc = GetCurrentProcess(); - PROCESS_MEMORY_COUNTERS PMC; - BOOL bOk = GetProcessMemoryInfo(hProc, &PMC, sizeof(PMC)); - if (!bOk) - return 1000000; - double Bytes = (double) PMC.WorkingSetSize; - if (Bytes > g_PeakMemUseBytes) - g_PeakMemUseBytes = Bytes; - return Bytes; - } -#elif linux || __linux__ +#if defined linux || __linux__ double GetMemUseBytes() - { +{ static char statm[64]; static int PageSize = 1; if (0 == statm[0]) - { + { PageSize = sysconf(_SC_PAGESIZE); pid_t pid = getpid(); sprintf(statm, "/proc/%d/statm", (int) pid); - } - + } + int fd = open(statm, O_RDONLY); if (-1 == fd) return 1000000; @@ -654,19 +660,19 @@ double GetMemUseBytes() int n = read(fd, Buffer, sizeof(Buffer) - 1); close(fd); fd = -1; - + if (n <= 0) return 1000000; - + Buffer[n] = 0; double Pages = atof(Buffer); - + double Bytes = Pages*PageSize; if (Bytes > g_PeakMemUseBytes) g_PeakMemUseBytes = Bytes; return Bytes; - } -#elif defined(__MACH__) +} +#elif defined(__APPLE__) || (__MACH__) #include #include #include @@ -688,7 +694,7 @@ double GetMemUseBytes() #define DEFAULT_MEM_USE 100000000.0 double GetMemUseBytes() - { +{ task_t mytask = mach_task_self(); struct task_basic_info ti; memset((void *) &ti, 0, sizeof(ti)); @@ -696,29 +702,29 @@ double GetMemUseBytes() kern_return_t ok = task_info(mytask, TASK_BASIC_INFO, (task_info_t) &ti, &count); if (ok == KERN_INVALID_ARGUMENT) return DEFAULT_MEM_USE; - + if (ok != KERN_SUCCESS) return DEFAULT_MEM_USE; - + double Bytes = (double ) ti.resident_size; if (Bytes > g_PeakMemUseBytes) g_PeakMemUseBytes = Bytes; return Bytes; - } +} #else double GetMemUseBytes() - { +{ return 0; - } +} #endif double GetPeakMemUseBytes() - { +{ return g_PeakMemUseBytes; - } +} const char *SecsToHHMMSS(int Secs) - { +{ int HH = Secs/3600; int MM = (Secs - HH*3600)/60; int SS = Secs%60; @@ -728,13 +734,13 @@ const char *SecsToHHMMSS(int Secs) else sprintf(Str, "%02d:%02d:%02d", HH, MM, SS); return Str; - } +} const char *SecsToStr(double Secs) - { +{ if (Secs >= 10.0) return SecsToHHMMSS((int) Secs); - + static char Str[16]; if (Secs < 1e-6) sprintf(Str, "%.2gs", Secs); @@ -743,12 +749,12 @@ const char *SecsToStr(double Secs) else sprintf(Str, "%.3fs", Secs); return Str; - } +} const char *MemBytesToStr(double Bytes) - { +{ static char Str[32]; - + if (Bytes < 1e6) sprintf(Str, "%.1fkb", Bytes/1e3); else if (Bytes < 10e6) @@ -762,12 +768,12 @@ const char *MemBytesToStr(double Bytes) else sprintf(Str, "%.3gb", Bytes); return Str; - } +} const char *IntToStr(unsigned i) - { +{ static char Str[32]; - + double d = (double) i; if (i < 10000) sprintf(Str, "%u", i); @@ -784,25 +790,25 @@ const char *IntToStr(unsigned i) else sprintf(Str, "%.3g", d); return Str; - } +} const char *FloatToStr(double d) - { +{ static char Str[32]; - + double a = fabs(d); if (a < 0.01) sprintf(Str, "%.3g", a); else if (a >= 0.01 && a < 1) sprintf(Str, "%.3f", a); else if (a <= 10 && a >= 1) - { + { double intpart; if (modf(a, &intpart) < 0.05) sprintf(Str, "%.0f", d); else sprintf(Str, "%.1f", d); - } + } else if (a > 10 && a < 10000) sprintf(Str, "%.0f", d); else if (a < 1e6) @@ -818,7 +824,7 @@ const char *FloatToStr(double d) else sprintf(Str, "%.3g", d); return Str; - } +} bool opt_quiet = false; bool opt_version = false; @@ -846,48 +852,48 @@ static unsigned g_StepCalls; static time_t g_TimeLastOutputStep; static string &GetProgressPrefixStr(string &s) - { +{ double Bytes = GetMemUseBytes(); unsigned Secs = GetElapsedSecs(); s = string(SecsToHHMMSS(Secs)); if (Bytes > 0) - { + { s.push_back(' '); char Str[32]; sprintf(Str, "%5.5s", MemBytesToStr(Bytes)); s += string(Str); - } + } s.push_back(' '); return s; - } +} void ProgressLog(const char *Format, ...) - { +{ string Str; va_list ArgList; va_start(ArgList, Format); myvstrprintf(Str, Format, ArgList); va_end(ArgList); - + Log("%s", Str.c_str()); Progress("%s", Str.c_str()); - } +} void Progress(const char *Format, ...) - { +{ if (opt_quiet) return; - + string Str; va_list ArgList; va_start(ArgList, Format); myvstrprintf(Str, Format, ArgList); va_end(ArgList); - + #if 0 Log("Progress("); for (unsigned i = 0; i < Str.size(); ++i) - { + { char c = Str[i]; if (c == '\r') Log("\\r"); @@ -895,26 +901,26 @@ void Progress(const char *Format, ...) Log("\\n"); else Log("%c", c); - } + } Log(")\n"); #endif //0 - + for (unsigned i = 0; i < Str.size(); ++i) - { + { if (g_CurrProgressLineLength == 0) - { + { string s; GetProgressPrefixStr(s); for (unsigned j = 0; j < s.size(); ++j) - { + { fputc(s[j], stderr); ++g_CurrProgressLineLength; - } } - + } + char c = Str[i]; if (c == '\n' || c == '\r') - { + { for (unsigned j = g_CurrProgressLineLength; j < g_LastProgressLineLength; ++j) fputc(' ', stderr); if (c == '\n') @@ -923,77 +929,77 @@ void Progress(const char *Format, ...) g_LastProgressLineLength = g_CurrProgressLineLength; g_CurrProgressLineLength = 0; fputc(c, stderr); - } + } else - { + { fputc(c, stderr); ++g_CurrProgressLineLength; - } } } +} void ProgressExit() - { +{ time_t Now = time(0); struct tm *t = localtime(&Now); const char *s = asctime(t); unsigned Secs = GetElapsedSecs(); - + Log("\n"); Log("Finished %s", s); // there is a newline in s Log("Elapsed time %s\n", SecsToHHMMSS((int) Secs)); Log("Max memory %s\n", MemBytesToStr(g_PeakMemUseBytes)); #if WIN32 && DEBUG -// Skip exit(), which can be very slow in DEBUG build -// VERY DANGEROUS practice, because it skips global destructors. -// But if you know the rules, you can break 'em, right? - ExitProcess(0); + // Skip exit(), which can be very slow in DEBUG build + // VERY DANGEROUS practice, because it skips global destructors. + // But if you know the rules, you can break 'em, right? + //ExitProcess(0); #endif - } +} const char *PctStr(double x, double y) - { +{ if (y == 0) - { + { if (x == 0) return "100%"; else return "inf%"; - } + } static char Str[16]; double p = x*100.0/y; sprintf(Str, "%5.1f%%", p); return Str; - } +} string &GetProgressLevelStr(string &s) - { +{ unsigned Index = g_ProgressIndex; unsigned Count = g_ProgressCount; if (Count == UINT_MAX) - { + { if (Index == UINT_MAX) s = "100%"; else - { + { char Tmp[16]; sprintf(Tmp, "%u", Index); s = Tmp; - } } + } else s = string(PctStr(Index+1, Count)); s += string(" ") + g_ProgressDesc; return s; - } +} void ProgressStep(unsigned i, unsigned N, const char *Format, ...) - { +{ if (opt_quiet) return; - + if (i == 0) - { + { string Str; va_list ArgList; va_start(ArgList, Format); @@ -1007,61 +1013,61 @@ void ProgressStep(unsigned i, unsigned N, const char *Format, ...) g_TimeLastOutputStep = 0; if (g_CurrProgressLineLength > 0) Progress("\n"); - } - + } + if (i >= N && i != UINT_MAX) Die("ProgressStep(%u,%u)", i, N); bool IsLastStep = (i == UINT_MAX || i + 1 == N); if (!IsLastStep) - { + { ++g_StepCalls; if (g_StepCalls%g_CountsInterval != 0) return; - + time_t Now = time(0); if (Now == g_TimeLastOutputStep) - { + { if (g_CountsInterval < 128) g_CountsInterval = (g_CountsInterval*3)/2; else g_CountsInterval += 64; return; - } + } else - { + { time_t Secs = Now - g_TimeLastOutputStep; if (Secs > 1) g_CountsInterval = unsigned(g_CountsInterval/(Secs*8)); - } - + } + if (g_CountsInterval < 1) g_CountsInterval = 1; - + g_TimeLastOutputStep = Now; - } - + } + g_ProgressIndex = i; - + if (i > 0) - { + { va_list ArgList; va_start(ArgList, Format); myvstrprintf(g_ProgressDesc, Format, ArgList); - } - + } + string LevelStr; GetProgressLevelStr(LevelStr); Progress(" %s\r", LevelStr.c_str()); - + if (IsLastStep) - { + { g_CountsInterval = 1; fputc('\n', stderr); - } } +} enum OptType - { +{ OT_Flag, OT_Tog, OT_Int, @@ -1069,10 +1075,10 @@ enum OptType OT_Str, OT_Float, OT_Enum - }; +}; struct OptInfo - { +{ void *Value; bool *OptSet; string LongName; @@ -1084,84 +1090,84 @@ struct OptInfo double dMin; double dMax; map EnumValues; - + bool bDefault; int iDefault; unsigned uDefault; double dDefault; string strDefault; - + string Help; - + bool operator<(const OptInfo &rhs) const - { + { return LongName < rhs.LongName; - } - }; + } +}; static set g_Opts; void Help() - { +{ printf("\n"); - + void Usage(); Usage(); - + for (set::const_iterator p = g_Opts.begin(); p != g_Opts.end(); ++p) - { + { const OptInfo &Opt = *p; - + printf("\n"); string LongName = Opt.LongName.c_str(); if (Opt.Type == OT_Tog) LongName = string("[no]") + LongName; printf(" --%s ", LongName.c_str()); - + switch (Opt.Type) - { - case OT_Flag: - break; - case OT_Tog: - break; - case OT_Int: - printf(""); - break; - case OT_Uns: - printf(""); - break; - case OT_Str: - printf(""); - break; - case OT_Float: - printf(""); - break; - case OT_Enum: - printf(""); - break; - default: - printf("??type"); - break; - } - + { + case OT_Flag: + break; + case OT_Tog: + break; + case OT_Int: + printf(""); + break; + case OT_Uns: + printf(""); + break; + case OT_Str: + printf(""); + break; + case OT_Float: + printf(""); + break; + case OT_Enum: + printf(""); + break; + default: + printf("??type"); + break; + } + printf(" "); const string &s = Opt.Help; for (string::const_iterator q = s.begin(); q != s.end(); ++q) - { + { char c = *q; if (c == '\n') printf("\n "); else printf("%c", c); - } - printf("\n"); } + printf("\n"); + } printf("\n"); exit(0); - } +} void CmdLineErr(const char *Format, ...) - { +{ va_list ArgList; va_start(ArgList, Format); string Str; @@ -1173,41 +1179,42 @@ void CmdLineErr(const char *Format, ...) fprintf(stderr, "For list of command-line options use --help.\n"); fprintf(stderr, "\n"); exit(1); - } +} static set::iterator GetOptInfo(const string &LongName, - bool ErrIfNotFound) - { + bool ErrIfNotFound) +{ for (set::iterator p = g_Opts.begin(); - p != g_Opts.end(); ++p) - { + p != g_Opts.end(); ++p) + { const OptInfo &Opt = *p; if (Opt.LongName == LongName) return p; if (Opt.Type == OT_Tog && "no" + Opt.LongName == LongName) return p; - } + } if (ErrIfNotFound) CmdLineErr("Option --%s is invalid", LongName.c_str()); return g_Opts.end(); - } +} static void AddOpt(const OptInfo &Opt) - { +{ if (GetOptInfo(Opt.LongName, false) != g_Opts.end()) Die("Option --%s defined twice", Opt.LongName.c_str()); g_Opts.insert(Opt); - } +} -#ifdef _MSC_VER +#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) +#else #pragma warning(disable: 4505) // unreferenced local function #endif static void DefineFlagOpt(const string &LongName, const string &Help, - void *Value, bool *OptSet) - { + void *Value, bool *OptSet) +{ *(bool *) Value = false; - + OptInfo Opt; Opt.Value = Value; Opt.OptSet = OptSet; @@ -1216,13 +1223,13 @@ static void DefineFlagOpt(const string &LongName, const string &Help, Opt.Help = Help; Opt.Type = OT_Flag; AddOpt(Opt); - } +} static void DefineTogOpt(const string &LongName, bool Default, const string &Help, - void *Value, bool *OptSet) - { + void *Value, bool *OptSet) +{ *(bool *) Value = Default; - + OptInfo Opt; Opt.Value = Value; Opt.OptSet = OptSet; @@ -1231,13 +1238,13 @@ static void DefineTogOpt(const string &LongName, bool Default, const string &Hel Opt.Help = Help; Opt.Type = OT_Tog; AddOpt(Opt); - } +} static void DefineIntOpt(const string &LongName, int Default, int Min, int Max, - const string &Help, void *Value, bool *OptSet) - { + const string &Help, void *Value, bool *OptSet) +{ *(int *) Value = Default; - + OptInfo Opt; Opt.Value = Value; Opt.OptSet = OptSet; @@ -1248,13 +1255,13 @@ static void DefineIntOpt(const string &LongName, int Default, int Min, int Max, Opt.Help = Help; Opt.Type = OT_Int; AddOpt(Opt); - } +} static void DefineUnsOpt(const string &LongName, unsigned Default, unsigned Min, - unsigned Max, const string &Help, void *Value, bool *OptSet) - { + unsigned Max, const string &Help, void *Value, bool *OptSet) +{ *(unsigned *) Value = Default; - + OptInfo Opt; Opt.Value = Value; Opt.OptSet = OptSet; @@ -1265,13 +1272,13 @@ static void DefineUnsOpt(const string &LongName, unsigned Default, unsigned Min, Opt.Help = Help; Opt.Type = OT_Uns; AddOpt(Opt); - } +} static void DefineFloatOpt(const string &LongName, double Default, double Min, - double Max, const string &Help, void *Value, bool *OptSet) - { + double Max, const string &Help, void *Value, bool *OptSet) +{ *(double *) Value = Default; - + OptInfo Opt; Opt.Value = Value; Opt.OptSet = OptSet; @@ -1282,13 +1289,13 @@ static void DefineFloatOpt(const string &LongName, double Default, double Min, Opt.Help = Help; Opt.Type = OT_Float; AddOpt(Opt); - } +} static void DefineStrOpt(const string &LongName, const char *Default, - const string &Help, void *Value, bool *OptSet) - { + const string &Help, void *Value, bool *OptSet) +{ *(string *) Value = (Default == 0 ? "" : string(Default)); - + OptInfo Opt; Opt.Value = Value; Opt.OptSet = OptSet; @@ -1297,34 +1304,34 @@ static void DefineStrOpt(const string &LongName, const char *Default, Opt.Help = Help; Opt.Type = OT_Str; AddOpt(Opt); - } +} static void ParseEnumValues(const string &Values, map &EnumValues) - { +{ EnumValues.clear(); string Name; string Value; bool Eq = false; for (string::const_iterator p = Values.begin(); ; ++p) - { + { char c = (p == Values.end() ? '|' : *p); if (isspace(c)) ; else if (c == '|') - { + { if (EnumValues.find(Name) != EnumValues.end()) Die("Invalid enum values, '%s' defined twice: '%s'", - Name.c_str(), Values.c_str()); + Name.c_str(), Values.c_str()); if (Name.empty() || Value.empty()) Die("Invalid enum values, empty name or value: '%s'", - Values.c_str()); - + Values.c_str()); + EnumValues[Name] = atoi(Value.c_str()); Name.clear(); Value.clear(); Eq = false; - } + } else if (c == '=') Eq = true; else if (Eq) @@ -1333,14 +1340,14 @@ static void ParseEnumValues(const string &Values, map &EnumVal Name.push_back(c); if (p == Values.end()) return; - } } +} static void DefineEnumOpt(const string &LongName, const string &ShortName, - int Default, const string &Values, const string &Help, void *Value) - { + int Default, const string &Values, const string &Help, void *Value) +{ *(int *) Value = Default; - + OptInfo Opt; Opt.Value = Value; Opt.LongName = LongName; @@ -1349,7 +1356,7 @@ static void DefineEnumOpt(const string &LongName, const string &ShortName, Opt.Type = OT_Enum; ParseEnumValues(Values, Opt.EnumValues); AddOpt(Opt); - } +} #undef FLAG_OPT #undef TOG_OPT #undef INT_OPT @@ -1367,110 +1374,110 @@ static void DefineEnumOpt(const string &LongName, const string &ShortName, #include "myopts.h" static int EnumStrToInt(const OptInfo &Opt, const string &Value) - { +{ const map &e = Opt.EnumValues; string s; for (map::const_iterator p = e.begin(); p != e.end(); ++p) - { + { if (Value == p->first) return p->second; s += " " + p->first; - } + } CmdLineErr("--%s %s not recognized, valid are: %s", - Opt.LongName.c_str(), Value.c_str(), s.c_str()); + Opt.LongName.c_str(), Value.c_str(), s.c_str()); ureturn(-1); - } +} static void SetOpt(OptInfo &Opt, const string &Value) - { +{ *Opt.OptSet = true; switch (Opt.Type) + { + case OT_Int: { - case OT_Int: - { - *(int *) Opt.Value = atoi(Value.c_str()); - break; + *(int *) Opt.Value = atoi(Value.c_str()); + break; } - case OT_Uns: + case OT_Uns: { - unsigned uValue = 0; - int n = sscanf(Value.c_str(), "%u", &uValue); - if (n != 1) - CmdLineErr("Invalid value '%s' for --%s", - Value.c_str(), Opt.LongName.c_str()); - *(unsigned *) Opt.Value = uValue; - break; + unsigned uValue = 0; + int n = sscanf(Value.c_str(), "%u", &uValue); + if (n != 1) + CmdLineErr("Invalid value '%s' for --%s", + Value.c_str(), Opt.LongName.c_str()); + *(unsigned *) Opt.Value = uValue; + break; } - case OT_Float: + case OT_Float: { - *(double *) Opt.Value = atof(Value.c_str()); - break; + *(double *) Opt.Value = atof(Value.c_str()); + break; } - case OT_Str: + case OT_Str: { - *(string *) Opt.Value = Value; - break; + *(string *) Opt.Value = Value; + break; } - case OT_Enum: + case OT_Enum: { - *(int *) Opt.Value = EnumStrToInt(Opt, Value); - break; - } - default: - asserta(false); + *(int *) Opt.Value = EnumStrToInt(Opt, Value); + break; } + default: + asserta(false); } +} void LogOpts() - { +{ for (set::const_iterator p = g_Opts.begin(); p != g_Opts.end(); ++p) - { + { const OptInfo &Opt = *p; Log("%s = ", Opt.LongName.c_str()); switch (Opt.Type) + { + case OT_Flag: + Log("%s", (*(bool *) Opt.Value) ? "yes" : "no"); + break; + case OT_Tog: + Log("%s", (*(bool *) Opt.Value) ? "on" : "off"); + break; + case OT_Int: + Log("%d", *(int *) Opt.Value); + break; + case OT_Uns: + Log("%u", *(unsigned *) Opt.Value); + break; + case OT_Float: { - case OT_Flag: - Log("%s", (*(bool *) Opt.Value) ? "yes" : "no"); - break; - case OT_Tog: - Log("%s", (*(bool *) Opt.Value) ? "on" : "off"); - break; - case OT_Int: - Log("%d", *(int *) Opt.Value); - break; - case OT_Uns: - Log("%u", *(unsigned *) Opt.Value); - break; - case OT_Float: - { - double Value = *(double *) Opt.Value; - if (Value == FLT_MAX) - Log("*"); - else - Log("%g", Value); - break; - } - case OT_Str: - Log("%s", (*(string *) Opt.Value).c_str()); - break; - case OT_Enum: - Log("%d", *(int *) Opt.Value); - break; - default: - asserta(false); + double Value = *(double *) Opt.Value; + if (Value == FLT_MAX) + Log("*"); + else + Log("%g", Value); + break; } - Log("\n"); + case OT_Str: + Log("%s", (*(string *) Opt.Value).c_str()); + break; + case OT_Enum: + Log("%d", *(int *) Opt.Value); + break; + default: + asserta(false); } + Log("\n"); } +} static void CompilerInfo() - { +{ #ifdef _FILE_OFFSET_BITS printf("_FILE_OFFSET_BITS=%d\n", _FILE_OFFSET_BITS); #else printf("_FILE_OFFSET_BITS not defined\n"); #endif - + #define x(t) printf("sizeof(" #t ") = %d\n", (int) sizeof(t)); x(int) x(long) @@ -1480,60 +1487,61 @@ static void CompilerInfo() x(off_t) #undef x exit(0); - } +} void Split(const string &Str, vector &Fields, char Sep) - { +{ Fields.clear(); const unsigned Length = (unsigned) Str.size(); string s; for (unsigned i = 0; i < Length; ++i) - { + { char c = Str[i]; if ((Sep == 0 && isspace(c)) || c == Sep) - { + { if (!s.empty() || Sep != 0) Fields.push_back(s); s.clear(); - } + } else s.push_back(c); - } + } if (!s.empty()) Fields.push_back(s); - } +} static void GetArgsFromFile(const string &FileName, vector &Args) - { +{ Args.clear(); - + FILE *f = OpenStdioFile(FileName); string Line; while (ReadLineStdioFile(f, Line)) - { + { size_t n = Line.find('#'); if (n != string::npos) Line = Line.substr(0, n); vector Fields; Split(Line, Fields); Args.insert(Args.end(), Fields.begin(), Fields.end()); - } - CloseStdioFile(f); } + CloseStdioFile(f); +} void MyCmdLine(int argc, char **argv) - { +{ + g_Opts.clear(); g_Argv.clear(); static unsigned RecurseDepth = 0; ++RecurseDepth; - + DefineFlagOpt("compilerinfo", "Write info about compiler types and #defines to stdout.", - (void *) &opt_compilerinfo, &optset_compilerinfo); + (void *) &opt_compilerinfo, &optset_compilerinfo); DefineFlagOpt("quiet", "Turn off progress messages.", (void *) &opt_quiet, &optset_quiet); DefineFlagOpt("version", "Show version and exit.", (void *) &opt_version, &optset_version); DefineFlagOpt("logopts", "Log options.", (void *) &opt_logopts, &optset_logopts); DefineFlagOpt("help", "Display command-line options.", (void *) &opt_help, &optset_help); DefineStrOpt("log", "", "Log file name.", (void *) &opt_log, &optset_log); - + #undef FLAG_OPT #undef TOG_OPT #undef INT_OPT @@ -1549,17 +1557,17 @@ void MyCmdLine(int argc, char **argv) #define STR_OPT(LongName, Default) DefineStrOpt(#LongName, Default, "help", (void *) &opt_##LongName, &optset_##LongName); #define ENUM_OPT(LongName, Values, Default) DefineEnumOpt(#LongName, Values, Default, "help", (void *) &opt_##LongName, &optset_##LongName); #include "myopts.h" - + if (RecurseDepth == 0) g_Argv.clear(); - + for (int i = 0; i < argc; ++i) g_Argv.push_back(string(argv[i])); - + int i = 1; for (;;) - { + { if (i >= argc) break; const string &Arg = g_Argv[i]; @@ -1567,75 +1575,75 @@ void MyCmdLine(int argc, char **argv) if (Arg.empty()) continue; else if (Arg == "file:" && i + 1 < argc) - { + { const string &FileName = g_Argv[i+1]; vector Args; GetArgsFromFile(FileName, Args); for (vector::const_iterator p = Args.begin(); - p != Args.end(); ++p) - { + p != Args.end(); ++p) + { g_Argv.push_back(*p); ++argc; - } + } i += 2; continue; - } + } else if (Arg.size() > 1 && Arg[0] == '-') - { + { string LongName = (Arg.size() > 2 && Arg[1] == '-' ? Arg.substr(2) : Arg.substr(1)); OptInfo Opt = *GetOptInfo(LongName, true); *Opt.OptSet = true; if (Opt.Type == OT_Flag) - { + { g_Opts.erase(Opt); *(bool *) Opt.Value = true; g_Opts.insert(Opt); ++i; continue; - } + } else if (Opt.Type == OT_Tog) - { + { g_Opts.erase(Opt); if (string("no") + Opt.LongName == LongName) *(bool *) Opt.Value = false; else - { + { asserta(Opt.LongName == LongName); *(bool *) Opt.Value = true; - } + } g_Opts.insert(Opt); ++i; continue; - } - + } + ++i; if (i >= argc) CmdLineErr("Missing value for option --%s", LongName.c_str()); - + string Value = g_Argv[i]; SetOpt(Opt, Value); - + ++i; continue; - } + } else CmdLineErr("Expected -option_name or --option_name, got '%s'", Arg.c_str()); - } - + } + --RecurseDepth; if (RecurseDepth > 0) return; - + if (opt_help) Help(); - + if (opt_compilerinfo) CompilerInfo(); - + SetLogFileName(opt_log); - + if (opt_log != "") - { + { for (int i = 0; i < argc; ++i) Log("%s%s", i == 0 ? "" : " ", g_Argv[i].c_str()); Log("\n"); @@ -1645,57 +1653,57 @@ void MyCmdLine(int argc, char **argv) Log("Started %s", s); // there is a newline in s Log("Version " MY_VERSION ".%s\n", SVN_VERSION); Log("\n"); - } - + } + if (opt_logopts) LogOpts(); - } +} double Pct(double x, double y) - { +{ if (y == 0.0f) return 0.0f; return (x*100.0f)/y; - } +} void GetCmdLine(string &s) - { +{ s.clear(); for (unsigned i = 0; i < SIZE(g_Argv); ++i) - { + { if (i > 0) s += " "; s += g_Argv[i]; - } } +} char *mystrsave(const char *s) - { +{ unsigned n = unsigned(strlen(s)); char *t = myalloc(char, n+1); memcpy(t, s, n+1); return t; - } +} void Logu(unsigned u, unsigned w, unsigned prefixspaces) - { +{ for (unsigned i = 0; i < prefixspaces; ++i) Log(" "); if (u == UINT_MAX) Log("%*.*s", w, w, "*"); else Log("%*u", w, u); - } +} void Logf(float x, unsigned w, unsigned prefixspaces) - { +{ for (unsigned i = 0; i < prefixspaces; ++i) Log(" "); if (x == FLT_MAX) Log("%*.*s", w, w, "*"); else Log("%*.2f", w, x); - } +} static uint32 g_SLCG_state = 1; @@ -1707,65 +1715,65 @@ static uint32 g_SLCG_c = 2531011; // Simple Linear Congruential Generator // Bad properties; used just to initialize the better generator. static uint32 SLCG_rand() - { +{ g_SLCG_state = g_SLCG_state*g_SLCG_a + g_SLCG_c; return g_SLCG_state; - } +} static void SLCG_srand(uint32 Seed) - { +{ g_SLCG_state = Seed; for (int i = 0; i < 10; ++i) SLCG_rand(); - } +} /*** -A multiply-with-carry random number generator, see: -http://en.wikipedia.org/wiki/Multiply-with-carry - -The particular multipliers used here were found on -the web where they are attributed to George Marsaglia. -***/ + A multiply-with-carry random number generator, see: + http://en.wikipedia.org/wiki/Multiply-with-carry + + The particular multipliers used here were found on + the web where they are attributed to George Marsaglia. + ***/ static bool g_InitRandDone = false; static uint32 g_X[5]; uint32 RandInt32() - { +{ InitRand(); - + uint64 Sum = 2111111111*(uint64) g_X[3] + 1492*(uint64) g_X[2] + - 1776*(uint64) g_X[1] + 5115*(uint64) g_X[0] + g_X[4]; + 1776*(uint64) g_X[1] + 5115*(uint64) g_X[0] + g_X[4]; g_X[3] = g_X[2]; g_X[2] = g_X[1]; g_X[1] = g_X[0]; g_X[4] = (uint32) (Sum >> 32); g_X[0] = (uint32) Sum; return g_X[0]; - } +} unsigned randu32() - { +{ return (unsigned) RandInt32(); - } +} void InitRand() - { +{ if (g_InitRandDone) return; -// Do this first to avoid recursion + // Do this first to avoid recursion g_InitRandDone = true; - + unsigned Seed = (optset_randseed ? opt_randseed : (unsigned) (time(0)*getpid())); Log("RandSeed=%u\n", Seed); SLCG_srand(Seed); - + for (unsigned i = 0; i < 5; i++) g_X[i] = SLCG_rand(); - + for (unsigned i = 0; i < 100; i++) RandInt32(); - } +} // MUST COME AT END BECAUSE OF #undef #if RCE_MALLOC @@ -1773,72 +1781,72 @@ void InitRand() #undef myfree #undef myfree2 void *mymalloc(unsigned bytes, const char *FileName, int Line) - { +{ void *rce_malloc(unsigned bytes, const char *FileName, int Line); return rce_malloc(bytes, FileName, Line); - } +} void myfree(void *p, const char *FileName, int Line) - { +{ void rce_free(void *p, const char *FileName, int Line); rce_free(p, FileName, Line); - } +} void myfree2(void *p, unsigned bytes, const char *FileName, int Line) - { +{ void rce_free(void *p, const char *FileName, int Line); rce_free(p, FileName, Line); - } +} #else // RCE_MALLOC void *mymalloc(unsigned bytes) - { +{ ++g_NewCalls; if (g_InitialMemUseBytes == 0) g_InitialMemUseBytes = GetMemUseBytes(); - + g_TotalAllocBytes += bytes; g_NetBytes += bytes; if (g_NetBytes > g_MaxNetBytes) - { + { if (g_NetBytes > g_MaxNetBytes + 10000000) GetMemUseBytes();//to force update of peak g_MaxNetBytes = g_NetBytes; - } + } void *p = malloc(bytes); //void *p = _malloc_dbg(bytes, _NORMAL_BLOCK, __FILE__, __LINE__); if (0 == p) - { + { double b = GetMemUseBytes(); fprintf(stderr, "\nOut of memory mymalloc(%u), curr %.3g bytes", - (unsigned) bytes, b); + (unsigned) bytes, b); void LogAllocs(); LogAllocs(); #if DEBUG && defined(_MSC_VER) asserta(_CrtCheckMemory()); #endif Die("Out of memory, mymalloc(%u), curr %.3g bytes\n", - (unsigned) bytes, b); - } - return p; + (unsigned) bytes, b); } + return p; +} void myfree(void *p) - { +{ if (p == 0) return; free(p); //_free_dbg(p, _NORMAL_BLOCK); - } +} void myfree2(void *p, unsigned bytes) - { +{ ++g_FreeCalls; g_TotalFreeBytes += bytes; g_NetBytes -= bytes; - + if (p == 0) return; free(p); - } +} #endif