// ============================================================== // This file is part of Glest Shared Library (www.glest.org) // // Copyright (C) 2001-2008 Martio Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published // by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version // ============================================================== #include "util.h" #include #include #include #include #include #include #include #include // for open() #ifdef WIN32 #include // for open() #include // for open() #endif #include "platform_util.h" #include "conversion.h" #include "leak_dumper.h" using namespace std; using namespace Shared::Platform; namespace Shared{ namespace Util{ std::map SystemFlags::debugLogFileList; void SystemFlags::init() { SystemFlags::debugLogFileList[SystemFlags::debugSystem] = SystemFlags::SystemFlagsType(SystemFlags::debugSystem); SystemFlags::debugLogFileList[SystemFlags::debugNetwork] = SystemFlags::SystemFlagsType(SystemFlags::debugNetwork); SystemFlags::debugLogFileList[SystemFlags::debugPerformance] = SystemFlags::SystemFlagsType(SystemFlags::debugPerformance); SystemFlags::debugLogFileList[SystemFlags::debugWorldSynch] = SystemFlags::SystemFlagsType(SystemFlags::debugWorldSynch); } //bool SystemFlags::enableDebugText = false; //bool SystemFlags::enableNetworkDebugInfo = false; //bool SystemFlags::enablePerformanceDebugInfo = false; //bool SystemFlags::enableWorldSynchDebugInfo = false; //const char * SystemFlags::debugLogFile = NULL; //ofstream SystemFlags::fileStream; int SystemFlags::lockFile = -1; string SystemFlags::lockfilename = ""; inline bool acquire_file_lock(int hnd) { #ifndef WIN32 struct ::flock lock; lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; return -1 != ::fcntl(hnd, F_SETLK, &lock); #else HANDLE hFile = (HANDLE)_get_osfhandle(hnd); return true == ::LockFile(hFile, 0, 0, 0, -0x10000); #endif } SystemFlags::SystemFlags() { } SystemFlags::~SystemFlags() { SystemFlags::Close(); } void SystemFlags::Close() { printf("Closing logfile\n"); for(std::map::iterator iterMap = SystemFlags::debugLogFileList.begin(); iterMap != SystemFlags::debugLogFileList.end(); iterMap++) { SystemFlags::SystemFlagsType ¤tDebugLog = iterMap->second; if( currentDebugLog.fileStream != NULL && currentDebugLog.fileStream->is_open() == true) { currentDebugLog.fileStream->close(); } delete currentDebugLog.fileStream; currentDebugLog.fileStream = NULL; } if(SystemFlags::lockfilename != "") { #ifndef WIN32 close(SystemFlags::lockFile); #else _close(SystemFlags::lockFile); #endif remove(SystemFlags::lockfilename.c_str()); SystemFlags::lockfilename = ""; } } void SystemFlags::OutputDebug(DebugType type, const char *fmt, ...) { SystemFlags::SystemFlagsType ¤tDebugLog = SystemFlags::debugLogFileList[type]; if(currentDebugLog.enabled == false) { return; } /* Get the current time. */ time_t curtime = time (NULL); /* Convert it to local time representation. */ struct tm *loctime = localtime (&curtime); char szBuf2[100]=""; strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",loctime); va_list argList; va_start(argList, fmt); char szBuf[1024]=""; vsprintf(szBuf,fmt, argList); // Either output to a logfile or if(currentDebugLog.debugLogFileName != "") { if( currentDebugLog.fileStream == NULL || currentDebugLog.fileStream->is_open() == false) { // If the file is already open (shared) by another debug type // do not over-write the file but append bool appendToFileOnly = false; for(std::map::iterator iterMap = SystemFlags::debugLogFileList.begin(); iterMap != SystemFlags::debugLogFileList.end(); iterMap++) { SystemFlags::SystemFlagsType ¤tDebugLog2 = iterMap->second; if( iterMap->first != type && currentDebugLog.debugLogFileName == currentDebugLog2.debugLogFileName && currentDebugLog2.fileStream != NULL) { appendToFileOnly = true; break; } } string debugLog = currentDebugLog.debugLogFileName; printf("Opening logfile [%s] type = %d, appendToFileOnly = %d\n",debugLog.c_str(),type, appendToFileOnly); const string lock_file_name = "debug.lck"; string lockfile = extractDirectoryPathFromFile(debugLog); lockfile += lock_file_name; SystemFlags::lockfilename = lockfile; #ifndef WIN32 //SystemFlags::lockFile = open(lockfile.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR|S_IWUSR); SystemFlags::lockFile = open(lockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); #else SystemFlags::lockFile = _open(lockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); #endif if (SystemFlags::lockFile < 0 || acquire_file_lock(SystemFlags::lockFile) == false) { string newlockfile = lockfile; int idx = 1; for(idx = 1; idx <= 100; ++idx) { newlockfile = lockfile + intToStr(idx); //SystemFlags::lockFile = open(newlockfile.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR|S_IWUSR); #ifndef WIN32 SystemFlags::lockFile = open(newlockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); #else SystemFlags::lockFile = _open(newlockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); #endif if(SystemFlags::lockFile >= 0 && acquire_file_lock(SystemFlags::lockFile) == true) { break; } } SystemFlags::lockfilename = newlockfile; debugLog += intToStr(idx); printf("Opening additional logfile [%s]\n",debugLog.c_str()); } if(currentDebugLog.fileStream == NULL) { currentDebugLog.fileStream = new std::ofstream(); } if(appendToFileOnly == false) { currentDebugLog.fileStream->open(debugLog.c_str(), ios_base::out | ios_base::trunc); } else { currentDebugLog.fileStream->open(debugLog.c_str(), ios_base::out | ios_base::app); } (*currentDebugLog.fileStream) << "Starting Mega-Glest logging for type: " << type << "\n"; (*currentDebugLog.fileStream).flush(); } //printf("Logfile is open [%s]\n",SystemFlags::debugLogFile); //printf("writing to logfile [%s]\n",szBuf); assert(currentDebugLog.fileStream != NULL); (*currentDebugLog.fileStream) << "[" << szBuf2 << "] " << szBuf; (*currentDebugLog.fileStream).flush(); } // output to console else { printf("[%s] %s", szBuf2, szBuf); } va_end(argList); } string lastDir(const string &s){ size_t i= s.find_last_of('/'); size_t j= s.find_last_of('\\'); size_t pos; if(i==string::npos){ pos= j; } else if(j==string::npos){ pos= i; } else{ pos= i1.f){ return 1.f; } return value; } int clamp(int value, int min, int max){ if (valuemax){ return max; } return value; } float clamp(float value, float min, float max){ if (valuemax){ return max; } return value; } int round(float f){ return (int) f; } // ==================== misc ==================== bool fileExists(const string &path){ FILE* file= fopen(path.c_str(), "rb"); if(file!=NULL){ fclose(file); return true; } return false; } }}//end namespace