diff --git a/FileXT/common.h b/FileXT/common.h index 3a06ed5..f63c2bf 100644 --- a/FileXT/common.h +++ b/FileXT/common.h @@ -11,22 +11,27 @@ // Debug logging macros #ifndef NDEBUG -#define LOG(...) log(__VA_ARGS__) +#define LOG(format, ...) log("FileXT: " format "\n", ##__VA_ARGS__) #else #define LOG(...) #endif #ifdef ENABLE_LOG_VERBOSE -#define LOG_VERBOSE(...) log("FileXT: ", __VA_ARGS__); +#define LOG_VERBOSE(format, ...) log("FileXT [VERBOSE]: " format "\n", ##__VA_ARGS__); #else #define LOG_VERBOSE(...) #endif -#define LOG_CRITICAL(...) logTrace(__LINE__, __FILE__, "FileXT: CRITICAL ERROR: ", __VA_ARGS__); +#define LOG_CRITICAL(format, ...) logTrace(__LINE__, __FILE__, "FileXT [CRITICAL ERROR]: " format " [%s] [line: %d]\n", ##__VA_ARGS__); + +#ifndef NDEBUG +#define LOG_G(...) log_g(__VA_ARGS__) +#else +#define LOG_G(...) +#endif // Forward Decls extern std::unique_ptr gpFile; -std::filesystem::path& getLogPath(); template void log(const char* format, Args&&...args) { @@ -36,8 +41,7 @@ void log(const char* format, Args&&...args) { FILE* pFile = gpFile.get(); #endif - if (pFile != nullptr) - { + if (pFile != nullptr) { std::fprintf(pFile, format, args...); std::fflush(pFile); } @@ -45,8 +49,26 @@ void log(const char* format, Args&&...args) { template inline void logTrace(int line, const char* fileName, const char* format, Args&&...args) { - size_t bufSize = std::snprintf(NULL, 0, "%s [%s] [line: %d]\n", format, fileName, line); - std::vector buf(bufSize + 1, '\0'); - std::snprintf(buf.data(), bufSize, "%s [%s] [line: %d]\n", format, fileName, line); - log(buf.data(), args...); -} \ No newline at end of file + log(format, args..., fileName, line); +} + +// Guaranteed to print somewhere, even without a log file. +// Windows: Visual Studio output window +// Linux: Terminal window +#ifndef NDEBUG +template +inline void log_g(const char* format, Args...args) { +#if defined(_WIN32) + std::vector buf; + + size_t bufSize = std::snprintf(nullptr, 0, format, args...); + buf.resize(++bufSize); + + std::snprintf(buf.data(), bufSize, format, args...); + ::OutputDebugStringA(buf.data()); +#else + fprintf(stderr, format, args...); + fflush(stderr); +#endif +} +#endif \ No newline at end of file diff --git a/FileXT/dllmain.cpp b/FileXT/dllmain.cpp index dd2a950..c688ab8 100644 --- a/FileXT/dllmain.cpp +++ b/FileXT/dllmain.cpp @@ -12,13 +12,15 @@ using namespace std; +// Forward Declerations +bool checkFileName(string& fileName); +string getDllFolder(); +std::filesystem::path& getLogPath(); + // Globals filext::filemgr gFileMgr; std::unique_ptr gpFile(std::fopen(getLogPath().u8string().c_str(), "w"), &std::fclose); -bool checkFileName(string& fileName); -string getDllFolder(); - const std::string& GetAndEnsureStorageDir() { // keep this static path internal so it doesn't get used too early or modified externally. @@ -58,7 +60,7 @@ __attribute__((constructor)) #endif static void Entry() { - LOG_VERBOSE("FileXT Dll entry\n"); + LOG_VERBOSE("FileXT Dll entry"); std::string const& storageDirectory = GetAndEnsureStorageDir(); } @@ -98,7 +100,7 @@ extern "C" // Macro for asserting correct argument count #define ASSERT_EXT_ARGC(argc, argcNeeded) if (argc != argcNeeded) { \ -LOG("Wrong arg count, received: %i, expected: %i\n", argc, argcNeeded); \ +LOG("Wrong arg count, received: %i, expected: %i", argc, argcNeeded); \ return FILEXT_ERROR_WRONG_ARG_COUNT; \ } @@ -128,7 +130,7 @@ FILEXT_EXPORT int FILEXT_CALL RVExtensionArgs(char* output, int outputSize, cons fileName = string(argv[1]); fileName.erase(0, 1); fileName.pop_back(); - //LOG("Argc: %i\n", argc); + //LOG("Argc: %i", argc); // Check file name // Bail if file name is wrong @@ -137,7 +139,7 @@ FILEXT_EXPORT int FILEXT_CALL RVExtensionArgs(char* output, int outputSize, cons fileName = storageDirectory + fileName; } - LOG_VERBOSE("RVExtensionArgs: function: %s, fileName: %s, outputSize: %i\n", functionName, fileName.c_str(), outputSize); + LOG_VERBOSE("RVExtensionArgs: function: %s, fileName: %s, outputSize: %i", functionName, fileName.c_str(), outputSize); // Resolve function name @@ -176,7 +178,7 @@ FILEXT_EXPORT int FILEXT_CALL RVExtensionArgs(char* output, int outputSize, cons reset = 0; } int retInt = gFileMgr.get(fileName, argv[2], strOut, outputSize-4, (bool)reset); // Just to be safe, reduce size a bit - LOG(" Returning string of size: %i\n", (unsigned int)strOut.size()); + LOG(" Returning string of size: %i", (unsigned int)strOut.size()); ASSERT_BUFFER_SIZE((int)outputSize -1, (int)strOut.size()); strcpy(output, strOut.c_str()); return retInt; @@ -208,7 +210,7 @@ FILEXT_EXPORT int FILEXT_CALL RVExtensionArgs(char* output, int outputSize, cons for (const auto& entry : filesystem::directory_iterator(storageDirectory)) { string fileName = entry.path().filename().string(); vectorFileNamesSQF.push_back(sqf::value(fileName)); - LOG("File: %s\n", fileName.c_str()); + LOG("File: %s", fileName.c_str()); } sqf::value fileNamesSQFArray(vectorFileNamesSQF); @@ -297,8 +299,8 @@ std::string getDllFolder() (LPCSTR)getDllFolder, &hm)) { - LOG("error: GetModuleHandle returned %i", GetLastError()); - return std::string(""); + LOG_G("Fatal Error: GetModuleHandle returned %i", GetLastError()); + throw new std::runtime_error("Fatal Error: GetModuleHandle failed."); } GetModuleFileNameA(hm, path, sizeof(path)); @@ -310,7 +312,10 @@ std::string getDllFolder() return p; #else Dl_info dl_info; - dladdr((void*)getDllFolder, &dl_info); + if (dladdr((void*)getDllFolder, &dl_info) == 0) { + LOG_G("Fatal Error: dladdr returned 0"); + throw new std::runtime_error("Fatal Error: dladdr returned 0"); + } std::string p = std::string(dl_info.dli_fname); // Remove DLL name from the path diff --git a/FileXT/filemgr.cpp b/FileXT/filemgr.cpp index 8bdbda2..54b96a5 100644 --- a/FileXT/filemgr.cpp +++ b/FileXT/filemgr.cpp @@ -15,12 +15,12 @@ fileInfo::fileInfo(std::string& fileName) : m_currentGetID(0), m_currentGetKey("") { - LOG("NEW fileInfo: %s\n", fileName.c_str()); + LOG("NEW fileInfo: %s", fileName.c_str()); } fileInfo::~fileInfo() { - LOG("DELETE fileinfo: %s\n", m_fileName.c_str()); + LOG("DELETE fileinfo: %s", m_fileName.c_str()); } @@ -30,15 +30,15 @@ fileInfo::~fileInfo() int filext::filemgr::open(const std::string& fName) { - LOG("open(%s)\n", fName.c_str()); + LOG("open(%s)", fName.c_str()); // Check if this file is already open string fNameStr(fName); auto search = m_fileMap.find(fNameStr); if (search != m_fileMap.end()) { - LOG(" FOUND in m_fileMap\n"); + LOG(" FOUND in m_fileMap"); } else { - LOG(" NOT found in m_fileMap\n"); + LOG(" NOT found in m_fileMap"); // Create a new entry fileInfo* finfoPtr = new fileInfo(fNameStr); m_fileMap[fNameStr] = finfoPtr; @@ -49,18 +49,18 @@ int filext::filemgr::open(const std::string& fName) int filext::filemgr::close(const std::string& fName) { - LOG("close(%s)\n", fName.c_str()); + LOG("close(%s)", fName.c_str()); // Check if this file is already open string fNameStr(fName); auto search = m_fileMap.find(fNameStr); if (search != m_fileMap.end()) { - LOG(" FOUND in m_fileMap\n"); + LOG(" FOUND in m_fileMap"); delete (search->second); m_fileMap.erase(search); } else { - LOG(" NOT found in m_fileMap\n"); + LOG(" NOT found in m_fileMap"); // Do nothing if it's closed already }; @@ -69,7 +69,7 @@ int filext::filemgr::close(const std::string& fName) int filext::filemgr::set(const std::string& fName, const char* key, const char* value) { - LOG("set(%s, %s, %s)\n", fName.c_str(), key, value); + LOG("set(%s, %s, %s)", fName.c_str(), key, value); // Check if this file is already open string fNameStr(fName); @@ -79,7 +79,7 @@ int filext::filemgr::set(const std::string& fName, const char* key, const char* finfo->m_map[string(key)] = string(value); return FILEXT_SUCCESS; } else { - LOG(" File is not open\n"); + LOG(" File is not open"); // Return error return FILEXT_ERROR_FILE_NOT_OPEN; }; @@ -87,7 +87,7 @@ int filext::filemgr::set(const std::string& fName, const char* key, const char* int filext::filemgr::eraseKey(const std::string& fName, const char* key) { - LOG("eraseKey(%s, %s)\n", fName.c_str(), key); + LOG("eraseKey(%s, %s)", fName.c_str(), key); // Check if this file is already open string fNameStr(fName); @@ -97,7 +97,7 @@ int filext::filemgr::eraseKey(const std::string& fName, const char* key) finfo->m_map.erase(string(key)); return FILEXT_SUCCESS; } else { - LOG(" File is not open\n"); + LOG(" File is not open"); // Return error return FILEXT_ERROR_FILE_NOT_OPEN; }; @@ -105,7 +105,7 @@ int filext::filemgr::eraseKey(const std::string& fName, const char* key) int filext::filemgr::get(const std::string& fName, const char* key, string& outValue, unsigned int outputSize, bool reset) { - LOG("get(%s, %s, reset: %i, outputSize: %i)\n", fName.c_str(), key, reset, outputSize); + LOG("get(%s, %s, reset: %i, outputSize: %i)", fName.c_str(), key, reset, outputSize); unsigned int nBytesToGet = outputSize - 1; // We need to reserve some space for null @@ -119,7 +119,7 @@ int filext::filemgr::get(const std::string& fName, const char* key, string& outV if (searchKey != finfo->m_map.end()) { // Key is found in map string* value = &searchKey->second; - LOG(" Key found, size: %i\n", (unsigned int) value->size()); + LOG(" Key found, size: %i", (unsigned int) value->size()); // Check if we were reading same key previously if (finfo->m_currentGetKey != keyStr || reset) { @@ -132,7 +132,7 @@ int filext::filemgr::get(const std::string& fName, const char* key, string& outV nBytesToGet = (unsigned int)(value->size()) - finfo->m_currentGetID; } - LOG(" Returning bytes: %i\n", nBytesToGet); + LOG(" Returning bytes: %i", nBytesToGet); // Read up to outputSize bytes outValue = value->substr(finfo->m_currentGetID, nBytesToGet); @@ -149,11 +149,11 @@ int filext::filemgr::get(const std::string& fName, const char* key, string& outV return FILEXT_GET_MORE_AVAILABLE; } } else { - LOG(" Key %s was not found\n", key); + LOG(" Key %s was not found", key); return FILEXT_ERROR_KEY_NOT_FOUND; } } else { - LOG(" File is not open\n"); + LOG(" File is not open"); // Return error return FILEXT_ERROR_FILE_NOT_OPEN; } @@ -161,7 +161,7 @@ int filext::filemgr::get(const std::string& fName, const char* key, string& outV int filext::filemgr::write(const std::string& fName) { - LOG("write(%s)\n", fName.c_str()); + LOG("write(%s)", fName.c_str()); // Check if this file is already open string fNameStr(fName); @@ -185,7 +185,7 @@ int filext::filemgr::write(const std::string& fName) const string* key = &(iter->first); const string* val = &(iter->second); - LOG(" writing %s, size: %i\n", iter->first.c_str(), (int)val->size()); + LOG(" writing %s, size: %i", iter->first.c_str(), (int)val->size()); f.write(key->data(), key->size()); f.write(endKey, sizeof(endKey)); @@ -195,12 +195,12 @@ int filext::filemgr::write(const std::string& fName) return FILEXT_SUCCESS; } else { - LOG(" Error writing file: file is not open\n"); + LOG(" Error writing file: file is not open"); return FILEXT_ERROR_WRITE; } } else { - LOG(" File is not open\n"); + LOG(" File is not open"); // Return error return FILEXT_ERROR_FILE_NOT_OPEN; } @@ -209,7 +209,7 @@ int filext::filemgr::write(const std::string& fName) int filext::filemgr::read(const std::string& fName) { - LOG("read(%s)\n", fName.c_str()); + LOG("read(%s)", fName.c_str()); // Check if this file is already open string fNameStr(fName); @@ -225,22 +225,22 @@ int filext::filemgr::read(const std::string& fName) f.seekg(0); f.read((char*)&header, sizeof(fileHeader)); bool magicNumberOk = header.magicNumber == FILEXT_HEADER_MAGIC_NUMBER; - LOG("size: %i, version: %i, magic number ok: %i\n", header.size, header.version, (int)magicNumberOk); + LOG("size: %i, version: %i, magic number ok: %i", header.size, header.version, (int)magicNumberOk); // Bail if header is wrong if (!magicNumberOk) { - LOG("Error: Magic number mismatch!\n"); + LOG("Error: Magic number mismatch!"); return FILEXT_ERROR_WRONG_FILE_FORMAT; } // Bail if version is not supported if (header.version != 1) { - LOG("Error: version is not supported!\n"); + LOG("Error: version is not supported!"); return FILEXT_ERROR_WRONG_FILE_FORMAT; } // Read content into RAM - LOG(" File was found in file system. Reading content... \n"); + LOG(" File was found in file system. Reading content... "); f.seekg(0, std::ios::end); unsigned int contentSize = (unsigned int)f.tellg() - header.size; char* fContent = new char[contentSize]; @@ -267,23 +267,23 @@ int filext::filemgr::read(const std::string& fName) string val(&fContent[iValStart]); finfo->m_map[key] = val; - LOG(" Added %s: size: %i\n", key.c_str(), (int)val.size()); + LOG(" Added %s: size: %i", key.c_str(), (int)val.size()); }; delete[]fContent; - LOG(" Ended reading content\n"); + LOG(" Ended reading content"); return FILEXT_SUCCESS; } else { - LOG(" Error reading file: file is not open\n"); + LOG(" Error reading file: file is not open"); return FILEXT_ERROR_READ; }; } else { - LOG(" File is not open\n"); + LOG(" File is not open"); // Return error return FILEXT_ERROR_FILE_NOT_OPEN; }