Ticket #3011: squashed.patch
File squashed.patch, 357.4 KB (added by , 9 years ago) |
---|
-
build/premake/premake4.lua
From b934df2a59a4fb6fd56a36018349c948c1105e9e Mon Sep 17 00:00:00 2001 From: Philip Taylor <philip@zaynar.co.uk> Date: Tue, 20 Jan 2015 23:15:28 +0000 Subject: [PATCH] Everything squashed together. --- build/premake/premake4.lua | 3 +- source/graphics/ColladaManager.cpp | 32 +- source/graphics/FontManager.cpp | 6 +- source/graphics/LOSTexture.cpp | 4 +- source/graphics/MapGenerator.cpp | 22 +- source/graphics/MapReader.cpp | 14 +- source/graphics/MapWriter.cpp | 4 +- source/graphics/MeshManager.cpp | 4 +- source/graphics/Model.cpp | 2 +- source/graphics/ModelAbstract.cpp | 4 +- source/graphics/ObjectBase.cpp | 4 +- source/graphics/ObjectEntry.cpp | 12 +- source/graphics/ObjectManager.cpp | 2 +- source/graphics/ParticleEmitterType.cpp | 2 +- source/graphics/ShaderManager.cpp | 8 +- source/graphics/ShaderProgram.cpp | 18 +- source/graphics/ShaderProgramFFP.cpp | 2 +- source/graphics/SkeletonAnimManager.cpp | 8 +- source/graphics/TerrainProperties.cpp | 14 +- source/graphics/TerrainTextureEntry.cpp | 8 +- source/graphics/TerrainTextureManager.cpp | 6 +- source/graphics/TextRenderer.cpp | 8 + source/graphics/TextRenderer.h | 7 + source/graphics/TextureConverter.cpp | 26 +- source/graphics/TextureManager.cpp | 10 +- source/graphics/scripting/JSInterface_GameView.cpp | 4 +- source/graphics/tests/test_MeshManager.h | 4 +- source/gui/CGUI.cpp | 82 +- source/gui/CGUIScrollBarVertical.cpp | 2 +- source/gui/COList.cpp | 6 +- source/gui/GUIManager.cpp | 20 +- source/gui/GUIRenderer.cpp | 4 +- source/gui/GUITooltip.cpp | 10 +- source/gui/GUIbase.cpp | 6 +- source/gui/GUItext.cpp | 34 +- source/gui/GUIutil.cpp | 22 +- source/gui/IGUIObject.cpp | 2 +- source/gui/scripting/ScriptFunctions.cpp | 12 +- source/i18n/L10n.cpp | 14 +- source/lib/path.h | 7 + source/lib/secure_crt.cpp | 2 +- source/lib/self_test.h | 3 + source/lib/sysdep/os/linux/dir_watch_inotify.cpp | 4 +- source/lib/sysdep/os/unix/printf.cpp | 39 - source/lib/sysdep/os/win/wprintf.cpp | 526 ----- source/lib/sysdep/sysdep.h | 11 - source/lib/sysdep/tests/test_printf.h | 99 - source/lib/tests/test_secure_crt.h | 29 +- source/lobby/XmppClient.cpp | 8 +- source/main.cpp | 2 +- source/network/NetClient.cpp | 8 +- source/network/NetFileTransfer.cpp | 18 +- source/network/NetHost.cpp | 6 +- source/network/NetMessage.cpp | 6 +- source/network/NetServer.cpp | 42 +- source/network/NetSession.cpp | 6 +- source/network/NetTurnManager.cpp | 31 +- source/ps/CLogger.cpp | 119 +- source/ps/CLogger.h | 29 +- source/ps/CStrIntern.cpp | 2 +- source/ps/ConfigDB.cpp | 26 +- source/ps/DllLoader.cpp | 6 +- source/ps/FileIo.cpp | 2 +- source/ps/Filesystem.cpp | 2 +- source/ps/GameSetup/Config.cpp | 4 +- source/ps/GameSetup/GameSetup.cpp | 26 +- source/ps/GameSetup/HWDetect.cpp | 2 +- source/ps/GameSetup/Paths.cpp | 2 +- source/ps/Hotkey.cpp | 2 +- source/ps/Joystick.cpp | 10 +- source/ps/Overlay.cpp | 8 +- source/ps/Preprocessor.cpp | 4 +- source/ps/PreprocessorWrapper.cpp | 4 +- source/ps/ProfileViewer.cpp | 4 +- source/ps/Profiler2.cpp | 10 +- source/ps/SavedGame.cpp | 4 +- source/ps/TemplateLoader.cpp | 26 +- source/ps/Util.cpp | 8 +- source/ps/VideoMode.cpp | 22 +- source/ps/World.cpp | 2 +- source/ps/XML/RelaxNG.cpp | 10 +- source/ps/XML/XMLWriter.cpp | 2 +- source/ps/XML/Xeromyces.cpp | 14 +- source/ps/XML/tests/test_RelaxNG.h | 6 +- source/ps/scripting/JSInterface_ConfigDB.cpp | 2 +- source/ps/scripting/JSInterface_Console.cpp | 2 +- source/ps/scripting/JSInterface_VFS.cpp | 2 +- source/ps/tests/test_CLogger.h | 71 +- source/renderer/DecalRData.cpp | 4 +- source/renderer/ModelRenderer.cpp | 2 +- source/renderer/PatchRData.cpp | 2 +- source/renderer/PostprocManager.cpp | 8 +- source/renderer/Renderer.cpp | 12 +- source/renderer/ShadowMap.cpp | 4 +- source/renderer/SkyManager.cpp | 4 +- source/renderer/TerrainRenderer.cpp | 2 +- source/renderer/VertexBufferManager.cpp | 2 +- source/renderer/WaterManager.cpp | 6 +- source/scriptinterface/DebuggingServer.cpp | 4 +- source/scriptinterface/ScriptInterface.cpp | 36 +- source/scriptinterface/ThreadDebugger.cpp | 8 +- .../scriptinterface/tests/test_ScriptInterface.h | 10 +- source/simulation2/Simulation2.cpp | 14 +- source/simulation2/components/CCmpAIManager.cpp | 36 +- source/simulation2/components/CCmpCommandQueue.cpp | 4 +- source/simulation2/components/CCmpObstruction.cpp | 6 +- source/simulation2/components/CCmpPathfinder.cpp | 4 +- source/simulation2/components/CCmpPosition.cpp | 24 +- .../components/CCmpProjectileManager.cpp | 2 +- .../components/CCmpRallyPointRenderer.cpp | 2 +- source/simulation2/components/CCmpRangeManager.cpp | 16 +- .../simulation2/components/CCmpTemplateManager.cpp | 4 +- source/simulation2/components/CCmpUnitMotion.cpp | 2 +- source/simulation2/components/CCmpVisualActor.cpp | 6 +- source/simulation2/components/ICmpVisibility.cpp | 2 +- .../scripting/EngineScriptConversions.cpp | 2 +- .../scripting/MessageTypeConversions.cpp | 22 +- source/simulation2/scripting/ScriptComponent.cpp | 6 +- source/simulation2/scripting/ScriptComponent.h | 4 +- .../simulation2/serialization/BinarySerializer.cpp | 6 +- source/simulation2/system/ComponentManager.cpp | 18 +- .../system/ComponentManagerSerialization.cpp | 8 +- source/simulation2/system/ParamNode.cpp | 4 +- source/simulation2/tests/test_ComponentManager.h | 6 +- source/soundmanager/SoundManager.cpp | 10 +- source/soundmanager/data/OggData.cpp | 2 +- source/soundmanager/data/SoundData.cpp | 2 +- source/soundmanager/items/CSoundBase.cpp | 2 +- source/soundmanager/scripting/SoundGroup.cpp | 6 +- source/test_setup.cpp | 5 + source/third_party/cppformat/format.cpp | 1312 +++++++++++++ source/third_party/cppformat/format.h | 2077 ++++++++++++++++++++ source/tools/atlas/GameInterface/GameLoop.cpp | 2 +- .../atlas/GameInterface/Handlers/MapHandlers.cpp | 8 +- .../GameInterface/Handlers/ObjectHandlers.cpp | 2 +- 135 files changed, 4062 insertions(+), 1400 deletions(-) delete mode 100644 source/lib/sysdep/os/unix/printf.cpp delete mode 100644 source/lib/sysdep/os/win/wprintf.cpp delete mode 100644 source/lib/sysdep/tests/test_printf.h create mode 100644 source/third_party/cppformat/format.cpp create mode 100644 source/third_party/cppformat/format.h diff --git a/build/premake/premake4.lua b/build/premake/premake4.lua index 44dbd76..cfb6980 100644
a b function setup_all_libs () 741 741 "maths", 742 742 "maths/scripting", 743 743 "i18n", 744 "i18n/scripting" 744 "i18n/scripting", 745 "third_party/cppformat", 745 746 } 746 747 extern_libs = { 747 748 "spidermonkey", -
source/graphics/ColladaManager.cpp
diff --git a/source/graphics/ColladaManager.cpp b/source/graphics/ColladaManager.cpp index 35552e1..c7b806a 100644
a b namespace 42 42 VfsPath* path = static_cast<VfsPath*>(cb_data); 43 43 44 44 if (severity == LOG_INFO) 45 LOGMESSAGE( L"%ls: %hs", path->string().c_str(), text);45 LOGMESSAGE("%s: %s", path->string8(), text); 46 46 else if (severity == LOG_WARNING) 47 LOGWARNING( L"%ls: %hs", path->string().c_str(), text);47 LOGWARNING("%s: %s", path->string8(), text); 48 48 else 49 LOGERROR( L"%ls: %hs", path->string().c_str(), text);49 LOGERROR("%s: %s", path->string8(), text); 50 50 } 51 51 52 52 void ColladaOutput(void* cb_data, const char* data, unsigned int length) … … public: 99 99 if (!dll.IsLoaded() && !TryLoadDLL()) 100 100 return ERR::FAIL; 101 101 102 LOGMESSAGE( L"Hotloading skeleton definitions from '%ls'", path.string().c_str());102 LOGMESSAGE("Hotloading skeleton definitions from '%s'", path.string8()); 103 103 // Set the filename for the logger to report 104 104 set_logger(ColladaLog, const_cast<void*>(static_cast<const void*>(&path))); 105 105 106 106 CVFSFile skeletonFile; 107 107 if (skeletonFile.Load(m_VFS, path) != PSRETURN_OK) 108 108 { 109 LOGERROR( L"Failed to read skeleton defintions from '%ls'", path.string().c_str());109 LOGERROR("Failed to read skeleton defintions from '%s'", path.string8()); 110 110 return ERR::FAIL; 111 111 } 112 112 113 113 int ok = set_skeleton_definitions((const char*)skeletonFile.GetBuffer(), (int)skeletonFile.GetBufferSize()); 114 114 if (ok < 0) 115 115 { 116 LOGERROR( L"Failed to load skeleton definitions from '%ls'", path.string().c_str());116 LOGERROR("Failed to load skeleton definitions from '%s'", path.string8()); 117 117 return ERR::FAIL; 118 118 } 119 119 … … public: 189 189 { 190 190 if (!dll.LoadDLL()) 191 191 { 192 LOGERROR( L"Failed to load COLLADA conversion DLL");192 LOGERROR("Failed to load COLLADA conversion DLL"); 193 193 return false; 194 194 } 195 195 … … public: 202 202 } 203 203 catch (PSERROR_DllLoader&) 204 204 { 205 LOGERROR( L"Failed to load symbols from COLLADA conversion DLL");205 LOGERROR("Failed to load symbols from COLLADA conversion DLL"); 206 206 dll.Unload(); 207 207 return false; 208 208 } … … public: 214 214 VfsPaths pathnames; 215 215 if (vfs::GetPathnames(m_VFS, L"art/skeletons/", L"*.xml", pathnames) < 0) 216 216 { 217 LOGERROR( L"No skeleton definition files present");217 LOGERROR("No skeleton definition files present"); 218 218 return false; 219 219 } 220 220 221 221 bool loaded = false; 222 222 for (VfsPaths::const_iterator it = pathnames.begin(); it != pathnames.end(); ++it) 223 223 { 224 LOGMESSAGE( L"Loading skeleton definitions from '%ls'", it->string().c_str());224 LOGMESSAGE("Loading skeleton definitions from '%s'", it->string8()); 225 225 // Set the filename for the logger to report 226 226 set_logger(ColladaLog, const_cast<void*>(static_cast<const void*>(&(*it)))); 227 227 228 228 CVFSFile skeletonFile; 229 229 if (skeletonFile.Load(m_VFS, *it) != PSRETURN_OK) 230 230 { 231 LOGERROR( L"Failed to read skeleton defintions from '%ls'", it->string().c_str());231 LOGERROR("Failed to read skeleton defintions from '%s'", it->string8()); 232 232 continue; 233 233 } 234 234 235 235 int ok = set_skeleton_definitions((const char*)skeletonFile.GetBuffer(), (int)skeletonFile.GetBufferSize()); 236 236 if (ok < 0) 237 237 { 238 LOGERROR( L"Failed to load skeleton definitions from '%ls'", it->string().c_str());238 LOGERROR("Failed to load skeleton definitions from '%s'", it->string8()); 239 239 continue; 240 240 } 241 241 … … public: 243 243 } 244 244 245 245 if (!loaded) 246 LOGERROR( L"Failed to load any skeleton definitions");246 LOGERROR("Failed to load any skeleton definitions"); 247 247 248 248 return loaded; 249 249 } … … public: 267 267 VfsPaths paths; 268 268 if (vfs::GetPathnames(m_VFS, L"art/skeletons/", L"*.xml", paths) != INFO::OK) 269 269 { 270 LOGWARNING( L"Failed to load skeleton definitions");270 LOGWARNING("Failed to load skeleton definitions"); 271 271 return; 272 272 } 273 273 … … public: 287 287 // should never happen, unless there really is a problem 288 288 if (m_VFS->GetFileInfo(*it, &fileInfo) != INFO::OK) 289 289 { 290 LOGERROR( L"Failed to stat '%ls' for DAE caching", it->string().c_str());290 LOGERROR("Failed to stat '%s' for DAE caching", it->string8()); 291 291 } 292 292 else 293 293 { … … public: 298 298 299 299 // Check if we were able to load any skeleton files 300 300 if (m_skeletonHashes.empty()) 301 LOGERROR( L"Failed to stat any skeleton definitions for DAE caching");301 LOGERROR("Failed to stat any skeleton definitions for DAE caching"); 302 302 // We can continue, something else will break if we try loading a skeletal model 303 303 304 304 m_skeletonHashInvalidated = false; -
source/graphics/FontManager.cpp
diff --git a/source/graphics/FontManager.cpp b/source/graphics/FontManager.cpp index c7180ce..f7038c0 100644
a b bool CFontManager::ReadFont(CFont* font, CStrIntern fontName) 59 59 const VfsPath fntName(fontName.string() + ".fnt"); 60 60 if (g_VFS->LoadFile(path / fntName, buf, size) < 0) 61 61 { 62 LOGERROR( L"Failed to open font file %ls", (path / fntName).string().c_str());62 LOGERROR("Failed to open font file %s", (path / fntName).string8()); 63 63 return false; 64 64 } 65 65 std::istringstream FNTStream(std::string((const char*)buf.get(), size)); … … bool CFontManager::ReadFont(CFont* font, CStrIntern fontName) 68 68 FNTStream >> Version; 69 69 if (Version != 101) // Make sure this is from a recent version of the font builder 70 70 { 71 LOGERROR( L"Font %hs has invalid version", fontName.c_str());71 LOGERROR("Font %s has invalid version", fontName.c_str()); 72 72 return 0; 73 73 } 74 74 … … bool CFontManager::ReadFont(CFont* font, CStrIntern fontName) 102 102 103 103 if (Codepoint < 0 || Codepoint > 0xFFFF) 104 104 { 105 LOGWARNING( L"Font %hs has invalid codepoint 0x%x", fontName.c_str(), Codepoint);105 LOGWARNING("Font %s has invalid codepoint 0x%x", fontName.c_str(), Codepoint); 106 106 continue; 107 107 } 108 108 -
source/graphics/LOSTexture.cpp
diff --git a/source/graphics/LOSTexture.cpp b/source/graphics/LOSTexture.cpp index 2bde7bb..ce6e136 100644
a b bool CLOSTexture::CreateShader() 82 82 83 83 if (!m_ShaderInitialized) 84 84 { 85 LOGERROR( L"Failed to load SmoothLOS shader, disabling.");85 LOGERROR("Failed to load SmoothLOS shader, disabling."); 86 86 g_Renderer.m_Options.m_SmoothLOS = false; 87 87 return false; 88 88 } … … void CLOSTexture::InterpolateLOS() 163 163 GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 164 164 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) 165 165 { 166 LOGWARNING( L"LOS framebuffer object incomplete: 0x%04X", status);166 LOGWARNING("LOS framebuffer object incomplete: 0x%04X", status); 167 167 } 168 168 169 169 m_smoothShader->BeginPass(); -
source/graphics/MapGenerator.cpp
diff --git a/source/graphics/MapGenerator.cpp b/source/graphics/MapGenerator.cpp index 780ca79..ed9a8d0 100644
a b bool CMapGeneratorWorker::Run() 111 111 JS::RootedValue settingsVal(cx); 112 112 if (!m_ScriptInterface->ParseJSON(m_Settings, &settingsVal) && settingsVal.isUndefined()) 113 113 { 114 LOGERROR( L"CMapGeneratorWorker::Run: Failed to parse settings");114 LOGERROR("CMapGeneratorWorker::Run: Failed to parse settings"); 115 115 return false; 116 116 } 117 117 … … bool CMapGeneratorWorker::Run() 119 119 u32 seed; 120 120 if (!m_ScriptInterface->GetProperty(settingsVal, "Seed", seed)) 121 121 { // No seed specified 122 LOGWARNING( L"CMapGeneratorWorker::Run: No seed value specified - using 0");122 LOGWARNING("CMapGeneratorWorker::Run: No seed value specified - using 0"); 123 123 seed = 0; 124 124 } 125 125 … … bool CMapGeneratorWorker::Run() 129 129 JS::RootedValue global(cx, m_ScriptInterface->GetGlobalObject()); 130 130 if (!m_ScriptInterface->SetProperty(global, "g_MapSettings", settingsVal)) 131 131 { 132 LOGERROR( L"CMapGeneratorWorker::Run: Failed to define g_MapSettings");132 LOGERROR("CMapGeneratorWorker::Run: Failed to define g_MapSettings"); 133 133 return false; 134 134 } 135 135 136 136 // Load RMS 137 LOGMESSAGE( L"Loading RMS '%ls'", m_ScriptPath.string().c_str());137 LOGMESSAGE("Loading RMS '%s'", m_ScriptPath.string8()); 138 138 if (!m_ScriptInterface->LoadGlobalScriptFile(m_ScriptPath)) 139 139 { 140 LOGERROR( L"CMapGeneratorWorker::Run: Failed to load RMS '%ls'", m_ScriptPath.string().c_str());140 LOGERROR("CMapGeneratorWorker::Run: Failed to load RMS '%s'", m_ScriptPath.string8()); 141 141 return false; 142 142 } 143 143 … … std::vector<std::string> CMapGeneratorWorker::GetCivData(ScriptInterface::CxPriv 210 210 PSRETURN ret = file.Load(g_VFS, *it); 211 211 if (ret != PSRETURN_OK) 212 212 { 213 LOGERROR( L"CMapGeneratorWorker::GetCivData: Failed to load file '%ls': %hs", path.string().c_str(), GetErrorString(ret));213 LOGERROR("CMapGeneratorWorker::GetCivData: Failed to load file '%s': %s", path.string8(), GetErrorString(ret)); 214 214 } 215 215 else 216 216 { … … std::vector<std::string> CMapGeneratorWorker::GetCivData(ScriptInterface::CxPriv 222 222 { 223 223 // Some error reading directory 224 224 wchar_t error[200]; 225 LOGERROR( L"CMapGeneratorWorker::GetCivData: Error reading directory '%ls': %ls", path.string().c_str(), StatusDescription(ret, error, ARRAY_SIZE(error)));225 LOGERROR("CMapGeneratorWorker::GetCivData: Error reading directory '%s': %s", path.string8(), utf8_from_wstring(StatusDescription(ret, error, ARRAY_SIZE(error)))); 226 226 } 227 227 228 228 return data; … … CParamNode CMapGeneratorWorker::GetTemplate(ScriptInterface::CxPrivate* pCxPriva 234 234 CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(pCxPrivate->pCBData); 235 235 const CParamNode& templateRoot = self->m_TemplateLoader.GetTemplateFileData(templateName).GetChild("Entity"); 236 236 if (!templateRoot.IsOk()) 237 LOGERROR( L"Invalid template found for '%hs'", templateName.c_str());237 LOGERROR("Invalid template found for '%s'", templateName.c_str()); 238 238 239 239 return templateRoot; 240 240 } … … bool CMapGeneratorWorker::LoadScripts(const std::wstring& libraryName) 271 271 { 272 272 for (VfsPaths::iterator it = pathnames.begin(); it != pathnames.end(); ++it) 273 273 { 274 LOGMESSAGE( L"Loading map generator script '%ls'", it->string().c_str());274 LOGMESSAGE("Loading map generator script '%s'", it->string8()); 275 275 276 276 if (!m_ScriptInterface->LoadGlobalScriptFile(*it)) 277 277 { 278 LOGERROR( L"CMapGeneratorWorker::LoadScripts: Failed to load script '%ls'", it->string().c_str());278 LOGERROR("CMapGeneratorWorker::LoadScripts: Failed to load script '%s'", it->string8()); 279 279 return false; 280 280 } 281 281 } … … bool CMapGeneratorWorker::LoadScripts(const std::wstring& libraryName) 284 284 { 285 285 // Some error reading directory 286 286 wchar_t error[200]; 287 LOGERROR( L"CMapGeneratorWorker::LoadScripts: Error reading scripts in directory '%ls': %ls", path.string().c_str(), StatusDescription(ret, error, ARRAY_SIZE(error)));287 LOGERROR("CMapGeneratorWorker::LoadScripts: Error reading scripts in directory '%s': %s", path.string8(), utf8_from_wstring(StatusDescription(ret, error, ARRAY_SIZE(error)))); 288 288 return false; 289 289 } 290 290 -
source/graphics/MapReader.cpp
diff --git a/source/graphics/MapReader.cpp b/source/graphics/MapReader.cpp index 090b70e..9683323 100644
a b int CXMLReader::ReadEntities(XMBElement parent, double end_time) 1052 1052 entity_id_t player = cmpPlayerManager->GetPlayerByID(PlayerID); 1053 1053 if (ent == INVALID_ENTITY || player == INVALID_ENTITY) 1054 1054 { // Don't add entities with invalid player IDs 1055 LOGERROR( L"Failed to load entity template '%ls'", TemplateName.c_str());1055 LOGERROR("Failed to load entity template '%s'", utf8_from_wstring(TemplateName)); 1056 1056 } 1057 1057 else 1058 1058 { … … int CMapReader::ParseTerrain() 1332 1332 // an error here should stop the loading process 1333 1333 #define GET_TERRAIN_PROPERTY(val, prop, out)\ 1334 1334 if (!pSimulation2->GetScriptInterface().GetProperty(val, #prop, out))\ 1335 { LOGERROR( L"CMapReader::ParseTerrain() failed to get '%hs' property", #prop);\1335 { LOGERROR("CMapReader::ParseTerrain() failed to get '%s' property", #prop);\ 1336 1336 throw PSERROR_Game_World_MapLoadFailed("Error parsing terrain data.\nCheck application log for details"); } 1337 1337 1338 1338 JS::RootedValue tmpMapData(cx, m_MapData.get()); // TODO: Check if this temporary root can be removed after SpiderMonkey 31 upgrade … … int CMapReader::ParseEntities() 1411 1411 std::vector<Entity> entities; 1412 1412 1413 1413 if (!pSimulation2->GetScriptInterface().GetProperty(tmpMapData, "entities", entities)) 1414 LOGWARNING( L"CMapReader::ParseEntities() failed to get 'entities' property");1414 LOGWARNING("CMapReader::ParseEntities() failed to get 'entities' property"); 1415 1415 1416 1416 CSimulation2& sim = *pSimulation2; 1417 1417 CmpPtr<ICmpPlayerManager> cmpPlayerManager(sim, SYSTEM_ENTITY); … … int CMapReader::ParseEntities() 1430 1430 entity_id_t player = cmpPlayerManager->GetPlayerByID(currEnt.playerID); 1431 1431 if (ent == INVALID_ENTITY || player == INVALID_ENTITY) 1432 1432 { // Don't add entities with invalid player IDs 1433 LOGERROR( L"Failed to load entity template '%ls'", currEnt.templateName.c_str());1433 LOGERROR("Failed to load entity template '%s'", utf8_from_wstring(currEnt.templateName)); 1434 1434 } 1435 1435 else 1436 1436 { … … int CMapReader::ParseEnvironment() 1476 1476 1477 1477 #define GET_ENVIRONMENT_PROPERTY(val, prop, out)\ 1478 1478 if (!pSimulation2->GetScriptInterface().GetProperty(val, #prop, out))\ 1479 LOGWARNING( L"CMapReader::ParseEnvironment() failed to get '%hs' property", #prop);1479 LOGWARNING("CMapReader::ParseEnvironment() failed to get '%s' property", #prop); 1480 1480 1481 1481 JS::RootedValue envObj(cx); 1482 1482 GET_ENVIRONMENT_PROPERTY(tmpMapData, Environment, &envObj) 1483 1483 1484 1484 if (envObj.isUndefined()) 1485 1485 { 1486 LOGWARNING( L"CMapReader::ParseEnvironment(): Environment settings not found");1486 LOGWARNING("CMapReader::ParseEnvironment(): Environment settings not found"); 1487 1487 return 0; 1488 1488 } 1489 1489 … … int CMapReader::ParseCamera() 1581 1581 1582 1582 #define GET_CAMERA_PROPERTY(val, prop, out)\ 1583 1583 if (!pSimulation2->GetScriptInterface().GetProperty(val, #prop, out))\ 1584 LOGWARNING( L"CMapReader::ParseCamera() failed to get '%hs' property", #prop);1584 LOGWARNING("CMapReader::ParseCamera() failed to get '%s' property", #prop); 1585 1585 1586 1586 JS::RootedValue tmpMapData(cx, m_MapData.get()); // TODO: Check if this temporary root can be removed after SpiderMonkey 31 upgrade 1587 1587 JS::RootedValue cameraObj(cx); -
source/graphics/MapWriter.cpp
diff --git a/source/graphics/MapWriter.cpp b/source/graphics/MapWriter.cpp index 6b00443..4259f3f 100644
a b void CMapWriter::SaveMap(const VfsPath& pathname, CTerrain* pTerrain, 71 71 } 72 72 catch (PSERROR_File_WriteFailed&) 73 73 { 74 LOGERROR( L"Failed to write map '%ls'", pathname.string().c_str());74 LOGERROR("Failed to write map '%s'", pathname.string8()); 75 75 return; 76 76 } 77 77 … … void CMapWriter::WriteXML(const VfsPath& filename, 447 447 } 448 448 } 449 449 if (!XML_StoreVFS(g_VFS, filename)) 450 LOGERROR( L"Failed to write map '%ls'", filename.string().c_str());450 LOGERROR("Failed to write map '%s'", filename.string8()); 451 451 } -
source/graphics/MeshManager.cpp
diff --git a/source/graphics/MeshManager.cpp b/source/graphics/MeshManager.cpp index 0a827d0..103c401 100644
a b CModelDefPtr CMeshManager::GetMesh(const VfsPath& pathname) 53 53 54 54 if (pmdFilename.empty()) 55 55 { 56 LOGERROR( L"Could not load mesh '%ls'", pathname.string().c_str());56 LOGERROR("Could not load mesh '%s'", pathname.string8()); 57 57 return CModelDefPtr(); 58 58 } 59 59 … … CModelDefPtr CMeshManager::GetMesh(const VfsPath& pathname) 65 65 } 66 66 catch (PSERROR_File&) 67 67 { 68 LOGERROR( L"Could not load mesh '%ls'", pmdFilename.string().c_str());68 LOGERROR("Could not load mesh '%s'", pmdFilename.string8()); 69 69 return CModelDefPtr(); 70 70 } 71 71 } -
source/graphics/Model.cpp
diff --git a/source/graphics/Model.cpp b/source/graphics/Model.cpp index 127bbd5..c4bb532 100644
a b bool CModel::SetAnimation(CSkeletonAnim* anim, bool once) 473 473 if (anim->m_AnimDef && anim->m_AnimDef->GetNumKeys() != m_pModelDef->GetNumBones()) 474 474 { 475 475 // mismatch between model's skeleton and animation's skeleton 476 LOGERROR( L"Mismatch between model's skeleton and animation's skeleton (%lu model bones != %lu animation keys)",476 LOGERROR("Mismatch between model's skeleton and animation's skeleton (%lu model bones != %lu animation keys)", 477 477 (unsigned long)m_pModelDef->GetNumBones(), (unsigned long)anim->m_AnimDef->GetNumKeys()); 478 478 return false; 479 479 } -
source/graphics/ModelAbstract.cpp
diff --git a/source/graphics/ModelAbstract.cpp b/source/graphics/ModelAbstract.cpp index aa56125..769de5d 100644
a b void CModelAbstract::CalcSelectionBox() 57 57 { 58 58 // TODO: unimplemented 59 59 m_SelectionBox.SetEmpty(); 60 LOGWARNING( L"[ModelAbstract] TODO: Cylinder selection boxes are not yet implemented. Use BOX or BOUNDS selection shapes instead.");60 LOGWARNING("[ModelAbstract] TODO: Cylinder selection boxes are not yet implemented. Use BOX or BOUNDS selection shapes instead."); 61 61 } 62 62 break; 63 63 default: 64 64 { 65 65 m_SelectionBox.SetEmpty(); 66 //LOGWARNING( L"[ModelAbstract] Unrecognized selection shape type: %ld", m_CustomSelectionShape->m_Type);66 //LOGWARNING("[ModelAbstract] Unrecognized selection shape type: %ld", m_CustomSelectionShape->m_Type); 67 67 debug_warn("[ModelAbstract] Unrecognized selection shape type"); 68 68 } 69 69 break; -
source/graphics/ObjectBase.cpp
diff --git a/source/graphics/ObjectBase.cpp b/source/graphics/ObjectBase.cpp index f55ff9a..c32e285 100644
a b bool CObjectBase::Load(const VfsPath& pathname) 90 90 91 91 if (root.GetNodeName() != el_actor) 92 92 { 93 LOGERROR( L"Invalid actor format (unrecognised root element '%hs')", XeroFile.GetElementString(root.GetNodeName()).c_str());93 LOGERROR("Invalid actor format (unrecognised root element '%s')", XeroFile.GetElementString(root.GetNodeName()).c_str()); 94 94 return false; 95 95 } 96 96 … … bool CObjectBase::Load(const VfsPath& pathname) 266 266 267 267 if (currentGroup->size() == 0) 268 268 { 269 LOGERROR( L"Actor group has zero variants ('%ls')", pathname.string().c_str());269 LOGERROR("Actor group has zero variants ('%s')", pathname.string8()); 270 270 } 271 271 272 272 ++currentGroup; -
source/graphics/ObjectEntry.cpp
diff --git a/source/graphics/ObjectEntry.cpp b/source/graphics/ObjectEntry.cpp index 16b4e48..fcd5113 100644
a b bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections 73 73 str << variation.color; 74 74 int r, g, b; 75 75 if (! (str >> r >> g >> b)) // Any trailing data is ignored 76 LOGERROR( L"Actor '%ls' has invalid RGB colour '%hs'", m_Base->m_ShortName.c_str(), variation.color.c_str());76 LOGERROR("Actor '%s' has invalid RGB colour '%s'", utf8_from_wstring(m_Base->m_ShortName), variation.color); 77 77 else 78 78 m_Color = CColor(r/255.0f, g/255.0f, b/255.0f, 1.0f); 79 79 } … … bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections 119 119 CModelDefPtr modeldef (objectManager.GetMeshManager().GetMesh(m_ModelName)); 120 120 if (!modeldef) 121 121 { 122 LOGERROR( L"CObjectEntry::BuildVariation(): Model %ls failed to load", m_ModelName.string().c_str());122 LOGERROR("CObjectEntry::BuildVariation(): Model %s failed to load", m_ModelName.string8()); 123 123 return false; 124 124 } 125 125 … … bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections 133 133 134 134 if (m_Samplers.size() == 0) 135 135 { 136 LOGERROR( L"Actor '%ls' has no textures.", m_Base->m_ShortName.c_str());136 LOGERROR("Actor '%s' has no textures.", utf8_from_wstring(m_Base->m_ShortName)); 137 137 } 138 138 139 139 std::vector<CObjectBase::Samp>::iterator samp; … … bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections 190 190 { 191 191 // start up idling 192 192 if (!model->SetAnimation(GetRandomAnimation("idle"))) 193 LOGERROR( L"Failed to set idle animation in model \"%ls\"", m_ModelName.string().c_str());193 LOGERROR("Failed to set idle animation in model \"%s\"", m_ModelName.string8()); 194 194 } 195 195 196 196 // build props - TODO, RC - need to fix up bounds here … … bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections 209 209 CObjectEntry* oe = objectManager.FindObjectVariation(prop.m_ModelName.c_str(), selections); 210 210 if (!oe) 211 211 { 212 LOGERROR( L"Failed to build prop model \"%ls\" on actor \"%ls\"", prop.m_ModelName.c_str(), m_Base->m_ShortName.c_str());212 LOGERROR("Failed to build prop model \"%s\" on actor \"%s\"", utf8_from_wstring(prop.m_ModelName), utf8_from_wstring(m_Base->m_ShortName)); 213 213 continue; 214 214 } 215 215 … … bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections 240 240 propmodel->ToCModel()->SetAnimation(oe->GetRandomAnimation("idle")); 241 241 } 242 242 else 243 LOGERROR( L"Failed to find matching prop point called \"%hs\" in model \"%ls\" for actor \"%ls\"", ppn.c_str(), m_ModelName.string().c_str(), m_Base->m_ShortName.c_str());243 LOGERROR("Failed to find matching prop point called \"%s\" in model \"%s\" for actor \"%s\"", ppn, m_ModelName.string8(), utf8_from_wstring(m_Base->m_ShortName)); 244 244 } 245 245 246 246 // setup flags -
source/graphics/ObjectManager.cpp
diff --git a/source/graphics/ObjectManager.cpp b/source/graphics/ObjectManager.cpp index b8bd6b8..9d23072 100644
a b CObjectBase* CObjectManager::FindObjectBase(const CStrW& objectname) 96 96 else 97 97 delete obj; 98 98 99 LOGERROR( L"CObjectManager::FindObjectBase(): Cannot find object '%ls'", objectname.c_str());99 LOGERROR("CObjectManager::FindObjectBase(): Cannot find object '%s'", utf8_from_wstring(objectname)); 100 100 101 101 return 0; 102 102 } -
source/graphics/ParticleEmitterType.cpp
diff --git a/source/graphics/ParticleEmitterType.cpp b/source/graphics/ParticleEmitterType.cpp index 657feed..46cc663 100644
a b int CParticleEmitterType::GetVariableID(const std::string& name) 329 329 if (name == "color.r") return VAR_COLOR_R; 330 330 if (name == "color.g") return VAR_COLOR_G; 331 331 if (name == "color.b") return VAR_COLOR_B; 332 LOGWARNING( L"Particle sets unknown variable '%hs'", name.c_str());332 LOGWARNING("Particle sets unknown variable '%s'", name.c_str()); 333 333 return -1; 334 334 } 335 335 -
source/graphics/ShaderManager.cpp
diff --git a/source/graphics/ShaderManager.cpp b/source/graphics/ShaderManager.cpp index 929123c..a65071d 100644
a b CShaderManager::CShaderManager() 49 49 TIMER_ACCRUE(tc_ShaderValidation); 50 50 CVFSFile grammar; 51 51 if (grammar.Load(g_VFS, L"shaders/program.rng") != PSRETURN_OK) 52 LOGERROR( L"Failed to read grammar shaders/program.rng");52 LOGERROR("Failed to read grammar shaders/program.rng"); 53 53 else 54 54 { 55 55 if (!m_Validator.LoadGrammar(grammar.GetAsString())) 56 LOGERROR( L"Failed to load grammar shaders/program.rng");56 LOGERROR("Failed to load grammar shaders/program.rng"); 57 57 } 58 58 } 59 59 #endif … … CShaderProgramPtr CShaderManager::LoadProgram(const char* name, const CShaderDef 77 77 CShaderProgramPtr program; 78 78 if (!NewProgram(name, defines, program)) 79 79 { 80 LOGERROR( L"Failed to load shader '%hs'", name);80 LOGERROR("Failed to load shader '%s'", name); 81 81 program = CShaderProgramPtr(); 82 82 } 83 83 … … CShaderTechniquePtr CShaderManager::LoadEffect(CStrIntern name, const CShaderDef 378 378 CShaderTechniquePtr tech(new CShaderTechnique()); 379 379 if (!NewEffect(name.c_str(), defines, tech)) 380 380 { 381 LOGERROR( L"Failed to load effect '%hs'", name.c_str());381 LOGERROR("Failed to load effect '%s'", name.c_str()); 382 382 tech = CShaderTechniquePtr(); 383 383 } 384 384 -
source/graphics/ShaderProgram.cpp
diff --git a/source/graphics/ShaderProgram.cpp b/source/graphics/ShaderProgram.cpp index 817ff41..55ffe5a 100644
a b public: 71 71 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos); 72 72 int errLine = std::count(code.begin(), code.begin() + std::min((int)code.length(), errPos + 1), '\n') + 1; 73 73 char* errStr = (char*)glGetString(GL_PROGRAM_ERROR_STRING_ARB); 74 LOGERROR( L"Failed to compile %hs program '%ls' (line %d):\n%hs", targetName, file.string().c_str(), errLine, errStr);74 LOGERROR("Failed to compile %s program '%s' (line %d):\n%s", targetName, file.string8(), errLine, errStr); 75 75 return false; 76 76 } 77 77 … … public: 310 310 pglGetShaderInfoLog(shader, length, NULL, infolog); 311 311 312 312 if (ok) 313 LOGMESSAGE( L"Info when compiling shader '%ls':\n%hs", file.string().c_str(), infolog);313 LOGMESSAGE("Info when compiling shader '%s':\n%s", file.string8(), infolog); 314 314 else 315 LOGERROR( L"Failed to compile shader '%ls':\n%hs", file.string().c_str(), infolog);315 LOGERROR("Failed to compile shader '%s':\n%s", file.string8(), infolog); 316 316 317 317 delete[] infolog; 318 318 } … … public: 357 357 pglGetProgramInfoLog(m_Program, length, NULL, infolog); 358 358 359 359 if (ok) 360 LOGMESSAGE( L"Info when linking program '%ls'+'%ls':\n%hs", m_VertexFile.string().c_str(), m_FragmentFile.string().c_str(), infolog);360 LOGMESSAGE("Info when linking program '%s'+'%s':\n%s", m_VertexFile.string8(), m_FragmentFile.string8(), infolog); 361 361 else 362 LOGERROR( L"Failed to link program '%ls'+'%ls':\n%hs", m_VertexFile.string().c_str(), m_FragmentFile.string().c_str(), infolog);362 LOGERROR("Failed to link program '%s'+'%s':\n%s", m_VertexFile.string8(), m_FragmentFile.string8(), infolog); 363 363 364 364 delete[] infolog; 365 365 } … … public: 561 561 else if (id.second == GL_FLOAT_VEC4) 562 562 pglUniform4fARB(id.first, v0, v1, v2, v3); 563 563 else 564 LOGERROR( L"CShaderProgramGLSL::Uniform(): Invalid uniform type (expected float, vec2, vec3, vec4)");564 LOGERROR("CShaderProgramGLSL::Uniform(): Invalid uniform type (expected float, vec2, vec3, vec4)"); 565 565 } 566 566 } 567 567 … … public: 572 572 if (id.second == GL_FLOAT_MAT4) 573 573 pglUniformMatrix4fvARB(id.first, 1, GL_FALSE, &v._11); 574 574 else 575 LOGERROR( L"CShaderProgramGLSL::Uniform(): Invalid uniform type (expected mat4)");575 LOGERROR("CShaderProgramGLSL::Uniform(): Invalid uniform type (expected mat4)"); 576 576 } 577 577 } 578 578 … … public: 583 583 if (id.second == GL_FLOAT_MAT4) 584 584 pglUniformMatrix4fvARB(id.first, count, GL_FALSE, &v->_11); 585 585 else 586 LOGERROR( L"CShaderProgramGLSL::Uniform(): Invalid uniform type (expected mat4)");586 LOGERROR("CShaderProgramGLSL::Uniform(): Invalid uniform type (expected mat4)"); 587 587 } 588 588 } 589 589 … … CShaderProgram::CShaderProgram(int streamflags) 663 663 const std::map<CStrIntern, int>& UNUSED(vertexIndexes), const std::map<CStrIntern, frag_index_pair_t>& UNUSED(fragmentIndexes), 664 664 int UNUSED(streamflags)) 665 665 { 666 LOGERROR( L"CShaderProgram::ConstructARB: '%ls'+'%ls': ARB shaders not supported on this device",666 LOGERROR("CShaderProgram::ConstructARB: '%s'+'%s': ARB shaders not supported on this device", 667 667 vertexFile.string().c_str(), fragmentFile.string().c_str()); 668 668 return NULL; 669 669 } -
source/graphics/ShaderProgramFFP.cpp
diff --git a/source/graphics/ShaderProgramFFP.cpp b/source/graphics/ShaderProgramFFP.cpp index a3ec42b..f46e629 100644
a b public: 1159 1159 if (id == "model_solid_tex") 1160 1160 return new CShaderProgramFFP_ModelSolidTex(defines); 1161 1161 1162 LOGERROR( L"CShaderProgram::ConstructFFP: '%hs': Invalid id", id.c_str());1162 LOGERROR("CShaderProgram::ConstructFFP: '%s': Invalid id", id.c_str()); 1163 1163 debug_warn(L"CShaderProgram::ConstructFFP: Invalid id"); 1164 1164 return NULL; 1165 1165 } -
source/graphics/SkeletonAnimManager.cpp
diff --git a/source/graphics/SkeletonAnimManager.cpp b/source/graphics/SkeletonAnimManager.cpp index 80bb336..fa4f121 100644
a b CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const VfsPath& pathname) 65 65 66 66 if (psaFilename.empty()) 67 67 { 68 LOGERROR( L"Could not load animation '%ls'", pathname.string().c_str());68 LOGERROR("Could not load animation '%s'", pathname.string8()); 69 69 def = NULL; 70 70 } 71 71 else … … CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const VfsPath& pathname) 76 76 } 77 77 catch (PSERROR_File&) 78 78 { 79 LOGERROR( L"Could not load animation '%ls'", psaFilename.string().c_str());79 LOGERROR("Could not load animation '%s'", psaFilename.string8()); 80 80 } 81 81 } 82 82 83 83 if (def) 84 LOGMESSAGE( L"CSkeletonAnimManager::GetAnimation(%ls): Loaded successfully", pathname.string().c_str());84 LOGMESSAGE("CSkeletonAnimManager::GetAnimation(%s): Loaded successfully", pathname.string8()); 85 85 else 86 LOGERROR( L"CSkeletonAnimManager::GetAnimation(%ls): Failed loading, marked file as bad", pathname.string().c_str());86 LOGERROR("CSkeletonAnimManager::GetAnimation(%s): Failed loading, marked file as bad", pathname.string8()); 87 87 88 88 // Add to map 89 89 m_Animations[name] = def; // NULL if failed to load - we won't try loading it again -
source/graphics/TerrainProperties.cpp
diff --git a/source/graphics/TerrainProperties.cpp b/source/graphics/TerrainProperties.cpp index e4bb788..3be85b7 100644
a b CTerrainPropertiesPtr CTerrainProperties::FromXML(const CTerrainPropertiesPtr& p 55 55 // Check that we've got the right kind of xml document 56 56 if (rootName != "Terrains") 57 57 { 58 LOGERROR( 59 L"TerrainProperties: Loading %ls: Root node is not terrains (found \"%hs\")", 60 pathname.string().c_str(), 61 rootName.c_str()); 58 LOGERROR("TerrainProperties: Loading %s: Root node is not terrains (found \"%s\")", 59 pathname.string8(), 60 rootName); 62 61 return CTerrainPropertiesPtr(); 63 62 } 64 63 … … CTerrainPropertiesPtr CTerrainProperties::FromXML(const CTerrainPropertiesPtr& p 80 79 } 81 80 else 82 81 { 83 LOGWARNING( 84 L"TerrainProperties: Loading %ls: Unexpected node %hs\n", 85 pathname.string().c_str(), 86 XeroFile.GetElementString(child.GetNodeName()).c_str()); 82 LOGWARNING("TerrainProperties: Loading %s: Unexpected node %s\n", 83 pathname.string8(), 84 XeroFile.GetElementString(child.GetNodeName())); 87 85 // Keep reading - typos shouldn't be showstoppers 88 86 } 89 87 } -
source/graphics/TerrainTextureEntry.cpp
diff --git a/source/graphics/TerrainTextureEntry.cpp b/source/graphics/TerrainTextureEntry.cpp index 7429dce..756fb2d 100644
a b CTerrainTextureEntry::CTerrainTextureEntry(CTerrainPropertiesPtr properties, con 47 47 CXeromyces XeroFile; 48 48 if (XeroFile.Load(g_VFS, path) != PSRETURN_OK) 49 49 { 50 LOGERROR( L"Terrain xml not found (%hs)", path.string().c_str());50 LOGERROR("Terrain xml not found (%s)", path.string8()); 51 51 return; 52 52 } 53 53 … … CTerrainTextureEntry::CTerrainTextureEntry(CTerrainPropertiesPtr properties, con 70 70 71 71 if (root.GetNodeName() != el_terrain) 72 72 { 73 LOGERROR( L"Invalid terrain format (unrecognised root element '%hs')", XeroFile.GetElementString(root.GetNodeName()).c_str());73 LOGERROR("Invalid terrain format (unrecognised root element '%s')", XeroFile.GetElementString(root.GetNodeName()).c_str()); 74 74 return; 75 75 } 76 76 … … void CTerrainTextureEntry::LoadAlphaMaps(VfsPath &amtype) 253 253 if (textures[i] < 0) 254 254 { 255 255 g_TexMan.m_TerrainAlphas.erase(it); 256 LOGERROR( (L"Failed to load alphamap: " + amtype.string()).c_str());256 LOGERROR("Failed to load alphamap: %s", amtype.string8()); 257 257 258 258 VfsPath standard("standard"); 259 259 if (path != standard) … … void CTerrainTextureEntry::LoadAlphaMaps(VfsPath &amtype) 362 362 result.m_hCompositeAlphaMap = hCompositeAlphaMap; 363 363 364 364 m_TerrainAlpha = it; 365 } 366 No newline at end of file 365 } -
source/graphics/TerrainTextureManager.cpp
diff --git a/source/graphics/TerrainTextureManager.cpp b/source/graphics/TerrainTextureManager.cpp index 5913c10..e7e3391 100644
a b CTerrainTextureEntry* CTerrainTextureManager::FindTexture(const CStr& tag_) 89 89 return m_TextureEntries[i]; 90 90 } 91 91 92 LOGWARNING( L"CTerrainTextureManager: Couldn't find terrain %hs", tag.c_str());92 LOGWARNING("CTerrainTextureManager: Couldn't find terrain %s", tag.c_str()); 93 93 return 0; 94 94 } 95 95 … … void CTerrainTextureManager::LoadTextures(const CTerrainPropertiesPtr& props, co 141 141 142 142 void CTerrainTextureManager::RecurseDirectory(const CTerrainPropertiesPtr& parentProps, const VfsPath& path) 143 143 { 144 //LOGMESSAGE( L"CTextureManager::RecurseDirectory(%ls)", path.string().c_str());144 //LOGMESSAGE("CTextureManager::RecurseDirectory(%s)", path.string8()); 145 145 146 146 CTerrainPropertiesPtr props; 147 147 … … void CTerrainTextureManager::RecurseDirectory(const CTerrainPropertiesPtr& paren 153 153 // No terrains.xml, or read failures -> use parent props (i.e. 154 154 if (!props) 155 155 { 156 LOGMESSAGE( L"CTerrainTextureManager::RecurseDirectory(%ls): no terrains.xml (or errors while loading) - using parent properties", path.string().c_str());156 LOGMESSAGE("CTerrainTextureManager::RecurseDirectory(%s): no terrains.xml (or errors while loading) - using parent properties", path.string8()); 157 157 props = parentProps; 158 158 } 159 159 -
source/graphics/TextRenderer.cpp
diff --git a/source/graphics/TextRenderer.cpp b/source/graphics/TextRenderer.cpp index 3149ed6..ae5ac69 100644
a b void CTextRenderer::Put(float x, float y, const wchar_t* buf) 144 144 PutString(x, y, new std::wstring(buf), true); 145 145 } 146 146 147 void CTextRenderer::Put(float x, float y, const char* buf) 148 { 149 if (buf[0] == 0) 150 return; // empty string; don't bother storing 151 152 PutString(x, y, new std::wstring(wstring_from_utf8(buf)), true); 153 } 154 147 155 void CTextRenderer::Put(float x, float y, const std::wstring* buf) 148 156 { 149 157 if (buf->empty()) -
source/graphics/TextRenderer.h
diff --git a/source/graphics/TextRenderer.h b/source/graphics/TextRenderer.h index ac4d3b1..0c096f9 100644
a b public: 91 91 /** 92 92 * Print text at (x,y) under the current transform. 93 93 * Does not alter the current transform. 94 * @p buf must be a UTF-8 string. 95 */ 96 void Put(float x, float y, const char* buf); 97 98 /** 99 * Print text at (x,y) under the current transform. 100 * Does not alter the current transform. 94 101 * @p buf must remain valid until Render() is called. 95 102 * (This should be used to minimise memory copies when possible.) 96 103 */ -
source/graphics/TextureConverter.cpp
diff --git a/source/graphics/TextureConverter.cpp b/source/graphics/TextureConverter.cpp index aadca03..3f9c7cb 100644
a b CTextureConverter::SettingsFile* CTextureConverter::LoadSettings(const VfsPath& 120 120 121 121 if (root.GetNodeName() != el_textures) 122 122 { 123 LOGERROR( L"Invalid texture settings file \"%ls\" (unrecognised root element)", path.string().c_str());123 LOGERROR("Invalid texture settings file \"%s\" (unrecognised root element)", path.string8()); 124 124 return NULL; 125 125 } 126 126 … … CTextureConverter::SettingsFile* CTextureConverter::LoadSettings(const VfsPath& 152 152 else if (v == "alpha") 153 153 p.settings.format = FMT_ALPHA; 154 154 else 155 LOGERROR( L"Invalid attribute value <file format='%hs'>", v.c_str());155 LOGERROR("Invalid attribute value <file format='%s'>", v.c_str()); 156 156 } 157 157 else if (attr.Name == at_mipmap) 158 158 { … … CTextureConverter::SettingsFile* CTextureConverter::LoadSettings(const VfsPath& 162 162 else if (v == "false") 163 163 p.settings.mipmap = MIP_FALSE; 164 164 else 165 LOGERROR( L"Invalid attribute value <file mipmap='%hs'>", v.c_str());165 LOGERROR("Invalid attribute value <file mipmap='%s'>", v.c_str()); 166 166 } 167 167 else if (attr.Name == at_normal) 168 168 { … … CTextureConverter::SettingsFile* CTextureConverter::LoadSettings(const VfsPath& 172 172 else if (v == "false") 173 173 p.settings.normal = NORMAL_FALSE; 174 174 else 175 LOGERROR( L"Invalid attribute value <file normal='%hs'>", v.c_str());175 LOGERROR("Invalid attribute value <file normal='%s'>", v.c_str()); 176 176 } 177 177 else if (attr.Name == at_alpha) 178 178 { … … CTextureConverter::SettingsFile* CTextureConverter::LoadSettings(const VfsPath& 184 184 else if (v == "transparency") 185 185 p.settings.alpha = ALPHA_TRANSPARENCY; 186 186 else 187 LOGERROR( L"Invalid attribute value <file alpha='%hs'>", v.c_str());187 LOGERROR("Invalid attribute value <file alpha='%s'>", v.c_str()); 188 188 } 189 189 else if (attr.Name == at_filter) 190 190 { … … CTextureConverter::SettingsFile* CTextureConverter::LoadSettings(const VfsPath& 196 196 else if (v == "kaiser") 197 197 p.settings.filter = FILTER_KAISER; 198 198 else 199 LOGERROR( L"Invalid attribute value <file filter='%hs'>", v.c_str());199 LOGERROR("Invalid attribute value <file filter='%s'>", v.c_str()); 200 200 } 201 201 else if (attr.Name == at_kaiserwidth) 202 202 { … … CTextureConverter::SettingsFile* CTextureConverter::LoadSettings(const VfsPath& 212 212 } 213 213 else 214 214 { 215 LOGERROR( L"Invalid attribute name <file %hs='...'>", XeroFile.GetAttributeString(attr.Name).c_str());215 LOGERROR("Invalid attribute name <file %s='...'>", XeroFile.GetAttributeString(attr.Name).c_str()); 216 216 } 217 217 } 218 218 … … bool CTextureConverter::ConvertTexture(const CTexturePtr& texture, const VfsPath 326 326 size_t fileSize; 327 327 if (m_VFS->LoadFile(src, file, fileSize) < 0) 328 328 { 329 LOGERROR( L"Failed to load texture \"%ls\"", src.string().c_str());329 LOGERROR("Failed to load texture \"%s\"", src.string8()); 330 330 return false; 331 331 } 332 332 333 333 Tex tex; 334 334 if (tex.decode(file, fileSize) < 0) 335 335 { 336 LOGERROR( L"Failed to decode texture \"%ls\"", src.string().c_str());336 LOGERROR("Failed to decode texture \"%s\"", src.string8()); 337 337 return false; 338 338 } 339 339 … … bool CTextureConverter::ConvertTexture(const CTexturePtr& texture, const VfsPath 345 345 // Convert to uncompressed 8-bit with no mipmaps 346 346 if (tex.transform_to((tex.m_Flags | TEX_GREY) & ~(TEX_DXT | TEX_MIPMAPS | TEX_ALPHA)) < 0) 347 347 { 348 LOGERROR( L"Failed to transform texture \"%ls\"", src.string().c_str());348 LOGERROR("Failed to transform texture \"%s\"", src.string8()); 349 349 return false; 350 350 } 351 351 } … … bool CTextureConverter::ConvertTexture(const CTexturePtr& texture, const VfsPath 356 356 // (plain_transform doesn't know how to construct the alpha channel) 357 357 if (tex.m_Flags & TEX_GREY) 358 358 { 359 LOGERROR( L"Failed to convert grayscale texture \"%ls\" - only RGB textures are currently supported", src.string().c_str());359 LOGERROR("Failed to convert grayscale texture \"%s\" - only RGB textures are currently supported", src.string8()); 360 360 return false; 361 361 } 362 362 363 363 // Convert to uncompressed BGRA with no mipmaps 364 364 if (tex.transform_to((tex.m_Flags | TEX_BGR | TEX_ALPHA) & ~(TEX_DXT | TEX_MIPMAPS)) < 0) 365 365 { 366 LOGERROR( L"Failed to transform texture \"%ls\"", src.string().c_str());366 LOGERROR("Failed to transform texture \"%s\"", src.string8()); 367 367 return false; 368 368 } 369 369 } … … bool CTextureConverter::ConvertTexture(const CTexturePtr& texture, const VfsPath 482 482 return true; 483 483 484 484 #else 485 LOGERROR( L"Failed to convert texture \"%ls\" (NVTT not available)", src.string().c_str());485 LOGERROR("Failed to convert texture \"%s\" (NVTT not available)", src.string8()); 486 486 return false; 487 487 #endif 488 488 } -
source/graphics/TextureManager.cpp
diff --git a/source/graphics/TextureManager.cpp b/source/graphics/TextureManager.cpp index bfccc8b..2adf7c9 100644
a b public: 178 178 Handle h = ogl_tex_load(m_VFS, path, RES_UNIQUE); 179 179 if (h <= 0) 180 180 { 181 LOGERROR( L"Texture failed to load; \"%ls\"", texture->m_Properties.m_Path.string().c_str());181 LOGERROR("Texture failed to load; \"%s\"", texture->m_Properties.m_Path.string8()); 182 182 183 183 // Replace with error texture to make it obvious 184 184 texture->SetHandle(m_ErrorHandle); … … public: 218 218 // Upload to GL 219 219 if (!m_DisableGL && ogl_tex_upload(h, texture->m_Properties.m_Format) < 0) 220 220 { 221 LOGERROR( L"Texture failed to upload: \"%ls\"", texture->m_Properties.m_Path.string().c_str());221 LOGERROR("Texture failed to upload: \"%s\"", texture->m_Properties.m_Path.string8()); 222 222 223 223 ogl_tex_free(h); 224 224 … … public: 277 277 278 278 // No source file or archive cache was found, so we can't load the 279 279 // real texture at all - return the error texture instead 280 LOGERROR( L"CCacheLoader failed to find archived or source file for: \"%ls\"", texture->m_Properties.m_Path.string().c_str());280 LOGERROR("CCacheLoader failed to find archived or source file for: \"%s\"", texture->m_Properties.m_Path.string8()); 281 281 texture->SetHandle(m_ErrorHandle); 282 282 return true; 283 283 } … … public: 299 299 PrepareCacheKey(texture, hash, version); 300 300 VfsPath looseCachePath = m_CacheLoader.LooseCachePath(sourcePath, hash, version); 301 301 302 // LOGWARNING( L"Converting texture \"%ls\"", srcPath.c_str());302 // LOGWARNING("Converting texture \"%s\"", srcPath.c_str()); 303 303 304 304 CTextureConverter::Settings settings = GetConverterSettings(texture); 305 305 … … public: 345 345 } 346 346 else 347 347 { 348 LOGERROR( L"Texture failed to convert: \"%ls\"", texture->m_Properties.m_Path.string().c_str());348 LOGERROR("Texture failed to convert: \"%s\"", texture->m_Properties.m_Path.string8()); 349 349 texture->SetHandle(m_ErrorHandle); 350 350 } 351 351 texture->m_State = CTexture::LOADED; -
source/graphics/scripting/JSInterface_GameView.cpp
diff --git a/source/graphics/scripting/JSInterface_GameView.cpp b/source/graphics/scripting/JSInterface_GameView.cpp index b5c0b13..22e1c7f 100644
a b bool JSI_GameView::Get##NAME##Enabled(ScriptInterface::CxPrivate* UNUSED(pCxPriv 28 28 { \ 29 29 if (!g_Game || !g_Game->GetView()) \ 30 30 { \ 31 LOGERROR( L"Trying to get a setting from GameView when it's not initialized!"); \31 LOGERROR("Trying to get a setting from GameView when it's not initialized!"); \ 32 32 return false; \ 33 33 } \ 34 34 return g_Game->GetView()->Get##NAME##Enabled(); \ … … void JSI_GameView::Set##NAME##Enabled(ScriptInterface::CxPrivate* UNUSED(pCxPriv 38 38 { \ 39 39 if (!g_Game || !g_Game->GetView()) \ 40 40 { \ 41 LOGERROR( L"Trying to set a setting of GameView when it's not initialized!"); \41 LOGERROR("Trying to set a setting of GameView when it's not initialized!"); \ 42 42 return; \ 43 43 } \ 44 44 g_Game->GetView()->Set##NAME##Enabled(Enabled); \ -
source/graphics/tests/test_MeshManager.h
diff --git a/source/graphics/tests/test_MeshManager.h b/source/graphics/tests/test_MeshManager.h index 4e59ba1..a35d3b3 100644
a b public: 190 190 191 191 CModelDefPtr modeldef = meshManager->GetMesh(testDAE); 192 192 TS_ASSERT(! modeldef); 193 TS_ASSERT_ WSTR_CONTAINS(logger.GetOutput(), L"parser error");193 TS_ASSERT_STR_CONTAINS(logger.GetOutput(), "parser error"); 194 194 } 195 195 196 196 void test_invalid_dae() … … public: 205 205 206 206 CModelDefPtr modeldef = meshManager->GetMesh(testDAE); 207 207 TS_ASSERT(! modeldef); 208 TS_ASSERT_ WSTR_CONTAINS(logger.GetOutput(), L"parser error");208 TS_ASSERT_STR_CONTAINS(logger.GetOutput(), "parser error"); 209 209 } 210 210 211 211 void test_load_nonexistent_pmd() -
source/gui/CGUI.cpp
diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp index 51e33f8..06e86d8 100644
a b void CGUI::Draw() 380 380 } 381 381 catch (PSERROR_GUI& e) 382 382 { 383 LOGERROR( L"GUI draw error: %hs", e.what());383 LOGERROR("GUI draw error: %s", e.what()); 384 384 } 385 385 } 386 386 … … void CGUI::LoadXmlFile(const VfsPath& Filename, boost::unordered_set<VfsPath>& P 969 969 } 970 970 catch (PSERROR_GUI& e) 971 971 { 972 LOGERROR( L"Errors loading GUI file %ls (%u)", Filename.string().c_str(), e.getCode());972 LOGERROR("Errors loading GUI file %s (%u)", Filename.string8(), e.getCode()); 973 973 return; 974 974 } 975 975 } … … void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec 1091 1091 if (!object) 1092 1092 { 1093 1093 // Report error that object was unsuccessfully loaded 1094 LOGERROR( L"GUI: Unrecognized object type \"%hs\"", type.c_str());1094 LOGERROR("GUI: Unrecognized object type \"%s\"", type.c_str()); 1095 1095 return; 1096 1096 } 1097 1097 … … void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec 1133 1133 { 1134 1134 // additional check 1135 1135 if (m_Styles.count(argStyle) == 0) 1136 LOGERROR( L"GUI: Trying to use style '%hs' that doesn't exist.", argStyle.c_str());1136 LOGERROR("GUI: Trying to use style '%s' that doesn't exist.", argStyle.c_str()); 1137 1137 else 1138 1138 object->LoadStyle(*this, argStyle); 1139 1139 } … … void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec 1185 1185 // Try setting the value 1186 1186 if (object->SetSetting(pFile->GetAttributeString(attr.Name), attr.Value.FromUTF8(), true) != PSRETURN_OK) 1187 1187 { 1188 LOGERROR( L"GUI: (object: %hs) Can't set \"%hs\" to \"%ls\"", object->GetPresentableName().c_str(), pFile->GetAttributeString(attr.Name).c_str(), attr.Value.FromUTF8().c_str());1188 LOGERROR("GUI: (object: %s) Can't set \"%s\" to \"%s\"", object->GetPresentableName(), pFile->GetAttributeString(attr.Name), attr.Value); 1189 1189 1190 1190 // This is not a fatal error 1191 1191 } … … void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec 1248 1248 CVFSFile scriptfile; 1249 1249 if (scriptfile.Load(g_VFS, filename) != PSRETURN_OK) 1250 1250 { 1251 LOGERROR( L"Error opening GUI script action file '%ls'", filename.c_str());1251 LOGERROR("Error opening GUI script action file '%s'", utf8_from_wstring(filename)); 1252 1252 throw PSERROR_GUI_JSOpenFailed(); 1253 1253 } 1254 1254 … … void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec 1293 1293 CStr attributeName(child.GetAttributes().GetNamedItem(attr_id)); // Read the attribute name. 1294 1294 if (attributeName.empty()) 1295 1295 { 1296 LOGERROR( L"GUI: ‘translatableAttribute’ XML element with empty ‘id’ XML attribute found. (object: %hs)", object->GetPresentableName().c_str());1296 LOGERROR("GUI: ‘translatableAttribute’ XML element with empty ‘id’ XML attribute found. (object: %s)", object->GetPresentableName().c_str()); 1297 1297 continue; 1298 1298 } 1299 1299 … … void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec 1320 1320 CStr attributeName(child.GetAttributes().GetNamedItem(attr_id)); // Read the attribute name. 1321 1321 if (attributeName.empty()) 1322 1322 { 1323 LOGERROR( L"GUI: ‘attribute’ XML element with empty ‘id’ XML attribute found. (object: %hs)", object->GetPresentableName().c_str());1323 LOGERROR("GUI: ‘attribute’ XML element with empty ‘id’ XML attribute found. (object: %s)", object->GetPresentableName().c_str()); 1324 1324 continue; 1325 1325 } 1326 1326 … … void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec 1348 1348 if (!filename.empty()) 1349 1349 { 1350 1350 if (!directory.empty()) 1351 LOGWARNING( L"GUI: Include element found with file name (%ls) and directory name (%ls). Only the file will be processed.", filename.c_str(), directory.c_str());1351 LOGWARNING("GUI: Include element found with file name (%s) and directory name (%s). Only the file will be processed.", utf8_from_wstring(filename), utf8_from_wstring(directory)); 1352 1352 1353 1353 Paths.insert(filename); 1354 1354 1355 1355 CXeromyces XeroIncluded; 1356 1356 if (XeroIncluded.Load(g_VFS, filename) != PSRETURN_OK) 1357 1357 { 1358 LOGERROR( L"GUI: Error reading included XML: '%ls'", filename.c_str());1358 LOGERROR("GUI: Error reading included XML: '%s'", utf8_from_wstring(filename)); 1359 1359 continue; 1360 1360 } 1361 1361 1362 1362 XMBElement node = XeroIncluded.GetRoot(); 1363 1363 if (node.GetNodeName() != XeroIncluded.GetElementID("object")) 1364 1364 { 1365 LOGERROR( L"GUI: Error reading included XML: '%ls', root element must have be of type 'object'.", filename.c_str());1365 LOGERROR("GUI: Error reading included XML: '%s', root element must have be of type 'object'.", utf8_from_wstring(filename)); 1366 1366 continue; 1367 1367 } 1368 1368 Xeromyces_ReadObject(node, &XeroIncluded, object, NameSubst, Paths, nesting_depth+1); … … void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec 1379 1379 CXeromyces XeroIncluded; 1380 1380 if (XeroIncluded.Load(g_VFS, *it) != PSRETURN_OK) 1381 1381 { 1382 LOGERROR( L"GUI: Error reading included XML: '%ls'", (*it).string().c_str());1382 LOGERROR("GUI: Error reading included XML: '%s'", (*it).string8()); 1383 1383 continue; 1384 1384 } 1385 1385 1386 1386 XMBElement node = XeroIncluded.GetRoot(); 1387 1387 if (node.GetNodeName() != XeroIncluded.GetElementID("object")) 1388 1388 { 1389 LOGERROR( L"GUI: Error reading included XML: '%ls', root element must have be of type 'object'.", (*it).string().c_str());1389 LOGERROR("GUI: Error reading included XML: '%s', root element must have be of type 'object'.", (*it).string8()); 1390 1390 continue; 1391 1391 } 1392 1392 Xeromyces_ReadObject(node, &XeroIncluded, object, NameSubst, Paths, nesting_depth+1); … … void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec 1394 1394 1395 1395 } 1396 1396 else 1397 LOGERROR( L"GUI: 'include' XML element must have valid 'file' or 'directory' attribute found. (object %hs)", object->GetPresentableName().c_str());1397 LOGERROR("GUI: 'include' XML element must have valid 'file' or 'directory' attribute found. (object %s)", object->GetPresentableName().c_str()); 1398 1398 } 1399 1399 else 1400 1400 { 1401 1401 // Try making the object read the tag. 1402 1402 if (!object->HandleAdditionalChildren(child, pFile)) 1403 1403 { 1404 LOGERROR( L"GUI: (object: %hs) Reading unknown children for its type", object->GetPresentableName().c_str());1404 LOGERROR("GUI: (object: %s) Reading unknown children for its type", object->GetPresentableName().c_str()); 1405 1405 } 1406 1406 } 1407 1407 } … … void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec 1442 1442 } 1443 1443 catch (PSERROR_GUI& e) 1444 1444 { 1445 LOGERROR( L"GUI error: %hs", e.what());1445 LOGERROR("GUI error: %s", e.what()); 1446 1446 } 1447 1447 } 1448 1448 … … void CGUI::Xeromyces_ReadScript(XMBElement Element, CXeromyces* pFile, boost::un 1491 1491 } 1492 1492 catch (PSERROR_Scripting& e) 1493 1493 { 1494 LOGERROR( L"GUI: Error executing script %ls: %hs", file.c_str(), e.what());1494 LOGERROR("GUI: Error executing script %s: %s", utf8_from_wstring(file), e.what()); 1495 1495 } 1496 1496 } 1497 1497 … … void CGUI::Xeromyces_ReadScript(XMBElement Element, CXeromyces* pFile, boost::un 1512 1512 } 1513 1513 catch (PSERROR_Scripting& e) 1514 1514 { 1515 LOGERROR( L"GUI: Error executing script %ls: %hs", (*it).string().c_str(), e.what());1515 LOGERROR("GUI: Error executing script %s: %s", (*it).string8(), e.what()); 1516 1516 } 1517 1517 } 1518 1518 } … … void CGUI::Xeromyces_ReadScript(XMBElement Element, CXeromyces* pFile, boost::un 1527 1527 } 1528 1528 catch (PSERROR_Scripting& e) 1529 1529 { 1530 LOGERROR( L"GUI: Error executing inline script: %hs", e.what());1530 LOGERROR("GUI: Error executing inline script: %s", e.what()); 1531 1531 } 1532 1532 } 1533 1533 … … void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile) 1547 1547 name = Element.GetAttributes().GetNamedItem( pFile->GetAttributeID("name") ); 1548 1548 1549 1549 if (m_Sprites.find(name) != m_Sprites.end()) 1550 LOGWARNING( L"GUI sprite name '%hs' used more than once; first definition will be discarded", name.c_str());1550 LOGWARNING("GUI sprite name '%s' used more than once; first definition will be discarded", name.c_str()); 1551 1551 1552 1552 // 1553 1553 // Read Children (the images) … … void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile) 1573 1573 { 1574 1574 if (effects) 1575 1575 { 1576 LOGERROR( L"GUI <sprite> must not have more than one <effect>");1576 LOGERROR("GUI <sprite> must not have more than one <effect>"); 1577 1577 } 1578 1578 else 1579 1579 { … … void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite 1636 1636 { 1637 1637 CClientArea ca; 1638 1638 if (!GUI<CClientArea>::ParseString(attr_value, ca)) 1639 LOGERROR( L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());1639 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); 1640 1640 else Image->m_Size = ca; 1641 1641 } 1642 1642 else … … void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite 1644 1644 { 1645 1645 CClientArea ca; 1646 1646 if (!GUI<CClientArea>::ParseString(attr_value, ca)) 1647 LOGERROR( L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());1647 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); 1648 1648 else Image->m_TextureSize = ca; 1649 1649 } 1650 1650 else … … void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite 1652 1652 { 1653 1653 CRect rect; 1654 1654 if (!GUI<CRect>::ParseString(attr_value, rect)) 1655 LOGERROR( L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());1655 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); 1656 1656 else Image->m_TexturePlacementInFile = rect; 1657 1657 } 1658 1658 else … … void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite 1660 1660 { 1661 1661 CSize size; 1662 1662 if (!GUI<CSize>::ParseString(attr_value, size)) 1663 LOGERROR( L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());1663 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); 1664 1664 else Image->m_CellSize = size; 1665 1665 } 1666 1666 else … … void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite 1668 1668 { 1669 1669 float val; 1670 1670 if (!GUI<float>::ParseString(attr_value, val)) 1671 LOGERROR( L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());1671 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); 1672 1672 else Image->m_FixedHAspectRatio = val; 1673 1673 } 1674 1674 else … … void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite 1676 1676 { 1677 1677 bool b; 1678 1678 if (!GUI<bool>::ParseString(attr_value, b)) 1679 LOGERROR( L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());1679 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); 1680 1680 else Image->m_RoundCoordinates = b; 1681 1681 } 1682 1682 else … … void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite 1689 1689 else if (attr_value == L"clamp_to_edge") 1690 1690 Image->m_WrapMode = GL_CLAMP_TO_EDGE; 1691 1691 else 1692 LOGERROR( L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());1692 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); 1693 1693 } 1694 1694 else 1695 1695 if (attr_name == "z_level") 1696 1696 { 1697 1697 float z_level; 1698 1698 if (!GUI<float>::ParseString(attr_value, z_level)) 1699 LOGERROR( L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());1699 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); 1700 1700 else Image->m_DeltaZ = z_level/100.f; 1701 1701 } 1702 1702 else … … void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite 1704 1704 { 1705 1705 CColor color; 1706 1706 if (!GUI<CColor>::ParseString(attr_value, color)) 1707 LOGERROR( L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());1707 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); 1708 1708 else Image->m_BackColor = color; 1709 1709 } 1710 1710 else … … void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite 1712 1712 { 1713 1713 CColor color; 1714 1714 if (!GUI<CColor>::ParseString(attr_value, color)) 1715 LOGERROR( L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());1715 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); 1716 1716 else Image->m_BorderColor = color; 1717 1717 } 1718 1718 else … … void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite 1720 1720 { 1721 1721 bool b; 1722 1722 if (!GUI<bool>::ParseString(attr_value, b)) 1723 LOGERROR( L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());1723 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); 1724 1724 else Image->m_Border = b; 1725 1725 } 1726 1726 else … … void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite 1739 1739 { 1740 1740 if (Image->m_Effects) 1741 1741 { 1742 LOGERROR( L"GUI <image> must not have more than one <effect>");1742 LOGERROR("GUI <image> must not have more than one <effect>"); 1743 1743 } 1744 1744 else 1745 1745 { … … void CGUI::Xeromyces_ReadEffects(XMBElement Element, CXeromyces* pFile, SGUIImag 1773 1773 { 1774 1774 CColor color; 1775 1775 if (!GUI<int>::ParseColor(attr_value, color, 0)) 1776 LOGERROR( L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());1776 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, utf8_from_wstring(attr_value)); 1777 1777 else effects.m_AddColor = color; 1778 1778 } 1779 1779 else if (attr_name == "grayscale") … … void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile) 1853 1853 { 1854 1854 bool b; 1855 1855 if (!GUI<bool>::ParseString(attr_value.FromUTF8(), b)) 1856 LOGERROR( L"GUI: Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str());1856 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, attr_value); 1857 1857 else 1858 1858 scrollbar.m_UseEdgeButtons = b; 1859 1859 } … … void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile) 1861 1861 { 1862 1862 float f; 1863 1863 if (!GUI<float>::ParseString(attr_value.FromUTF8(), f)) 1864 LOGERROR( L"GUI: Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str());1864 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, attr_value); 1865 1865 else 1866 1866 scrollbar.m_Width = f; 1867 1867 } … … void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile) 1870 1870 { 1871 1871 float f; 1872 1872 if (!GUI<float>::ParseString(attr_value.FromUTF8(), f)) 1873 LOGERROR( L"GUI: Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str());1873 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, attr_value); 1874 1874 else 1875 1875 scrollbar.m_MinimumBarSize = f; 1876 1876 } … … void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile) 1879 1879 { 1880 1880 float f; 1881 1881 if (!GUI<float>::ParseString(attr_value.FromUTF8(), f)) 1882 LOGERROR( L"GUI: Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str());1882 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name, attr_value); 1883 1883 else 1884 1884 scrollbar.m_MaximumBarSize = f; 1885 1885 } … … void CGUI::Xeromyces_ReadIcon(XMBElement Element, CXeromyces* pFile) 1952 1952 { 1953 1953 CSize size; 1954 1954 if (!GUI<CSize>::ParseString(attr_value.FromUTF8(), size)) 1955 LOGERROR( L"Error parsing '%hs' (\"%hs\") inside <icon>.", attr_name.c_str(), attr_value.c_str());1955 LOGERROR("Error parsing '%s' (\"%s\") inside <icon>.", attr_name, attr_value); 1956 1956 else 1957 1957 icon.m_Size = size; 1958 1958 } … … void CGUI::Xeromyces_ReadIcon(XMBElement Element, CXeromyces* pFile) 1960 1960 { 1961 1961 int cell_id; 1962 1962 if (!GUI<int>::ParseString(attr_value.FromUTF8(), cell_id)) 1963 LOGERROR( L"GUI: Error parsing '%hs' (\"%hs\") inside <icon>.", attr_name.c_str(), attr_value.c_str());1963 LOGERROR("GUI: Error parsing '%s' (\"%s\") inside <icon>.", attr_name, attr_value); 1964 1964 else 1965 1965 icon.m_CellID = cell_id; 1966 1966 } … … void CGUI::Xeromyces_ReadColor(XMBElement Element, CXeromyces* pFile) 2013 2013 // Try setting color to value 2014 2014 if (!color.ParseString(value)) 2015 2015 { 2016 LOGERROR( L"GUI: Unable to create custom color '%hs'. Invalid color syntax.", name.c_str());2016 LOGERROR("GUI: Unable to create custom color '%s'. Invalid color syntax.", name.c_str()); 2017 2017 } 2018 2018 else 2019 2019 { -
source/gui/CGUIScrollBarVertical.cpp
diff --git a/source/gui/CGUIScrollBarVertical.cpp b/source/gui/CGUIScrollBarVertical.cpp index 4e0efe6..4c5c6eb 100644
a b void CGUIScrollBarVertical::Draw() 51 51 { 52 52 if (!GetStyle()) 53 53 { 54 LOGWARNING( L"Attempt to draw scrollbar without a style.");54 LOGWARNING("Attempt to draw scrollbar without a style."); 55 55 return; 56 56 } 57 57 -
source/gui/COList.cpp
diff --git a/source/gui/COList.cpp b/source/gui/COList.cpp index 09ff828..d42ed1f 100644
a b bool COList::HandleAdditionalChildren(const XMBElement& child, CXeromyces* pFile 158 158 { 159 159 CColor color; 160 160 if (!GUI<CColor>::ParseString(attr_value.FromUTF8(), color)) 161 LOGERROR( L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());161 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); 162 162 else oDef.m_TextColor = color; 163 163 } 164 164 else if (attr_name == "id") … … bool COList::HandleAdditionalChildren(const XMBElement& child, CXeromyces* pFile 169 169 { 170 170 float width; 171 171 if (!GUI<float>::ParseString(attr_value.FromUTF8(), width)) 172 LOGERROR( L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());172 LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); 173 173 else 174 174 { 175 175 // Check if it's a relative value, and save as decimal if so. … … bool COList::HandleAdditionalChildren(const XMBElement& child, CXeromyces* pFile 215 215 } 216 216 else // Ignore. 217 217 { 218 LOGERROR( L"GUI: translatable attribute in olist def that isn't a heading. (object: %hs)", this->GetPresentableName().c_str());218 LOGERROR("GUI: translatable attribute in olist def that isn't a heading. (object: %s)", this->GetPresentableName().c_str()); 219 219 } 220 220 } 221 221 } -
source/gui/GUIManager.cpp
diff --git a/source/gui/GUIManager.cpp b/source/gui/GUIManager.cpp index d0999c7..4656f37 100644
a b void CGUIManager::PopPageCB(shared_ptr<ScriptInterface::StructuredClone> args) 117 117 scriptInterface->ReadStructuredClone(initDataClone, &initDataVal); 118 118 else 119 119 { 120 LOGERROR( L"Called PopPageCB when initData (which should contain the callback function name) isn't set!");120 LOGERROR("Called PopPageCB when initData (which should contain the callback function name) isn't set!"); 121 121 return; 122 122 } 123 123 124 124 if (!scriptInterface->HasProperty(initDataVal, "callback")) 125 125 { 126 LOGERROR( L"Called PopPageCB when the callback function name isn't set!");126 LOGERROR("Called PopPageCB when the callback function name isn't set!"); 127 127 return; 128 128 } 129 129 130 130 std::string callback; 131 131 if (!scriptInterface->GetProperty(initDataVal, "callback", callback)) 132 132 { 133 LOGERROR( L"Failed to get the callback property as a string from initData in PopPageCB!");133 LOGERROR("Failed to get the callback property as a string from initData in PopPageCB!"); 134 134 return; 135 135 } 136 136 137 137 JS::RootedValue global(cx, scriptInterface->GetGlobalObject()); 138 138 if (!scriptInterface->HasProperty(global, callback.c_str())) 139 139 { 140 LOGERROR( L"The specified callback function %hs does not exist in the page %ls", callback.c_str(), m_PageStack.back().name.c_str());140 LOGERROR("The specified callback function %s does not exist in the page %s", callback, utf8_from_wstring(m_PageStack.back().name)); 141 141 return; 142 142 } 143 143 … … void CGUIManager::PopPageCB(shared_ptr<ScriptInterface::StructuredClone> args) 146 146 scriptInterface->ReadStructuredClone(args, &argVal); 147 147 if (!scriptInterface->CallFunctionVoid(global, callback.c_str(), argVal)) 148 148 { 149 LOGERROR( L"Failed to call the callback function %hs in the page %ls", callback.c_str(), m_PageStack.back().name.c_str());149 LOGERROR("Failed to call the callback function %s in the page %s", callback, utf8_from_wstring(m_PageStack.back().name)); 150 150 return; 151 151 } 152 152 } … … void CGUIManager::LoadPage(SGUIPage& page) 204 204 205 205 if (root.GetNodeName() != elmt_page) 206 206 { 207 LOGERROR( L"GUI page '%ls' must have root element <page>", page.name.c_str());207 LOGERROR("GUI page '%s' must have root element <page>", utf8_from_wstring(page.name)); 208 208 return; 209 209 } 210 210 … … void CGUIManager::LoadPage(SGUIPage& page) 212 212 { 213 213 if (node.GetNodeName() != elmt_include) 214 214 { 215 LOGERROR( L"GUI page '%ls' must only have <include> elements inside <page>", page.name.c_str());215 LOGERROR("GUI page '%s' must only have <include> elements inside <page>", utf8_from_wstring(page.name)); 216 216 continue; 217 217 } 218 218 … … void CGUIManager::LoadPage(SGUIPage& page) 252 252 hotloadDataVal) 253 253 ) 254 254 { 255 LOGERROR( L"GUI page '%ls': Failed to call init() function", page.name.c_str());255 LOGERROR("GUI page '%s': Failed to call init() function", utf8_from_wstring(page.name)); 256 256 } 257 257 258 258 m_CurrentGUI = oldGUI; … … Status CGUIManager::ReloadChangedFile(const VfsPath& path) 264 264 { 265 265 if (it->inputs.count(path)) 266 266 { 267 LOGMESSAGE( L"GUI file '%ls' changed - reloading page '%ls'", path.string().c_str(), it->name.c_str());267 LOGMESSAGE("GUI file '%s' changed - reloading page '%s'", path.string8(), utf8_from_wstring(it->name)); 268 268 LoadPage(*it); 269 269 // TODO: this can crash if LoadPage runs an init script which modifies the page stack and breaks our iterators 270 270 } … … const CParamNode& CGUIManager::GetTemplate(const std::string& templateName) 407 407 { 408 408 const CParamNode& templateRoot = m_TemplateLoader.GetTemplateFileData(templateName).GetChild("Entity"); 409 409 if (!templateRoot.IsOk()) 410 LOGERROR( L"Invalid template found for '%hs'", templateName.c_str());410 LOGERROR("Invalid template found for '%s'", templateName.c_str()); 411 411 412 412 return templateRoot; 413 413 } -
source/gui/GUIRenderer.cpp
diff --git a/source/gui/GUIRenderer.cpp b/source/gui/GUIRenderer.cpp index 75b133a..88f3115 100644
a b void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, 144 144 // Check colour is valid 145 145 if (!GUI<CColor>::ParseString(value, color)) 146 146 { 147 LOGERROR( L"GUI: Error parsing sprite 'colour' (\"%ls\")", value.c_str());147 LOGERROR("GUI: Error parsing sprite 'colour' (\"%s\")", utf8_from_wstring(value)); 148 148 return; 149 149 } 150 150 … … void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, 167 167 else 168 168 { 169 169 // Otherwise, just complain and give up: 170 LOGERROR( L"Trying to use a sprite that doesn't exist (\"%hs\").", SpriteName.c_str());170 LOGERROR("Trying to use a sprite that doesn't exist (\"%s\").", SpriteName.c_str()); 171 171 return; 172 172 } 173 173 } -
source/gui/GUITooltip.cpp
diff --git a/source/gui/GUITooltip.cpp b/source/gui/GUITooltip.cpp index c560885..55907bc 100644
a b void GUITooltip::ShowTooltip(IGUIObject* obj, CPos pos, const CStr& style, CGUI* 149 149 IGUIObject* tooltipobj = gui->FindObjectByName("__tooltip_"+style); 150 150 if (! tooltipobj) 151 151 { 152 LOGERROR( L"Cannot find tooltip named '%hs'", style.c_str());152 LOGERROR("Cannot find tooltip named '%s'", style.c_str()); 153 153 return; 154 154 } 155 155 … … void GUITooltip::ShowTooltip(IGUIObject* obj, CPos pos, const CStr& style, CGUI* 162 162 usedobj = gui->FindObjectByName(usedObjectName); 163 163 if (! usedobj) 164 164 { 165 LOGERROR( L"Cannot find object named '%hs' used by tooltip '%hs'", usedObjectName.c_str(), style.c_str());165 LOGERROR("Cannot find object named '%s' used by tooltip '%s'", usedObjectName.c_str(), style.c_str()); 166 166 return; 167 167 } 168 168 … … void GUITooltip::HideTooltip(const CStr& style, CGUI* gui) 213 213 IGUIObject* tooltipobj = gui->FindObjectByName("__tooltip_"+style); 214 214 if (! tooltipobj) 215 215 { 216 LOGERROR( L"Cannot find tooltip named '%hs'", style.c_str());216 LOGERROR("Cannot find tooltip named '%s'", style.c_str()); 217 217 return; 218 218 } 219 219 … … void GUITooltip::HideTooltip(const CStr& style, CGUI* gui) 224 224 IGUIObject* usedobj = gui->FindObjectByName(usedObjectName); 225 225 if (! usedobj) 226 226 { 227 LOGERROR( L"Cannot find object named '%hs' used by tooltip '%hs'", usedObjectName.c_str(), style.c_str());227 LOGERROR("Cannot find object named '%s' used by tooltip '%s'", usedObjectName.c_str(), style.c_str()); 228 228 return; 229 229 } 230 230 … … static int GetTooltipDelay(CStr& style, CGUI* gui) 254 254 IGUIObject* tooltipobj = gui->FindObjectByName("__tooltip_"+style); 255 255 if (! tooltipobj) 256 256 { 257 LOGERROR( L"Cannot find tooltip object named '%hs'", style.c_str());257 LOGERROR("Cannot find tooltip object named '%s'", style.c_str()); 258 258 return delay; 259 259 } 260 260 GUI<int>::GetSetting(tooltipobj, "delay", delay); -
source/gui/GUIbase.cpp
diff --git a/source/gui/GUIbase.cpp b/source/gui/GUIbase.cpp index 491c2ec..4d730a0 100644
a b bool CClientArea::SetClientArea(const CStr& Value) 113 113 coord++; 114 114 break; 115 115 default: 116 LOGWARNING( L"ClientArea definitions may only contain numerics. Your input: '%hs'", Value.c_str());116 LOGWARNING("ClientArea definitions may only contain numerics. Your input: '%s'", Value.c_str()); 117 117 return false; 118 118 } 119 119 if (coord > 3) 120 120 { 121 LOGWARNING( L"Too many CClientArea parameters (4 max). Your input: '%hs'", Value.c_str());121 LOGWARNING("Too many CClientArea parameters (4 max). Your input: '%s'", Value.c_str()); 122 122 return false; 123 123 } 124 124 } 125 125 126 126 if (coord < 3) 127 127 { 128 LOGWARNING( L"Too few CClientArea parameters (4 min). Your input: '%hs'", Value.c_str());128 LOGWARNING("Too few CClientArea parameters (4 min). Your input: '%s'", Value.c_str()); 129 129 return false; 130 130 } 131 131 -
source/gui/GUItext.cpp
diff --git a/source/gui/GUItext.cpp b/source/gui/GUItext.cpp index 69d9f47..783bb30 100644
a b void CGUIString::GenerateTextCall(const CGUI *pGUI, 109 109 if (!pGUI->IconExists(path)) 110 110 { 111 111 if (pObject) 112 LOGERROR( L"Trying to use an icon, imgleft or imgright-tag with an undefined icon (\"%hs\").", path.c_str());112 LOGERROR("Trying to use an icon, imgleft or imgright-tag with an undefined icon (\"%s\").", path.c_str()); 113 113 continue; 114 114 } 115 115 … … void CGUIString::GenerateTextCall(const CGUI *pGUI, 158 158 CSize displacement; 159 159 // Parse the value 160 160 if (!GUI<CSize>::ParseString(tagAttrib.value, displacement)) 161 LOGERROR( L"Error parsing 'displace' value for tag [ICON]");161 LOGERROR("Error parsing 'displace' value for tag [ICON]"); 162 162 else 163 163 SpriteCall.m_Area += displacement; 164 164 } … … void CGUIString::GenerateTextCall(const CGUI *pGUI, 182 182 } 183 183 break; 184 184 default: 185 LOGERROR( L"Encountered unexpected tag applied to text");185 LOGERROR("Encountered unexpected tag applied to text"); 186 186 break; 187 187 } 188 188 } … … void CGUIString::GenerateTextCall(const CGUI *pGUI, 207 207 208 208 if (!GUI<CColor>::ParseString(it2->m_TagValue, TextCall.m_Color) 209 209 && pObject) 210 LOGERROR( L"Error parsing the value of a [color]-tag in GUI text when reading object \"%hs\".", pObject->GetPresentableName().c_str());210 LOGERROR("Error parsing the value of a [color]-tag in GUI text when reading object \"%s\".", pObject->GetPresentableName().c_str()); 211 211 break; 212 212 case CGUIString::TextChunk::Tag::TAG_FONT: 213 213 // TODO Gee: (2004-08-15) Check if Font exists? 214 214 TextCall.m_Font = CStrIntern(utf8_from_wstring(it2->m_TagValue)); 215 215 break; 216 216 default: 217 LOGERROR( L"Encountered unexpected tag applied to text");217 LOGERROR("Encountered unexpected tag applied to text"); 218 218 break; 219 219 } 220 220 } … … void CGUIString::SetValue(const CStrW& str) 306 306 closing = false; 307 307 if (++p == l) 308 308 { 309 LOGERROR( L"Partial tag at end of string '%ls'", str.c_str());309 LOGERROR("Partial tag at end of string '%s'", utf8_from_wstring(str)); 310 310 break; 311 311 } 312 312 if (str[p] == L'/') … … void CGUIString::SetValue(const CStrW& str) 314 314 closing = true; 315 315 if (tags.empty()) 316 316 { 317 LOGERROR( L"Encountered closing tag without having any open tags. At %d in '%ls'", p, str.c_str());317 LOGERROR("Encountered closing tag without having any open tags. At %d in '%s'", p, utf8_from_wstring(str)); 318 318 break; 319 319 } 320 320 if (++p == l) 321 321 { 322 LOGERROR( L"Partial closing tag at end of string '%ls'", str.c_str());322 LOGERROR("Partial closing tag at end of string '%s'", utf8_from_wstring(str)); 323 323 break; 324 324 } 325 325 } … … void CGUIString::SetValue(const CStrW& str) 332 332 { 333 333 case L' ': 334 334 if (closing) // We still parse them to make error handling cleaner 335 LOGERROR( L"Closing tags do not support parameters (at pos %d '%ls')", p, str.c_str());335 LOGERROR("Closing tags do not support parameters (at pos %d '%s')", p, utf8_from_wstring(str)); 336 336 337 337 // parse something="something else" 338 338 for (++p; p < l && str[p] != L'='; ++p) … … void CGUIString::SetValue(const CStrW& str) 340 340 341 341 if (p == l) 342 342 { 343 LOGERROR( L"Parameter without value at pos %d '%ls'", p, str.c_str());343 LOGERROR("Parameter without value at pos %d '%s'", p, utf8_from_wstring(str)); 344 344 break; 345 345 } 346 346 // fall-through 347 347 case L'=': 348 348 // parse a quoted parameter 349 349 if (closing) // We still parse them to make error handling cleaner 350 LOGERROR( L"Closing tags do not support parameters (at pos %d '%ls')", p, str.c_str());350 LOGERROR("Closing tags do not support parameters (at pos %d '%s')", p, utf8_from_wstring(str)); 351 351 352 352 if (++p == l) 353 353 { 354 LOGERROR( L"Expected parameter, got end of string '%ls'", str.c_str());354 LOGERROR("Expected parameter, got end of string '%s'", utf8_from_wstring(str)); 355 355 break; 356 356 } 357 357 if (str[p] != L'"') 358 358 { 359 LOGERROR( L"Unquoted parameters are not supported (at pos %d '%ls')", p, str.c_str());359 LOGERROR("Unquoted parameters are not supported (at pos %d '%s')", p, utf8_from_wstring(str)); 360 360 break; 361 361 } 362 362 for (++p; p < l && str[p] != L'"'; ++p) … … void CGUIString::SetValue(const CStrW& str) 366 366 case L'\\': 367 367 if (++p == l) 368 368 { 369 LOGERROR( L"Escape character at end of string '%ls'", str.c_str());369 LOGERROR("Escape character at end of string '%s'", utf8_from_wstring(str)); 370 370 break; 371 371 } 372 372 // NOTE: We do not support \n in tag parameters … … void CGUIString::SetValue(const CStrW& str) 392 392 393 393 if (!tag_.SetTagType(tag)) 394 394 { 395 LOGERROR( L"Invalid tag '%ls' at %d in '%ls'", tag.c_str(), p, str.c_str());395 LOGERROR("Invalid tag '%s' at %d in '%s'", utf8_from_wstring(tag), p, utf8_from_wstring(str)); 396 396 break; 397 397 } 398 398 if (!closing) … … void CGUIString::SetValue(const CStrW& str) 415 415 { 416 416 if (tag != tags.back()) 417 417 { 418 LOGERROR( L"Closing tag '%ls' does not match last opened tag '%ls' at %d in '%ls'", tag.c_str(), tags.back().c_str(), p, str.c_str());418 LOGERROR("Closing tag '%s' does not match last opened tag '%s' at %d in '%s'", utf8_from_wstring(tag), utf8_from_wstring(tags.back()), p, utf8_from_wstring(str)); 419 419 break; 420 420 } 421 421 … … void CGUIString::SetValue(const CStrW& str) 426 426 case L'\\': 427 427 if (++p == l) 428 428 { 429 LOGERROR( L"Escape character at end of string '%ls'", str.c_str());429 LOGERROR("Escape character at end of string '%s'", utf8_from_wstring(str)); 430 430 break; 431 431 } 432 432 if (str[p] == L'n') -
source/gui/GUIutil.cpp
diff --git a/source/gui/GUIutil.cpp b/source/gui/GUIutil.cpp index 009c702..95ff0fd 100644
a b bool __ParseString<CRect>(const CStrW& Value, CRect &Output) 69 69 { 70 70 if (stream.eof()) 71 71 { 72 LOGWARNING( L"Too few CRect parameters (min %i). Your input: '%hs'", NUM_COORDS, Value.ToUTF8().c_str());72 LOGWARNING("Too few CRect parameters (min %i). Your input: '%s'", NUM_COORDS, Value.ToUTF8().c_str()); 73 73 return false; 74 74 } 75 75 stream >> coords[i]; 76 76 if ((stream.rdstate() & std::wstringstream::failbit) != 0) 77 77 { 78 LOGWARNING( L"Unable to parse CRect parameters. Your input: '%hs'", Value.ToUTF8().c_str());78 LOGWARNING("Unable to parse CRect parameters. Your input: '%s'", Value.ToUTF8().c_str()); 79 79 return false; 80 80 } 81 81 } 82 82 83 83 if (!stream.eof()) 84 84 { 85 LOGWARNING( L"Too many CRect parameters (max %i). Your input: '%hs'", NUM_COORDS, Value.ToUTF8().c_str());85 LOGWARNING("Too many CRect parameters (max %i). Your input: '%s'", NUM_COORDS, Value.ToUTF8().c_str()); 86 86 return false; 87 87 } 88 88 … … bool __ParseString<CSize>(const CStrW& Value, CSize &Output) 134 134 { 135 135 if (stream.eof()) 136 136 { 137 LOGWARNING( L"Too few CSize parameters (min %i). Your input: '%hs'", NUM_COORDS, Value.ToUTF8().c_str());137 LOGWARNING("Too few CSize parameters (min %i). Your input: '%s'", NUM_COORDS, Value.ToUTF8().c_str()); 138 138 return false; 139 139 } 140 140 stream >> coords[i]; 141 141 if ((stream.rdstate() & std::wstringstream::failbit) != 0) 142 142 { 143 LOGWARNING( L"Unable to parse CSize parameters. Your input: '%hs'", Value.ToUTF8().c_str());143 LOGWARNING("Unable to parse CSize parameters. Your input: '%s'", Value.ToUTF8().c_str()); 144 144 return false; 145 145 } 146 146 } … … bool __ParseString<CSize>(const CStrW& Value, CSize &Output) 150 150 151 151 if (!stream.eof()) 152 152 { 153 LOGWARNING( L"Too many CSize parameters (max %i). Your input: '%hs'", NUM_COORDS, Value.ToUTF8().c_str());153 LOGWARNING("Too many CSize parameters (max %i). Your input: '%s'", NUM_COORDS, Value.ToUTF8().c_str()); 154 154 return false; 155 155 } 156 156 … … bool __ParseString<CPos>(const CStrW& Value, CPos &Output) 169 169 { 170 170 if (stream.eof()) 171 171 { 172 LOGWARNING( L"Too few CPos parameters (min %i). Your input: '%hs'", NUM_COORDS, Value.ToUTF8().c_str());172 LOGWARNING("Too few CPos parameters (min %i). Your input: '%s'", NUM_COORDS, Value.ToUTF8().c_str()); 173 173 return false; 174 174 } 175 175 stream >> coords[i]; 176 176 if ((stream.rdstate() & std::wstringstream::failbit) != 0) 177 177 { 178 LOGWARNING( L"Unable to parse CPos parameters. Your input: '%hs'", Value.ToUTF8().c_str());178 LOGWARNING("Unable to parse CPos parameters. Your input: '%s'", Value.ToUTF8().c_str()); 179 179 return false; 180 180 } 181 181 } … … bool __ParseString<CPos>(const CStrW& Value, CPos &Output) 185 185 186 186 if (!stream.eof()) 187 187 { 188 LOGWARNING( L"Too many CPos parameters (max %i). Your input: '%hs'", NUM_COORDS, Value.ToUTF8().c_str());188 LOGWARNING("Too many CPos parameters (max %i). Your input: '%s'", NUM_COORDS, Value.ToUTF8().c_str()); 189 189 return false; 190 190 } 191 191 … … PSRETURN GUI<T>::GetSettingPointer(const IGUIObject *pObject, const CStr& Settin 339 339 std::map<CStr, SGUISetting>::const_iterator it = pObject->m_Settings.find(Setting); 340 340 if (it == pObject->m_Settings.end()) 341 341 { 342 LOGWARNING( L"setting %hs was not found on object %hs",342 LOGWARNING("setting %s was not found on object %s", 343 343 Setting.c_str(), 344 344 pObject->GetPresentableName().c_str()); 345 345 return PSRETURN_GUI_InvalidSetting; … … PSRETURN GUI<T>::SetSetting(IGUIObject *pObject, const CStr& Setting, 388 388 389 389 if (!pObject->SettingExists(Setting)) 390 390 { 391 LOGWARNING( L"setting %hs was not found on object %hs",391 LOGWARNING("setting %s was not found on object %s", 392 392 Setting.c_str(), 393 393 pObject->GetPresentableName().c_str()); 394 394 return PSRETURN_GUI_InvalidSetting; -
source/gui/IGUIObject.cpp
diff --git a/source/gui/IGUIObject.cpp b/source/gui/IGUIObject.cpp index d32cb28..091cdd3 100644
a b bool IGUIObject::IsRootObject() const 561 561 562 562 PSRETURN IGUIObject::LogInvalidSettings(const CStr8 &Setting) const 563 563 { 564 LOGWARNING( L"IGUIObject: setting %hs was not found on an object",564 LOGWARNING("IGUIObject: setting %s was not found on an object", 565 565 Setting.c_str()); 566 566 return PSRETURN_GUI_InvalidSetting; 567 567 } -
source/gui/scripting/ScriptFunctions.cpp
diff --git a/source/gui/scripting/ScriptFunctions.cpp b/source/gui/scripting/ScriptFunctions.cpp index 1f7f309..ad56e91 100644
a b void SaveGame(ScriptInterface::CxPrivate* pCxPrivate, std::wstring filename, std 308 308 309 309 shared_ptr<ScriptInterface::StructuredClone> GUIMetadataClone = pCxPrivate->pScriptInterface->WriteStructuredClone(GUIMetadata); 310 310 if (SavedGames::Save(filename, description, *g_Game->GetSimulation2(), GUIMetadataClone, g_Game->GetPlayerID()) < 0) 311 LOGERROR( L"Failed to save game");311 LOGERROR("Failed to save game"); 312 312 } 313 313 314 314 void SaveGamePrefix(ScriptInterface::CxPrivate* pCxPrivate, std::wstring prefix, std::wstring description, CScriptVal GUIMetadata1) … … void SaveGamePrefix(ScriptInterface::CxPrivate* pCxPrivate, std::wstring prefix, 320 320 321 321 shared_ptr<ScriptInterface::StructuredClone> GUIMetadataClone = pCxPrivate->pScriptInterface->WriteStructuredClone(GUIMetadata); 322 322 if (SavedGames::SavePrefix(prefix, description, *g_Game->GetSimulation2(), GUIMetadataClone, g_Game->GetPlayerID()) < 0) 323 LOGERROR( L"Failed to save game");323 LOGERROR("Failed to save game"); 324 324 } 325 325 326 326 void SetNetworkGameAttributes(ScriptInterface::CxPrivate* pCxPrivate, CScriptVal attribs1) … … void SetTurnLength(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int length) 630 630 if (g_NetServer) 631 631 g_NetServer->SetTurnLength(length); 632 632 else 633 LOGERROR( L"Only network host can change turn length");633 LOGERROR("Only network host can change turn length"); 634 634 } 635 635 636 636 // Focus the game camera on a given position. … … void DumpTerrainMipmap(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) 676 676 g_Game->GetWorld()->GetTerrain()->GetHeightMipmap().DumpToDisk(filename); 677 677 OsPath realPath; 678 678 g_VFS->GetRealPath(filename, realPath); 679 LOGMESSAGERENDER( L"Terrain mipmap written to '%ls'", realPath.string().c_str());679 LOGMESSAGERENDER("Terrain mipmap written to '%s'", realPath.string8()); 680 680 } 681 681 682 682 void EnableTimeWarpRecording(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), unsigned int numTurns) … … void StartJsTimer(ScriptInterface::CxPrivate* pCxPrivate, unsigned int slot) 906 906 ONCE(InitJsTimers(*(pCxPrivate->pScriptInterface))); 907 907 908 908 if (slot >= MAX_JS_TIMERS) 909 LOGERROR( L"Exceeded the maximum number of timer slots for scripts!");909 LOGERROR("Exceeded the maximum number of timer slots for scripts!"); 910 910 911 911 js_start_times[slot].SetFromTimer(); 912 912 } … … void StartJsTimer(ScriptInterface::CxPrivate* pCxPrivate, unsigned int slot) 914 914 void StopJsTimer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), unsigned int slot) 915 915 { 916 916 if (slot >= MAX_JS_TIMERS) 917 LOGERROR( L"Exceeded the maximum number of timer slots for scripts!");917 LOGERROR("Exceeded the maximum number of timer slots for scripts!"); 918 918 919 919 TimerUnit now; 920 920 now.SetFromTimer(); -
source/i18n/L10n.cpp
diff --git a/source/i18n/L10n.cpp b/source/i18n/L10n.cpp index a77c7da..e1eb005 100644
a b void L10n::GetDictionaryLocale(const std::string& configLocaleString, Locale& ou 203 203 return; 204 204 } 205 205 else 206 LOGWARNING( L"The configured locale is not valid or no translations are available. Falling back to another locale.");206 LOGWARNING("The configured locale is not valid or no translations are available. Falling back to another locale."); 207 207 } 208 208 209 209 Locale systemLocale = Locale::getDefault(); … … std::string L10n::FormatMillisecondsIntoDateString(const UDate& milliseconds, co 408 408 UnicodeString unicodeFormat = UnicodeString::fromUTF8(formatString.c_str()); 409 409 SimpleDateFormat* dateFormat = new SimpleDateFormat(unicodeFormat, status); 410 410 if (U_FAILURE(status)) 411 LOGERROR( L"Error creating SimpleDateFormat: %hs", u_errorName(status));411 LOGERROR("Error creating SimpleDateFormat: %s", u_errorName(status)); 412 412 413 413 const TimeZone* timeZone = TimeZone::getGMT(); 414 414 415 415 status = U_ZERO_ERROR; 416 416 Calendar* calendar = Calendar::createInstance(*timeZone, currentLocale, status); 417 417 if (U_FAILURE(status)) 418 LOGERROR( L"Error creating calendar: %hs", u_errorName(status));418 LOGERROR("Error creating calendar: %s", u_errorName(status)); 419 419 420 420 dateFormat->adoptCalendar(calendar); 421 421 dateFormat->format(milliseconds, dateString); … … Status L10n::ReloadChangedFile(const VfsPath& path) 470 470 if (path.string().rfind(dictName) == std::string::npos) 471 471 return INFO::OK; 472 472 473 LOGMESSAGE( L"Hotloading translations from '%ls'", path.string().c_str());473 LOGMESSAGE("Hotloading translations from '%s'", path.string8()); 474 474 475 475 CVFSFile file; 476 476 if (file.Load(g_VFS, path) != PSRETURN_OK) 477 477 { 478 LOGERROR( L"Failed to read translations from '%ls'", path.string().c_str());478 LOGERROR("Failed to read translations from '%s'", path.string8()); 479 479 return ERR::FAIL; 480 480 } 481 481 … … void L10n::LoadDictionaryForCurrentLocale() 505 505 std::wstring dictName = GetFallbackToAvailableDictLocale(currentLocale); 506 506 if (vfs::GetPathnames(g_VFS, L"l10n/", dictName.append(L".*.po").c_str(), filenames) < 0) 507 507 { 508 LOGERROR( L"No files for the dictionary found, but at this point the input should already be validated!");508 LOGERROR("No files for the dictionary found, but at this point the input should already be validated!"); 509 509 return; 510 510 } 511 511 } … … void L10n::ReadPoIntoDictionary(const std::string& poContent, tinygettext::Dicti 569 569 } 570 570 catch(std::exception& e) 571 571 { 572 LOGERROR( L"[Localization] Exception while reading virtual PO file: %hs", e.what());572 LOGERROR("[Localization] Exception while reading virtual PO file: %s", e.what()); 573 573 } 574 574 } 575 575 -
source/lib/path.h
diff --git a/source/lib/path.h b/source/lib/path.h index 02083ec..7facfb6 100644
a b 41 41 # include "boost/functional/hash.hpp" 42 42 #endif 43 43 44 #include "lib/utf8.h" 45 44 46 #include <cstring> 45 47 46 48 namespace ERR … … public: 125 127 return path; 126 128 } 127 129 130 std::string string8() const 131 { 132 return utf8_from_wstring(path); 133 } 134 128 135 bool operator<(const Path& rhs) const 129 136 { 130 137 return path < rhs.path; -
source/lib/secure_crt.cpp
diff --git a/source/lib/secure_crt.cpp b/source/lib/secure_crt.cpp index 849c76e..40c0771 100644
a b int tvsprintf_s(tchar* dst, size_t max_dst_chars, const tchar* fmt, va_list ap) 237 237 } 238 238 239 239 const int ret = tvsnprintf(dst, max_dst_chars, fmt, ap); 240 if(ret >= int(max_dst_chars)) // not enough space240 if(ret < 0 || ret >= int(max_dst_chars)) // not enough space 241 241 { 242 242 dst[0] = '\0'; 243 243 return -1; -
source/lib/self_test.h
diff --git a/source/lib/self_test.h b/source/lib/self_test.h index 27e3870..4b68be0 100644
a b namespace CxxTest 269 269 #define TS_ASSERT_PATH_EQUALS(path1, path2) TS_ASSERT_EQUALS((path1).string(), (path2).string()) 270 270 #define TSM_ASSERT_PATH_EQUALS(m, path1, path2) TSM_ASSERT_EQUALS(m, (path1).string(), (path2).string()) 271 271 272 bool ts_str_contains(const std::string& str1, const std::string& str2); // defined in test_setup.cpp 272 273 bool ts_str_contains(const std::wstring& str1, const std::wstring& str2); // defined in test_setup.cpp 274 #define TS_ASSERT_STR_CONTAINS(str1, str2) TSM_ASSERT(str1, ts_str_contains(str1, str2)) 275 #define TS_ASSERT_STR_NOT_CONTAINS(str1, str2) TSM_ASSERT(str1, !ts_str_contains(str1, str2)) 273 276 #define TS_ASSERT_WSTR_CONTAINS(str1, str2) TSM_ASSERT(str1, ts_str_contains(str1, str2)) 274 277 #define TS_ASSERT_WSTR_NOT_CONTAINS(str1, str2) TSM_ASSERT(str1, !ts_str_contains(str1, str2)) 275 278 -
source/lib/sysdep/os/linux/dir_watch_inotify.cpp
diff --git a/source/lib/sysdep/os/linux/dir_watch_inotify.cpp b/source/lib/sysdep/os/linux/dir_watch_inotify.cpp index 52bd702..93c5ad2 100644
a b Status dir_watch_Add(const OsPath& path, PDirWatch& dirWatch) 188 188 // Check for error ? 189 189 int err = errno; 190 190 initialized = -1; 191 LOGERROR( L"Error initializing inotify file descriptor; hotloading will be disabled, errno=%d", err);191 LOGERROR("Error initializing inotify file descriptor; hotloading will be disabled, errno=%d", err); 192 192 errno = err; 193 193 return StatusFromErrno(); // NOWARN 194 194 } … … Status dir_watch_Add(const OsPath& path, PDirWatch& dirWatch) 198 198 if (ret != 0) 199 199 { 200 200 initialized = -1; 201 LOGERROR( L"Error creating inotify event loop thread; hotloading will be disabled, err=%d", ret);201 LOGERROR("Error creating inotify event loop thread; hotloading will be disabled, err=%d", ret); 202 202 errno = ret; 203 203 return StatusFromErrno(); // NOWARN 204 204 } -
deleted file source/lib/sysdep/os/unix/printf.cpp
diff --git a/source/lib/sysdep/os/unix/printf.cpp b/source/lib/sysdep/os/unix/printf.cpp deleted file mode 100644 index 6c5a8be..0000000
+ - 1 /* Copyright (c) 2010 Wildfire Games2 *3 * Permission is hereby granted, free of charge, to any person obtaining4 * a copy of this software and associated documentation files (the5 * "Software"), to deal in the Software without restriction, including6 * without limitation the rights to use, copy, modify, merge, publish,7 * distribute, sublicense, and/or sell copies of the Software, and to8 * permit persons to whom the Software is furnished to do so, subject to9 * the following conditions:10 *11 * The above copyright notice and this permission notice shall be included12 * in all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.17 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY18 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,19 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.21 */22 23 #include "precompiled.h"24 25 #include <cstdio>26 #include <cstdarg>27 28 // See declaration in sysdep.h for explanation of need29 30 int sys_vswprintf(wchar_t* buffer, size_t count, const wchar_t* format, va_list argptr)31 {32 int ret = vswprintf(buffer, count, format, argptr);33 34 // Guarantee the buffer is null terminated on error35 if (ret < 0 && count > 0)36 buffer[count-1] = '\0';37 38 return ret;39 } -
deleted file source/lib/sysdep/os/win/wprintf.cpp
diff --git a/source/lib/sysdep/os/win/wprintf.cpp b/source/lib/sysdep/os/win/wprintf.cpp deleted file mode 100644 index dce843c..0000000
+ - 1 /* Copyright (c) 2010 Wildfire Games2 *3 * Permission is hereby granted, free of charge, to any person obtaining4 * a copy of this software and associated documentation files (the5 * "Software"), to deal in the Software without restriction, including6 * without limitation the rights to use, copy, modify, merge, publish,7 * distribute, sublicense, and/or sell copies of the Software, and to8 * permit persons to whom the Software is furnished to do so, subject to9 * the following conditions:10 *11 * The above copyright notice and this permission notice shall be included12 * in all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.17 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY18 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,19 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.21 */22 23 /*24 * implementation of sys_vswprintf.25 */26 27 #include "precompiled.h"28 29 #if ARCH_IA3230 31 /*32 See http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html33 for the specification (apparently an extension to ISO C) that was used34 when creating this code.35 */36 37 /*38 Added features (compared to MSVC's printf):39 Positional parameters (e.g. "%1$d", where '1' means '1st in the parameter list')40 %lld (equivalent to %I64d in MSVC7.1, though it's supported natively by MSVC8)41 42 Unsupported features (compared to a perfect implementation):43 ' <-- because MSVC doesn't support it44 %S }45 %C } because they're unnecessary and can cause confusion46 * <-- probably works in some situations, but don't expect it to47 *m$ <-- positional precision parameters, because they're not worthwhile48 portability <-- just use GCC49 efficiency <-- nothing in the spec says it should be as fast as possible50 (the code could be made a lot faster if speed mattered more51 than non-fixed size buffers)52 53 */54 55 #ifndef _UNICODE56 #define _UNICODE57 #endif58 #include <tchar.h>59 #ifdef _UNICODE60 # define tstring wstring61 # define tstringstream wstringstream62 #else63 # define tstring string64 # define tstringstream stringstream65 #endif66 #include <string>67 #include <vector>68 69 #include <stdio.h>70 #include <sstream>71 #include <stdarg.h>72 73 #if MSC_VERSION < 140074 # define USE_I64_FORMAT 175 #else76 # define USE_I64_FORMAT 077 #endif78 79 enum80 {81 SPECFLAG_THOUSANDS = 1, // '82 SPECFLAG_LEFTJUSTIFIED = 2, // -83 SPECFLAG_SIGNED = 4, // +84 SPECFLAG_SPACEPREFIX = 8, // <space>85 SPECFLAG_ALTERNATE = 16, // #86 SPECFLAG_ZEROPAD = 32 // 087 };88 89 struct FormatChunk90 {91 virtual ~FormatChunk() { }92 virtual int ChunkType() = 0; // 0 = FormatSpecification, 1 = FormatString93 };94 95 struct FormatVariable : public FormatChunk96 {97 int ChunkType() { return 0; }98 int position; // undefined if the format includes no positional elements99 char flags; // ['-+ #0]100 int width; // -1 for *, 0 for unspecified101 int precision; // -1 for *102 int length; // "\0\0\0l", "\0\0hh", etc103 char type; // 'd', etc104 };105 106 struct FormatString : public FormatChunk107 {108 int ChunkType() { return 1; }109 FormatString(std::tstring t) : text(t) {}110 std::tstring text;111 };112 113 114 int get_flag(TCHAR c)115 {116 switch (c)117 {118 case _T('\''): return SPECFLAG_THOUSANDS;119 case _T('-'): return SPECFLAG_LEFTJUSTIFIED;120 case _T('+'): return SPECFLAG_SIGNED;121 case _T(' '): return SPECFLAG_SPACEPREFIX;122 case _T('#'): return SPECFLAG_ALTERNATE;123 case _T('0'): return SPECFLAG_ZEROPAD;124 }125 return 0;126 }127 128 std::tstring flags_to_string(char flags)129 {130 std::tstring s;131 const char* c = "\'-+ #0";132 for (int i=0; i<6; ++i)133 if (flags & (1<<i))134 s += c[i];135 return s;136 }137 138 template<typename T>139 std::tstring to_string(T n)140 {141 std::tstring s;142 std::tstringstream str;143 str << n;144 str >> s;145 return s;146 }147 148 int is_lengthmod(TCHAR c)149 {150 return151 c == _T('h') ||152 c == _T('l') ||153 c == _T('j') ||154 c == _T('z') ||155 c == _T('t') ||156 c == _T('L');157 }158 159 // _T2('l') == 'll'160 #define _T2(a) ((a<<8) | a)161 162 int type_size(TCHAR type, int length)163 {164 switch (type)165 {166 case 'd':167 case 'i':168 switch (length)169 {170 case _T ('l'): return sizeof(long);171 case _T2('l'): return sizeof(long long);172 case _T ('h'): return sizeof(short);173 case _T2('h'): return sizeof(char);174 default: return sizeof(int);175 }176 case 'o':177 case 'u':178 case 'x':179 case 'X': return sizeof(unsigned);180 case 'f':181 case 'F':182 case 'e':183 case 'E':184 case 'g':185 case 'G':186 case 'a':187 case 'A':188 if (length == _T('L'))189 return sizeof(long double);190 else191 return sizeof(double);192 193 case 'c':194 // "%lc" is a wide character, passed as a wint_t (ushort)195 if (length == _T('l'))196 return sizeof(wint_t);197 // "%c" is an int, apparently198 else199 return sizeof(int);200 201 case 's':202 if (length == _T('l'))203 return sizeof(wchar_t*);204 else205 return sizeof(char*);206 207 case 'p':208 return sizeof(void*);209 210 case 'n':211 return sizeof(int*);212 213 }214 return 0;215 }216 217 int sys_vswprintf(TCHAR* buffer, size_t count, const TCHAR* format, va_list argptr)218 {219 // To help quickly detect incorrect 'count' values, fill the buffer with 0s220 memset(buffer, 0, count*sizeof(TCHAR));221 222 /*223 224 Format 'variable' specifications are (in pseudo-Perl regexp syntax):225 226 % (\d+$)? ['-+ #0]? (* | \d+)? (. (* | \d*) )? (hh|h|l|ll|j|z|t|L)? [diouxXfFeEgGaAcspnCS%]227 position flags width precision length type228 229 */230 231 /**** Parse the format string into constant/variable chunks ****/232 233 std::vector<FormatChunk*> specs;234 std::tstring stringchunk;235 236 TCHAR chr;237 238 #define readchar(x) if ((x = *format++) == '\0') { delete s; goto finished_reading; }239 240 while ((chr = *format++) != '\0')241 {242 if (chr == _T('%'))243 {244 // Handle %% correctly245 if (*format == _T('%'))246 {247 stringchunk += _T('%');248 continue;249 }250 251 // End the current string and start a new spec chunk252 if (stringchunk.length())253 {254 specs.push_back(new FormatString(stringchunk));255 stringchunk = _T("");256 }257 258 FormatVariable *s = new FormatVariable;259 s->position = -1;260 s->flags = 0;261 s->width = 0;262 s->precision = 0;263 s->length = 0;264 s->type = 0;265 266 // Read either the position or the width267 int number = 0;268 269 while (1)270 {271 readchar(chr);272 273 // Read flags (but not if it's a 0 appearing after other digits)274 if (!number && get_flag(chr))275 s->flags = (char)(s->flags|get_flag(chr));276 277 // Read decimal numbers (position or width)278 else if (isdigit(chr))279 number = number*10 + (chr-'0');280 281 // If we've reached a $, 'number' was the position,282 // so remember it and start getting the width283 else if (chr == _T('$'))284 {285 s->position = number;286 number = 0;287 }288 289 // End of the number section290 else291 {292 // Remember the width293 s->width = number;294 295 // Start looking for a precision296 if (chr == _T('.'))297 {298 // Found a precision: read the digits299 300 number = 0;301 302 while (1)303 {304 readchar(chr);305 306 if (isdigit(chr))307 number = number*10 + (chr-'0');308 else309 {310 s->precision = number;311 break;312 }313 }314 }315 316 // Finished dealing with any precision.317 318 // Now check for length and type codes.319 320 if (chr == _T('I'))321 {322 DEBUG_WARN_ERR(ERR::LOGIC); // MSVC-style \"%I64\" is not allowed!323 }324 325 if (is_lengthmod(chr))326 {327 s->length = chr;328 329 // Check for ll and hh330 if (chr == _T('l') || chr == _T('h'))331 {332 if (*format == chr)333 {334 s->length |= (chr << 8);335 ++format;336 }337 }338 339 readchar(chr);340 }341 342 s->type = (char)chr;343 344 specs.push_back(s);345 346 break;347 }348 }349 }350 else351 {352 stringchunk += chr;353 }354 }355 356 #undef readchar357 358 finished_reading:359 360 if (stringchunk.length())361 {362 specs.push_back(new FormatString(stringchunk));363 stringchunk = _T("");364 }365 366 /**** Build a new format string (to pass to the system printf) ****/367 368 std::tstring newformat;369 370 std::vector<int> varsizes; // stores the size of each variable type, to allow stack twiddling371 372 typedef std::vector<FormatChunk*>::iterator ChunkIt;373 374 for (ChunkIt it = specs.begin(); it != specs.end(); ++it)375 {376 if ((*it)->ChunkType() == 0)377 {378 FormatVariable* s = static_cast<FormatVariable*>(*it);379 380 if (s->position > 0)381 {382 // Grow if necessary383 if (s->position >= (int)varsizes.size())384 varsizes.resize(s->position+1, -1);385 // Store the size of the current type386 varsizes[s->position] = type_size(s->type, s->length);387 }388 389 390 newformat += _T("%");391 392 if (s->flags)393 newformat += flags_to_string(s->flags);394 395 if (s->width == -1)396 newformat += '*';397 else if (s->width)398 newformat += to_string(s->width);399 400 if (s->precision)401 {402 newformat += '.';403 if (s->precision == -1)404 newformat += '*';405 else406 newformat += to_string(s->precision);407 }408 409 if (s->length)410 {411 if (s->length > 256)412 {413 if (s->length == 0x00006c6c)414 #if USE_I64_FORMAT415 newformat += "I64";416 #else417 newformat += _T("ll");418 #endif419 else if (s->length == 0x00006868)420 newformat += _T("hh");421 }422 else423 {424 newformat += (char) s->length;425 }426 }427 428 newformat += s->type;429 }430 else431 {432 FormatString* s = static_cast<FormatString*>(*it);433 newformat += s->text;434 }435 }436 437 438 /*439 varargs on x86:440 441 All types are padded to 4 bytes, so size-in-stack == _INTSIZEOF(type).442 No special alignment is required.443 444 first+_INTSIZEOF(first) == first item in stack445 446 Keep adding _INTSIZEOF(item) to get the next item447 */448 449 // Because of those dangerous assumptions about varargs:450 #if !ARCH_IA32451 #error SLIGHTLY FATAL ERROR: Only x86 is supported!452 #endif453 454 // Highly efficient buffer to store the rearranged copy of the stack455 std::string newstack;456 457 std::vector< std::pair<char*, char*> > stackitems;458 459 va_list arglist = argptr;460 //va_start(arglist, format);461 462 const u8* newstackptr;463 464 if (varsizes.size())465 {466 467 for (size_t i = 1; i < varsizes.size(); ++i)468 {469 if (varsizes[i] <= 0)470 {471 DEBUG_WARN_ERR(ERR::LOGIC); // Invalid variable type somewhere - make sure all variable things are positional and defined472 return -1;473 }474 475 // Based on _INTSIZEOF in stdarg.h:476 // (Warning - slightly non-portable. But we use gcc's default printf477 // when portability matters.)478 #define INTSIZE(n) ( (n + sizeof(int) - 1) & ~(sizeof(int) - 1) )479 480 size_t size = INTSIZE(varsizes[i]);481 stackitems.push_back( std::pair<char*, char*>( arglist, arglist+size ));482 arglist += size;483 }484 485 486 for (ChunkIt it = specs.begin(); it != specs.end(); ++it)487 {488 FormatChunk* chunk = *it;489 if (chunk->ChunkType() == 0)490 {491 FormatVariable* s = static_cast<FormatVariable*>(chunk);492 if (s->position <= 0)493 {494 DEBUG_WARN_ERR(ERR::LOGIC); // Invalid use of positional elements - make sure all variable things are positional and defined495 return -1;496 }497 newstack += std::string( stackitems[s->position-1].first, stackitems[s->position-1].second );498 }499 }500 501 newstackptr = (const u8*)newstack.c_str();502 }503 else504 {505 newstackptr = (const u8*)arglist;506 }507 508 for (ChunkIt it = specs.begin(); it != specs.end(); ++it)509 if ((*it)->ChunkType() == 0)510 delete static_cast<FormatVariable*>(*it);511 else512 delete static_cast<FormatString*>(*it);513 514 int ret = _vsntprintf(buffer, count, newformat.c_str(), (va_list)newstackptr);515 516 // For consistency with GCC's vsnprintf, make sure the buffer is null-terminated517 // and return an error if that truncates the output518 if(count > 0)519 buffer[count-1] = '\0';520 if (ret == (int)count)521 return -1;522 523 return ret;524 }525 526 #endif -
source/lib/sysdep/sysdep.h
diff --git a/source/lib/sysdep/sysdep.h b/source/lib/sysdep/sysdep.h index bbb032d..2517309 100644
a b 30 30 #include "lib/debug.h" // ErrorReactionInternal 31 31 #include "lib/os_path.h" 32 32 33 #include <cstdarg> // needed for sys_vswprintf34 35 33 36 34 // 37 35 // output … … LIB_API bool sys_IsDebuggerPresent(); 81 79 LIB_API std::wstring sys_WideFromArgv(const char* argv_i); 82 80 83 81 /** 84 * sys_vswprintf: doesn't quite follow the standard for vswprintf, but works85 * better across compilers:86 * - handles positional parameters and %lld87 * - always null-terminates the buffer, if count > 088 * - returns -1 on overflow (if the output string (including null) does not fit in the buffer)89 **/90 extern int sys_vswprintf(wchar_t* buffer, size_t count, const wchar_t* format, va_list argptr);91 92 /**93 82 * describe the current OS error state. 94 83 * 95 84 * @param err: if not 0, use that as the error code to translate; otherwise, -
deleted file source/lib/sysdep/tests/test_printf.h
diff --git a/source/lib/sysdep/tests/test_printf.h b/source/lib/sysdep/tests/test_printf.h deleted file mode 100644 index 341a81f..0000000
+ - 1 /* Copyright (c) 2010 Wildfire Games2 *3 * Permission is hereby granted, free of charge, to any person obtaining4 * a copy of this software and associated documentation files (the5 * "Software"), to deal in the Software without restriction, including6 * without limitation the rights to use, copy, modify, merge, publish,7 * distribute, sublicense, and/or sell copies of the Software, and to8 * permit persons to whom the Software is furnished to do so, subject to9 * the following conditions:10 *11 * The above copyright notice and this permission notice shall be included12 * in all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.17 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY18 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,19 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.21 */22 23 #include "lib/self_test.h"24 25 #include "lib/sysdep/sysdep.h"26 27 class TestPrintf : public CxxTest::TestSuite28 {29 // Split some bits into separate functions, so we can get30 // a legitimate va_list to pass to sys_vswprintf:31 32 void _test_truncate(int buffer_size, const wchar_t* expected_output, int expected_return, /* wchar_t* input_string */...)33 {34 wchar_t buf[17] = L"................"; // fill with dots so null-termination is made obvious35 36 va_list ap;37 va_start(ap, expected_return);38 39 int ret = sys_vswprintf(buf, buffer_size, L"%ls", ap);40 41 TS_ASSERT_WSTR_EQUALS(buf, expected_output);42 TS_ASSERT_EQUALS(ret, expected_return);43 44 std::wstring past_buffer(buf + buffer_size);45 TS_ASSERT(past_buffer.find_first_not_of('.') == past_buffer.npos);46 47 va_end(ap);48 }49 50 void _test_sprintf(const wchar_t* expected_output, const wchar_t* format, ...)51 {52 wchar_t buf[256];53 54 va_list ap;55 va_start(ap, format);56 57 sys_vswprintf(buf, ARRAY_SIZE(buf), format, ap);58 TS_ASSERT_WSTR_EQUALS(buf, expected_output);59 60 va_end(ap);61 }62 63 public:64 void test_truncate()65 {66 _test_truncate(0, L"................", -1, L"1234");67 _test_truncate(1, L"", -1, L"1234");68 69 _test_truncate(8, L"1234", 4, L"1234");70 _test_truncate(8, L"1234567", 7, L"1234567");71 _test_truncate(8, L"1234567", -1, L"12345678");72 _test_truncate(8, L"1234567", -1, L"123456789");73 _test_truncate(8, L"1234567", -1, L"123456789abcdef");74 }75 76 void test_lld()77 {78 i64 z = 0;79 i64 n = 65536;80 _test_sprintf(L"0", L"%lld", z);81 _test_sprintf(L"65536", L"%lld", n);82 _test_sprintf(L"4294967296", L"%lld", n*n);83 _test_sprintf(L"281474976710656", L"%lld", n*n*n);84 _test_sprintf(L"-281474976710656", L"%lld", -n*n*n);85 _test_sprintf(L"123 456 281474976710656 789", L"%d %d %lld %d", 123, 456, n*n*n, 789);86 }87 88 void test_pos()89 {90 _test_sprintf(L"a b", L"%1$c %2$c", 'a', 'b');91 _test_sprintf(L"b a", L"%2$c %1$c", 'a', 'b');92 }93 94 void test_pos_lld()95 {96 _test_sprintf(L"1 2 3", L"%1$d %2$lld %3$d", 1, (i64)2, 3);97 _test_sprintf(L"2 1 3", L"%2$lld %1$d %3$d", 1, (i64)2, 3);98 }99 }; -
source/lib/tests/test_secure_crt.h
diff --git a/source/lib/tests/test_secure_crt.h b/source/lib/tests/test_secure_crt.h index b52480d..422bea1 100644
a b class TestString_s : public CxxTest::TestSuite 81 81 const char* const s1; 82 82 const char* const s5; 83 83 const char* const s10; 84 const wchar_t* const ws10; 84 85 85 86 char d1[1]; 86 87 char d2[2]; … … class TestString_s : public CxxTest::TestSuite 88 89 char d5[5]; 89 90 char d6[6]; 90 91 char d10[10]; 92 wchar_t wd10[10]; 91 93 char d11[11]; 92 94 93 95 char no_null[7]; … … class TestString_s : public CxxTest::TestSuite 157 159 158 160 public: 159 161 TestString_s() 160 : s0(""), s1("a"), s5("abcde"), s10("abcdefghij") 162 : s0(""), s1("a"), s5("abcde"), s10("abcdefghij"), ws10(L"abcdefghij") 161 163 { 162 164 const char no_null_tmp[] = { 'n','o','_','n','u','l','l'}; 163 165 memcpy(no_null, no_null_tmp, sizeof(no_null)); … … public: 303 305 if (dst) TS_ASSERT_STR_EQUALS(dst, expected_dst); 304 306 } 305 307 308 static void TEST_WPRINTF(wchar_t* dst, size_t max_dst_chars, const wchar_t* dst_val, 309 int expected_ret, const wchar_t* expected_dst, const wchar_t* fmt, ...) 310 { 311 if (dst) wcscpy(dst, dst_val); 312 va_list ap; 313 va_start(ap, fmt); 314 int ret = vswprintf_s(dst, max_dst_chars, fmt, ap); 315 va_end(ap); 316 TS_ASSERT_EQUALS(ret, expected_ret); 317 if (dst) TS_ASSERT_WSTR_EQUALS(dst, expected_dst); 318 } 319 306 320 void test_printf() 307 321 { 308 322 TEST_PRINTF(d10,10, s10, 4, "1234", "%d", 1234); … … public: 315 329 TEST_PRINTF(NULL,0, NULL, -1, "", "%d", 1234); 316 330 TEST_PRINTF(d10,10, s10, -1, "abcdefghij", NULL); 317 331 } 332 333 void test_wprintf() 334 { 335 TEST_WPRINTF(wd10,10, ws10, 4, L"1234", L"%d", 1234); 336 TEST_WPRINTF(wd10,5, ws10, 4, L"1234", L"%d", 1234); 337 338 SuppressErrors suppress; 339 TEST_WPRINTF(wd10,4, ws10, -1, L"", L"%d", 1234); 340 TEST_WPRINTF(wd10,3, ws10, -1, L"", L"%d", 1234); 341 TEST_WPRINTF(wd10,0, ws10, -1, L"abcdefghij", L"%d", 1234); 342 TEST_WPRINTF(NULL,0, NULL, -1, L"", L"%d", 1234); 343 TEST_WPRINTF(wd10,10, ws10, -1, L"abcdefghij", NULL); 344 } 318 345 }; -
source/lobby/XmppClient.cpp
diff --git a/source/lobby/XmppClient.cpp b/source/lobby/XmppClient.cpp index 4b454e0..26c8c2e 100644
a b bool XmppClient::handleIq(const glooxwrapper::IQ& iq) 749 749 { 750 750 CreateSimpleMessage("system", g_L10n.Translate("unknown subtype (see logs)"), "error"); 751 751 std::string tag = tag_name(iq); 752 LOGMESSAGE( L"unknown subtype '%hs'", tag.c_str());752 LOGMESSAGE("unknown subtype '%s'", tag.c_str()); 753 753 } 754 754 755 755 return true; … … void XmppClient::SetPresence(const std::string& presence) 896 896 else IF("offline", Unavailable); 897 897 // The others are not to be set 898 898 #undef IF 899 else LOGERROR( L"Unknown presence '%hs'", presence.c_str());899 else LOGERROR("Unknown presence '%s'", presence.c_str()); 900 900 } 901 901 902 902 /** … … void XmppClient::GetPresenceString(const gloox::Presence::PresenceType p, std::s 952 952 CASE(Error, "error"); 953 953 CASE(Invalid, "invalid"); 954 954 default: 955 LOGERROR( L"Unknown presence type '%d'", (int)p);955 LOGERROR("Unknown presence type '%d'", (int)p); 956 956 break; 957 957 #undef CASE 958 958 } … … void XmppClient::GetRoleString(const gloox::MUCRoomRole r, std::string& role) co 975 975 CASE(RoleModerator, "moderator"); 976 976 CASE(RoleInvalid, "invalid"); 977 977 default: 978 LOGERROR( L"Unknown role type '%d'", (int)r);978 LOGERROR("Unknown role type '%d'", (int)r); 979 979 break; 980 980 #undef CASE 981 981 } -
source/main.cpp
diff --git a/source/main.cpp b/source/main.cpp index 4d90e76..051e2f9 100644
a b static InReaction MainInputHandler(const SDL_Event_* ev) 159 159 // Fullscreen toggling is broken on OS X w/ SDL 1.2, see http://trac.wildfiregames.com/ticket/741 160 160 g_VideoMode.ToggleFullscreen(); 161 161 #else 162 LOGWARNING( L"Toggling fullscreen and resizing are disabled on OS X due to a known bug. Please use the config file to change display settings.");162 LOGWARNING("Toggling fullscreen and resizing are disabled on OS X due to a known bug. Please use the config file to change display settings."); 163 163 #endif 164 164 return IN_HANDLED; 165 165 } -
source/network/NetClient.cpp
diff --git a/source/network/NetClient.cpp b/source/network/NetClient.cpp index 8062cc8..fec7a80 100644
a b bool CNetClient::HandleMessage(CNetMessage* message) 304 304 305 305 std::stringstream stream; 306 306 307 LOGMESSAGERENDER( L"Serializing game at turn %u for rejoining player", m_ClientTurnManager->GetCurrentTurn());307 LOGMESSAGERENDER("Serializing game at turn %u for rejoining player", m_ClientTurnManager->GetCurrentTurn()); 308 308 u32 turn = to_le32(m_ClientTurnManager->GetCurrentTurn()); 309 309 stream.write((char*)&turn, sizeof(turn)); 310 310 … … bool CNetClient::HandleMessage(CNetMessage* message) 324 324 // Update FSM 325 325 bool ok = Update(message->GetType(), message); 326 326 if (!ok) 327 LOGERROR( L"Net client: Error running FSM update (type=%d state=%d)", (int)message->GetType(), (int)GetCurrState());327 LOGERROR("Net client: Error running FSM update (type=%d state=%d)", (int)message->GetType(), (int)GetCurrState()); 328 328 return ok; 329 329 } 330 330 … … void CNetClient::LoadFinished() 347 347 stream.read((char*)&turn, sizeof(turn)); 348 348 turn = to_le32(turn); 349 349 350 LOGMESSAGE( L"Rejoining client deserializing state at turn %u\n", turn);350 LOGMESSAGE("Rejoining client deserializing state at turn %u\n", turn); 351 351 352 352 bool ok = m_Game->GetSimulation2()->DeserializeState(stream); 353 353 ENSURE(ok); … … bool CNetClient::OnAuthenticate(void* context, CFsmEvent* event) 428 428 429 429 CAuthenticateResultMessage* message = (CAuthenticateResultMessage*)event->GetParamRef(); 430 430 431 LOGMESSAGE( L"Net: Authentication result: host=%u, %ls", message->m_HostID, message->m_Message.c_str());431 LOGMESSAGE("Net: Authentication result: host=%u, %s", message->m_HostID, utf8_from_wstring(message->m_Message)); 432 432 433 433 bool isRejoining = (message->m_Code == ARC_OK_REJOINING); 434 434 -
source/network/NetFileTransfer.cpp
diff --git a/source/network/NetFileTransfer.cpp b/source/network/NetFileTransfer.cpp index 02805e3..1bf4da9 100644
a b Status CNetFileTransferer::HandleMessageReceive(const CNetMessage* message) 15 15 16 16 if (m_FileReceiveTasks.find(respMessage->m_RequestID) == m_FileReceiveTasks.end()) 17 17 { 18 LOGERROR( L"Net transfer: Unsolicited file transfer response (id=%d)", (int)respMessage->m_RequestID);18 LOGERROR("Net transfer: Unsolicited file transfer response (id=%d)", (int)respMessage->m_RequestID); 19 19 return ERR::FAIL; 20 20 } 21 21 22 22 if (respMessage->m_Length == 0 || respMessage->m_Length > MAX_FILE_TRANSFER_SIZE) 23 23 { 24 LOGERROR( L"Net transfer: Invalid size for file transfer response (length=%d)", (int)respMessage->m_Length);24 LOGERROR("Net transfer: Invalid size for file transfer response (length=%d)", (int)respMessage->m_Length); 25 25 return ERR::FAIL; 26 26 } 27 27 … … Status CNetFileTransferer::HandleMessageReceive(const CNetMessage* message) 30 30 task->m_Length = respMessage->m_Length; 31 31 task->m_Buffer.reserve(respMessage->m_Length); 32 32 33 LOGMESSAGERENDER( L"Downloading data over network (%d KB) - please wait...", (int)(task->m_Length/1024));33 LOGMESSAGERENDER("Downloading data over network (%d KB) - please wait...", (int)(task->m_Length/1024)); 34 34 m_LastProgressReportTime = timer_Time(); 35 35 36 36 return INFO::OK; … … Status CNetFileTransferer::HandleMessageReceive(const CNetMessage* message) 41 41 42 42 if (m_FileReceiveTasks.find(dataMessage->m_RequestID) == m_FileReceiveTasks.end()) 43 43 { 44 LOGERROR( L"Net transfer: Unsolicited file transfer data (id=%d)", (int)dataMessage->m_RequestID);44 LOGERROR("Net transfer: Unsolicited file transfer data (id=%d)", (int)dataMessage->m_RequestID); 45 45 return ERR::FAIL; 46 46 } 47 47 … … Status CNetFileTransferer::HandleMessageReceive(const CNetMessage* message) 51 51 52 52 if (task->m_Buffer.size() > task->m_Length) 53 53 { 54 LOGERROR( L"Net transfer: Invalid size for file transfer data (length=%d actual=%d)", (int)task->m_Length, (int)task->m_Buffer.size());54 LOGERROR("Net transfer: Invalid size for file transfer data (length=%d actual=%d)", (int)task->m_Length, (int)task->m_Buffer.size()); 55 55 return ERR::FAIL; 56 56 } 57 57 … … Status CNetFileTransferer::HandleMessageReceive(const CNetMessage* message) 62 62 63 63 if (task->m_Buffer.size() == task->m_Length) 64 64 { 65 LOGMESSAGERENDER( L"Download completed");65 LOGMESSAGERENDER("Download completed"); 66 66 67 67 task->OnComplete(); 68 68 m_FileReceiveTasks.erase(dataMessage->m_RequestID); … … Status CNetFileTransferer::HandleMessageReceive(const CNetMessage* message) 75 75 double t = timer_Time(); 76 76 if (t > m_LastProgressReportTime + 0.5) 77 77 { 78 LOGMESSAGERENDER( L"Downloading data: %.1f%% of %d KB", 100.f*task->m_Buffer.size()/task->m_Length, (int)(task->m_Length/1024));78 LOGMESSAGERENDER("Downloading data: %.1f%% of %d KB", 100.f*task->m_Buffer.size()/task->m_Length, (int)(task->m_Length/1024)); 79 79 m_LastProgressReportTime = t; 80 80 } 81 81 … … Status CNetFileTransferer::HandleMessageReceive(const CNetMessage* message) 87 87 88 88 if (m_FileSendTasks.find(ackMessage->m_RequestID) == m_FileSendTasks.end()) 89 89 { 90 LOGERROR( L"Net transfer: Unsolicited file transfer ack (id=%d)", (int)ackMessage->m_RequestID);90 LOGERROR("Net transfer: Unsolicited file transfer ack (id=%d)", (int)ackMessage->m_RequestID); 91 91 return ERR::FAIL; 92 92 } 93 93 … … Status CNetFileTransferer::HandleMessageReceive(const CNetMessage* message) 95 95 96 96 if (ackMessage->m_NumPackets > task.packetsInFlight) 97 97 { 98 LOGERROR( L"Net transfer: Invalid num packets for file transfer ack (num=%d inflight=%d)",98 LOGERROR("Net transfer: Invalid num packets for file transfer ack (num=%d inflight=%d)", 99 99 (int)ackMessage->m_NumPackets, (int)task.packetsInFlight); 100 100 return ERR::FAIL; 101 101 } -
source/network/NetHost.cpp
diff --git a/source/network/NetHost.cpp b/source/network/NetHost.cpp index 7d0d682..e81a4ce 100644
a b bool CNetHost::SendMessage(const CNetMessage* message, ENetPeer* peer, const cha 29 29 if (!packet) 30 30 return false; 31 31 32 LOGMESSAGE( L"Net: Sending message %hs of size %lu to %hs", message->ToString().c_str(), (unsigned long)packet->dataLength, peerName);32 LOGMESSAGE("Net: Sending message %s of size %lu to %s", message->ToString().c_str(), (unsigned long)packet->dataLength, peerName); 33 33 34 34 // Let ENet send the message to peer 35 35 if (enet_peer_send(peer, DEFAULT_CHANNEL, packet) < 0) 36 36 { 37 LOGERROR( L"Net: Failed to send packet to peer");37 LOGERROR("Net: Failed to send packet to peer"); 38 38 return false; 39 39 } 40 40 … … ENetPacket* CNetHost::CreatePacket(const CNetMessage* message) 62 62 // Create a reliable packet 63 63 ENetPacket* packet = enet_packet_create(&buffer[0], size, ENET_PACKET_FLAG_RELIABLE); 64 64 if (!packet) 65 LOGERROR( L"Net: Failed to construct packet");65 LOGERROR("Net: Failed to construct packet"); 66 66 67 67 return packet; 68 68 } -
source/network/NetMessage.cpp
diff --git a/source/network/NetMessage.cpp b/source/network/NetMessage.cpp index d2c3be2..daa892c 100644
a b const u8* CNetMessage::Deserialize(const u8* pStart, const u8* pEnd) 54 54 { 55 55 if (pStart + 3 > pEnd) 56 56 { 57 LOGERROR( L"CNetMessage: Corrupt packet (smaller than header)");57 LOGERROR("CNetMessage: Corrupt packet (smaller than header)"); 58 58 return NULL; 59 59 } 60 60 … … const u8* CNetMessage::Deserialize(const u8* pStart, const u8* pEnd) 68 68 69 69 if (pStart + size != pEnd) 70 70 { 71 LOGERROR( L"CNetMessage: Corrupt packet (incorrect size)");71 LOGERROR("CNetMessage: Corrupt packet (incorrect size)"); 72 72 return NULL; 73 73 } 74 74 … … CNetMessage* CNetMessageFactory::CreateMessage(const void* pData, 184 184 break; 185 185 186 186 default: 187 LOGERROR( L"CNetMessageFactory::CreateMessage(): Unknown message type '%d' received", header.GetType());187 LOGERROR("CNetMessageFactory::CreateMessage(): Unknown message type '%d' received", header.GetType()); 188 188 break; 189 189 } 190 190 -
source/network/NetServer.cpp
diff --git a/source/network/NetServer.cpp b/source/network/NetServer.cpp index bcf904d..1a8187a 100644
a b public: 94 94 95 95 if (!session) 96 96 { 97 LOGMESSAGE( L"Net server: rejoining client disconnected before we sent to it");97 LOGMESSAGE("Net server: rejoining client disconnected before we sent to it"); 98 98 return; 99 99 } 100 100 … … bool CNetServerWorker::SetupConnection() 177 177 m_Host = enet_host_create(&addr, MAX_CLIENTS, CHANNEL_COUNT, 0, 0); 178 178 if (!m_Host) 179 179 { 180 LOGERROR( L"Net server: enet_host_create failed");180 LOGERROR("Net server: enet_host_create failed"); 181 181 return false; 182 182 } 183 183 … … void* CNetServerWorker::SetupUPnP(void*) 224 224 std::string rootDescURL; 225 225 CFG_GET_VAL("network.upnprootdescurl", rootDescURL); 226 226 if (!rootDescURL.empty()) 227 LOGMESSAGE( L"Net server: attempting to use cached root descriptor URL: %hs", rootDescURL.c_str());227 LOGMESSAGE("Net server: attempting to use cached root descriptor URL: %s", rootDescURL.c_str()); 228 228 229 229 int ret = 0; 230 230 bool allocatedUrls = false; … … void* CNetServerWorker::SetupUPnP(void*) 232 232 // Try a cached URL first 233 233 if (!rootDescURL.empty() && UPNP_GetIGDFromUrl(rootDescURL.c_str(), &urls, &data, internalIPAddress, sizeof(internalIPAddress))) 234 234 { 235 LOGMESSAGE( L"Net server: using cached IGD = %hs", urls.controlURL);235 LOGMESSAGE("Net server: using cached IGD = %s", urls.controlURL); 236 236 ret = 1; 237 237 } 238 238 // No cached URL, or it did not respond. Try getting a valid UPnP device for 10 seconds. … … void* CNetServerWorker::SetupUPnP(void*) 243 243 } 244 244 else 245 245 { 246 LOGMESSAGE( L"Net server: upnpDiscover failed and no working cached URL.");246 LOGMESSAGE("Net server: upnpDiscover failed and no working cached URL."); 247 247 return NULL; 248 248 } 249 249 250 250 switch (ret) 251 251 { 252 252 case 0: 253 LOGMESSAGE( L"Net server: No IGD found");253 LOGMESSAGE("Net server: No IGD found"); 254 254 break; 255 255 case 1: 256 LOGMESSAGE( L"Net server: found valid IGD = %hs", urls.controlURL);256 LOGMESSAGE("Net server: found valid IGD = %s", urls.controlURL); 257 257 break; 258 258 case 2: 259 LOGMESSAGE( L"Net server: found a valid, not connected IGD = %hs, will try to continue anyway", urls.controlURL);259 LOGMESSAGE("Net server: found a valid, not connected IGD = %s, will try to continue anyway", urls.controlURL); 260 260 break; 261 261 case 3: 262 LOGMESSAGE( L"Net server: found a UPnP device unrecognized as IGD = %hs, will try to continue anyway", urls.controlURL);262 LOGMESSAGE("Net server: found a UPnP device unrecognized as IGD = %s, will try to continue anyway", urls.controlURL); 263 263 break; 264 264 default: 265 265 debug_warn(L"Unrecognized return value from UPNP_GetValidIGD"); … … void* CNetServerWorker::SetupUPnP(void*) 269 269 ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress); 270 270 if (ret != UPNPCOMMAND_SUCCESS) 271 271 { 272 LOGMESSAGE( L"Net server: GetExternalIPAddress failed with code %d (%hs)", ret, strupnperror(ret));272 LOGMESSAGE("Net server: GetExternalIPAddress failed with code %d (%s)", ret, strupnperror(ret)); 273 273 return NULL; 274 274 } 275 LOGMESSAGE( L"Net server: ExternalIPAddress = %hs", externalIPAddress);275 LOGMESSAGE("Net server: ExternalIPAddress = %s", externalIPAddress); 276 276 277 277 // Try to setup port forwarding. 278 278 ret = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, psPort, psPort, 279 279 internalIPAddress, description, protocall, 0, leaseDuration); 280 280 if (ret != UPNPCOMMAND_SUCCESS) 281 281 { 282 LOGMESSAGE( L"Net server: AddPortMapping(%hs, %hs, %hs) failed with code %d (%hs)",282 LOGMESSAGE("Net server: AddPortMapping(%s, %s, %s) failed with code %d (%s)", 283 283 psPort, psPort, internalIPAddress, ret, strupnperror(ret)); 284 284 return NULL; 285 285 } … … void* CNetServerWorker::SetupUPnP(void*) 296 296 297 297 if (ret != UPNPCOMMAND_SUCCESS) 298 298 { 299 LOGMESSAGE( L"Net server: GetSpecificPortMappingEntry() failed with code %d (%hs)", ret, strupnperror(ret));299 LOGMESSAGE("Net server: GetSpecificPortMappingEntry() failed with code %d (%s)", ret, strupnperror(ret)); 300 300 return NULL; 301 301 } 302 302 303 LOGMESSAGE( L"Net server: External %hs:%hs %hs is redirected to internal %hs:%hs (duration=%hs)",303 LOGMESSAGE("Net server: External %s:%s %s is redirected to internal %s:%s (duration=%s)", 304 304 externalIPAddress, psPort, protocall, intClient, intPort, duration); 305 305 306 306 // Cache root descriptor URL to try to avoid discovery next time. 307 307 g_ConfigDB.SetValueString(CFG_USER, "network.upnprootdescurl", urls.controlURL); 308 308 g_ConfigDB.WriteFile(CFG_USER); 309 LOGMESSAGE( L"Net server: cached UPnP root descriptor URL as %hs", urls.controlURL);309 LOGMESSAGE("Net server: cached UPnP root descriptor URL as %s", urls.controlURL); 310 310 311 311 // Make sure everything is properly freed. 312 312 if (allocatedUrls) … … bool CNetServerWorker::RunStep() 451 451 int status = enet_host_service(m_Host, &event, HOST_SERVICE_TIMEOUT); 452 452 if (status < 0) 453 453 { 454 LOGERROR( L"CNetServerWorker: enet_host_service failed (%d)", status);454 LOGERROR("CNetServerWorker: enet_host_service failed (%d)", status); 455 455 // TODO: notify game that the server has shut down 456 456 return false; 457 457 } … … bool CNetServerWorker::RunStep() 471 471 // Report the client address 472 472 char hostname[256] = "(error)"; 473 473 enet_address_get_host_ip(&event.peer->address, hostname, ARRAY_SIZE(hostname)); 474 LOGMESSAGE( L"Net server: Received connection from %hs:%u", hostname, (unsigned int)event.peer->address.port);474 LOGMESSAGE("Net server: Received connection from %s:%u", hostname, (unsigned int)event.peer->address.port); 475 475 476 476 // Set up a session object for this peer 477 477 … … bool CNetServerWorker::RunStep() 496 496 CNetServerSession* session = static_cast<CNetServerSession*>(event.peer->data); 497 497 if (session) 498 498 { 499 LOGMESSAGE( L"Net server: Disconnected %hs", DebugName(session).c_str());499 LOGMESSAGE("Net server: Disconnected %s", DebugName(session).c_str()); 500 500 501 501 // Remove the session first, so we won't send player-update messages to it 502 502 // when updating the FSM … … bool CNetServerWorker::RunStep() 522 522 CNetMessage* msg = CNetMessageFactory::CreateMessage(event.packet->data, event.packet->dataLength, GetScriptInterface()); 523 523 if (msg) 524 524 { 525 LOGMESSAGE( L"Net server: Received message %hs of size %lu from %hs", msg->ToString().c_str(), (unsigned long)msg->GetSerializedLength(), DebugName(session).c_str());525 LOGMESSAGE("Net server: Received message %s of size %lu from %s", msg->ToString().c_str(), (unsigned long)msg->GetSerializedLength(), DebugName(session).c_str()); 526 526 527 527 HandleMessageReceive(msg, session); 528 528 … … void CNetServerWorker::HandleMessageReceive(const CNetMessage* message, CNetServ 566 566 // Update FSM 567 567 bool ok = session->Update(message->GetType(), (void*)message); 568 568 if (!ok) 569 LOGERROR( L"Net server: Error running FSM update (type=%d state=%d)", (int)message->GetType(), (int)session->GetCurrState());569 LOGERROR("Net server: Error running FSM update (type=%d state=%d)", (int)message->GetType(), (int)session->GetCurrState()); 570 570 } 571 571 572 572 void CNetServerWorker::SetupSession(CNetServerSession* session) … … bool CNetServerWorker::OnAuthenticate(void* context, CFsmEvent* event) 810 810 // Players who weren't already in the game are not allowed to join now that it's started 811 811 if (!isRejoining) 812 812 { 813 LOGMESSAGE( L"Refused connection after game start from not-previously-known user \"%ls\"", username.c_str());813 LOGMESSAGE("Refused connection after game start from not-previously-known user \"%s\"", utf8_from_wstring(username)); 814 814 session->Disconnect(NDR_SERVER_ALREADY_IN_GAME); 815 815 return true; 816 816 } -
source/network/NetSession.cpp
diff --git a/source/network/NetSession.cpp b/source/network/NetSession.cpp index 6bdaa57..82fa031 100644
a b void CNetClientSession::Poll() 112 112 // Report the server address 113 113 char hostname[256] = "(error)"; 114 114 enet_address_get_host_ip(&event.peer->address, hostname, ARRAY_SIZE(hostname)); 115 LOGMESSAGE( L"Net client: Connected to %hs:%u", hostname, (unsigned int)event.peer->address.port);115 LOGMESSAGE("Net client: Connected to %s:%u", hostname, (unsigned int)event.peer->address.port); 116 116 117 117 m_Client.HandleConnect(); 118 118 … … void CNetClientSession::Poll() 123 123 { 124 124 ENSURE(event.peer == m_Server); 125 125 126 LOGMESSAGE( L"Net client: Disconnected");126 LOGMESSAGE("Net client: Disconnected"); 127 127 m_Client.HandleDisconnect(event.data); 128 128 return; 129 129 } … … void CNetClientSession::Poll() 133 133 CNetMessage* msg = CNetMessageFactory::CreateMessage(event.packet->data, event.packet->dataLength, m_Client.GetScriptInterface()); 134 134 if (msg) 135 135 { 136 LOGMESSAGE( L"Net client: Received message %hs of size %lu from server", msg->ToString().c_str(), (unsigned long)msg->GetSerializedLength());136 LOGMESSAGE("Net client: Received message %s of size %lu from server", msg->ToString().c_str(), (unsigned long)msg->GetSerializedLength()); 137 137 138 138 m_Client.HandleMessage(msg); 139 139 -
source/network/NetTurnManager.cpp
diff --git a/source/network/NetTurnManager.cpp b/source/network/NetTurnManager.cpp index 70059ec..575dca3 100644
a b static std::wstring Hexify(const std::string& s) 57 57 return str.str(); 58 58 } 59 59 60 static std::string Hexify8(const std::string& s) 61 { 62 std::stringstream str; 63 str << std::hex; 64 for (size_t i = 0; i < s.size(); ++i) 65 str << std::setfill('0') << std::setw(2) << (int)(unsigned char)s[i]; 66 return str.str(); 67 } 68 60 69 CNetTurnManager::CNetTurnManager(CSimulation2& simulation, u32 defaultTurnLength, int clientId, IReplayLogger& replay) : 61 70 m_Simulation2(simulation), m_CurrentTurn(0), m_ReadyTurn(1), m_TurnLength(defaultTurnLength), m_DeltaSimTime(0), 62 71 m_PlayerId(-1), m_ClientId(clientId), m_HasSyncError(false), m_Replay(replay), … … void CNetTurnManager::OnSyncError(u32 turn, const std::string& expectedHash) 237 246 m_Simulation2.DumpDebugState(file); 238 247 file.close(); 239 248 240 std:: wstringstream msg;241 msg << L"Out of sync on turn " << turn << L": expected hash " << Hexify(expectedHash) << L"\n\n";242 msg << L"Current state: turn " << m_CurrentTurn << L", hash " << Hexify(hash) << L"\n\n";243 msg << L"Dumping current state to " << path;249 std::stringstream msg; 250 msg << "Out of sync on turn " << turn << ": expected hash " << Hexify8(expectedHash) << "\n\n"; 251 msg << "Current state: turn " << m_CurrentTurn << ", hash " << Hexify8(hash) << "\n\n"; 252 msg << "Dumping current state to " << utf8_from_wstring(path.string()); 244 253 if (g_GUI) 245 g_GUI->DisplayMessageBox(600, 350, L"Sync error", msg.str());254 g_GUI->DisplayMessageBox(600, 350, L"Sync error", wstring_from_utf8(msg.str())); 246 255 else 247 LOGERROR( L"%ls", msg.str().c_str());256 LOGERROR("%s", msg.str()); 248 257 } 249 258 250 259 void CNetTurnManager::Interpolate(float simFrameLength, float realFrameLength) … … void CNetTurnManager::QuickSave() 327 336 bool ok = m_Simulation2.SerializeState(stream); 328 337 if (!ok) 329 338 { 330 LOGERROR( L"Failed to quicksave game");339 LOGERROR("Failed to quicksave game"); 331 340 return; 332 341 } 333 342 … … void CNetTurnManager::QuickSave() 337 346 else 338 347 m_QuickSaveMetadata = std::string(); 339 348 340 LOGMESSAGERENDER( L"Quicksaved game");349 LOGMESSAGERENDER("Quicksaved game"); 341 350 342 351 } 343 352 … … void CNetTurnManager::QuickLoad() 347 356 348 357 if (m_QuickSaveState.empty()) 349 358 { 350 LOGERROR( L"Cannot quickload game - no game was quicksaved");359 LOGERROR("Cannot quickload game - no game was quicksaved"); 351 360 return; 352 361 } 353 362 … … void CNetTurnManager::QuickLoad() 355 364 bool ok = m_Simulation2.DeserializeState(stream); 356 365 if (!ok) 357 366 { 358 LOGERROR( L"Failed to quickload game");367 LOGERROR("Failed to quickload game"); 359 368 return; 360 369 } 361 370 362 371 if (g_GUI && !m_QuickSaveMetadata.empty()) 363 372 g_GUI->RestoreSavedGameData(m_QuickSaveMetadata); 364 373 365 LOGMESSAGERENDER( L"Quickloaded game");374 LOGMESSAGERENDER("Quickloaded game"); 366 375 367 376 // See RewindTimeWarp 368 377 ResetState(0, 1); -
source/ps/CLogger.cpp
diff --git a/source/ps/CLogger.cpp b/source/ps/CLogger.cpp index 1a68943..58cf7c2 100644
a b 1 /* Copyright (C) 201 2Wildfire Games.1 /* Copyright (C) 2015 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 25 25 #include "lib/ogl.h" 26 26 #include "lib/timer.h" 27 27 #include "lib/utf8.h" 28 #include "lib/sysdep/sysdep.h"29 28 #include "ps/Profile.h" 30 29 #include "renderer/Renderer.h" 31 30 … … CLogger::~CLogger() 140 139 } 141 140 } 142 141 143 static std::string ToHTML(const wchar_t* message)142 static std::string ToHTML(const char* message) 144 143 { 145 Status err; 146 std::string cmessage = utf8_from_wstring(message, &err); 144 std::string cmessage = message; 147 145 boost::algorithm::replace_all(cmessage, "&", "&"); 148 146 boost::algorithm::replace_all(cmessage, "<", "<"); 149 147 return cmessage; 150 148 } 151 149 152 void CLogger::WriteMessage(const wchar_t* message, bool doRender = false)150 void CLogger::WriteMessage(const char* message, bool doRender = false) 153 151 { 154 152 std::string cmessage = ToHTML(message); 155 153 … … void CLogger::WriteMessage(const wchar_t* message, bool doRender = false) 157 155 158 156 ++m_NumberOfMessages; 159 157 // if (m_UseDebugPrintf) 160 // debug_printf(L"MESSAGE: % ls\n", message);158 // debug_printf(L"MESSAGE: %hs\n", message); 161 159 162 160 *m_MainLog << "<p>" << cmessage << "</p>\n"; 163 161 m_MainLog->flush(); 164 162 165 163 if (doRender) 166 164 { 167 if (g_Console) g_Console->InsertMessage(L"INFO: % ls", message);165 if (g_Console) g_Console->InsertMessage(L"INFO: %hs", message); 168 166 169 167 PushRenderMessage(Normal, message); 170 168 } 171 169 } 172 170 173 void CLogger::WriteError(const wchar_t* message)171 void CLogger::WriteError(const char* message) 174 172 { 175 173 std::string cmessage = ToHTML(message); 176 174 … … void CLogger::WriteError(const wchar_t* message) 178 176 179 177 ++m_NumberOfErrors; 180 178 if (m_UseDebugPrintf) 181 debug_printf(L"ERROR: % ls\n", message);179 debug_printf(L"ERROR: %hs\n", message); 182 180 183 if (g_Console) g_Console->InsertMessage(L"ERROR: % ls", message);181 if (g_Console) g_Console->InsertMessage(L"ERROR: %hs", message); 184 182 *m_InterestingLog << "<p class=\"error\">ERROR: " << cmessage << "</p>\n"; 185 183 m_InterestingLog->flush(); 186 184 … … void CLogger::WriteError(const wchar_t* message) 190 188 PushRenderMessage(Error, message); 191 189 } 192 190 193 void CLogger::WriteWarning(const wchar_t* message)191 void CLogger::WriteWarning(const char* message) 194 192 { 195 193 std::string cmessage = ToHTML(message); 196 194 … … void CLogger::WriteWarning(const wchar_t* message) 198 196 199 197 ++m_NumberOfWarnings; 200 198 if (m_UseDebugPrintf) 201 debug_printf(L"WARNING: % ls\n", message);199 debug_printf(L"WARNING: %hs\n", message); 202 200 203 if (g_Console) g_Console->InsertMessage(L"WARNING: % ls", message);201 if (g_Console) g_Console->InsertMessage(L"WARNING: %hs", message); 204 202 *m_InterestingLog << "<p class=\"warning\">WARNING: " << cmessage << "</p>\n"; 205 203 m_InterestingLog->flush(); 206 204 … … void CLogger::WriteWarning(const wchar_t* message) 210 208 PushRenderMessage(Warning, message); 211 209 } 212 210 213 void CLogger::LogMessage(const wchar_t* fmt, ...)214 {215 va_list argp;216 wchar_t buffer[BUFFER_SIZE] = {0};217 218 va_start(argp, fmt);219 if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1)220 {221 // Buffer too small - ensure the string is nicely terminated222 wcscpy_s(buffer+ARRAY_SIZE(buffer)-4, 4, L"...");223 }224 va_end(argp);225 226 WriteMessage(buffer);227 }228 229 void CLogger::LogMessageRender(const wchar_t* fmt, ...)230 {231 va_list argp;232 wchar_t buffer[BUFFER_SIZE] = {0};233 234 va_start(argp, fmt);235 if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1)236 {237 // Buffer too small - ensure the string is nicely terminated238 wcscpy_s(buffer+ARRAY_SIZE(buffer)-4, 4, L"...");239 }240 va_end(argp);241 242 WriteMessage(buffer, true);243 }244 245 void CLogger::LogWarning(const wchar_t* fmt, ...)246 {247 va_list argp;248 wchar_t buffer[BUFFER_SIZE] = {0};249 250 va_start(argp, fmt);251 if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1)252 {253 // Buffer too small - ensure the string is nicely terminated254 wcscpy_s(buffer+ARRAY_SIZE(buffer)-4, 4, L"...");255 }256 va_end(argp);257 258 WriteWarning(buffer);259 }260 261 void CLogger::LogError(const wchar_t* fmt, ...)262 {263 va_list argp;264 wchar_t buffer[BUFFER_SIZE] = {0};265 266 va_start(argp, fmt);267 if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1)268 {269 // Buffer too small - ensure the string is nicely terminated270 wcscpy_s(buffer+ARRAY_SIZE(buffer)-4, 4, L"...");271 }272 va_end(argp);273 274 WriteError(buffer);275 }276 277 211 void CLogger::Render() 278 212 { 279 213 PROFILE3_GPU("logger"); … … void CLogger::Render() 300 234 301 235 for (std::deque<RenderedMessage>::iterator it = m_RenderMessages.begin(); it != m_RenderMessages.end(); ++it) 302 236 { 303 const wchar_t* type;237 const char* type; 304 238 if (it->method == Normal) 305 239 { 306 type = L"info";240 type = "info"; 307 241 textRenderer.Color(0.0f, 0.8f, 0.0f); 308 242 } 309 243 else if (it->method == Warning) 310 244 { 311 type = L"warning";245 type = "warning"; 312 246 textRenderer.Color(1.0f, 1.0f, 0.0f); 313 247 } 314 248 else 315 249 { 316 type = L"error";250 type = "error"; 317 251 textRenderer.Color(1.0f, 0.0f, 0.0f); 318 252 } 319 253 320 254 CMatrix3D savedTransform = textRenderer.GetTransform(); 321 255 322 textRenderer.PrintfAdvance(L"[%8.3f] % ls: ", it->time, type);256 textRenderer.PrintfAdvance(L"[%8.3f] %hs: ", it->time, type); 323 257 // Display the actual message in white so it's more readable 324 258 textRenderer.Color(1.0f, 1.0f, 1.0f); 325 259 textRenderer.Put(0.0f, 0.0f, it->message.c_str()); … … void CLogger::Render() 334 268 textTech->EndPass(); 335 269 } 336 270 337 void CLogger::PushRenderMessage(ELogMethod method, const wchar_t* message)271 void CLogger::PushRenderMessage(ELogMethod method, const char* message) 338 272 { 339 273 double now = timer_Time(); 340 274 341 275 // Add each message line separately 342 const wchar_t* pos = message;343 const wchar_t* eol;344 while ((eol = wcschr(pos, L'\n')) != NULL)276 const char* pos = message; 277 const char* eol; 278 while ((eol = strchr(pos, '\n')) != NULL) 345 279 { 346 280 if (eol != pos) 347 281 { 348 RenderedMessage r = { method, now, std:: wstring(pos, eol) };282 RenderedMessage r = { method, now, std::string(pos, eol) }; 349 283 m_RenderMessages.push_back(r); 350 284 } 351 285 pos = eol + 1; 352 286 } 353 287 // Add the last line, if we didn't end on a \n 354 if (*pos != L'\0')288 if (*pos != '\0') 355 289 { 356 RenderedMessage r = { method, now, std:: wstring(pos) };290 RenderedMessage r = { method, now, std::string(pos) }; 357 291 m_RenderMessages.push_back(r); 358 292 } 359 293 } … … TestLogger::~TestLogger() 398 332 g_Logger = m_OldLogger; 399 333 } 400 334 401 std:: wstring TestLogger::GetOutput()335 std::string TestLogger::GetOutput() 402 336 { 403 Status err; 404 return wstring_from_utf8(m_Stream.str(), &err); 337 return m_Stream.str(); 405 338 } 406 339 407 340 TestStdoutLogger::TestStdoutLogger() -
source/ps/CLogger.h
diff --git a/source/ps/CLogger.h b/source/ps/CLogger.h index 78e9ad8..ba23976 100644
a b 1 /* Copyright (C) 201 0Wildfire Games.1 /* Copyright (C) 2015 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 24 24 #include <sstream> 25 25 26 26 #include "ps/ThreadUtil.h" 27 #include "third_party/cppformat/format.h" 27 28 28 29 class CLogger; 29 30 extern CLogger* g_Logger; 30 31 31 32 32 #define LOGMESSAGE g_Logger->LogMessage33 #define LOGMESSAGERENDER g_Logger->LogMessageRender34 #define LOGWARNING g_Logger->LogWarning35 #define LOGERROR g_Logger->LogError33 #define LOGMESSAGE(...) g_Logger->WriteMessage(fmt::sprintf(__VA_ARGS__).c_str(), false) 34 #define LOGMESSAGERENDER(...) g_Logger->WriteMessage(fmt::sprintf(__VA_ARGS__).c_str(), true) 35 #define LOGWARNING(...) g_Logger->WriteWarning(fmt::sprintf(__VA_ARGS__).c_str()) 36 #define LOGERROR(...) g_Logger->WriteError (fmt::sprintf(__VA_ARGS__).c_str()) 36 37 37 38 /** 38 39 * Error/warning/message logging class. … … public: 64 65 65 66 // Functions to write different message types (Errors and warnings are placed 66 67 // both in mainLog and intrestingLog.) 67 void WriteMessage(const wchar_t* message, bool doRender);68 void WriteError (const wchar_t* message);69 void WriteWarning(const wchar_t* message);68 void WriteMessage(const char* message, bool doRender); 69 void WriteError (const char* message); 70 void WriteWarning(const char* message); 70 71 71 // Functions to write a message, warning or error to file.72 void LogMessage(const wchar_t* fmt, ...) WPRINTF_ARGS(2);73 void LogMessageRender(const wchar_t* fmt, ...) WPRINTF_ARGS(2);74 void LogWarning(const wchar_t* fmt, ...) WPRINTF_ARGS(2);75 void LogError(const wchar_t* fmt, ...) WPRINTF_ARGS(2);76 77 72 // Render recent log messages onto the screen 78 73 void Render(); 79 74 80 75 private: 81 76 void Init(); 82 77 83 void PushRenderMessage(ELogMethod method, const wchar_t* message);78 void PushRenderMessage(ELogMethod method, const char* message); 84 79 85 80 // Delete old timed-out entries from the list of text to render 86 81 void CleanupRenderQueue(); … … private: 104 99 { 105 100 ELogMethod method; 106 101 double time; 107 std:: wstring message;102 std::string message; 108 103 }; 109 104 std::deque<RenderedMessage> m_RenderMessages; 110 105 double m_RenderLastEraseTime; … … class TestLogger 123 118 public: 124 119 TestLogger(); 125 120 ~TestLogger(); 126 std:: wstring GetOutput();121 std::string GetOutput(); 127 122 private: 128 123 CLogger* m_OldLogger; 129 124 std::stringstream m_Stream; -
source/ps/CStrIntern.cpp
diff --git a/source/ps/CStrIntern.cpp b/source/ps/CStrIntern.cpp index 53a5098..6692b35 100644
a b public: 30 30 CStrInternInternals(const char* str, size_t len) 31 31 : data(str, str+len), hash(fnv_hash(str, len)) 32 32 { 33 // LOGWARNING( L"New interned string '%hs'", data.c_str());33 // LOGWARNING("New interned string '%s'", data.c_str()); 34 34 } 35 35 36 36 bool operator==(const CStrInternInternals& b) const -
source/ps/ConfigDB.cpp
diff --git a/source/ps/ConfigDB.cpp b/source/ps/ConfigDB.cpp index 11ce79e..ab4dca3 100644
a b bool CConfigDB::Reload(EConfigNamespace ns) 214 214 // Handle missing files quietly 215 215 if (g_VFS->GetFileInfo(m_ConfigFile[ns], NULL) < 0) 216 216 { 217 LOGMESSAGE( L"Cannot find config file \"%ls\" - ignoring", m_ConfigFile[ns].string().c_str());217 LOGMESSAGE("Cannot find config file \"%s\" - ignoring", m_ConfigFile[ns].string8()); 218 218 return false; 219 219 } 220 220 221 LOGMESSAGE( L"Loading config file \"%ls\"", m_ConfigFile[ns].string().c_str());221 LOGMESSAGE("Loading config file \"%s\"", m_ConfigFile[ns].string8()); 222 222 Status ret = g_VFS->LoadFile(m_ConfigFile[ns], buffer, buflen); 223 223 if (ret != INFO::OK) 224 224 { 225 LOGERROR( L"CConfigDB::Reload(): vfs_load for \"%ls\" failed: return was %lld", m_ConfigFile[ns].string().c_str(), (long long)ret);225 LOGERROR("CConfigDB::Reload(): vfs_load for \"%s\" failed: return was %lld", m_ConfigFile[ns].string8(), (long long)ret); 226 226 return false; 227 227 } 228 228 } … … bool CConfigDB::Reload(EConfigNamespace ns) 256 256 257 257 if (pos == filebufend || *pos == '\n') 258 258 { 259 LOGERROR( L"Config header with missing close tag encountered on line %d in '%ls'", line, m_ConfigFile[ns].string().c_str());259 LOGERROR("Config header with missing close tag encountered on line %d in '%s'", line, m_ConfigFile[ns].string8()); 260 260 header.clear(); 261 261 ++line; 262 262 continue; 263 263 } 264 264 265 LOGMESSAGE( L"Found config header '%hs'", header.c_str());265 LOGMESSAGE("Found config header '%s'", header.c_str()); 266 266 header.push_back('.'); 267 267 while (++pos < filebufend && *pos != '\n' && *pos != ';') 268 268 if (*pos != ' ' && *pos != '\r') 269 269 { 270 LOGERROR( L"Config settings on the same line as a header on line %d in '%ls'", line, m_ConfigFile[ns].string().c_str());270 LOGERROR("Config settings on the same line as a header on line %d in '%s'", line, m_ConfigFile[ns].string8()); 271 271 break; 272 272 } 273 273 while (pos < filebufend && *pos != '\n') … … bool CConfigDB::Reload(EConfigNamespace ns) 288 288 { 289 289 if (*pos == '\\' && ++pos == filebufend) 290 290 { 291 LOGERROR( L"Escape character at end of input (line %d in '%ls')", line, m_ConfigFile[ns].string().c_str());291 LOGERROR("Escape character at end of input (line %d in '%s')", line, m_ConfigFile[ns].string8()); 292 292 break; 293 293 } 294 294 … … bool CConfigDB::Reload(EConfigNamespace ns) 316 316 } 317 317 } 318 318 if (quoted) // We ignore the invalid parameter 319 LOGERROR( L"Unmatched quote while parsing config file '%ls' on line %d", m_ConfigFile[ns].string().c_str(), line);319 LOGERROR("Unmatched quote while parsing config file '%s' on line %d", m_ConfigFile[ns].string8(), line); 320 320 else if (!value.empty()) 321 321 values.push_back(value); 322 322 value.clear(); … … bool CConfigDB::Reload(EConfigNamespace ns) 337 337 CStr key(header + name); 338 338 newMap[key] = values; 339 339 if (key == "lobby.password") 340 LOGMESSAGE( L"Loaded config string \"%hs\"", key.c_str());340 LOGMESSAGE("Loaded config string \"%s\"", key); 341 341 else 342 342 { 343 343 std::string vals; 344 344 for (size_t i = 0; i < newMap[key].size() - 1; ++i) 345 345 vals += "\"" + EscapeString(newMap[key][i]) + "\", "; 346 346 vals += "\"" + EscapeString(newMap[key][values.size()-1]) + "\""; 347 LOGMESSAGE( L"Loaded config string \"%hs\" = %hs", key.c_str(), vals.c_str());347 LOGMESSAGE("Loaded config string \"%s\" = %s", key, vals); 348 348 } 349 349 } 350 350 else if (!name.empty()) 351 LOGERROR( L"Encountered config setting '%hs' without value while parsing '%ls' on line %d", name.c_str(), m_ConfigFile[ns].string().c_str(), line);351 LOGERROR("Encountered config setting '%s' without value while parsing '%s' on line %d", name, m_ConfigFile[ns].string8(), line); 352 352 353 353 name.clear(); 354 354 values.clear(); … … bool CConfigDB::Reload(EConfigNamespace ns) 356 356 } 357 357 358 358 if (!name.empty()) 359 LOGERROR( L"Config file does not have a new line after the last config setting '%hs'", name.c_str());359 LOGERROR("Config file does not have a new line after the last config setting '%s'", name); 360 360 361 361 m_Map[ns].swap(newMap); 362 362 … … bool CConfigDB::WriteFile(EConfigNamespace ns, const VfsPath& path) 393 393 Status ret = g_VFS->CreateFile(path, buf, len); 394 394 if (ret < 0) 395 395 { 396 LOGERROR( L"CConfigDB::WriteFile(): CreateFile \"%ls\" failed (error: %d)", path.string().c_str(), (int)ret);396 LOGERROR("CConfigDB::WriteFile(): CreateFile \"%s\" failed (error: %d)", path.string8(), (int)ret); 397 397 return false; 398 398 } 399 399 -
source/ps/DllLoader.cpp
diff --git a/source/ps/DllLoader.cpp b/source/ps/DllLoader.cpp index ad120fb..18151ad 100644
a b void DllLoader::LogLoadError(const char* errors) 196 196 switch (m_LoadErrorLogMethod) 197 197 { 198 198 case CLogger::Normal: 199 LOGMESSAGE( L"DllLoader: %hs", errors);199 LOGMESSAGE("DllLoader: %s", errors); 200 200 break; 201 201 case CLogger::Warning: 202 LOGWARNING( L"DllLoader: %hs", errors);202 LOGWARNING("DllLoader: %s", errors); 203 203 break; 204 204 case CLogger::Error: 205 LOGERROR( L"DllLoader: %hs", errors);205 LOGERROR("DllLoader: %s", errors); 206 206 break; 207 207 } 208 208 } -
source/ps/FileIo.cpp
diff --git a/source/ps/FileIo.cpp b/source/ps/FileIo.cpp index e06d339..f8c358e 100644
a b void CFilePacker::Write(const VfsPath& filename) 69 69 const Status st = g_VFS->CreateFile(filename, m_writeBuffer.Data(), m_writeBuffer.Size()); 70 70 if (st < 0) 71 71 { 72 LOGERROR( L"Failed to write file '%ls' with status '%lld'", filename.string().c_str(), (long long)st);72 LOGERROR("Failed to write file '%s' with status '%lld'", filename.string8(), (long long)st); 73 73 throw PSERROR_File_WriteFailed(); 74 74 } 75 75 } -
source/ps/Filesystem.cpp
diff --git a/source/ps/Filesystem.cpp b/source/ps/Filesystem.cpp index de0ba9e..be16108 100644
a b PSRETURN CVFSFile::Load(const PIVFS& vfs, const VfsPath& filename, bool log /* = 124 124 if (ret != INFO::OK) 125 125 { 126 126 if (log) 127 LOGERROR( L"CVFSFile: file %ls couldn't be opened (vfs_load: %lld)", filename.string().c_str(), (long long)ret);127 LOGERROR("CVFSFile: file %s couldn't be opened (vfs_load: %lld)", filename.string8(), (long long)ret); 128 128 m_Buffer.reset(); 129 129 m_BufferSize = 0; 130 130 return PSRETURN_CVFSFile_LoadFailed; -
source/ps/GameSetup/Config.cpp
diff --git a/source/ps/GameSetup/Config.cpp b/source/ps/GameSetup/Config.cpp index 0f18291..67fc7b2 100644
a b static void LoadGlobals() 131 131 CFG_GET_VAL("profiler2.script.enable", g_ScriptProfilingEnabled); 132 132 133 133 if (g_JSDebuggerEnabled) 134 LOGERROR( L"JS debugger temporarily disabled during the SpiderMonkey upgrade (check trac ticket #2348 for details)");134 LOGERROR("JS debugger temporarily disabled during the SpiderMonkey upgrade (check trac ticket #2348 for details)"); 135 135 // Script Debugging and profiling does not make sense together because of the hooks 136 136 // that reduce performance a lot - and it wasn't tested if it even works together. 137 137 if (g_JSDebuggerEnabled && g_ScriptProfilingEnabled) 138 LOGERROR( L"Enabling both script profiling and script debugging is not supported!");138 LOGERROR("Enabling both script profiling and script debugging is not supported!"); 139 139 } 140 140 141 141 -
source/ps/GameSetup/GameSetup.cpp
diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index 3709648..44b166e 100644
a b void Render() 293 293 #warning TODO: cursors for Android 294 294 #else 295 295 if (cursor_draw(g_VFS, cursorName.c_str(), g_mouse_x, g_yres-g_mouse_y, forceGL) < 0) 296 LOGWARNING( L"Failed to draw cursor '%ls'", cursorName.c_str());296 LOGWARNING("Failed to draw cursor '%s'", utf8_from_wstring(cursorName)); 297 297 #endif 298 298 299 299 #if CONFIG2_GLES … … static void InitSDL() 656 656 657 657 if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE) < 0) 658 658 { 659 LOGERROR( L"SDL library initialization failed: %hs", SDL_GetError());659 LOGERROR("SDL library initialization failed: %s", SDL_GetError()); 660 660 throw PSERROR_System_SDLInitFailed(); 661 661 } 662 662 atexit(SDL_Quit); … … static void FixLocales() 814 814 } 815 815 catch (std::runtime_error&) 816 816 { 817 LOGWARNING( L"Invalid locale settings");817 LOGWARNING("Invalid locale settings"); 818 818 819 819 for (size_t i = 0; i < ARRAY_SIZE(LocaleEnvVars); i++) 820 820 { 821 821 if (char* envval = getenv(LocaleEnvVars[i])) 822 LOGWARNING( L" %hs=\"%hs\"", LocaleEnvVars[i], envval);822 LOGWARNING(" %s=\"%s\"", LocaleEnvVars[i], envval); 823 823 else 824 LOGWARNING( L" %hs=\"(unset)\"", LocaleEnvVars[i]);824 LOGWARNING(" %s=\"(unset)\"", LocaleEnvVars[i]); 825 825 } 826 826 827 827 // We should set LC_ALL since it overrides LANG 828 828 if (setenv("LC_ALL", std::locale::classic().name().c_str(), 1)) 829 829 debug_warn(L"Invalid locale settings, and unable to set LC_ALL env variable."); 830 830 else 831 LOGWARNING( L"Setting LC_ALL env variable to: %hs", getenv("LC_ALL"));831 LOGWARNING("Setting LC_ALL env variable to: %s", getenv("LC_ALL")); 832 832 } 833 833 } 834 834 #else … … CStr8 LoadSettingsOfScenarioMap(const VfsPath &mapPath) 1132 1132 1133 1133 if (INFO::OK != loadResult) 1134 1134 { 1135 LOGERROR( L"LoadSettingsOfScenarioMap: Unable to load map file '%ls'", mapPath.string().c_str());1135 LOGERROR("LoadSettingsOfScenarioMap: Unable to load map file '%s'", mapPath.string8()); 1136 1136 throw PSERROR_Game_World_MapLoadFailed("Unable to load map file, check the path for typos."); 1137 1137 } 1138 1138 XMBElement mapElement = mapFile.GetRoot(); … … bool Autostart(const CmdLineArgs& args) 1246 1246 else 1247 1247 { 1248 1248 // Problem with JSON file 1249 LOGERROR( L"Autostart: Error reading random map script '%ls'", scriptPath.c_str());1249 LOGERROR("Autostart: Error reading random map script '%s'", utf8_from_wstring(scriptPath)); 1250 1250 throw PSERROR_Game_World_MapLoadFailed("Error reading random map script.\nCheck application log for details."); 1251 1251 } 1252 1252 … … bool Autostart(const CmdLineArgs& args) 1301 1301 } 1302 1302 else 1303 1303 { 1304 LOGERROR( L"Autostart: Unrecognized map type '%ls'", mapDirectory.c_str());1304 LOGERROR("Autostart: Unrecognized map type '%s'", utf8_from_wstring(mapDirectory)); 1305 1305 throw PSERROR_Game_World_MapLoadFailed("Unrecognized map type.\nConsult readme.txt for the currently supported types."); 1306 1306 } 1307 1307 scriptInterface.SetProperty(attrs, "mapType", mapType); … … bool Autostart(const CmdLineArgs& args) 1336 1336 if (mapDirectory == L"scenarios" || mapDirectory == L"skirmishes") 1337 1337 { 1338 1338 // playerID is certainly bigger than this map player number 1339 LOGWARNING( L"Autostart: Invalid player %d in autostart-ai option", playerID);1339 LOGWARNING("Autostart: Invalid player %d in autostart-ai option", playerID); 1340 1340 continue; 1341 1341 } 1342 1342 scriptInterface.Eval("({})", &player); … … bool Autostart(const CmdLineArgs& args) 1363 1363 if (mapDirectory == L"scenarios" || mapDirectory == L"skirmishes") 1364 1364 { 1365 1365 // playerID is certainly bigger than this map player number 1366 LOGWARNING( L"Autostart: Invalid player %d in autostart-aidiff option", playerID);1366 LOGWARNING("Autostart: Invalid player %d in autostart-aidiff option", playerID); 1367 1367 continue; 1368 1368 } 1369 1369 scriptInterface.Eval("({})", &player); … … bool Autostart(const CmdLineArgs& args) 1391 1391 if (mapDirectory == L"skirmishes") 1392 1392 { 1393 1393 // playerID is certainly bigger than this map player number 1394 LOGWARNING( L"Autostart: Invalid player %d in autostart-civ option", playerID);1394 LOGWARNING("Autostart: Invalid player %d in autostart-civ option", playerID); 1395 1395 continue; 1396 1396 } 1397 1397 scriptInterface.Eval("({})", &player); … … bool Autostart(const CmdLineArgs& args) 1403 1403 } 1404 1404 } 1405 1405 else 1406 LOGWARNING( L"Autostart: Option 'autostart-civ' is invalid for scenarios");1406 LOGWARNING("Autostart: Option 'autostart-civ' is invalid for scenarios"); 1407 1407 } 1408 1408 1409 1409 // Add player data to map settings -
source/ps/GameSetup/HWDetect.cpp
diff --git a/source/ps/GameSetup/HWDetect.cpp b/source/ps/GameSetup/HWDetect.cpp index 4d7668a..97276f7 100644
a b void RunHardwareDetection() 203 203 CVFSFile file; 204 204 if (file.Load(g_VFS, scriptName) != PSRETURN_OK) 205 205 { 206 LOGERROR( L"Failed to load hardware detection script");206 LOGERROR("Failed to load hardware detection script"); 207 207 return; 208 208 } 209 209 -
source/ps/GameSetup/Paths.cpp
diff --git a/source/ps/GameSetup/Paths.cpp b/source/ps/GameSetup/Paths.cpp index 7d9883e..434f02c 100644
a b Paths::Paths(const CmdLineArgs& args) 172 172 // make sure it's valid 173 173 if(!FileExists(pathname)) 174 174 { 175 LOGERROR( L"Cannot find executable (expected at '%ls')", pathname.string().c_str());175 LOGERROR("Cannot find executable (expected at '%s')", pathname.string8()); 176 176 WARN_IF_ERR(StatusFromErrno()); 177 177 } 178 178 -
source/ps/Hotkey.cpp
diff --git a/source/ps/Hotkey.cpp b/source/ps/Hotkey.cpp index 22ceeba..42cc72a 100644
a b static void LoadConfigBindings() 83 83 int mapping = FindKeyCode(*it); 84 84 if (!mapping) 85 85 { 86 LOGWARNING( L"Hotkey mapping used invalid key '%hs'", hotkey.c_str());86 LOGWARNING("Hotkey mapping used invalid key '%s'", hotkey.c_str()); 87 87 continue; 88 88 } 89 89 -
source/ps/Joystick.cpp
diff --git a/source/ps/Joystick.cpp b/source/ps/Joystick.cpp index 2950620..d219f1d 100644
a b void CJoystick::Initialise() 41 41 42 42 if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) 43 43 { 44 LOGERROR( L"CJoystick::Initialise failed to initialise joysticks (\"%hs\")", SDL_GetError());44 LOGERROR("CJoystick::Initialise failed to initialise joysticks (\"%s\")", SDL_GetError()); 45 45 return; 46 46 } 47 47 48 48 int numJoysticks = SDL_NumJoysticks(); 49 49 50 LOGMESSAGE( L"Found %d joystick(s)", numJoysticks);50 LOGMESSAGE("Found %d joystick(s)", numJoysticks); 51 51 52 52 for (int i = 0; i < numJoysticks; ++i) 53 53 { … … void CJoystick::Initialise() 55 55 SDL_Joystick* stick = SDL_JoystickOpen(i); 56 56 if (!stick) 57 57 { 58 LOGERROR( L"CJoystick::Initialise failed to open joystick %d (\"%hs\")", i, SDL_GetError());58 LOGERROR("CJoystick::Initialise failed to open joystick %d (\"%s\")", i, SDL_GetError()); 59 59 continue; 60 60 } 61 61 const char* name = SDL_JoystickName(stick); 62 62 #else // SDL 1.2 63 63 const char* name = SDL_JoystickName(i); 64 64 #endif 65 LOGMESSAGE( L"Joystick %d: %hs", i, name);65 LOGMESSAGE("Joystick %d: %s", i, name); 66 66 #if SDL_VERSION_ATLEAST(2, 0, 0) 67 67 SDL_JoystickClose(stick); 68 68 #endif … … void CJoystick::Initialise() 75 75 // Always pick the first joystick, and assume that's the right one 76 76 m_Joystick = SDL_JoystickOpen(0); 77 77 if (!m_Joystick) 78 LOGERROR( L"CJoystick::Initialise failed to open joystick (\"%hs\")", SDL_GetError());78 LOGERROR("CJoystick::Initialise failed to open joystick (\"%s\")", SDL_GetError()); 79 79 } 80 80 } 81 81 -
source/ps/Overlay.cpp
diff --git a/source/ps/Overlay.cpp b/source/ps/Overlay.cpp index f09d3d2..2bf190c 100644
a b bool CColor::ParseString(const CStr8& Value, int DefaultAlpha) 48 48 stream >> values[i]; 49 49 if ((stream.rdstate() & std::stringstream::failbit) != 0) 50 50 { 51 LOGWARNING( L"Unable to parse CColor parameters. Your input: '%hs'", Value.c_str());51 LOGWARNING("Unable to parse CColor parameters. Your input: '%s'", Value.c_str()); 52 52 return false; 53 53 } 54 54 if (values[i] < 0 || values[i] > 255) 55 55 { 56 LOGWARNING( L"Invalid value (<0 or >255) when parsing CColor parameters. Your input: '%hs'", Value.c_str());56 LOGWARNING("Invalid value (<0 or >255) when parsing CColor parameters. Your input: '%s'", Value.c_str()); 57 57 return false; 58 58 } 59 59 } 60 60 61 61 if (i < 3) 62 62 { 63 LOGWARNING( L"Not enough parameters when parsing as CColor. Your input: '%hs'", Value.c_str());63 LOGWARNING("Not enough parameters when parsing as CColor. Your input: '%s'", Value.c_str()); 64 64 return false; 65 65 } 66 66 if (!stream.eof()) 67 67 { 68 LOGWARNING( L"Too many parameters when parsing as CColor. Your input: '%hs'", Value.c_str());68 LOGWARNING("Too many parameters when parsing as CColor. Your input: '%s'", Value.c_str()); 69 69 return false; 70 70 } 71 71 -
source/ps/Preprocessor.cpp
diff --git a/source/ps/Preprocessor.cpp b/source/ps/Preprocessor.cpp index d7c228d..f3a9ede 100644
a b static void DefaultError (void *iData, int iLine, const char *iError, 231 231 { 232 232 (void)iData; 233 233 if (iToken) 234 LOGERROR( L"Preprocessor error: line %d: %hs: '%.*hs'\n",234 LOGERROR("Preprocessor error: line %d: %s: '%.*hs'\n", 235 235 iLine, iError, int (iTokenLen), iToken); 236 236 else 237 LOGERROR( L"Preprocessor error: line %d: %hs\n", iLine, iError);237 LOGERROR("Preprocessor error: line %d: %s\n", iLine, iError); 238 238 } 239 239 240 240 //---------------------------------------------------------------------------// -
source/ps/PreprocessorWrapper.cpp
diff --git a/source/ps/PreprocessorWrapper.cpp b/source/ps/PreprocessorWrapper.cpp index 720edb1..f4ca4ce 100644
a b bool CPreprocessorWrapper::TestConditional(const CStr& expr) 51 51 52 52 if (!output) 53 53 { 54 LOGERROR( L"Failed to parse conditional expression '%hs'", expr.c_str());54 LOGERROR("Failed to parse conditional expression '%s'", expr.c_str()); 55 55 return false; 56 56 } 57 57 … … CStr CPreprocessorWrapper::Preprocess(const CStr& input) 72 72 73 73 if (!output) 74 74 { 75 LOGERROR( L"Shader preprocessing failed");75 LOGERROR("Shader preprocessing failed"); 76 76 return ""; 77 77 } 78 78 -
source/ps/ProfileViewer.cpp
diff --git a/source/ps/ProfileViewer.cpp b/source/ps/ProfileViewer.cpp index e976e90..d1ef938 100644
a b void CProfileViewer::SaveToFile() 570 570 571 571 if (m->outputStream.fail()) 572 572 { 573 LOGERROR( L"Failed to open profile log file");573 LOGERROR("Failed to open profile log file"); 574 574 return; 575 575 } 576 576 else 577 577 { 578 LOGMESSAGERENDER( L"Profiler snapshot saved to '%ls'", path.string().c_str());578 LOGMESSAGERENDER("Profiler snapshot saved to '%s'", path.string8()); 579 579 } 580 580 } 581 581 -
source/ps/Profiler2.cpp
diff --git a/source/ps/Profiler2.cpp b/source/ps/Profiler2.cpp index ae49b0c..5f8a505 100644
a b static void* MgCallback(mg_event event, struct mg_connection *conn, const struct 126 126 127 127 case MG_EVENT_LOG: 128 128 // Called by Mongoose's cry() 129 LOGERROR( L"Mongoose error: %hs", request_info->log_message);129 LOGERROR("Mongoose error: %s", request_info->log_message); 130 130 return NULL; 131 131 132 132 case MG_INIT_SSL: … … void CProfiler2::InitialiseGPU() 157 157 void CProfiler2::EnableHTTP() 158 158 { 159 159 ENSURE(m_Initialised); 160 LOGMESSAGERENDER( L"Starting profiler2 HTTP server");160 LOGMESSAGERENDER("Starting profiler2 HTTP server"); 161 161 162 162 // Ignore multiple enablings 163 163 if (m_MgContext) … … void CProfiler2::EnableGPU() 177 177 ENSURE(m_Initialised); 178 178 if (!m_GPU) 179 179 { 180 LOGMESSAGERENDER( L"Starting profiler2 GPU mode");180 LOGMESSAGERENDER("Starting profiler2 GPU mode"); 181 181 InitialiseGPU(); 182 182 } 183 183 } 184 184 185 185 void CProfiler2::ShutdownGPU() 186 186 { 187 LOGMESSAGERENDER( L"Shutting down profiler2 GPU mode");187 LOGMESSAGERENDER("Shutting down profiler2 GPU mode"); 188 188 SAFE_DELETE(m_GPU); 189 189 } 190 190 191 191 void CProfiler2::ShutDownHTTP() 192 192 { 193 LOGMESSAGERENDER( L"Shutting down profiler2 HTTP server");193 LOGMESSAGERENDER("Shutting down profiler2 HTTP server"); 194 194 if (m_MgContext) 195 195 { 196 196 mg_stop(m_MgContext); -
source/ps/SavedGame.cpp
diff --git a/source/ps/SavedGame.cpp b/source/ps/SavedGame.cpp index 007dcb2..94421b5 100644
a b Status SavedGames::Save(const std::wstring& name, const std::wstring& descriptio 126 126 127 127 OsPath realPath; 128 128 WARN_RETURN_STATUS_IF_ERR(g_VFS->GetRealPath(filename, realPath)); 129 LOGMESSAGERENDER( wstring_from_utf8(g_L10n.Translate("Saved game to '%ls'") + "\n").c_str(), realPath.string().c_str());129 LOGMESSAGERENDER(g_L10n.Translate("Saved game to '%s'"), realPath.string8()); 130 130 131 131 return INFO::OK; 132 132 } … … std::vector<CScriptValRooted> SavedGames::GetSavedGames(ScriptInterface& scriptI 244 244 if (!archiveReader) 245 245 { 246 246 // Triggered by e.g. the file being open in another program 247 LOGWARNING( L"Failed to read saved game '%ls'", realPath.string().c_str());247 LOGWARNING("Failed to read saved game '%s'", realPath.string8()); 248 248 continue; // skip this file 249 249 } 250 250 -
source/ps/TemplateLoader.cpp
diff --git a/source/ps/TemplateLoader.cpp b/source/ps/TemplateLoader.cpp index d2e8345..dba610f 100644
a b bool CTemplateLoader::LoadTemplateFile(const std::string& templateName, int dept 39 39 // Handle infinite loops more gracefully than running out of stack space and crashing 40 40 if (depth > 100) 41 41 { 42 LOGERROR( L"Probable infinite inheritance loop in entity template '%hs'", templateName.c_str());42 LOGERROR("Probable infinite inheritance loop in entity template '%s'", templateName.c_str()); 43 43 return false; 44 44 } 45 45 … … bool CTemplateLoader::LoadTemplateFile(const std::string& templateName, int dept 57 57 std::string baseName = templateName.substr(8); 58 58 if (!LoadTemplateFile(baseName, depth+1)) 59 59 { 60 LOGERROR( L"Failed to load entity template '%hs'", baseName.c_str());60 LOGERROR("Failed to load entity template '%s'", baseName.c_str()); 61 61 return false; 62 62 } 63 63 // Copy a subset to the requested template … … bool CTemplateLoader::LoadTemplateFile(const std::string& templateName, int dept 72 72 std::string baseName = templateName.substr(7); 73 73 if (!LoadTemplateFile(baseName, depth+1)) 74 74 { 75 LOGERROR( L"Failed to load entity template '%hs'", baseName.c_str());75 LOGERROR("Failed to load entity template '%s'", baseName.c_str()); 76 76 return false; 77 77 } 78 78 // Copy a subset to the requested template … … bool CTemplateLoader::LoadTemplateFile(const std::string& templateName, int dept 87 87 std::string baseName = templateName.substr(7); 88 88 if (!LoadTemplateFile(baseName, depth+1)) 89 89 { 90 LOGERROR( L"Failed to load entity template '%hs'", baseName.c_str());90 LOGERROR("Failed to load entity template '%s'", baseName.c_str()); 91 91 return false; 92 92 } 93 93 // Copy a subset to the requested template … … bool CTemplateLoader::LoadTemplateFile(const std::string& templateName, int dept 102 102 std::string baseName = templateName.substr(11); 103 103 if (!LoadTemplateFile(baseName, depth+1)) 104 104 { 105 LOGERROR( L"Failed to load entity template '%hs'", baseName.c_str());105 LOGERROR("Failed to load entity template '%s'", baseName.c_str()); 106 106 return false; 107 107 } 108 108 // Copy a subset to the requested template … … bool CTemplateLoader::LoadTemplateFile(const std::string& templateName, int dept 117 117 std::string baseName = templateName.substr(13); 118 118 if (!LoadTemplateFile(baseName, depth+1)) 119 119 { 120 LOGERROR( L"Failed to load entity template '%hs'", baseName.c_str());120 LOGERROR("Failed to load entity template '%s'", baseName.c_str()); 121 121 return false; 122 122 } 123 123 // Copy a subset to the requested template … … bool CTemplateLoader::LoadTemplateFile(const std::string& templateName, int dept 132 132 std::string baseName = templateName.substr(9); 133 133 if (!LoadTemplateFile(baseName, depth+1)) 134 134 { 135 LOGERROR( L"Failed to load entity template '%hs'", baseName.c_str());135 LOGERROR("Failed to load entity template '%s'", baseName.c_str()); 136 136 return false; 137 137 } 138 138 // Copy a subset to the requested template … … bool CTemplateLoader::LoadTemplateFile(const std::string& templateName, int dept 155 155 // To prevent needless complexity in template design, we don't allow |-separated strings as parents 156 156 if (parentName.find('|') != parentName.npos) 157 157 { 158 LOGERROR( L"Invalid parent '%hs' in entity template '%hs'", parentName.c_str(), templateName.c_str());158 LOGERROR("Invalid parent '%s' in entity template '%s'", parentName.c_str(), templateName.c_str()); 159 159 return false; 160 160 } 161 161 162 162 // Ensure the parent is loaded 163 163 if (!LoadTemplateFile(parentName, depth+1)) 164 164 { 165 LOGERROR( L"Failed to load parent '%hs' of entity template '%hs'", parentName.c_str(), templateName.c_str());165 LOGERROR("Failed to load parent '%s' of entity template '%s'", parentName.c_str(), templateName.c_str()); 166 166 return false; 167 167 } 168 168 … … std::vector<std::string> CTemplateLoader::FindPlaceableTemplates(const std::stri 272 272 } 273 273 274 274 if (templatesType != SIMULATION_TEMPLATES && templatesType != ACTOR_TEMPLATES && templatesType != ALL_TEMPLATES) 275 LOGERROR( L"Undefined template type (valid: all, simulation, actor)");275 LOGERROR("Undefined template type (valid: all, simulation, actor)"); 276 276 277 277 return templates; 278 278 } … … std::vector<std::string> CTemplateLoader::FindTemplates(const std::string& path, 304 304 } 305 305 306 306 if (templatesType != SIMULATION_TEMPLATES && templatesType != ACTOR_TEMPLATES && templatesType != ALL_TEMPLATES) 307 LOGERROR( L"Undefined template type (valid: all, simulation, actor)");307 LOGERROR("Undefined template type (valid: all, simulation, actor)"); 308 308 309 309 return templates; 310 310 } … … const CParamNode& CTemplateLoader::GetTemplateFileData(const std::string& templa 314 314 // Load the template if necessary 315 315 if (!LoadTemplateFile(templateName, 0)) 316 316 { 317 LOGERROR( L"Failed to load entity template '%hs'", templateName.c_str());317 LOGERROR("Failed to load entity template '%s'", templateName.c_str()); 318 318 return NULL_NODE; 319 319 } 320 320 … … void CTemplateLoader::ConstructTemplateActor(const std::string& actorName, CPara 327 327 const char* templateName = "special/actor"; 328 328 if (!LoadTemplateFile(templateName, 0)) 329 329 { 330 LOGERROR( L"Failed to load entity template '%hs'", templateName);330 LOGERROR("Failed to load entity template '%s'", templateName); 331 331 return; 332 332 } 333 333 -
source/ps/Util.cpp
diff --git a/source/ps/Util.cpp b/source/ps/Util.cpp index 3817112..17c58d1 100644
a b void WriteScreenshot(const VfsPath& extension) 241 241 { 242 242 OsPath realPath; 243 243 g_VFS->GetRealPath(filename, realPath); 244 LOGMESSAGERENDER( wstring_from_utf8(g_L10n.Translate("Screenshot written to '%ls'")).c_str(), realPath.string().c_str());244 LOGMESSAGERENDER(g_L10n.Translate("Screenshot written to '%s'"), realPath.string8()); 245 245 } 246 246 else 247 LOGERROR( L"Error writing screenshot to '%ls'", filename.string().c_str());247 LOGERROR("Error writing screenshot to '%s'", filename.string8()); 248 248 } 249 249 250 250 … … void WriteBigScreenshot(const VfsPath& extension, int tiles) 374 374 { 375 375 OsPath realPath; 376 376 g_VFS->GetRealPath(filename, realPath); 377 LOGMESSAGERENDER(wstring_from_utf8(g_L10n.Translate("Screenshot written to '%ls'")).c_str(), realPath.string().c_str());377 LOGMESSAGERENDER(g_L10n.Translate("Screenshot written to '%s'"), realPath.string8()); 378 378 } 379 379 else 380 LOGERROR( L"Error writing screenshot to '%ls'", filename.string().c_str());380 LOGERROR("Error writing screenshot to '%s'", filename.string8()); 381 381 382 382 free(tile_data); 383 383 } -
source/ps/VideoMode.cpp
diff --git a/source/ps/VideoMode.cpp b/source/ps/VideoMode.cpp index 7ff6870..08b6a44 100644
a b bool CVideoMode::SetVideoMode(int w, int h, int bpp, bool fullscreen) 88 88 // If fullscreen fails, try windowed mode 89 89 if (fullscreen) 90 90 { 91 LOGWARNING( L"Failed to set the video mode to fullscreen for the chosen resolution "92 L"%dx%d:%d (\"%hs\"), falling back to windowed mode",91 LOGWARNING("Failed to set the video mode to fullscreen for the chosen resolution " 92 "%dx%d:%d (\"%hs\"), falling back to windowed mode", 93 93 w, h, bpp, SDL_GetError()); 94 94 // Using default size for the window for now, as the attempted setting 95 95 // could be as large, or larger than the screen size. … … bool CVideoMode::SetVideoMode(int w, int h, int bpp, bool fullscreen) 97 97 } 98 98 else 99 99 { 100 LOGERROR( L"SetVideoMode failed in SDL_CreateWindow: %dx%d:%d %d (\"%hs\")",100 LOGERROR("SetVideoMode failed in SDL_CreateWindow: %dx%d:%d %d (\"%s\")", 101 101 w, h, bpp, fullscreen ? 1 : 0, SDL_GetError()); 102 102 return false; 103 103 } … … bool CVideoMode::SetVideoMode(int w, int h, int bpp, bool fullscreen) 105 105 106 106 if (SDL_SetWindowDisplayMode(m_Window, NULL) < 0) 107 107 { 108 LOGERROR( L"SetVideoMode failed in SDL_SetWindowDisplayMode: %dx%d:%d %d (\"%hs\")",108 LOGERROR("SetVideoMode failed in SDL_SetWindowDisplayMode: %dx%d:%d %d (\"%s\")", 109 109 w, h, bpp, fullscreen ? 1 : 0, SDL_GetError()); 110 110 return false; 111 111 } … … bool CVideoMode::SetVideoMode(int w, int h, int bpp, bool fullscreen) 113 113 SDL_GLContext context = SDL_GL_CreateContext(m_Window); 114 114 if (!context) 115 115 { 116 LOGERROR( L"SetVideoMode failed in SDL_GL_CreateContext: %dx%d:%d %d (\"%hs\")",116 LOGERROR("SetVideoMode failed in SDL_GL_CreateContext: %dx%d:%d %d (\"%s\")", 117 117 w, h, bpp, fullscreen ? 1 : 0, SDL_GetError()); 118 118 return false; 119 119 } … … bool CVideoMode::SetVideoMode(int w, int h, int bpp, bool fullscreen) 132 132 133 133 if (SDL_SetWindowFullscreen(m_Window, flags) < 0) 134 134 { 135 LOGERROR( L"SetVideoMode failed in SDL_SetWindowFullscreen: %dx%d:%d %d (\"%hs\")",135 LOGERROR("SetVideoMode failed in SDL_SetWindowFullscreen: %dx%d:%d %d (\"%s\")", 136 136 w, h, bpp, fullscreen ? 1 : 0, SDL_GetError()); 137 137 return false; 138 138 } … … bool CVideoMode::SetVideoMode(int w, int h, int bpp, bool fullscreen) 172 172 // If fullscreen fails, try windowed mode 173 173 if (fullscreen) 174 174 { 175 LOGWARNING( L"Failed to set the video mode to fullscreen for the chosen resolution "176 L"%dx%d:%d (\"%hs\"), falling back to windowed mode",175 LOGWARNING("Failed to set the video mode to fullscreen for the chosen resolution " 176 "%dx%d:%d (\"%hs\"), falling back to windowed mode", 177 177 w, h, bpp, SDL_GetError()); 178 178 // Using default size for the window for now, as the attempted setting 179 179 // could be as large, or larger than the screen size. … … bool CVideoMode::SetVideoMode(int w, int h, int bpp, bool fullscreen) 181 181 } 182 182 else 183 183 { 184 LOGERROR( L"SetVideoMode failed: %dx%d:%d %d (\"%hs\")",184 LOGERROR("SetVideoMode failed: %dx%d:%d %d (\"%s\")", 185 185 w, h, bpp, fullscreen ? 1 : 0, SDL_GetError()); 186 186 return false; 187 187 } … … bool CVideoMode::InitSDL() 294 294 u16 ramp[256]; 295 295 SDL_CalculateGammaRamp(g_Gamma, ramp); 296 296 if (SDL_SetWindowGammaRamp(m_Window, ramp, ramp, ramp) < 0) 297 LOGWARNING( L"SDL_SetWindowGammaRamp failed");297 LOGWARNING("SDL_SetWindowGammaRamp failed"); 298 298 #else 299 299 # if OS_MACOSX 300 300 // Workaround for crash on Mavericks, see http://trac.wildfiregames.com/ticket/2272 … … bool CVideoMode::InitSDL() 304 304 { 305 305 # endif 306 306 if (SDL_SetGamma(g_Gamma, g_Gamma, g_Gamma) < 0) 307 LOGWARNING( L"SDL_SetGamma failed");307 LOGWARNING("SDL_SetGamma failed"); 308 308 # if OS_MACOSX 309 309 } 310 310 # endif -
source/ps/World.cpp
diff --git a/source/ps/World.cpp b/source/ps/World.cpp index 879825d..5a20b3c 100644
a b void CWorld::RegisterInit(const CStrW& mapFile, const CScriptValRooted& settings 89 89 catch (PSERROR_File& err) 90 90 { 91 91 delete reader; 92 LOGERROR( L"Failed to load map %ls: %hs", mapfilename.string().c_str(), err.what());92 LOGERROR("Failed to load map %s: %s", mapfilename.string8(), err.what()); 93 93 throw PSERROR_Game_World_MapLoadFailed("Failed to load map.\nCheck application log for details."); 94 94 } 95 95 } -
source/ps/XML/RelaxNG.cpp
diff --git a/source/ps/XML/RelaxNG.cpp b/source/ps/XML/RelaxNG.cpp index 8a63869..57d6344 100644
a b public: 46 46 xmlRelaxNGFreeParserCtxt(ctxt); 47 47 48 48 if (m_Schema == NULL) 49 LOGERROR( L"RelaxNGValidator: Failed to compile schema");49 LOGERROR("RelaxNGValidator: Failed to compile schema"); 50 50 } 51 51 52 52 ~RelaxNGSchema() … … bool RelaxNGValidator::ValidateEncoded(const std::wstring& filename, const std:: 108 108 109 109 if (!m_Schema) 110 110 { 111 LOGERROR( L"RelaxNGValidator: No grammar loaded");111 LOGERROR("RelaxNGValidator: No grammar loaded"); 112 112 return false; 113 113 } 114 114 115 115 xmlDocPtr doc = xmlReadMemory(document.c_str(), (int)document.size(), utf8_from_wstring(filename).c_str(), NULL, XML_PARSE_NONET); 116 116 if (doc == NULL) 117 117 { 118 LOGERROR( L"RelaxNGValidator: Failed to parse document");118 LOGERROR("RelaxNGValidator: Failed to parse document"); 119 119 return false; 120 120 } 121 121 … … bool RelaxNGValidator::ValidateEncoded(const std::wstring& filename, const std:: 130 130 } 131 131 else if (ret > 0) 132 132 { 133 LOGERROR( L"RelaxNGValidator: Validation failed");133 LOGERROR("RelaxNGValidator: Validation failed"); 134 134 return false; 135 135 } 136 136 else 137 137 { 138 LOGERROR( L"RelaxNGValidator: Internal error %d", ret);138 LOGERROR("RelaxNGValidator: Internal error %d", ret); 139 139 return false; 140 140 } 141 141 } -
source/ps/XML/XMLWriter.cpp
diff --git a/source/ps/XML/XMLWriter.cpp b/source/ps/XML/XMLWriter.cpp index e77ce17..9c3e9a0 100644
a b bool XMLWriter_File::StoreVFS(const PIVFS& vfs, const VfsPath& pathname) 102 102 Status ret = vfs->CreateFile(pathname, data, size); 103 103 if (ret < 0) 104 104 { 105 LOGERROR( L"Error saving XML data through VFS: %lld '%ls'", (long long)ret, pathname.string().c_str());105 LOGERROR("Error saving XML data through VFS: %lld '%s'", (long long)ret, pathname.string8()); 106 106 return false; 107 107 } 108 108 return true; -
source/ps/XML/Xeromyces.cpp
diff --git a/source/ps/XML/Xeromyces.cpp b/source/ps/XML/Xeromyces.cpp index e7b2e57..68ba0c6 100644
a b static void errorHandler(void* UNUSED(userData), xmlErrorPtr error) 38 38 if (message.length() > 0 && message[message.length()-1] == '\n') 39 39 message.erase(message.length()-1); 40 40 41 LOGERROR( L"CXeromyces: Parse %ls: %hs:%d: %hs",42 error->level == XML_ERR_WARNING ? L"warning" : L"error",43 error->file, error->line, message .c_str());41 LOGERROR("CXeromyces: Parse %s: %s:%d: %s", 42 error->level == XML_ERR_WARNING ? "warning" : "error", 43 error->file, error->line, message); 44 44 // TODO: The (non-fatal) warnings and errors don't get stored in the XMB, 45 45 // so the caching is less transparent than it should be 46 46 } … … PSRETURN CXeromyces::Load(const PIVFS& vfs, const VfsPath& filename) 89 89 90 90 // No source file or archive cache was found, so we can't load the 91 91 // XML file at all 92 LOGERROR( L"CCacheLoader failed to find archived or source file for: \"%ls\"", filename.string().c_str());92 LOGERROR("CCacheLoader failed to find archived or source file for: \"%s\"", filename.string8()); 93 93 return PSRETURN_Xeromyces_XMLOpenFailed; 94 94 } 95 95 … … PSRETURN CXeromyces::ConvertFile(const PIVFS& vfs, const VfsPath& filename, cons 111 111 CVFSFile input; 112 112 if (input.Load(vfs, filename)) 113 113 { 114 LOGERROR( L"CXeromyces: Failed to open XML file %ls", filename.string().c_str());114 LOGERROR("CXeromyces: Failed to open XML file %s", filename.string8()); 115 115 return PSRETURN_Xeromyces_XMLOpenFailed; 116 116 } 117 117 … … PSRETURN CXeromyces::ConvertFile(const PIVFS& vfs, const VfsPath& filename, cons 120 120 filename8.c_str(), NULL, XML_PARSE_NONET|XML_PARSE_NOCDATA); 121 121 if (! doc) 122 122 { 123 LOGERROR( L"CXeromyces: Failed to parse XML file %ls", filename.string().c_str());123 LOGERROR("CXeromyces: Failed to parse XML file %s", filename.string8()); 124 124 return PSRETURN_Xeromyces_XMLParseError; 125 125 } 126 126 … … PSRETURN CXeromyces::LoadString(const char* xml) 167 167 xmlDocPtr doc = xmlReadMemory(xml, (int)strlen(xml), "", NULL, XML_PARSE_NONET|XML_PARSE_NOCDATA); 168 168 if (! doc) 169 169 { 170 LOGERROR( L"CXeromyces: Failed to parse XML string");170 LOGERROR("CXeromyces: Failed to parse XML string"); 171 171 return PSRETURN_Xeromyces_XMLParseError; 172 172 } 173 173 -
source/ps/XML/tests/test_RelaxNG.h
diff --git a/source/ps/XML/tests/test_RelaxNG.h b/source/ps/XML/tests/test_RelaxNG.h index 0cb11c6..3b10986 100644
a b public: 44 44 { 45 45 TestLogger logger; 46 46 TS_ASSERT(!v.Validate(L"doc", L"<bogus/>")); 47 TS_ASSERT_ WSTR_CONTAINS(logger.GetOutput(), L"Parse error: doc:1: Expecting element test, got bogus");47 TS_ASSERT_STR_CONTAINS(logger.GetOutput(), "Parse error: doc:1: Expecting element test, got bogus"); 48 48 } 49 49 50 50 { 51 51 TestLogger logger; 52 52 TS_ASSERT(!v.Validate(L"doc", L"bogus")); 53 TS_ASSERT_ WSTR_CONTAINS(logger.GetOutput(), L"RelaxNGValidator: Failed to parse document");53 TS_ASSERT_STR_CONTAINS(logger.GetOutput(), "RelaxNGValidator: Failed to parse document"); 54 54 } 55 55 56 56 TS_ASSERT(v.Validate(L"doc", L"<test/>")); … … public: 82 82 83 83 TestLogger logger; 84 84 TS_ASSERT(!v.LoadGrammar("whoops")); 85 TS_ASSERT_ WSTR_CONTAINS(logger.GetOutput(), L"RelaxNGValidator: Failed to compile schema");85 TS_ASSERT_STR_CONTAINS(logger.GetOutput(), "RelaxNGValidator: Failed to compile schema"); 86 86 87 87 TS_ASSERT(!v.Validate(L"doc", L"<test/>")); 88 88 } -
source/ps/scripting/JSInterface_ConfigDB.cpp
diff --git a/source/ps/scripting/JSInterface_ConfigDB.cpp b/source/ps/scripting/JSInterface_ConfigDB.cpp index 43c6a4d..319db0e 100644
a b bool JSI_ConfigDB::GetConfigNamespace(std::wstring cfgNsString, EConfigNamespace 35 35 cfgNs = CFG_MOD; 36 36 else 37 37 { 38 LOGERROR( L"Invalid namespace name passed to the ConfigDB!");38 LOGERROR("Invalid namespace name passed to the ConfigDB!"); 39 39 cfgNs = CFG_DEFAULT; 40 40 return false; 41 41 } -
source/ps/scripting/JSInterface_Console.cpp
diff --git a/source/ps/scripting/JSInterface_Console.cpp b/source/ps/scripting/JSInterface_Console.cpp index bc7ab85..d65d9a9 100644
a b bool JSI_Console::CheckGlobalInitialized() 26 26 { 27 27 if (!g_Console) 28 28 { 29 LOGERROR( L"Trying to access the console when it's not initialized!");29 LOGERROR("Trying to access the console when it's not initialized!"); 30 30 return false; 31 31 } 32 32 return true; -
source/ps/scripting/JSInterface_VFS.cpp
diff --git a/source/ps/scripting/JSInterface_VFS.cpp b/source/ps/scripting/JSInterface_VFS.cpp index ccc804b..bf74daf 100644
a b 36 36 }\ 37 37 /* unknown failure. We output an error message. */\ 38 38 else if (err < 0)\ 39 LOGERROR( L"Unknown failure in VFS %i", err );39 LOGERROR("Unknown failure in VFS %i", err ); 40 40 /* else: success */ 41 41 42 42 -
source/ps/tests/test_CLogger.h
diff --git a/source/ps/tests/test_CLogger.h b/source/ps/tests/test_CLogger.h index 285abd6..8d1dc34 100644
a b class TestCLogger : public CxxTest::TestSuite 24 24 public: 25 25 void test_basic() 26 26 { 27 logger-> LogMessage(L"Test 1");28 logger-> LogMessage(L"Test 2");27 logger->WriteMessage("Test 1", false); 28 logger->WriteMessage("Test 2", false); 29 29 30 30 ParseOutput(); 31 31 … … public: 34 34 TS_ASSERT_EQUALS(lines[1], "Test 2"); 35 35 } 36 36 37 void test_ overflow()37 void test_unicode() 38 38 { 39 const int buflen = 1024; 40 41 std::string msg0 (buflen-2, '*'); 42 std::string msg1 (buflen-1, '*'); 43 std::string msg2 (buflen, '*'); 44 std::string msg3 (buflen+1, '*'); 45 46 std::string clipped (buflen-4, '*'); 47 clipped += "..."; 48 49 logger->LogMessage(L"%hs", msg0.c_str()); 50 logger->LogMessage(L"%hs", msg1.c_str()); 51 logger->LogMessage(L"%hs", msg2.c_str()); 52 logger->LogMessage(L"%hs", msg3.c_str()); 53 54 logger->LogMessageRender(L"%hs", msg0.c_str()); 55 logger->LogMessageRender(L"%hs", msg1.c_str()); 56 logger->LogMessageRender(L"%hs", msg2.c_str()); 57 logger->LogMessageRender(L"%hs", msg3.c_str()); 58 59 logger->LogWarning(L"%hs", msg0.c_str()); 60 logger->LogWarning(L"%hs", msg1.c_str()); 61 logger->LogWarning(L"%hs", msg2.c_str()); 62 logger->LogWarning(L"%hs", msg3.c_str()); 63 64 logger->LogError(L"%hs", msg0.c_str()); 65 logger->LogError(L"%hs", msg1.c_str()); 66 logger->LogError(L"%hs", msg2.c_str()); 67 logger->LogError(L"%hs", msg3.c_str()); 39 wchar_t str[] = { 226, 32, 295, 0 }; 40 logger->WriteMessage(utf8_from_wstring(str).c_str(), false); 68 41 69 42 ParseOutput(); 70 43 71 TS_ASSERT_EQUALS((int)lines.size(), 4*4); 72 TS_ASSERT_EQUALS(lines[0], msg0); 73 TS_ASSERT_EQUALS(lines[1], msg1); 74 TS_ASSERT_EQUALS(lines[2], clipped); 75 TS_ASSERT_EQUALS(lines[3], clipped); 76 77 TS_ASSERT_EQUALS(lines[4], msg0); 78 TS_ASSERT_EQUALS(lines[5], msg1); 79 TS_ASSERT_EQUALS(lines[6], clipped); 80 TS_ASSERT_EQUALS(lines[7], clipped); 81 82 TS_ASSERT_EQUALS(lines[8], "WARNING: "+msg0); 83 TS_ASSERT_EQUALS(lines[9], "WARNING: "+msg1); 84 TS_ASSERT_EQUALS(lines[10], "WARNING: "+clipped); 85 TS_ASSERT_EQUALS(lines[11], "WARNING: "+clipped); 86 87 TS_ASSERT_EQUALS(lines[12], "ERROR: "+msg0); 88 TS_ASSERT_EQUALS(lines[13], "ERROR: "+msg1); 89 TS_ASSERT_EQUALS(lines[14], "ERROR: "+clipped); 90 TS_ASSERT_EQUALS(lines[15], "ERROR: "+clipped); 44 TS_ASSERT_EQUALS((int)lines.size(), 1); 45 TS_ASSERT_EQUALS(lines[0], "\xC3\xA2 \xC4\xA7"); 91 46 } 92 47 93 void test_ unicode()48 void test_html() 94 49 { 95 logger-> LogMessage(L"%lc %lc", 226, 295);50 logger->WriteMessage("Test<a&b>c<d&e>", false); 96 51 97 52 ParseOutput(); 98 53 99 54 TS_ASSERT_EQUALS((int)lines.size(), 1); 100 TS_ASSERT_EQUALS(lines[0], " \xC3\xA2 \xC4\xA7");55 TS_ASSERT_EQUALS(lines[0], "Test<a&b>c<d&e>"); 101 56 } 102 57 103 void test_ html()58 void test_null() 104 59 { 105 logger-> LogMessage(L"Test<a&b>c<d&e>");60 logger->WriteMessage(fmt::sprintf("a %s b", (const char *)NULL).c_str(), false); 106 61 107 62 ParseOutput(); 108 63 109 64 TS_ASSERT_EQUALS((int)lines.size(), 1); 110 TS_ASSERT_EQUALS(lines[0], " Test<a&b>c<d&e>");65 TS_ASSERT_EQUALS(lines[0], "a (null) b"); 111 66 } 112 67 113 68 ////////////////////////////////////////////////////////////////////////// -
source/renderer/DecalRData.cpp
diff --git a/source/renderer/DecalRData.cpp b/source/renderer/DecalRData.cpp index 0c85902..363f7b4 100644
a b void CDecalRData::RenderDecals(std::vector<CDecalRData*>& decals, const CShaderD 84 84 85 85 if (material.GetShaderEffect().length() == 0) 86 86 { 87 LOGERROR( L"Terrain renderer failed to load shader effect.\n");87 LOGERROR("Terrain renderer failed to load shader effect.\n"); 88 88 continue; 89 89 } 90 90 … … void CDecalRData::RenderDecals(std::vector<CDecalRData*>& decals, const CShaderD 98 98 99 99 if (!techBase) 100 100 { 101 LOGERROR( L"Terrain renderer failed to load shader effect (%hs)\n",101 LOGERROR("Terrain renderer failed to load shader effect (%s)\n", 102 102 material.GetShaderEffect().string().c_str()); 103 103 continue; 104 104 } -
source/renderer/ModelRenderer.cpp
diff --git a/source/renderer/ModelRenderer.cpp b/source/renderer/ModelRenderer.cpp index 3737f61..941b4e2 100644
a b void ModelRenderer::BuildPositionAndNormals( 98 98 // some broken situations 99 99 if (numVertices && vertices[0].m_Blend.m_Bone[0] == 0xff) 100 100 { 101 LOGERROR( L"Model %ls is boned with unboned animation", mdef->GetName().string().c_str());101 LOGERROR("Model %s is boned with unboned animation", mdef->GetName().string8()); 102 102 return; 103 103 } 104 104 -
source/renderer/PatchRData.cpp
diff --git a/source/renderer/PatchRData.cpp b/source/renderer/PatchRData.cpp index c8c5553..2604567 100644
a b void CPatchRData::RenderBases(const std::vector<CPatchRData*>& patches, const CS 766 766 { 767 767 if (itt->first->GetMaterial().GetShaderEffect().length() == 0) 768 768 { 769 LOGERROR( L"Terrain renderer failed to load shader effect.\n");769 LOGERROR("Terrain renderer failed to load shader effect.\n"); 770 770 continue; 771 771 } 772 772 -
source/renderer/PostprocManager.cpp
diff --git a/source/renderer/PostprocManager.cpp b/source/renderer/PostprocManager.cpp index 0dadb89..81cc923 100644
a b void CPostprocManager::RecreateBuffers() 159 159 GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 160 160 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) 161 161 { 162 LOGWARNING( L"Framebuffer object incomplete (A): 0x%04X", status);162 LOGWARNING("Framebuffer object incomplete (A): 0x%04X", status); 163 163 } 164 164 165 165 pglGenFramebuffersEXT(1, &m_PongFbo); … … void CPostprocManager::RecreateBuffers() 174 174 status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 175 175 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) 176 176 { 177 LOGWARNING( L"Framebuffer object incomplete (B): 0x%04X", status);177 LOGWARNING("Framebuffer object incomplete (B): 0x%04X", status); 178 178 } 179 179 180 180 pglGenFramebuffersEXT(1, &m_BloomFbo); … … void CPostprocManager::RecreateBuffers() 187 187 status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 188 188 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) 189 189 { 190 LOGWARNING( L"Framebuffer object incomplete (B): 0x%04X", status);190 LOGWARNING("Framebuffer object incomplete (B): 0x%04X", status); 191 191 } 192 192 */ 193 193 … … std::vector<CStrW> CPostprocManager::GetPostEffects() 519 519 520 520 VfsPaths pathnames; 521 521 if(vfs::GetPathnames(g_VFS, path, 0, pathnames) < 0) 522 LOGERROR( L"Error finding Post effects in '%ls'", path.string().c_str());522 LOGERROR("Error finding Post effects in '%s'", path.string8()); 523 523 524 524 for(size_t i = 0; i < pathnames.size(); i++) 525 525 { -
source/renderer/Renderer.cpp
diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 404d90a..3fe81ab 100644
a b bool CRenderer::Open(int width, int height) 636 636 637 637 GLint bits; 638 638 glGetIntegerv(GL_DEPTH_BITS,&bits); 639 LOGMESSAGE( L"CRenderer::Open: depth bits %d",bits);639 LOGMESSAGE("CRenderer::Open: depth bits %d",bits); 640 640 glGetIntegerv(GL_STENCIL_BITS,&bits); 641 LOGMESSAGE( L"CRenderer::Open: stencil bits %d",bits);641 LOGMESSAGE("CRenderer::Open: stencil bits %d",bits); 642 642 glGetIntegerv(GL_ALPHA_BITS,&bits); 643 LOGMESSAGE( L"CRenderer::Open: alpha bits %d",bits);643 LOGMESSAGE("CRenderer::Open: alpha bits %d",bits); 644 644 645 645 // Validate the currently selected render path 646 646 SetRenderPath(m_Options.m_RenderPath); … … void CRenderer::SetRenderPath(RenderPath rp) 808 808 { 809 809 if (!(m_Caps.m_ARBProgram || (m_Caps.m_VertexShader && m_Caps.m_FragmentShader && m_Options.m_PreferGLSL))) 810 810 { 811 LOGWARNING( L"Falling back to fixed function\n");811 LOGWARNING("Falling back to fixed function\n"); 812 812 rp = RP_FIXED; 813 813 } 814 814 } … … CRenderer::RenderPath CRenderer::GetRenderPathByName(const CStr& name) 843 843 if (name == "default") 844 844 return RP_DEFAULT; 845 845 846 LOGWARNING( L"Unknown render path name '%hs', assuming 'default'", name.c_str());846 LOGWARNING("Unknown render path name '%s', assuming 'default'", name.c_str()); 847 847 return RP_DEFAULT; 848 848 } 849 849 … … void CRenderer::EndFrame() 1629 1629 int err = glGetError(); 1630 1630 if (err) 1631 1631 { 1632 ONCE(LOGERROR( L"CRenderer::EndFrame: GL errors %i occurred", err));1632 ONCE(LOGERROR("CRenderer::EndFrame: GL errors %i occurred", err)); 1633 1633 } 1634 1634 } 1635 1635 } -
source/renderer/ShadowMap.cpp
diff --git a/source/renderer/ShadowMap.cpp b/source/renderer/ShadowMap.cpp index f776175..934eefd 100644
a b void ShadowMapInternals::CreateTexture() 406 406 default: formatname = "DEPTH_COMPONENT"; break; 407 407 } 408 408 409 LOGMESSAGE( L"Creating shadow texture (size %dx%d) (format = %hs)",409 LOGMESSAGE("Creating shadow texture (size %dx%d) (format = %s)", 410 410 Width, Height, formatname); 411 411 412 412 … … void ShadowMapInternals::CreateTexture() 494 494 495 495 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) 496 496 { 497 LOGWARNING( L"Framebuffer object incomplete: 0x%04X", status);497 LOGWARNING("Framebuffer object incomplete: 0x%04X", status); 498 498 499 499 // Disable shadow rendering (but let the user try again if they want) 500 500 g_Renderer.m_Options.m_Shadows = false; -
source/renderer/SkyManager.cpp
diff --git a/source/renderer/SkyManager.cpp b/source/renderer/SkyManager.cpp index e0368e7..d65c054 100644
a b void SkyManager::LoadSkyTextures() 126 126 if (g_VFS->LoadFile(path2, file, fileSize) < 0) 127 127 { 128 128 glDeleteTextures(1, &m_SkyCubeMap); 129 LOGERROR( L"Error creating sky cubemap.");129 LOGERROR("Error creating sky cubemap."); 130 130 return; 131 131 } 132 132 } … … std::vector<CStrW> SkyManager::GetSkySets() const 207 207 DirectoryNames subdirectories; 208 208 if(g_VFS->GetDirectoryEntries(path, 0, &subdirectories) < 0) 209 209 { 210 LOGERROR( L"Error opening directory '%ls'", path.string().c_str());210 LOGERROR("Error opening directory '%s'", path.string8()); 211 211 return std::vector<CStrW>(1, GetSkySet()); // just return what we currently have 212 212 } 213 213 -
source/renderer/TerrainRenderer.cpp
diff --git a/source/renderer/TerrainRenderer.cpp b/source/renderer/TerrainRenderer.cpp index 4f6d9bc..026f49b 100644
a b bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr 653 653 654 654 if (!m->fancyWaterShader) 655 655 { 656 LOGERROR( L"Failed to load water shader. Falling back to fixed pipeline water.\n");656 LOGERROR("Failed to load water shader. Falling back to fixed pipeline water.\n"); 657 657 WaterMgr->m_RenderWater = false; 658 658 return false; 659 659 } -
source/renderer/VertexBufferManager.cpp
diff --git a/source/renderer/VertexBufferManager.cpp b/source/renderer/VertexBufferManager.cpp index d9ada2f..3911efa 100644
a b CVertexBuffer::VBChunk* CVertexBufferManager::Allocate(size_t vertexSize, size_t 87 87 88 88 if (!result) 89 89 { 90 LOGERROR( L"Failed to create VBOs (%lu*%lu)", (unsigned long)vertexSize, (unsigned long)numVertices);90 LOGERROR("Failed to create VBOs (%lu*%lu)", (unsigned long)vertexSize, (unsigned long)numVertices); 91 91 } 92 92 93 93 return result; -
source/renderer/WaterManager.cpp
diff --git a/source/renderer/WaterManager.cpp b/source/renderer/WaterManager.cpp index aa66016..2e48d34 100644
a b int WaterManager::LoadWaterTextures() 326 326 GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 327 327 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) 328 328 { 329 LOGWARNING( L"Reflection framebuffer object incomplete: 0x%04X", status);329 LOGWARNING("Reflection framebuffer object incomplete: 0x%04X", status); 330 330 g_Renderer.m_Options.m_WaterReflection = false; 331 331 } 332 332 … … int WaterManager::LoadWaterTextures() 341 341 status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 342 342 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) 343 343 { 344 LOGWARNING( L"Refraction framebuffer object incomplete: 0x%04X", status);344 LOGWARNING("Refraction framebuffer object incomplete: 0x%04X", status); 345 345 g_Renderer.m_Options.m_WaterRefraction = false; 346 346 } 347 347 … … int WaterManager::LoadWaterTextures() 356 356 status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 357 357 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) 358 358 { 359 LOGWARNING( L"Fancy Effects framebuffer object incomplete: 0x%04X", status);359 LOGWARNING("Fancy Effects framebuffer object incomplete: 0x%04X", status); 360 360 g_Renderer.m_Options.m_WaterRefraction = false; 361 361 } 362 362 -
source/scriptinterface/DebuggingServer.cpp
diff --git a/source/scriptinterface/DebuggingServer.cpp b/source/scriptinterface/DebuggingServer.cpp index fa484b0..366a1c1 100644
a b CDebuggingServer::CDebuggingServer() : 94 94 m_SettingBreakOnException = true; 95 95 96 96 EnableHTTP(); 97 LOGWARNING( L"Javascript debugging webserver enabled.");97 LOGWARNING("Javascript debugging webserver enabled."); 98 98 } 99 99 100 100 CDebuggingServer::~CDebuggingServer() … … void* CDebuggingServer::MgDebuggingServerCallback(mg_event event, struct mg_conn 396 396 397 397 case MG_EVENT_LOG: 398 398 // Called by Mongoose's cry() 399 LOGERROR( L"Mongoose error: %hs", request_info->log_message);399 LOGERROR("Mongoose error: %s", request_info->log_message); 400 400 return NULL; 401 401 402 402 case MG_INIT_SSL: -
source/scriptinterface/ScriptInterface.cpp
diff --git a/source/scriptinterface/ScriptInterface.cpp b/source/scriptinterface/ScriptInterface.cpp index d87ab68..a86ab5d 100644
a b void ErrorReporter(JSContext* cx, const char* message, JSErrorReport* report) 126 126 } 127 127 128 128 if (isWarning) 129 LOGWARNING( L"%hs", msg.str().c_str());129 LOGWARNING("%s", msg.str().c_str()); 130 130 else 131 LOGERROR( L"%hs", msg.str().c_str());131 LOGERROR("%s", msg.str().c_str()); 132 132 133 133 // When running under Valgrind, print more information in the error message 134 134 // VALGRIND_PRINTF_BACKTRACE("->"); … … JSBool logmsg(JSContext* cx, uint argc, jsval* vp) 163 163 std::wstring str; 164 164 if (!ScriptInterface::FromJSVal(cx, args.handleAt(0), str)) 165 165 return JS_FALSE; 166 LOGMESSAGE( L"%ls", str.c_str());166 LOGMESSAGE("%s", utf8_from_wstring(str)); 167 167 args.rval().setUndefined(); 168 168 return JS_TRUE; 169 169 } … … JSBool warn(JSContext* cx, uint argc, jsval* vp) 180 180 std::wstring str; 181 181 if (!ScriptInterface::FromJSVal(cx, args.handleAt(0), str)) 182 182 return JS_FALSE; 183 LOGWARNING( L"%ls", str.c_str());183 LOGWARNING("%s", utf8_from_wstring(str)); 184 184 args.rval().setUndefined(); 185 185 return JS_TRUE; 186 186 } … … JSBool error(JSContext* cx, uint argc, jsval* vp) 197 197 std::wstring str; 198 198 if (!ScriptInterface::FromJSVal(cx, args.handleAt(0), str)) 199 199 return JS_FALSE; 200 LOGERROR( L"%ls", str.c_str());200 LOGERROR("%s", utf8_from_wstring(str)); 201 201 args.rval().setUndefined(); 202 202 return JS_TRUE; 203 203 } … … ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugN 420 420 if (g_JSDebuggerEnabled && g_DebuggingServer != NULL) 421 421 { 422 422 if(!JS_SetDebugMode(GetContext(), true)) 423 LOGERROR( L"Failed to set Spidermonkey to debug mode!");423 LOGERROR("Failed to set Spidermonkey to debug mode!"); 424 424 else 425 425 g_DebuggingServer->RegisterScriptinterface(debugName, this); 426 426 } */ … … bool ScriptInterface::LoadGlobalScripts() 478 478 { 479 479 if (!LoadGlobalScriptFile(*it)) 480 480 { 481 LOGERROR( L"LoadGlobalScripts: Failed to load script %ls", it->string().c_str());481 LOGERROR("LoadGlobalScripts: Failed to load script %s", it->string8()); 482 482 return false; 483 483 } 484 484 } … … bool ScriptInterface::ReplaceNondeterministicRNG(boost::rand48& rng) 507 507 } 508 508 } 509 509 510 LOGERROR( L"ReplaceNondeterministicRNG: failed to replace Math.random");510 LOGERROR("ReplaceNondeterministicRNG: failed to replace Math.random"); 511 511 return false; 512 512 } 513 513 … … void ScriptInterface::CallConstructor(JS::HandleValue ctor, JS::AutoValueVector& 543 543 JSAutoRequest rq(m->m_cx); 544 544 if (!ctor.isObject()) 545 545 { 546 LOGERROR( L"CallConstructor: ctor is not an object");546 LOGERROR("CallConstructor: ctor is not an object"); 547 547 out.setNull(); 548 548 return; 549 549 } … … bool ScriptInterface::EnumeratePropertyNamesWithPrefix(JS::HandleValue objVal, c 750 750 751 751 if (!objVal.isObjectOrNull()) 752 752 { 753 LOGERROR( L"EnumeratePropertyNamesWithPrefix expected object type!");753 LOGERROR("EnumeratePropertyNamesWithPrefix expected object type!"); 754 754 return false; 755 755 } 756 756 … … bool ScriptInterface::LoadGlobalScriptFile(const VfsPath& path) 866 866 JSAutoRequest rq(m->m_cx); 867 867 if (!VfsFileExists(path)) 868 868 { 869 LOGERROR( L"File '%ls' does not exist", path.string().c_str());869 LOGERROR("File '%s' does not exist", path.string8()); 870 870 return false; 871 871 } 872 872 … … bool ScriptInterface::LoadGlobalScriptFile(const VfsPath& path) 876 876 877 877 if (ret != PSRETURN_OK) 878 878 { 879 LOGERROR( L"Failed to load file '%ls': %hs", path.string().c_str(), GetErrorString(ret));879 LOGERROR("Failed to load file '%s': %s", path.string8(), GetErrorString(ret)); 880 880 return false; 881 881 } 882 882 … … bool ScriptInterface::ParseJSON(const std::string& string_utf8, JS::MutableHandl 926 926 if (JS_ParseJSON(m->m_cx, reinterpret_cast<const jschar*>(string.c_str()), (u32)string.size(), out)) 927 927 return true; 928 928 929 LOGERROR( L"JS_ParseJSON failed!");929 LOGERROR("JS_ParseJSON failed!"); 930 930 if (!JS_IsExceptionPending(m->m_cx)) 931 931 return false; 932 932 … … bool ScriptInterface::ParseJSON(const std::string& string_utf8, JS::MutableHandl 946 946 947 947 std::wstring error; 948 948 ScriptInterface::FromJSVal(m->m_cx, rval, error); 949 LOGERROR( L"%ls", error.c_str());949 LOGERROR("%s", utf8_from_wstring(error)); 950 950 return false; 951 951 } 952 952 … … void ScriptInterface::ReadJSONFile(const VfsPath& path, JS::MutableHandleValue o 954 954 { 955 955 if (!VfsFileExists(path)) 956 956 { 957 LOGERROR( L"File '%ls' does not exist", path.string().c_str());957 LOGERROR("File '%s' does not exist", path.string8()); 958 958 return; 959 959 } 960 960 … … void ScriptInterface::ReadJSONFile(const VfsPath& path, JS::MutableHandleValue o 964 964 965 965 if (ret != PSRETURN_OK) 966 966 { 967 LOGERROR( L"Failed to load file '%ls': %hs", path.string().c_str(), GetErrorString(ret));967 LOGERROR("Failed to load file '%s': %s", path.string8(), GetErrorString(ret)); 968 968 return; 969 969 } 970 970 971 971 std::string content(file.DecodeUTF8()); // assume it's UTF-8 972 972 973 973 if (!ParseJSON(content, out)) 974 LOGERROR( L"Failed to parse '%ls'", path.string().c_str());974 LOGERROR("Failed to parse '%s'", path.string8()); 975 975 } 976 976 977 977 struct Stringifier … … std::string ScriptInterface::StringifyJSON(JS::MutableHandleValue obj, bool inde 1011 1011 if (!JS_Stringify(m->m_cx, obj.address(), NULL, indentVal, &Stringifier::callback, &str)) 1012 1012 { 1013 1013 JS_ClearPendingException(m->m_cx); 1014 LOGERROR( L"StringifyJSON failed");1014 LOGERROR("StringifyJSON failed"); 1015 1015 return std::string(); 1016 1016 } 1017 1017 -
source/scriptinterface/ThreadDebugger.cpp
diff --git a/source/scriptinterface/ThreadDebugger.cpp b/source/scriptinterface/ThreadDebugger.cpp index e9eebbc..f5d9768 100644
a b JSTrapStatus CThreadDebugger::BreakHandler(JSContext* cx, JSScript* script, jsby 493 493 *m->m_pLastBreakFrame = JS_FrameIterator(m->m_pScriptInterface->GetContext(), &iter); 494 494 495 495 if (!JS_SetSingleStepMode(cx, script, true)) 496 LOGERROR( L"JS_SetSingleStepMode returned false!"); // TODO: When can this happen?496 LOGERROR("JS_SetSingleStepMode returned false!"); // TODO: When can this happen? 497 497 else 498 498 { 499 499 if (nextDbgCmd == DBG_CMD_SINGLESTEP) … … JSTrapStatus CThreadDebugger::BreakHandler(JSContext* cx, JSScript* script, jsby 516 516 else if (nextDbgCmd == DBG_CMD_CONTINUE) 517 517 { 518 518 if (!JS_SetSingleStepMode(cx, script, true)) 519 LOGERROR( L"JS_SetSingleStepMode returned false!"); // TODO: When can this happen?519 LOGERROR("JS_SetSingleStepMode returned false!"); // TODO: When can this happen? 520 520 else 521 521 { 522 522 // Setup a handler to check for break-requests from the DebuggingServer regularly … … std::string CThreadDebugger::StringifyCyclicJSON(jsval obj, bool indent) 846 846 JSObject* replacer = JS_GetFunctionObject(fun); 847 847 if (!JS_Stringify(m->m_pScriptInterface->GetContext(), &obj, replacer, indent ? INT_TO_JSVAL(2) : JSVAL_VOID, &CyclicRefWorkaround::Stringifier::callback, &str)) 848 848 { 849 LOGERROR( L"StringifyJSON failed");849 LOGERROR("StringifyJSON failed"); 850 850 jsval exec; 851 851 jsval execString; 852 852 if (JS_GetPendingException(m->m_pScriptInterface->GetContext(), &exec)) … … std::string CThreadDebugger::StringifyCyclicJSON(jsval obj, bool indent) 858 858 if (JSVAL_IS_STRING(execString)) 859 859 { 860 860 std::string strExec = JS_EncodeString(m->m_pScriptInterface->GetContext(), JSVAL_TO_STRING(execString)); 861 LOGERROR( L"Error: %hs", strExec.c_str());861 LOGERROR("Error: %s", strExec.c_str()); 862 862 } 863 863 } 864 864 -
source/scriptinterface/tests/test_ScriptInterface.h
diff --git a/source/scriptinterface/tests/test_ScriptInterface.h b/source/scriptinterface/tests/test_ScriptInterface.h index 3089ea6..e966ee4 100644
a b public: 31 31 ScriptInterface script("Test", "Test", g_ScriptRuntime); 32 32 TestLogger logger; 33 33 TS_ASSERT(script.LoadScript(L"test.js", "var x = 1+1;")); 34 TS_ASSERT_ WSTR_NOT_CONTAINS(logger.GetOutput(), L"JavaScript error");35 TS_ASSERT_ WSTR_NOT_CONTAINS(logger.GetOutput(), L"JavaScript warning");34 TS_ASSERT_STR_NOT_CONTAINS(logger.GetOutput(), "JavaScript error"); 35 TS_ASSERT_STR_NOT_CONTAINS(logger.GetOutput(), "JavaScript warning"); 36 36 } 37 37 38 38 void test_loadscript_error() … … public: 40 40 ScriptInterface script("Test", "Test", g_ScriptRuntime); 41 41 TestLogger logger; 42 42 TS_ASSERT(!script.LoadScript(L"test.js", "1+")); 43 TS_ASSERT_ WSTR_CONTAINS(logger.GetOutput(), L"JavaScript error: test.js line 1\nSyntaxError: syntax error");43 TS_ASSERT_STR_CONTAINS(logger.GetOutput(), "JavaScript error: test.js line 1\nSyntaxError: syntax error"); 44 44 } 45 45 46 46 void test_loadscript_strict_warning() … … public: 49 49 TestLogger logger; 50 50 // in strict mode, this inside a function doesn't point to the global object 51 51 TS_ASSERT(script.LoadScript(L"test.js", "var isStrict = (function() { return !this; })();warn('isStrict is '+isStrict);")); 52 TS_ASSERT_ WSTR_CONTAINS(logger.GetOutput(), L"WARNING: isStrict is true");52 TS_ASSERT_STR_CONTAINS(logger.GetOutput(), "WARNING: isStrict is true"); 53 53 } 54 54 55 55 void test_loadscript_strict_error() … … public: 57 57 ScriptInterface script("Test", "Test", g_ScriptRuntime); 58 58 TestLogger logger; 59 59 TS_ASSERT(!script.LoadScript(L"test.js", "with(1){}")); 60 TS_ASSERT_ WSTR_CONTAINS(logger.GetOutput(), L"JavaScript error: test.js line 1\nSyntaxError: strict mode code may not contain \'with\' statements");60 TS_ASSERT_STR_CONTAINS(logger.GetOutput(), "JavaScript error: test.js line 1\nSyntaxError: strict mode code may not contain \'with\' statements"); 61 61 } 62 62 63 63 void test_clone_basic() -
source/simulation2/Simulation2.cpp
diff --git a/source/simulation2/Simulation2.cpp b/source/simulation2/Simulation2.cpp index 4e5a366..ac70109 100644
a b bool CSimulation2Impl::LoadScripts(CComponentManager& componentManager, std::set 187 187 VfsPath filename = *it; 188 188 if (loadedScripts) 189 189 loadedScripts->insert(filename); 190 LOGMESSAGE( L"Loading simulation script '%ls'", filename.string().c_str());190 LOGMESSAGE("Loading simulation script '%s'", filename.string8()); 191 191 if (!componentManager.LoadScript(filename)) 192 192 ok = false; 193 193 } … … bool CSimulation2Impl::LoadTriggerScripts(CComponentManager& componentManager, J 204 204 for (u32 i = 0; i < scriptNames.size(); ++i) 205 205 { 206 206 std::string scriptName = "maps/" + scriptNames[i]; 207 LOGMESSAGE( L"Loading trigger script '%hs'", scriptName.c_str());207 LOGMESSAGE("Loading trigger script '%s'", scriptName.c_str()); 208 208 if (!componentManager.LoadScript(scriptName.data())) 209 209 ok = false; 210 210 } … … Status CSimulation2Impl::ReloadChangedFile(const VfsPath& path) 224 224 if (!VfsFileExists(path)) 225 225 return INFO::OK; 226 226 227 LOGMESSAGE( L"Reloading simulation script '%ls'", path.string().c_str());227 LOGMESSAGE("Reloading simulation script '%s'", path.string8()); 228 228 if (!m_ComponentManager.LoadScript(path, true)) 229 229 return ERR::FAIL; 230 230 … … static std::vector<std::string> GetJSONData(const VfsPath& path) 828 828 { 829 829 // Some error reading directory 830 830 wchar_t error[200]; 831 LOGERROR( L"Error reading directory '%ls': %ls", path.string().c_str(), StatusDescription(ret, error, ARRAY_SIZE(error)));831 LOGERROR("Error reading directory '%s': %s", path.string8(), utf8_from_wstring(StatusDescription(ret, error, ARRAY_SIZE(error)))); 832 832 return std::vector<std::string>(); 833 833 } 834 834 … … static std::vector<std::string> GetJSONData(const VfsPath& path) 840 840 PSRETURN ret = file.Load(g_VFS, *it); 841 841 if (ret != PSRETURN_OK) 842 842 { 843 LOGERROR( L"GetJSONData: Failed to load file '%ls': %hs", path.string().c_str(), GetErrorString(ret));843 LOGERROR("GetJSONData: Failed to load file '%s': %s", path.string8(), GetErrorString(ret)); 844 844 continue; 845 845 } 846 846 … … static std::string ReadJSON(const VfsPath& path) 864 864 { 865 865 if (!VfsFileExists(path)) 866 866 { 867 LOGERROR( L"File '%ls' does not exist", path.string().c_str());867 LOGERROR("File '%s' does not exist", path.string8()); 868 868 return std::string(); 869 869 } 870 870 … … static std::string ReadJSON(const VfsPath& path) 873 873 PSRETURN ret = file.Load(g_VFS, path); 874 874 if (ret != PSRETURN_OK) 875 875 { 876 LOGERROR( L"Failed to load file '%ls': %hs", path.string().c_str(), GetErrorString(ret));876 LOGERROR("Failed to load file '%s': %s", path.string8(), GetErrorString(ret)); 877 877 return std::string(); 878 878 } 879 879 -
source/simulation2/components/CCmpAIManager.cpp
diff --git a/source/simulation2/components/CCmpAIManager.cpp b/source/simulation2/components/CCmpAIManager.cpp index ac1c542..e2a067a 100644
a b private: 104 104 m_Worker.LoadMetadata(path, &metadata); 105 105 if (metadata.isUndefined()) 106 106 { 107 LOGERROR( L"Failed to create AI player: can't find %ls", path.string().c_str());107 LOGERROR("Failed to create AI player: can't find %s", path.string8()); 108 108 return false; 109 109 } 110 110 … … private: 116 116 JS::RootedValue ctor(cx); 117 117 if (!m_ScriptInterface->HasProperty(metadata, "moduleName")) 118 118 { 119 LOGERROR( L"Failed to create AI player: %ls: missing 'moduleName'", path.string().c_str());119 LOGERROR("Failed to create AI player: %s: missing 'moduleName'", path.string8()); 120 120 return false; 121 121 } 122 122 … … private: 124 124 if (!m_ScriptInterface->GetProperty(global, moduleName.c_str(), &objectWithConstructor) 125 125 || objectWithConstructor.isUndefined()) 126 126 { 127 LOGERROR( L"Failed to create AI player: %ls: can't find the module that should contain the constructor: '%hs'", path.string().c_str(), moduleName.c_str());127 LOGERROR("Failed to create AI player: %s: can't find the module that should contain the constructor: '%s'", path.string8(), moduleName); 128 128 return false; 129 129 } 130 130 131 131 if (!m_ScriptInterface->GetProperty(metadata, "constructor", constructor)) 132 132 { 133 LOGERROR( L"Failed to create AI player: %ls: missing 'constructor'", path.string().c_str());133 LOGERROR("Failed to create AI player: %s: missing 'constructor'", path.string8()); 134 134 return false; 135 135 } 136 136 … … private: 138 138 if (!m_ScriptInterface->GetProperty(objectWithConstructor, constructor.c_str(), &ctor) 139 139 || ctor.isNull()) 140 140 { 141 LOGERROR( L"Failed to create AI player: %ls: can't find constructor '%hs'", path.string().c_str(), constructor.c_str());141 LOGERROR("Failed to create AI player: %s: can't find constructor '%s'", path.string8(), constructor); 142 142 return false; 143 143 } 144 144 … … private: 160 160 161 161 if (obj.isNull()) 162 162 { 163 LOGERROR( L"Failed to create AI player: %ls: error calling constructor '%hs'", path.string().c_str(), constructor.c_str());163 LOGERROR("Failed to create AI player: %s: error calling constructor '%s'", path.string8(), constructor); 164 164 return false; 165 165 } 166 166 … … public: 261 261 VfsPaths pathnames; 262 262 if (vfs::GetPathnames(g_VFS, L"simulation/ai/" + moduleName + L"/", L"*.js", pathnames) < 0) 263 263 { 264 LOGERROR( L"Failed to load AI scripts for module %ls", moduleName.c_str());264 LOGERROR("Failed to load AI scripts for module %s", utf8_from_wstring(moduleName)); 265 265 return false; 266 266 } 267 267 … … public: 269 269 { 270 270 if (!m_ScriptInterface->LoadGlobalScriptFile(*it)) 271 271 { 272 LOGERROR( L"Failed to load script %ls", it->string().c_str());272 LOGERROR("Failed to load script %s", it->string8()); 273 273 return false; 274 274 } 275 275 } … … public: 308 308 } 309 309 } 310 310 311 LOGERROR( L"Invalid playerid in PostCommand!");311 LOGERROR("Invalid playerid in PostCommand!"); 312 312 } 313 313 // The next two ought to be implmeneted someday but for now as it returns "null" it can't 314 314 static void DumpHeap(ScriptInterface::CxPrivate* pCxPrivate) … … public: 391 391 JS::RootedValue ctor(cx); 392 392 if (!m_ScriptInterface->GetProperty(global, "API3", &AIModule) || AIModule.isUndefined()) 393 393 { 394 LOGERROR( L"Failed to create shared AI component: %ls: can't find module '%hs'", path.string().c_str(), "API3");394 LOGERROR("Failed to create shared AI component: %s: can't find module '%s'", path.string8(), "API3"); 395 395 return false; 396 396 } 397 397 398 398 if (!m_ScriptInterface->GetProperty(AIModule, "SharedScript", &ctor) 399 399 || ctor.isUndefined()) 400 400 { 401 LOGERROR( L"Failed to create shared AI component: %ls: can't find constructor '%hs'", path.string().c_str(), "SharedScript");401 LOGERROR("Failed to create shared AI component: %s: can't find constructor '%s'", path.string8(), "SharedScript"); 402 402 return false; 403 403 } 404 404 … … public: 440 440 441 441 if (tmpSharedAIObj.isNull()) 442 442 { 443 LOGERROR( L"Failed to create shared AI component: %ls: error calling constructor '%hs'", path.string().c_str(), "SharedScript");443 LOGERROR("Failed to create shared AI component: %s: error calling constructor '%s'", path.string8(), "SharedScript"); 444 444 return false; 445 445 } 446 446 … … public: 617 617 JS::RootedValue sharedData(cx); 618 618 JS::RootedValue tmpSharedAIObj(cx, m_SharedAIObj.get()); // TODO: Check if this temporary root can be removed after SpiderMonkey 31 upgrade 619 619 if (!m_ScriptInterface->CallFunction(tmpSharedAIObj, "Serialize", &sharedData)) 620 LOGERROR( L"AI shared script Serialize call failed");620 LOGERROR("AI shared script Serialize call failed"); 621 621 serializer.ScriptVal("sharedData", &sharedData); 622 622 } 623 623 for (size_t i = 0; i < m_Players.size(); ++i) … … public: 640 640 { 641 641 JS::RootedValue scriptData(cx); 642 642 if (!m_ScriptInterface->CallFunction(tmpPlayerObj, "Serialize", &scriptData)) 643 LOGERROR( L"AI script Serialize call failed");643 LOGERROR("AI script Serialize call failed"); 644 644 serializer.ScriptVal("data", &scriptData); 645 645 } 646 646 else … … public: 681 681 JS::RootedValue tmpSharedAIObj(cx, m_SharedAIObj.get()); // TODO: Check if this temporary root can be removed after SpiderMonkey 31 682 682 deserializer.ScriptVal("sharedData", &sharedData); 683 683 if (!m_ScriptInterface->CallFunctionVoid(tmpSharedAIObj, "Deserialize", sharedData)) 684 LOGERROR( L"AI shared script Deserialize call failed");684 LOGERROR("AI shared script Deserialize call failed"); 685 685 } 686 686 687 687 for (size_t i = 0; i < numAis; ++i) … … public: 720 720 if (m_Players[i]->m_UseSharedComponent) 721 721 { 722 722 if (!m_ScriptInterface->CallFunctionVoid(tmpPlayerObj, "Deserialize", scriptData, m_SharedAIObj)) 723 LOGERROR( L"AI script Deserialize call failed");723 LOGERROR("AI script Deserialize call failed"); 724 724 } 725 725 else if (!m_ScriptInterface->CallFunctionVoid(tmpPlayerObj, "Deserialize", scriptData)) 726 726 { 727 LOGERROR( L"AI script deserialize() call failed");727 LOGERROR("AI script deserialize() call failed"); 728 728 } 729 729 } 730 730 else … … public: 748 748 std::pair<std::map<JSObject*, std::wstring>::iterator, bool> ret1 = m_SerializablePrototypes.insert(std::make_pair(obj, name)); 749 749 std::pair<std::map<std::wstring, JSObject*>::iterator, bool> ret2 = m_DeserializablePrototypes.insert(std::make_pair(name, obj)); 750 750 if (!ret1.second || !ret2.second) 751 LOGERROR( L"RegisterSerializablePrototype called with same prototype multiple times: p=%p n='%ls'", obj, name.c_str());751 LOGERROR("RegisterSerializablePrototype called with same prototype multiple times: p=%p n='%s'", (void *)obj, utf8_from_wstring(name)); 752 752 } 753 753 754 754 private: -
source/simulation2/components/CCmpCommandQueue.cpp
diff --git a/source/simulation2/components/CCmpCommandQueue.cpp b/source/simulation2/components/CCmpCommandQueue.cpp index 3b3b0c6..c66ef5d 100644
a b public: 119 119 { 120 120 bool ok = scriptInterface.CallFunctionVoid(global, "ProcessCommand", localCommands[i].player, localCommands[i].data); 121 121 if (!ok) 122 LOGERROR( L"Failed to call ProcessCommand() global script function");122 LOGERROR("Failed to call ProcessCommand() global script function"); 123 123 } 124 124 125 125 for (size_t i = 0; i < commands.size(); ++i) 126 126 { 127 127 bool ok = scriptInterface.CallFunctionVoid(global, "ProcessCommand", commands[i].player, commands[i].data); 128 128 if (!ok) 129 LOGERROR( L"Failed to call ProcessCommand() global script function");129 LOGERROR("Failed to call ProcessCommand() global script function"); 130 130 } 131 131 } 132 132 }; -
source/simulation2/components/CCmpObstruction.cpp
diff --git a/source/simulation2/components/CCmpObstruction.cpp b/source/simulation2/components/CCmpObstruction.cpp index 638d804..37afbcd 100644
a b public: 515 515 // required precondition to use SkipControlGroupsRequireFlagObstructionFilter 516 516 if (m_ControlGroup == INVALID_ENTITY) 517 517 { 518 LOGERROR( L"[CmpObstruction] Cannot test for foundation obstructions; primary control group must be valid");518 LOGERROR("[CmpObstruction] Cannot test for foundation obstructions; primary control group must be valid"); 519 519 return FOUNDATION_CHECK_FAIL_ERROR; 520 520 } 521 521 … … public: 552 552 // required precondition to use SkipControlGroupsRequireFlagObstructionFilter 553 553 if (m_ControlGroup == INVALID_ENTITY) 554 554 { 555 LOGERROR( L"[CmpObstruction] Cannot test for foundation obstructions; primary control group must be valid");555 LOGERROR("[CmpObstruction] Cannot test for foundation obstructions; primary control group must be valid"); 556 556 return false; 557 557 } 558 558 … … public: 586 586 // required precondition to use SkipControlGroupsRequireFlagObstructionFilter 587 587 if (m_ControlGroup == INVALID_ENTITY) 588 588 { 589 LOGERROR( L"[CmpObstruction] Cannot test for unit or structure obstructions; primary control group must be valid");589 LOGERROR("[CmpObstruction] Cannot test for unit or structure obstructions; primary control group must be valid"); 590 590 return ret; 591 591 } 592 592 -
source/simulation2/components/CCmpPathfinder.cpp
diff --git a/source/simulation2/components/CCmpPathfinder.cpp b/source/simulation2/components/CCmpPathfinder.cpp index b2a321c..59c700a 100644
a b ICmpPathfinder::pass_class_t CCmpPathfinder::GetPassabilityClass(const std::stri 254 254 { 255 255 if (m_PassClassMasks.find(name) == m_PassClassMasks.end()) 256 256 { 257 LOGERROR( L"Invalid passability class name '%hs'", name.c_str());257 LOGERROR("Invalid passability class name '%s'", name.c_str()); 258 258 return 0; 259 259 } 260 260 … … ICmpPathfinder::cost_class_t CCmpPathfinder::GetCostClass(const std::string& nam 270 270 { 271 271 if (m_UnitCostClassTags.find(name) == m_UnitCostClassTags.end()) 272 272 { 273 LOGERROR( L"Invalid unit cost class name '%hs'", name.c_str());273 LOGERROR("Invalid unit cost class name '%s'", name.c_str()); 274 274 return m_UnitCostClassTags["default"]; 275 275 } 276 276 -
source/simulation2/components/CCmpPosition.cpp
diff --git a/source/simulation2/components/CCmpPosition.cpp b/source/simulation2/components/CCmpPosition.cpp index 51004b4..d5838b7 100644
a b public: 271 271 CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent); 272 272 if (!cmpPosition) 273 273 { 274 LOGERROR( L"Turret with parent without position component");274 LOGERROR("Turret with parent without position component"); 275 275 return; 276 276 } 277 277 if (!cmpPosition->IsInWorld()) … … public: 482 482 { 483 483 if (!m_InWorld) 484 484 { 485 LOGERROR( L"CCmpPosition::GetPosition called on entity when IsInWorld is false");485 LOGERROR("CCmpPosition::GetPosition called on entity when IsInWorld is false"); 486 486 return CFixedVector3D(); 487 487 } 488 488 … … public: 493 493 { 494 494 if (!m_InWorld) 495 495 { 496 LOGERROR( L"CCmpPosition::GetPosition2D called on entity when IsInWorld is false");496 LOGERROR("CCmpPosition::GetPosition2D called on entity when IsInWorld is false"); 497 497 return CFixedVector2D(); 498 498 } 499 499 … … public: 504 504 { 505 505 if (!m_InWorld) 506 506 { 507 LOGERROR( L"CCmpPosition::GetPreviousPosition called on entity when IsInWorld is false");507 LOGERROR("CCmpPosition::GetPreviousPosition called on entity when IsInWorld is false"); 508 508 return CFixedVector3D(); 509 509 } 510 510 … … public: 515 515 { 516 516 if (!m_InWorld) 517 517 { 518 LOGERROR( L"CCmpPosition::GetPreviousPosition2D called on entity when IsInWorld is false");518 LOGERROR("CCmpPosition::GetPreviousPosition2D called on entity when IsInWorld is false"); 519 519 return CFixedVector2D(); 520 520 } 521 521 … … public: 589 589 { 590 590 if (!m_InWorld) 591 591 { 592 LOGERROR( L"CCmpPosition::GetDistanceTravelled called on entity when IsInWorld is false");592 LOGERROR("CCmpPosition::GetDistanceTravelled called on entity when IsInWorld is false"); 593 593 return fixed::Zero(); 594 594 } 595 595 … … public: 630 630 { 631 631 if (!m_InWorld) 632 632 { 633 LOGERROR( L"CCmpPosition::GetInterpolatedPosition2D called on entity when IsInWorld is false");633 LOGERROR("CCmpPosition::GetInterpolatedPosition2D called on entity when IsInWorld is false"); 634 634 return; 635 635 } 636 636 … … public: 647 647 CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_TurretParent); 648 648 if (!cmpPosition) 649 649 { 650 LOGERROR( L"Turret with parent without position component");650 LOGERROR("Turret with parent without position component"); 651 651 CMatrix3D m; 652 652 m.SetIdentity(); 653 653 return m; 654 654 } 655 655 if (!cmpPosition->IsInWorld()) 656 656 { 657 LOGERROR( L"CCmpPosition::GetInterpolatedTransform called on turret entity when IsInWorld is false");657 LOGERROR("CCmpPosition::GetInterpolatedTransform called on turret entity when IsInWorld is false"); 658 658 CMatrix3D m; 659 659 m.SetIdentity(); 660 660 return m; … … public: 670 670 } 671 671 if (!m_InWorld) 672 672 { 673 LOGERROR( L"CCmpPosition::GetInterpolatedTransform called on entity when IsInWorld is false");673 LOGERROR("CCmpPosition::GetInterpolatedTransform called on entity when IsInWorld is false"); 674 674 CMatrix3D m; 675 675 m.SetIdentity(); 676 676 return m; … … private: 925 925 { 926 926 if (!m_InWorld) 927 927 { 928 LOGERROR( L"CCmpPosition::UpdateXZRotation called on entity when IsInWorld is false");928 LOGERROR("CCmpPosition::UpdateXZRotation called on entity when IsInWorld is false"); 929 929 return; 930 930 } 931 931 … … private: 940 940 CmpPtr<ICmpTerrain> cmpTerrain(GetSystemEntity()); 941 941 if (!cmpTerrain || !cmpTerrain->IsLoaded()) 942 942 { 943 LOGERROR( L"Terrain not loaded");943 LOGERROR("Terrain not loaded"); 944 944 return; 945 945 } 946 946 -
source/simulation2/components/CCmpProjectileManager.cpp
diff --git a/source/simulation2/components/CCmpProjectileManager.cpp b/source/simulation2/components/CCmpProjectileManager.cpp index 3b243a7..8e0d5c3 100644
a b uint32_t CCmpProjectileManager::LaunchProjectile(entity_id_t source, CFixedVecto 175 175 { 176 176 // If the actor was actually loaded, complain that it doesn't have a projectile 177 177 if (!cmpSourceVisual->GetActorShortName().empty()) 178 LOGERROR( L"Unit with actor '%ls' launched a projectile but has no actor on 'projectile' attachpoint", cmpSourceVisual->GetActorShortName().c_str());178 LOGERROR("Unit with actor '%s' launched a projectile but has no actor on 'projectile' attachpoint", utf8_from_wstring(cmpSourceVisual->GetActorShortName())); 179 179 return 0; 180 180 } 181 181 -
source/simulation2/components/CCmpRallyPointRenderer.cpp
diff --git a/source/simulation2/components/CCmpRallyPointRenderer.cpp b/source/simulation2/components/CCmpRallyPointRenderer.cpp index a5258fe..e686c40 100644
a b void CCmpRallyPointRenderer::UpdateMarkers() 521 521 522 522 // the marker entity should be valid at this point, otherwise something went wrong trying to allocate it 523 523 if (m_MarkerEntityIds[i] == INVALID_ENTITY) 524 LOGERROR( L"Failed to create rally point marker entity");524 LOGERROR("Failed to create rally point marker entity"); 525 525 526 526 CmpPtr<ICmpPosition> markerCmpPosition(GetSimContext(), m_MarkerEntityIds[i]); 527 527 if (markerCmpPosition) -
source/simulation2/components/CCmpRangeManager.cpp
diff --git a/source/simulation2/components/CCmpRangeManager.cpp b/source/simulation2/components/CCmpRangeManager.cpp index b4988b9..275b1ec 100644
a b public: 738 738 { 739 739 if (m_Queries.find(tag) == m_Queries.end()) 740 740 { 741 LOGERROR( L"CCmpRangeManager: DestroyActiveQuery called with invalid tag %u", tag);741 LOGERROR("CCmpRangeManager: DestroyActiveQuery called with invalid tag %u", tag); 742 742 return; 743 743 } 744 744 … … public: 750 750 std::map<tag_t, Query>::iterator it = m_Queries.find(tag); 751 751 if (it == m_Queries.end()) 752 752 { 753 LOGERROR( L"CCmpRangeManager: EnableActiveQuery called with invalid tag %u", tag);753 LOGERROR("CCmpRangeManager: EnableActiveQuery called with invalid tag %u", tag); 754 754 return; 755 755 } 756 756 … … public: 763 763 std::map<tag_t, Query>::iterator it = m_Queries.find(tag); 764 764 if (it == m_Queries.end()) 765 765 { 766 LOGERROR( L"CCmpRangeManager: DisableActiveQuery called with invalid tag %u", tag);766 LOGERROR("CCmpRangeManager: DisableActiveQuery called with invalid tag %u", tag); 767 767 return; 768 768 } 769 769 … … public: 820 820 std::map<tag_t, Query>::iterator it = m_Queries.find(tag); 821 821 if (it == m_Queries.end()) 822 822 { 823 LOGERROR( L"CCmpRangeManager: ResetActiveQuery called with invalid tag %u", tag);823 LOGERROR("CCmpRangeManager: ResetActiveQuery called with invalid tag %u", tag); 824 824 return r; 825 825 } 826 826 … … public: 1156 1156 { 1157 1157 // Min range must be non-negative 1158 1158 if (minRange < entity_pos_t::Zero()) 1159 LOGWARNING( L"CCmpRangeManager: Invalid min range %f in query for entity %u", minRange.ToDouble(), source);1159 LOGWARNING("CCmpRangeManager: Invalid min range %f in query for entity %u", minRange.ToDouble(), source); 1160 1160 1161 1161 // Max range must be non-negative, or else -1 1162 1162 if (maxRange < entity_pos_t::Zero() && maxRange != entity_pos_t::FromInt(-1)) 1163 LOGWARNING( L"CCmpRangeManager: Invalid max range %f in query for entity %u", maxRange.ToDouble(), source);1163 LOGWARNING("CCmpRangeManager: Invalid max range %f in query for entity %u", maxRange.ToDouble(), source); 1164 1164 1165 1165 Query q; 1166 1166 q.enabled = false; … … public: 1337 1337 if (identifier == "injured") 1338 1338 return 2; 1339 1339 1340 LOGWARNING( L"CCmpRangeManager: Invalid flag identifier %hs", identifier.c_str());1340 LOGWARNING("CCmpRangeManager: Invalid flag identifier %s", identifier.c_str()); 1341 1341 return 0; 1342 1342 } 1343 1343 … … public: 1354 1354 // We don't have a flag set 1355 1355 if (flag == 0) 1356 1356 { 1357 LOGWARNING( L"CCmpRangeManager: Invalid flag identifier %hs for entity %u", identifier.c_str(), ent);1357 LOGWARNING("CCmpRangeManager: Invalid flag identifier %s for entity %u", identifier.c_str(), ent); 1358 1358 return; 1359 1359 } 1360 1360 -
source/simulation2/components/CCmpTemplateManager.cpp
diff --git a/source/simulation2/components/CCmpTemplateManager.cpp b/source/simulation2/components/CCmpTemplateManager.cpp index ffb3cd8..8f90626 100644
a b const CParamNode* CCmpTemplateManager::GetTemplate(std::string templateName) 187 187 188 188 // Show error on the first failure to validate the template 189 189 if (!m_TemplateSchemaValidity[templateName]) 190 LOGERROR( L"Failed to validate entity template '%hs'", templateName.c_str());190 LOGERROR("Failed to validate entity template '%s'", templateName.c_str()); 191 191 } 192 192 // Refuse to return invalid templates 193 193 if (!m_TemplateSchemaValidity[templateName]) … … const CParamNode* CCmpTemplateManager::GetTemplate(std::string templateName) 198 198 if (!templateRoot.IsOk()) 199 199 { 200 200 // The validator should never let this happen 201 LOGERROR( L"Invalid root element in entity template '%hs'", templateName.c_str());201 LOGERROR("Invalid root element in entity template '%s'", templateName.c_str()); 202 202 return NULL; 203 203 } 204 204 -
source/simulation2/components/CCmpUnitMotion.cpp
diff --git a/source/simulation2/components/CCmpUnitMotion.cpp b/source/simulation2/components/CCmpUnitMotion.cpp index 6a4ebda..d24eb12 100644
a b void CCmpUnitMotion::PathResult(u32 ticket, const ICmpPathfinder::Path& path) 814 814 } 815 815 else 816 816 { 817 LOGWARNING( L"unexpected PathResult (%u %d %d)", GetEntityId(), m_State, m_PathState);817 LOGWARNING("unexpected PathResult (%u %d %d)", GetEntityId(), m_State, m_PathState); 818 818 } 819 819 } 820 820 -
source/simulation2/components/CCmpVisualActor.cpp
diff --git a/source/simulation2/components/CCmpVisualActor.cpp b/source/simulation2/components/CCmpVisualActor.cpp index 52c189b..0e4a003 100644
a b void CCmpVisualActor::InitSelectionShapeDescriptor(const CParamNode& paramNode) 655 655 } 656 656 else 657 657 { 658 LOGERROR( L"[VisualActor] Cannot apply footprint-based SelectionShape; Footprint component not initialized.");658 LOGERROR("[VisualActor] Cannot apply footprint-based SelectionShape; Footprint component not initialized."); 659 659 } 660 660 } 661 661 else if (shapeNode.GetChild("Box").IsOk()) … … void CCmpVisualActor::InitSelectionShapeDescriptor(const CParamNode& paramNode) 669 669 } 670 670 else if (shapeNode.GetChild("Cylinder").IsOk()) 671 671 { 672 LOGWARNING( L"[VisualActor] TODO: Cylinder selection shapes are not yet implemented; defaulting to recursive bounding boxes");672 LOGWARNING("[VisualActor] TODO: Cylinder selection shapes are not yet implemented; defaulting to recursive bounding boxes"); 673 673 } 674 674 else 675 675 { 676 676 // shouldn't happen by virtue of validation against schema 677 LOGERROR( L"[VisualActor] No selection shape specified");677 LOGERROR("[VisualActor] No selection shape specified"); 678 678 } 679 679 } 680 680 -
source/simulation2/components/ICmpVisibility.cpp
diff --git a/source/simulation2/components/ICmpVisibility.cpp b/source/simulation2/components/ICmpVisibility.cpp index f597605..b700f87 100644
a b public: 43 43 case ICmpRangeManager::VIS_VISIBLE: 44 44 return ICmpRangeManager::VIS_VISIBLE; 45 45 default: 46 LOGERROR( L"Received the invalid visibility value %d from the Visibility scripted component!", visibility);46 LOGERROR("Received the invalid visibility value %d from the Visibility scripted component!", visibility); 47 47 return ICmpRangeManager::VIS_HIDDEN; 48 48 } 49 49 } -
source/simulation2/scripting/EngineScriptConversions.cpp
diff --git a/source/simulation2/scripting/EngineScriptConversions.cpp b/source/simulation2/scripting/EngineScriptConversions.cpp index 2f907a3..baeffc6 100644
a b template<> void ScriptInterface::ToJSVal<IComponent*>(JSContext* cx, JS::Mutable 55 55 if (!val->NewJSObject(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface, &obj)) 56 56 { 57 57 // Report as an error, since scripts really shouldn't try to use unscriptable interfaces 58 LOGERROR( L"IComponent does not have a scriptable interface");58 LOGERROR("IComponent does not have a scriptable interface"); 59 59 ret.setUndefined(); 60 60 return; 61 61 } -
source/simulation2/scripting/MessageTypeConversions.cpp
diff --git a/source/simulation2/scripting/MessageTypeConversions.cpp b/source/simulation2/scripting/MessageTypeConversions.cpp index d6a909d..2adb6fe 100644
a b CMessage* CMessageInterpolate::FromJSVal(ScriptInterface& scriptInterface, JS::H 119 119 120 120 JS::Value CMessageRenderSubmit::ToJSVal(ScriptInterface& UNUSED(scriptInterface)) const 121 121 { 122 LOGWARNING( L"CMessageRenderSubmit::ToJSVal not implemented");122 LOGWARNING("CMessageRenderSubmit::ToJSVal not implemented"); 123 123 return JS::UndefinedValue(); 124 124 } 125 125 126 126 CMessage* CMessageRenderSubmit::FromJSVal(ScriptInterface& UNUSED(scriptInterface), JS::HandleValue UNUSED(val)) 127 127 { 128 LOGWARNING( L"CMessageRenderSubmit::FromJSVal not implemented");128 LOGWARNING("CMessageRenderSubmit::FromJSVal not implemented"); 129 129 return NULL; 130 130 } 131 131 … … CMessage* CMessageRenderSubmit::FromJSVal(ScriptInterface& UNUSED(scriptInterfac 133 133 134 134 JS::Value CMessageProgressiveLoad::ToJSVal(ScriptInterface& UNUSED(scriptInterface)) const 135 135 { 136 LOGWARNING( L"CMessageProgressiveLoad::ToJSVal not implemented");136 LOGWARNING("CMessageProgressiveLoad::ToJSVal not implemented"); 137 137 return JS::UndefinedValue(); 138 138 } 139 139 140 140 CMessage* CMessageProgressiveLoad::FromJSVal(ScriptInterface& UNUSED(scriptInterface), JS::HandleValue UNUSED(val)) 141 141 { 142 LOGWARNING( L"CMessageProgressiveLoad::FromJSVal not implemented");142 LOGWARNING("CMessageProgressiveLoad::FromJSVal not implemented"); 143 143 return NULL; 144 144 } 145 145 … … CMessage* CMessageProgressiveLoad::FromJSVal(ScriptInterface& UNUSED(scriptInter 147 147 148 148 JS::Value CMessageDeserialized::ToJSVal(ScriptInterface& UNUSED(scriptInterface)) const 149 149 { 150 LOGWARNING( L"CMessageDeserialized::ToJSVal not implemented");150 LOGWARNING("CMessageDeserialized::ToJSVal not implemented"); 151 151 return JS::UndefinedValue(); 152 152 } 153 153 154 154 CMessage* CMessageDeserialized::FromJSVal(ScriptInterface& UNUSED(scriptInterface), JS::HandleValue UNUSED(val)) 155 155 { 156 LOGWARNING( L"CMessageDeserialized::FromJSVal not implemented");156 LOGWARNING("CMessageDeserialized::FromJSVal not implemented"); 157 157 return NULL; 158 158 } 159 159 … … CMessage* CMessagePositionChanged::FromJSVal(ScriptInterface& scriptInterface, J 237 237 238 238 JS::Value CMessageInterpolatedPositionChanged::ToJSVal(ScriptInterface& UNUSED(scriptInterface)) const 239 239 { 240 LOGWARNING( L"CMessageInterpolatedPositionChanged::ToJSVal not implemented");240 LOGWARNING("CMessageInterpolatedPositionChanged::ToJSVal not implemented"); 241 241 return JS::UndefinedValue(); 242 242 } 243 243 244 244 CMessage* CMessageInterpolatedPositionChanged::FromJSVal(ScriptInterface& UNUSED(scriptInterface), JS::HandleValue UNUSED(val)) 245 245 { 246 LOGWARNING( L"CMessageInterpolatedPositionChanged::FromJSVal not implemented");246 LOGWARNING("CMessageInterpolatedPositionChanged::FromJSVal not implemented"); 247 247 return NULL; 248 248 } 249 249 … … JS::Value CMessageRangeUpdate::ToJSVal(ScriptInterface& scriptInterface) const 379 379 380 380 CMessage* CMessageRangeUpdate::FromJSVal(ScriptInterface& UNUSED(scriptInterface), JS::HandleValue UNUSED(val)) 381 381 { 382 LOGWARNING( L"CMessageRangeUpdate::FromJSVal not implemented");382 LOGWARNING("CMessageRangeUpdate::FromJSVal not implemented"); 383 383 return NULL; 384 384 } 385 385 … … CMessage* CMessageRangeUpdate::FromJSVal(ScriptInterface& UNUSED(scriptInterface 387 387 388 388 JS::Value CMessagePathResult::ToJSVal(ScriptInterface& UNUSED(scriptInterface)) const 389 389 { 390 LOGWARNING( L"CMessagePathResult::ToJSVal not implemented");390 LOGWARNING("CMessagePathResult::ToJSVal not implemented"); 391 391 return JS::UndefinedValue(); 392 392 } 393 393 394 394 CMessage* CMessagePathResult::FromJSVal(ScriptInterface& UNUSED(scriptInterface), JS::HandleValue UNUSED(val)) 395 395 { 396 LOGWARNING( L"CMessagePathResult::FromJSVal not implemented");396 LOGWARNING("CMessagePathResult::FromJSVal not implemented"); 397 397 return NULL; 398 398 } 399 399 -
source/simulation2/scripting/ScriptComponent.cpp
diff --git a/source/simulation2/scripting/ScriptComponent.cpp b/source/simulation2/scripting/ScriptComponent.cpp index f3ada5b..f2fe1fc 100644
a b void CComponentTypeScript::HandleMessage(const CMessage& msg, bool global) 73 73 74 74 JS::RootedValue tmpInstance(cx, m_Instance.get()); // TODO: Check if this temporary root can be removed after SpiderMonkey 31 upgrade 75 75 if (!m_ScriptInterface.CallFunctionVoid(tmpInstance, name, msgVal)) 76 LOGERROR( L"Script message handler %hs failed", name);76 LOGERROR("Script message handler %s failed", name); 77 77 } 78 78 79 79 void CComponentTypeScript::Serialize(ISerializer& serialize) … … void CComponentTypeScript::Serialize(ISerializer& serialize) 92 92 { 93 93 JS::RootedValue val(cx); 94 94 if (!m_ScriptInterface.CallFunction(tmpInstance, "Serialize", &val)) 95 LOGERROR( L"Script Serialize call failed");95 LOGERROR("Script Serialize call failed"); 96 96 serialize.ScriptVal("object", &val); 97 97 } 98 98 else … … void CComponentTypeScript::Deserialize(const CParamNode& paramNode, IDeserialize 118 118 deserialize.ScriptVal("object", &val); 119 119 120 120 if (!m_ScriptInterface.CallFunctionVoid(tmpInstance, "Deserialize", val)) 121 LOGERROR( L"Script Deserialize call failed");121 LOGERROR("Script Deserialize call failed"); 122 122 } 123 123 else 124 124 { -
source/simulation2/scripting/ScriptComponent.h
diff --git a/source/simulation2/scripting/ScriptComponent.h b/source/simulation2/scripting/ScriptComponent.h index 035013c..7268499 100644
a b public: 64 64 R ret; \ 65 65 if (m_ScriptInterface.CallFunction(tmpInstance, funcname BOOST_PP_ENUM_TRAILING_PARAMS(i, a), ret)) \ 66 66 return ret; \ 67 LOGERROR( L"Error calling component script function %hs", funcname); \67 LOGERROR("Error calling component script function %s", funcname); \ 68 68 return R(); \ 69 69 } \ 70 70 BOOST_PP_IF(i, template<, ) BOOST_PP_ENUM_PARAMS(i, typename T) BOOST_PP_IF(i, >, ) \ … … public: 75 75 JS::RootedValue tmpInstance(cx, m_Instance.get()); \ 76 76 if (m_ScriptInterface.CallFunctionVoid(tmpInstance, funcname BOOST_PP_ENUM_TRAILING_PARAMS(i, a))) \ 77 77 return; \ 78 LOGERROR( L"Error calling component script function %hs", funcname); \78 LOGERROR("Error calling component script function %s", funcname); \ 79 79 } 80 80 BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~) 81 81 #undef OVERLOADS -
source/simulation2/serialization/BinarySerializer.cpp
diff --git a/source/simulation2/serialization/BinarySerializer.cpp b/source/simulation2/serialization/BinarySerializer.cpp index 9cc61ac..4878226 100644
a b static u8 GetArrayType(JSArrayBufferViewType arrayType) 49 49 case js::ArrayBufferView::TYPE_UINT8_CLAMPED: 50 50 return SCRIPT_TYPED_ARRAY_UINT8_CLAMPED; 51 51 default: 52 LOGERROR( L"Cannot serialize unrecognized typed array view: %d", arrayType);52 LOGERROR("Cannot serialize unrecognized typed array view: %d", arrayType); 53 53 throw PSERROR_Serialize_InvalidScriptValue(); 54 54 } 55 55 } … … void CBinarySerializerScriptImpl::HandleScriptVal(JS::HandleValue val) 258 258 else 259 259 { 260 260 // Unrecognized class 261 LOGERROR( L"Cannot serialise JS objects with unrecognized class '%hs'", jsclass->name);261 LOGERROR("Cannot serialise JS objects with unrecognized class '%s'", jsclass->name); 262 262 throw PSERROR_Serialize_InvalidScriptValue(); 263 263 } 264 264 } … … void CBinarySerializerScriptImpl::HandleScriptVal(JS::HandleValue val) 317 317 } 318 318 } 319 319 320 LOGERROR( L"Cannot serialise JS objects of type 'function': %ls", funcname.c_str());320 LOGERROR("Cannot serialise JS objects of type 'function': %s", utf8_from_wstring(funcname)); 321 321 throw PSERROR_Serialize_InvalidScriptValue(); 322 322 } 323 323 case JSTYPE_STRING: -
source/simulation2/system/ComponentManager.cpp
diff --git a/source/simulation2/system/ComponentManager.cpp b/source/simulation2/system/ComponentManager.cpp index 3e8aef7..0ee90a0 100644
a b std::vector<IComponent*> CComponentManager::Script_GetComponentsWithInterface(Sc 429 429 CMessage* CComponentManager::ConstructMessage(int mtid, JS::HandleValue data) 430 430 { 431 431 if (mtid == MT__Invalid || mtid > (int)m_MessageTypeIdsByName.size()) // (IDs start at 1 so use '>' here) 432 LOGERROR( L"PostMessage with invalid message type ID '%d'", mtid);432 LOGERROR("PostMessage with invalid message type ID '%d'", mtid); 433 433 434 434 if (mtid < MT__LastNative) 435 435 { … … CComponentManager::ComponentTypeId CComponentManager::GetScriptWrapper(Interface 672 672 for (; iiit != m_InterfaceIdsByName.end(); ++iiit) 673 673 if (iiit->second == iid) 674 674 { 675 LOGERROR( L"No script wrapper found for interface id %d '%hs'", iid, iiit->first.c_str());675 LOGERROR("No script wrapper found for interface id %d '%s'", iid, iiit->first.c_str()); 676 676 return CID__Invalid; 677 677 } 678 678 679 LOGERROR( L"No script wrapper found for interface id %d", iid);679 LOGERROR("No script wrapper found for interface id %d", iid); 680 680 return CID__Invalid; 681 681 } 682 682 … … IComponent* CComponentManager::ConstructComponent(CEntityHandle ent, ComponentTy 753 753 std::map<ComponentTypeId, ComponentType>::const_iterator it = m_ComponentTypesById.find(cid); 754 754 if (it == m_ComponentTypesById.end()) 755 755 { 756 LOGERROR( L"Invalid component id %d", cid);756 LOGERROR("Invalid component id %d", cid); 757 757 return NULL; 758 758 } 759 759 … … IComponent* CComponentManager::ConstructComponent(CEntityHandle ent, ComponentTy 764 764 boost::unordered_map<entity_id_t, IComponent*>& emap1 = m_ComponentsByInterface[ct.iid]; 765 765 if (emap1.find(ent.GetId()) != emap1.end()) 766 766 { 767 LOGERROR( L"Multiple components for interface %d", ct.iid);767 LOGERROR("Multiple components for interface %d", ct.iid); 768 768 return NULL; 769 769 } 770 770 … … IComponent* CComponentManager::ConstructComponent(CEntityHandle ent, ComponentTy 780 780 m_ScriptInterface.CallConstructor(tmpCtor, argv, &obj); 781 781 if (obj.isNull()) 782 782 { 783 LOGERROR( L"Script component constructor failed");783 LOGERROR("Script component constructor failed"); 784 784 return NULL; 785 785 } 786 786 } … … entity_id_t CComponentManager::AddEntity(const std::wstring& templateName, entit 887 887 CComponentManager::ComponentTypeId cid = LookupCID(it->first); 888 888 if (cid == CID__Invalid) 889 889 { 890 LOGERROR( L"Unrecognised component type name '%hs' in entity template '%ls'", it->first.c_str(), templateName.c_str());890 LOGERROR("Unrecognised component type name '%s' in entity template '%s'", it->first, utf8_from_wstring(templateName)); 891 891 return INVALID_ENTITY; 892 892 } 893 893 894 894 if (!AddComponent(handle, cid, it->second)) 895 895 { 896 LOGERROR( L"Failed to construct component type name '%hs' in entity template '%ls'", it->first.c_str(), templateName.c_str());896 LOGERROR("Failed to construct component type name '%s' in entity template '%s'", it->first, utf8_from_wstring(templateName)); 897 897 return INVALID_ENTITY; 898 898 } 899 899 // TODO: maybe we should delete already-constructed components if one of them fails? … … std::vector<std::string> CComponentManager::Script_FindJSONFiles(ScriptInterface 1226 1226 { 1227 1227 // Some error reading directory 1228 1228 wchar_t error[200]; 1229 LOGERROR( L"Error reading directory '%ls': %ls", cbData.path.string().c_str(), StatusDescription(ret, error, ARRAY_SIZE(error)));1229 LOGERROR("Error reading directory '%s': %s", cbData.path.string8(), utf8_from_wstring(StatusDescription(ret, error, ARRAY_SIZE(error)))); 1230 1230 } 1231 1231 1232 1232 return cbData.templates; -
source/simulation2/system/ComponentManagerSerialization.cpp
diff --git a/source/simulation2/system/ComponentManagerSerialization.cpp b/source/simulation2/system/ComponentManagerSerialization.cpp index 78b2cd3..053b3c6 100644
a b bool CComponentManager::DeserializeState(std::istream& stream) 322 322 ComponentTypeId ctid = LookupCID(ctname); 323 323 if (ctid == CID__Invalid) 324 324 { 325 LOGERROR( L"Deserialization saw unrecognised component type '%hs'", ctname.c_str());325 LOGERROR("Deserialization saw unrecognised component type '%s'", ctname.c_str()); 326 326 return false; 327 327 } 328 328 … … bool CComponentManager::DeserializeState(std::istream& stream) 349 349 ComponentTypeId ctid = LookupCID(ctname); 350 350 if (ctid == CID__Invalid) 351 351 { 352 LOGERROR( L"Deserialization saw unrecognised component type '%hs'", ctname.c_str());352 LOGERROR("Deserialization saw unrecognised component type '%s'", ctname.c_str()); 353 353 return false; 354 354 } 355 355 … … bool CComponentManager::DeserializeState(std::istream& stream) 379 379 380 380 if (stream.peek() != EOF) 381 381 { 382 LOGERROR( L"Deserialization didn't reach EOF");382 LOGERROR("Deserialization didn't reach EOF"); 383 383 return false; 384 384 } 385 385 … … bool CComponentManager::DeserializeState(std::istream& stream) 391 391 } 392 392 catch (PSERROR_Deserialize& e) 393 393 { 394 LOGERROR( L"Deserialization failed: %hs", e.what());394 LOGERROR("Deserialization failed: %s", e.what()); 395 395 return false; 396 396 } 397 397 } -
source/simulation2/system/ParamNode.cpp
diff --git a/source/simulation2/system/ParamNode.cpp b/source/simulation2/system/ParamNode.cpp index f966004..2e4b172 100644
a b void CParamNode::ApplyLayer(const XMBFile& xmb, const XMBElement& element, const 123 123 if (tokenIt != tokens.end()) 124 124 tokens.erase(tokenIt); 125 125 else 126 LOGWARNING( L"[ParamNode] Could not remove token '%ls' from node '%hs'%ls; not present in list nor inherited (possible typo?)",127 newTokens[i].substr(1).c_str(), name.c_str(), sourceIdentifier ? (L" in '" + std::wstring(sourceIdentifier) + L"'").c_str() : L"");126 LOGWARNING("[ParamNode] Could not remove token '%s' from node '%s'%s; not present in list nor inherited (possible typo?)", 127 utf8_from_wstring(newTokens[i].substr(1)), name, sourceIdentifier ? (" in '" + utf8_from_wstring(sourceIdentifier) + "'").c_str() : ""); 128 128 } 129 129 else 130 130 { -
source/simulation2/tests/test_ComponentManager.h
diff --git a/source/simulation2/tests/test_ComponentManager.h b/source/simulation2/tests/test_ComponentManager.h index c84fe34..9c92b4b 100644
a b public: 109 109 { 110 110 TestLogger log; 111 111 TS_ASSERT(! man.AddComponent(hnd1, 12345, noParam)); 112 TS_ASSERT_ WSTR_CONTAINS(log.GetOutput(), L"ERROR: Invalid component id 12345");112 TS_ASSERT_STR_CONTAINS(log.GetOutput(), "ERROR: Invalid component id 12345"); 113 113 } 114 114 115 115 { 116 116 TestLogger log; 117 117 TS_ASSERT(! man.AddComponent(hnd1, CID_Test1B, noParam)); 118 TS_ASSERT_ WSTR_CONTAINS(log.GetOutput(), L"ERROR: Multiple components for interface ");118 TS_ASSERT_STR_CONTAINS(log.GetOutput(), "ERROR: Multiple components for interface "); 119 119 } 120 120 } 121 121 … … public: 347 347 // In SpiderMonkey 1.6, JS_ReportError calls the error reporter even if it's inside 348 348 // a try{} in the script; in recent versions (not sure when it changed) it doesn't 349 349 // so the error here won't get reported. 350 TS_ASSERT_ WSTR_NOT_CONTAINS(log.GetOutput(), L"ERROR: JavaScript error: simulation/components/error.js line 4\nInvalid interface id");350 TS_ASSERT_STR_NOT_CONTAINS(log.GetOutput(), "ERROR: JavaScript error: simulation/components/error.js line 4\nInvalid interface id"); 351 351 } 352 352 } 353 353 -
source/soundmanager/SoundManager.cpp
diff --git a/source/soundmanager/SoundManager.cpp b/source/soundmanager/SoundManager.cpp index daa6f3e..48d0917 100644
a b void ISoundManager::CloseGame() 204 204 205 205 void CSoundManager::al_ReportError(ALenum err, const char* caller, int line) 206 206 { 207 LOGERROR( L"OpenAL error: %hs; called from %hs (line %d)\n", alGetString(err), caller, line);207 LOGERROR("OpenAL error: %s; called from %s (line %d)\n", alGetString(err), caller, line); 208 208 } 209 209 210 210 void CSoundManager::al_check(const char* caller, int line) … … void CSoundManager::al_check(const char* caller, int line) 216 216 217 217 Status CSoundManager::ReloadChangedFiles(const VfsPath& UNUSED(path)) 218 218 { 219 // LOGERROR( L"GUI file '%ls' changed - reloading page", path.string().c_str());219 // LOGERROR("GUI file '%s' changed - reloading page", path.string8()); 220 220 221 221 return INFO::OK; 222 222 } … … Status CSoundManager::AlcInit() 338 338 } 339 339 else 340 340 { 341 LOGERROR( L"error in gensource = %d", err);341 LOGERROR("error in gensource = %d", err); 342 342 } 343 343 delete[] sourceList; 344 344 } … … Status CSoundManager::AlcInit() 354 354 debug_printf(L"Sound: AlcInit success, using %hs\n", dev_name); 355 355 else 356 356 { 357 LOGERROR( L"Sound: AlcInit failed, m_Device=%p m_Context=%p dev_name=%hs err=%x\n", m_Device,m_Context, dev_name, err);357 LOGERROR("Sound: AlcInit failed, m_Device=%p m_Context=%p dev_name=%s err=%x\n", (void *)m_Device, (void *)m_Context, dev_name, err); 358 358 359 359 // FIXME Hack to get around exclusive access to the sound device 360 360 #if OS_UNIX … … void CSoundManager::PlayAsGroup(const VfsPath& groupPath, CVector3D sourcePos, e 654 654 group = new CSoundGroup(); 655 655 if (!group->LoadSoundGroup(L"audio/" + groupPath.string())) 656 656 { 657 LOGERROR( L"Failed to load sound group '%ls'", groupPath.string().c_str());657 LOGERROR("Failed to load sound group '%s'", groupPath.string8()); 658 658 delete group; 659 659 group = NULL; 660 660 } -
source/soundmanager/data/OggData.cpp
diff --git a/source/soundmanager/data/OggData.cpp b/source/soundmanager/data/OggData.cpp index 6165c5c..26321fc 100644
a b bool COggData::InitOggFile(const VfsPath& itemPath) 78 78 79 79 if(alGetError() != AL_NO_ERROR) 80 80 { 81 LOGERROR( L"- Error creating initial buffer !!\n");81 LOGERROR( "- Error creating initial buffer !!\n"); 82 82 return false; 83 83 } 84 84 else -
source/soundmanager/data/SoundData.cpp
diff --git a/source/soundmanager/data/SoundData.cpp b/source/soundmanager/data/SoundData.cpp index e3f6173..80bb547 100644
a b CSoundData* CSoundData::SoundDataFromOgg(const VfsPath& itemPath) 107 107 } 108 108 else 109 109 { 110 LOGERROR( L"could not initialize ogg data at %ls", itemPath.string().c_str());110 LOGERROR("could not initialize ogg data at %s", itemPath.string8()); 111 111 delete oggAnswer; 112 112 } 113 113 -
source/soundmanager/items/CSoundBase.cpp
diff --git a/source/soundmanager/items/CSoundBase.cpp b/source/soundmanager/items/CSoundBase.cpp index e7dce37..8486114 100644
a b bool CSoundBase::InitOpenAL() 112 112 } 113 113 else 114 114 { 115 // LOGERROR( L"Source not allocated by SoundManager\n", 0);115 // LOGERROR("Source not allocated by SoundManager\n", 0); 116 116 } 117 117 return false; 118 118 } -
source/soundmanager/scripting/SoundGroup.cpp
diff --git a/source/soundmanager/scripting/SoundGroup.cpp b/source/soundmanager/scripting/SoundGroup.cpp index 2969e2e..0dc524c 100644
a b void CSoundGroup::UploadPropertiesAndPlay(size_t theIndex, const CVector3D& posi 197 197 itemRollOff = 0; 198 198 199 199 if ( sndData->IsStereo() ) 200 LOGWARNING( L"OpenAL: stereo sounds can't be positioned: %ls", sndData->GetFileName()->string().c_str() );200 LOGWARNING( "OpenAL: stereo sounds can't be positioned: %s", sndData->GetFileName()->string8() ); 201 201 202 202 hSound->SetLocation(CVector3D((sndDist * sin(offSet)), 0, - sndDist * cos(offSet))); 203 203 hSound->SetRollOff(itemRollOff); … … static void HandleError(const CStrW& message, const VfsPath& pathname, Status er 227 227 { 228 228 if (err == ERR::AGAIN) 229 229 return; // open failed because sound is disabled (don't log this) 230 LOGERROR( L"%ls: pathname=%ls, error=%ls", message.c_str(), pathname.string().c_str(), ErrorString(err));230 LOGERROR("%s: pathname=%s, error=%s", utf8_from_wstring(message), pathname.string8(), utf8_from_wstring(ErrorString(err))); 231 231 } 232 232 233 233 void CSoundGroup::PlayNext(const CVector3D& position, entity_id_t source) … … bool CSoundGroup::LoadSoundGroup(const VfsPath& pathnameXML) 320 320 321 321 if (root.GetNodeName() != el_soundgroup) 322 322 { 323 LOGERROR( L"Invalid SoundGroup format (unrecognised root element '%hs')", XeroFile.GetElementString(root.GetNodeName()).c_str());323 LOGERROR("Invalid SoundGroup format (unrecognised root element '%s')", XeroFile.GetElementString(root.GetNodeName()).c_str()); 324 324 return false; 325 325 } 326 326 -
source/test_setup.cpp
diff --git a/source/test_setup.cpp b/source/test_setup.cpp index 448a650..c75f43a 100644
a b static MiscSetup miscSetup; 100 100 101 101 // Definition of functions from lib/self_test.h 102 102 103 bool ts_str_contains(const std::string& str1, const std::string& str2) 104 { 105 return str1.find(str2) != str1.npos; 106 } 107 103 108 bool ts_str_contains(const std::wstring& str1, const std::wstring& str2) 104 109 { 105 110 return str1.find(str2) != str1.npos; -
new file source/third_party/cppformat/format.cpp
diff --git a/source/third_party/cppformat/format.cpp b/source/third_party/cppformat/format.cpp new file mode 100644 index 0000000..580d6cd
- + 1 /* 2 * Slightly modified version of cppformat, by Wildfire Games, for 0 A.D. 3 * Based on cppformat v0.11.0 from https://github.com/cppformat/cppformat 4 */ 5 6 /* 7 Formatting library for C++ 8 9 Copyright (c) 2012 - 2014, Victor Zverovich 10 All rights reserved. 11 12 Redistribution and use in source and binary forms, with or without 13 modification, are permitted provided that the following conditions are met: 14 15 1. Redistributions of source code must retain the above copyright notice, this 16 list of conditions and the following disclaimer. 17 2. Redistributions in binary form must reproduce the above copyright notice, 18 this list of conditions and the following disclaimer in the documentation 19 and/or other materials provided with the distribution. 20 21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 25 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 // Disable useless MSVC warnings. 34 #undef _CRT_SECURE_NO_WARNINGS 35 #define _CRT_SECURE_NO_WARNINGS 36 #undef _SCL_SECURE_NO_WARNINGS 37 #define _SCL_SECURE_NO_WARNINGS 38 39 #include "format.h" 40 41 #include <string.h> 42 43 #include <cctype> 44 #include <cerrno> 45 #include <climits> 46 #include <cmath> 47 #include <cstdarg> 48 49 #ifdef _WIN32 50 # define WIN32_LEAN_AND_MEAN 51 # ifdef __MINGW32__ 52 # include <cstring> 53 # endif 54 # include <windows.h> 55 # undef ERROR 56 #endif 57 58 using fmt::LongLong; 59 using fmt::ULongLong; 60 using fmt::internal::Arg; 61 62 #ifdef _MSC_VER 63 # pragma warning(push) 64 # pragma warning(disable: 4127) // conditional expression is constant 65 #endif 66 67 namespace { 68 69 #ifndef _MSC_VER 70 71 // Portable version of signbit. 72 // When compiled in C++11 mode signbit is no longer a macro but a function 73 // defined in namespace std and the macro is undefined. 74 inline int getsign(double x) { 75 #ifdef signbit 76 return signbit(x); 77 #else 78 return std::signbit(x); 79 #endif 80 } 81 82 // Portable version of isinf. 83 #ifdef isinf 84 inline int isinfinity(double x) { return isinf(x); } 85 inline int isinfinity(long double x) { return isinf(x); } 86 #else 87 inline int isinfinity(double x) { return std::isinf(x); } 88 inline int isinfinity(long double x) { return std::isinf(x); } 89 #endif 90 91 #define FMT_SNPRINTF snprintf 92 93 #else // _MSC_VER 94 95 inline int getsign(double value) { 96 if (value < 0) return 1; 97 if (value == value) return 0; 98 int dec = 0, sign = 0; 99 char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail. 100 _ecvt_s(buffer, sizeof(buffer), value, 0, &dec, &sign); 101 return sign; 102 } 103 104 inline int isinfinity(double x) { return !_finite(x); } 105 106 inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) { 107 va_list args; 108 va_start(args, format); 109 int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args); 110 va_end(args); 111 return result; 112 } 113 #define FMT_SNPRINTF fmt_snprintf 114 115 #endif // _MSC_VER 116 117 template <typename T> 118 struct IsLongDouble { enum {VALUE = 0}; }; 119 120 template <> 121 struct IsLongDouble<long double> { enum {VALUE = 1}; }; 122 123 // Checks if a value fits in int - used to avoid warnings about comparing 124 // signed and unsigned integers. 125 template <bool IsSigned> 126 struct IntChecker { 127 template <typename T> 128 static bool fits_in_int(T value) { 129 unsigned max = INT_MAX; 130 return value <= max; 131 } 132 }; 133 134 template <> 135 struct IntChecker<true> { 136 template <typename T> 137 static bool fits_in_int(T value) { 138 return value >= INT_MIN && value <= INT_MAX; 139 } 140 }; 141 142 const char RESET_COLOR[] = "\x1b[0m"; 143 144 typedef void (*FormatFunc)(fmt::Writer &, int , fmt::StringRef); 145 146 void report_error(FormatFunc func, 147 int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { 148 try { 149 fmt::Writer full_message; 150 func(full_message, error_code, message); // TODO: make sure this doesn't throw 151 std::fwrite(full_message.c_str(), full_message.size(), 1, stderr); 152 std::fputc('\n', stderr); 153 } catch (...) {} 154 } 155 156 const Arg DUMMY_ARG = {Arg::INT, {0}}; 157 158 // IsZeroInt::visit(arg) returns true iff arg is a zero integer. 159 class IsZeroInt : public fmt::internal::ArgVisitor<IsZeroInt, bool> { 160 public: 161 template <typename T> 162 bool visit_any_int(T value) { return value == 0; } 163 }; 164 165 // Parses an unsigned integer advancing s to the end of the parsed input. 166 // This function assumes that the first character of s is a digit. 167 template <typename Char> 168 int parse_nonnegative_int( 169 const Char *&s, const char *&error) FMT_NOEXCEPT(true) { 170 assert('0' <= *s && *s <= '9'); 171 unsigned value = 0; 172 do { 173 unsigned new_value = value * 10 + (*s++ - '0'); 174 // Check if value wrapped around. 175 value = new_value >= value ? new_value : UINT_MAX; 176 } while ('0' <= *s && *s <= '9'); 177 if (value > INT_MAX) { 178 if (!error) 179 error = "number is too big in format"; 180 return 0; 181 } 182 return value; 183 } 184 185 template <typename Char> 186 const Char *find_closing_brace(const Char *s, int num_open_braces = 1) { 187 for (int n = num_open_braces; *s; ++s) { 188 if (*s == '{') { 189 ++n; 190 } else if (*s == '}') { 191 if (--n == 0) 192 return s; 193 } 194 } 195 throw fmt::FormatError("unmatched '{' in format"); 196 } 197 198 // Checks if an argument is a valid printf width specifier and sets 199 // left alignment if it is negative. 200 class WidthHandler : public fmt::internal::ArgVisitor<WidthHandler, unsigned> { 201 private: 202 fmt::FormatSpec &spec_; 203 204 public: 205 explicit WidthHandler(fmt::FormatSpec &spec) : spec_(spec) {} 206 207 unsigned visit_unhandled_arg() { 208 throw fmt::FormatError("width is not integer"); 209 } 210 211 template <typename T> 212 unsigned visit_any_int(T value) { 213 typedef typename fmt::internal::IntTraits<T>::MainType UnsignedType; 214 UnsignedType width = value; 215 if (fmt::internal::is_negative(value)) { 216 spec_.align_ = fmt::ALIGN_LEFT; 217 width = 0 - width; 218 } 219 if (width > INT_MAX) 220 throw fmt::FormatError("number is too big in format"); 221 return static_cast<unsigned>(width); 222 } 223 }; 224 225 class PrecisionHandler : 226 public fmt::internal::ArgVisitor<PrecisionHandler, int> { 227 public: 228 unsigned visit_unhandled_arg() { 229 throw fmt::FormatError("precision is not integer"); 230 } 231 232 template <typename T> 233 int visit_any_int(T value) { 234 if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value)) 235 throw fmt::FormatError("number is too big in format"); 236 return static_cast<int>(value); 237 } 238 }; 239 240 // Converts an integer argument to type T. 241 template <typename T> 242 class ArgConverter : public fmt::internal::ArgVisitor<ArgConverter<T>, void> { 243 private: 244 fmt::internal::Arg &arg_; 245 wchar_t type_; 246 247 public: 248 ArgConverter(fmt::internal::Arg &arg, wchar_t type) 249 : arg_(arg), type_(type) {} 250 251 template <typename U> 252 void visit_any_int(U value) { 253 bool is_signed = type_ == 'd' || type_ == 'i'; 254 using fmt::internal::Arg; 255 if (sizeof(T) <= sizeof(int)) { 256 if (is_signed) { 257 arg_.type = Arg::INT; 258 arg_.int_value = static_cast<int>(static_cast<T>(value)); 259 } else { 260 arg_.type = Arg::UINT; 261 arg_.uint_value = static_cast<unsigned>( 262 static_cast<typename fmt::internal::MakeUnsigned<T>::Type>(value)); 263 } 264 } else { 265 if (is_signed) { 266 arg_.type = Arg::LONG_LONG; 267 arg_.long_long_value = 268 static_cast<typename fmt::internal::MakeUnsigned<U>::Type>(value); 269 } else { 270 arg_.type = Arg::ULONG_LONG; 271 arg_.ulong_long_value = 272 static_cast<typename fmt::internal::MakeUnsigned<U>::Type>(value); 273 } 274 } 275 } 276 }; 277 278 // Converts an integer argument to char. 279 class CharConverter : public fmt::internal::ArgVisitor<CharConverter, void> { 280 private: 281 fmt::internal::Arg &arg_; 282 283 public: 284 explicit CharConverter(fmt::internal::Arg &arg) : arg_(arg) {} 285 286 template <typename T> 287 void visit_any_int(T value) { 288 arg_.type = Arg::CHAR; 289 arg_.int_value = static_cast<char>(value); 290 } 291 }; 292 293 // This function template is used to prevent compile errors when handling 294 // incompatible string arguments, e.g. handling a wide string in a narrow 295 // string formatter. 296 template <typename Char> 297 Arg::StringValue<Char> ignore_incompatible_str(Arg::StringValue<wchar_t>); 298 299 template <> 300 inline Arg::StringValue<char> ignore_incompatible_str( 301 Arg::StringValue<wchar_t>) { return Arg::StringValue<char>(); } 302 303 template <> 304 inline Arg::StringValue<wchar_t> ignore_incompatible_str( 305 Arg::StringValue<wchar_t> s) { return s; } 306 } // namespace 307 308 void fmt::SystemError::init( 309 int error_code, StringRef format_str, const ArgList &args) { 310 error_code_ = error_code; 311 Writer w; 312 internal::format_system_error(w, error_code, format(format_str, args)); 313 std::runtime_error &base = *this; 314 base = std::runtime_error(w.str()); 315 } 316 317 template <typename T> 318 int fmt::internal::CharTraits<char>::format_float( 319 char *buffer, std::size_t size, const char *format, 320 unsigned width, int precision, T value) { 321 if (width == 0) { 322 return precision < 0 ? 323 FMT_SNPRINTF(buffer, size, format, value) : 324 FMT_SNPRINTF(buffer, size, format, precision, value); 325 } 326 return precision < 0 ? 327 FMT_SNPRINTF(buffer, size, format, width, value) : 328 FMT_SNPRINTF(buffer, size, format, width, precision, value); 329 } 330 331 template <typename T> 332 int fmt::internal::CharTraits<wchar_t>::format_float( 333 wchar_t *buffer, std::size_t size, const wchar_t *format, 334 unsigned width, int precision, T value) { 335 if (width == 0) { 336 return precision < 0 ? 337 swprintf(buffer, size, format, value) : 338 swprintf(buffer, size, format, precision, value); 339 } 340 return precision < 0 ? 341 swprintf(buffer, size, format, width, value) : 342 swprintf(buffer, size, format, width, precision, value); 343 } 344 345 const char fmt::internal::DIGITS[] = 346 "0001020304050607080910111213141516171819" 347 "2021222324252627282930313233343536373839" 348 "4041424344454647484950515253545556575859" 349 "6061626364656667686970717273747576777879" 350 "8081828384858687888990919293949596979899"; 351 352 #define FMT_POWERS_OF_10(factor) \ 353 factor * 10, \ 354 factor * 100, \ 355 factor * 1000, \ 356 factor * 10000, \ 357 factor * 100000, \ 358 factor * 1000000, \ 359 factor * 10000000, \ 360 factor * 100000000, \ 361 factor * 1000000000 362 363 const uint32_t fmt::internal::POWERS_OF_10_32[] = {0, FMT_POWERS_OF_10(1)}; 364 const uint64_t fmt::internal::POWERS_OF_10_64[] = { 365 0, 366 FMT_POWERS_OF_10(1), 367 FMT_POWERS_OF_10(ULongLong(1000000000)), 368 // Multiply several constants instead of using a single long long constant 369 // to avoid warnings about C++98 not supporting long long. 370 ULongLong(1000000000) * ULongLong(1000000000) * 10 371 }; 372 373 void fmt::internal::report_unknown_type(char code, const char *type) { 374 if (std::isprint(static_cast<unsigned char>(code))) { 375 throw fmt::FormatError( 376 fmt::format("unknown format code '{}' for {}", code, type)); 377 } 378 throw fmt::FormatError( 379 fmt::format("unknown format code '\\x{:02x}' for {}", 380 static_cast<unsigned>(code), type)); 381 } 382 383 #ifdef _WIN32 384 385 fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) { 386 int length = MultiByteToWideChar( 387 CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), -1, 0, 0); 388 static const char ERROR[] = "cannot convert string from UTF-8 to UTF-16"; 389 if (length == 0) 390 throw WindowsError(GetLastError(), ERROR); 391 buffer_.resize(length); 392 length = MultiByteToWideChar( 393 CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), -1, &buffer_[0], length); 394 if (length == 0) 395 throw WindowsError(GetLastError(), ERROR); 396 } 397 398 fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) { 399 if (int error_code = convert(s)) { 400 throw WindowsError(error_code, 401 "cannot convert string from UTF-16 to UTF-8"); 402 } 403 } 404 405 int fmt::internal::UTF16ToUTF8::convert(fmt::WStringRef s) { 406 int length = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, 0, 0, 0, 0); 407 if (length == 0) 408 return GetLastError(); 409 buffer_.resize(length); 410 length = WideCharToMultiByte( 411 CP_UTF8, 0, s.c_str(), -1, &buffer_[0], length, 0, 0); 412 if (length == 0) 413 return GetLastError(); 414 return 0; 415 } 416 417 void fmt::WindowsError::init( 418 int error_code, StringRef format_str, const ArgList &args) { 419 error_code_ = error_code; 420 Writer w; 421 internal::format_windows_error(w, error_code, format(format_str, args)); 422 std::runtime_error &base = *this; 423 base = std::runtime_error(w.str()); 424 } 425 426 #endif 427 428 int fmt::internal::safe_strerror( 429 int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT(true) { 430 assert(buffer != 0 && buffer_size != 0); 431 int result = 0; 432 #ifdef _GNU_SOURCE 433 char *message = strerror_r(error_code, buffer, buffer_size); 434 // If the buffer is full then the message is probably truncated. 435 if (message == buffer && strlen(buffer) == buffer_size - 1) 436 result = ERANGE; 437 buffer = message; 438 #elif defined(__MINGW32__) 439 errno = 0; 440 (void)buffer_size; 441 buffer = strerror(error_code); 442 result = errno; 443 #elif defined(_WIN32) 444 result = strerror_s(buffer, buffer_size, error_code); 445 // If the buffer is full then the message is probably truncated. 446 if (result == 0 && std::strlen(buffer) == buffer_size - 1) 447 result = ERANGE; 448 #else 449 result = strerror_r(error_code, buffer, buffer_size); 450 if (result == -1) 451 result = errno; // glibc versions before 2.13 return result in errno. 452 #endif 453 return result; 454 } 455 456 void fmt::internal::format_system_error( 457 fmt::Writer &out, int error_code, fmt::StringRef message) { 458 Array<char, INLINE_BUFFER_SIZE> buffer; 459 buffer.resize(INLINE_BUFFER_SIZE); 460 char *system_message = 0; 461 for (;;) { 462 system_message = &buffer[0]; 463 int result = safe_strerror(error_code, system_message, buffer.size()); 464 if (result == 0) 465 break; 466 if (result != ERANGE) { 467 // Can't get error message, report error code instead. 468 out << message << ": error code = " << error_code; 469 return; 470 } 471 buffer.resize(buffer.size() * 2); 472 } 473 out << message << ": " << system_message; 474 } 475 476 #ifdef _WIN32 477 void fmt::internal::format_windows_error( 478 fmt::Writer &out, int error_code, fmt::StringRef message) { 479 class String { 480 private: 481 LPWSTR str_; 482 483 public: 484 String() : str_() {} 485 ~String() { LocalFree(str_); } 486 LPWSTR *ptr() { return &str_; } 487 LPCWSTR c_str() const { return str_; } 488 }; 489 String system_message; 490 if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | 491 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, 492 error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 493 reinterpret_cast<LPWSTR>(system_message.ptr()), 0, 0)) { 494 UTF16ToUTF8 utf8_message; 495 if (!utf8_message.convert(system_message.c_str())) { 496 out << message << ": " << utf8_message; 497 return; 498 } 499 } 500 // Can't get error message, report error code instead. 501 out << message << ": error code = " << error_code; 502 } 503 #endif 504 505 // An argument formatter. 506 template <typename Char> 507 class fmt::internal::ArgFormatter : 508 public fmt::internal::ArgVisitor<fmt::internal::ArgFormatter<Char>, void> { 509 private: 510 fmt::BasicFormatter<Char> &formatter_; 511 fmt::BasicWriter<Char> &writer_; 512 fmt::FormatSpec &spec_; 513 const Char *format_; 514 515 public: 516 ArgFormatter( 517 fmt::BasicFormatter<Char> &f,fmt::FormatSpec &s, const Char *fmt) 518 : formatter_(f), writer_(f.writer()), spec_(s), format_(fmt) {} 519 520 template <typename T> 521 void visit_any_int(T value) { writer_.write_int(value, spec_); } 522 523 template <typename T> 524 void visit_any_double(T value) { writer_.write_double(value, spec_); } 525 526 void visit_char(int value) { 527 if (spec_.type_ && spec_.type_ != 'c') { 528 spec_.flags_ |= CHAR_FLAG; 529 writer_.write_int(value, spec_); 530 return; 531 } 532 if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0) 533 throw FormatError("invalid format specifier for char"); 534 typedef typename fmt::BasicWriter<Char>::CharPtr CharPtr; 535 CharPtr out = CharPtr(); 536 if (spec_.width_ > 1) { 537 Char fill = static_cast<Char>(spec_.fill()); 538 out = writer_.grow_buffer(spec_.width_); 539 if (spec_.align_ == fmt::ALIGN_RIGHT) { 540 std::fill_n(out, spec_.width_ - 1, fill); 541 out += spec_.width_ - 1; 542 } else if (spec_.align_ == fmt::ALIGN_CENTER) { 543 out = writer_.fill_padding(out, spec_.width_, 1, fill); 544 } else { 545 std::fill_n(out + 1, spec_.width_ - 1, fill); 546 } 547 } else { 548 out = writer_.grow_buffer(1); 549 } 550 *out = static_cast<Char>(value); 551 } 552 553 void visit_string(Arg::StringValue<char> value) { 554 writer_.write_str(value, spec_); 555 } 556 void visit_wstring(Arg::StringValue<wchar_t> value) { 557 writer_.write_str(ignore_incompatible_str<Char>(value), spec_); 558 } 559 560 void visit_pointer(const void *value) { 561 if (spec_.type_ && spec_.type_ != 'p') 562 fmt::internal::report_unknown_type(spec_.type_, "pointer"); 563 spec_.flags_ = fmt::HASH_FLAG; 564 spec_.type_ = 'x'; 565 writer_.write_int(reinterpret_cast<uintptr_t>(value), spec_); 566 } 567 568 void visit_custom(Arg::CustomValue c) { 569 c.format(&formatter_, c.value, format_); 570 } 571 }; 572 573 template <typename Char> 574 void fmt::internal::FormatErrorReporter<Char>::operator()( 575 const Char *s, fmt::StringRef message) const { 576 if (find_closing_brace(s, num_open_braces)) 577 throw fmt::FormatError(message); 578 } 579 580 // Fills the padding around the content and returns the pointer to the 581 // content area. 582 template <typename Char> 583 typename fmt::BasicWriter<Char>::CharPtr 584 fmt::BasicWriter<Char>::fill_padding(CharPtr buffer, 585 unsigned total_size, std::size_t content_size, wchar_t fill) { 586 std::size_t padding = total_size - content_size; 587 std::size_t left_padding = padding / 2; 588 Char fill_char = static_cast<Char>(fill); 589 std::fill_n(buffer, left_padding, fill_char); 590 buffer += left_padding; 591 CharPtr content = buffer; 592 std::fill_n(buffer + content_size, padding - left_padding, fill_char); 593 return content; 594 } 595 596 template <typename Char> 597 template <typename T> 598 void fmt::BasicWriter<Char>::write_double(T value, const FormatSpec &spec) { 599 // Check type. 600 char type = spec.type(); 601 bool upper = false; 602 switch (type) { 603 case 0: 604 type = 'g'; 605 break; 606 case 'e': case 'f': case 'g': case 'a': 607 break; 608 case 'F': 609 #ifdef _MSC_VER 610 // MSVC's printf doesn't support 'F'. 611 type = 'f'; 612 #endif 613 // Fall through. 614 case 'E': case 'G': case 'A': 615 upper = true; 616 break; 617 default: 618 internal::report_unknown_type(type, "double"); 619 break; 620 } 621 622 char sign = 0; 623 // Use getsign instead of value < 0 because the latter is always 624 // false for NaN. 625 if (getsign(static_cast<double>(value))) { 626 sign = '-'; 627 value = -value; 628 } else if (spec.flag(SIGN_FLAG)) { 629 sign = spec.flag(PLUS_FLAG) ? '+' : ' '; 630 } 631 632 if (value != value) { 633 // Format NaN ourselves because sprintf's output is not consistent 634 // across platforms. 635 std::size_t size = 4; 636 const char *nan = upper ? " NAN" : " nan"; 637 if (!sign) { 638 --size; 639 ++nan; 640 } 641 CharPtr out = write_str(nan, size, spec); 642 if (sign) 643 *out = sign; 644 return; 645 } 646 647 if (isinfinity(value)) { 648 // Format infinity ourselves because sprintf's output is not consistent 649 // across platforms. 650 std::size_t size = 4; 651 const char *inf = upper ? " INF" : " inf"; 652 if (!sign) { 653 --size; 654 ++inf; 655 } 656 CharPtr out = write_str(inf, size, spec); 657 if (sign) 658 *out = sign; 659 return; 660 } 661 662 std::size_t offset = buffer_.size(); 663 unsigned width = spec.width(); 664 if (sign) { 665 buffer_.reserve(buffer_.size() + (std::max)(width, 1u)); 666 if (width > 0) 667 --width; 668 ++offset; 669 } 670 671 // Build format string. 672 enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg 673 Char format[MAX_FORMAT_SIZE]; 674 Char *format_ptr = format; 675 *format_ptr++ = '%'; 676 unsigned width_for_sprintf = width; 677 if (spec.flag(HASH_FLAG)) 678 *format_ptr++ = '#'; 679 if (spec.align() == ALIGN_CENTER) { 680 width_for_sprintf = 0; 681 } else { 682 if (spec.align() == ALIGN_LEFT) 683 *format_ptr++ = '-'; 684 if (width != 0) 685 *format_ptr++ = '*'; 686 } 687 if (spec.precision() >= 0) { 688 *format_ptr++ = '.'; 689 *format_ptr++ = '*'; 690 } 691 if (IsLongDouble<T>::VALUE) 692 *format_ptr++ = 'L'; 693 *format_ptr++ = type; 694 *format_ptr = '\0'; 695 696 // Format using snprintf. 697 Char fill = static_cast<Char>(spec.fill()); 698 for (;;) { 699 std::size_t size = buffer_.capacity() - offset; 700 #ifdef _MSC_VER 701 // MSVC's vsnprintf_s doesn't work with zero size, so reserve 702 // space for at least one extra character to make the size non-zero. 703 // Note that the buffer's capacity will increase by more than 1. 704 if (size == 0) { 705 buffer_.reserve(offset + 1); 706 size = buffer_.capacity() - offset; 707 } 708 #endif 709 Char *start = &buffer_[offset]; 710 int n = internal::CharTraits<Char>::format_float( 711 start, size, format, width_for_sprintf, spec.precision(), value); 712 if (n >= 0 && offset + n < buffer_.capacity()) { 713 if (sign) { 714 if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) || 715 *start != ' ') { 716 *(start - 1) = sign; 717 sign = 0; 718 } else { 719 *(start - 1) = fill; 720 } 721 ++n; 722 } 723 if (spec.align() == ALIGN_CENTER && 724 spec.width() > static_cast<unsigned>(n)) { 725 unsigned width = spec.width(); 726 CharPtr p = grow_buffer(width); 727 std::copy(p, p + n, p + (width - n) / 2); 728 fill_padding(p, spec.width(), n, fill); 729 return; 730 } 731 if (spec.fill() != ' ' || sign) { 732 while (*start == ' ') 733 *start++ = fill; 734 if (sign) 735 *(start - 1) = sign; 736 } 737 grow_buffer(n); 738 return; 739 } 740 // If n is negative we ask to increase the capacity by at least 1, 741 // but as std::vector, the buffer grows exponentially. 742 buffer_.reserve(n >= 0 ? offset + n + 1 : buffer_.capacity() + 1); 743 } 744 } 745 746 template <typename Char> 747 template <typename StrChar> 748 void fmt::BasicWriter<Char>::write_str( 749 const Arg::StringValue<StrChar> &str, const FormatSpec &spec) { 750 // Check if StrChar is convertible to Char. 751 internal::CharTraits<Char>::convert(StrChar()); 752 if (spec.type_ && spec.type_ != 's') 753 internal::report_unknown_type(spec.type_, "string"); 754 const StrChar *s = str.value; 755 std::size_t size = str.size; 756 if (size == 0) { 757 if (!s) { 758 Char err[] = { '(', 'n', 'u', 'l', 'l', ')', 0 }; 759 write_str(err, 6, spec); 760 return; 761 } 762 if (*s) 763 size = std::char_traits<StrChar>::length(s); 764 } 765 write_str(s, size, spec); 766 } 767 768 template <typename Char> 769 inline const Arg 770 &fmt::BasicFormatter<Char>::parse_arg_index(const Char *&s) { 771 unsigned arg_index = 0; 772 if (*s < '0' || *s > '9') { 773 if (*s != '}' && *s != ':') 774 report_error_(s, "invalid argument index in format string"); 775 const Arg &arg = next_arg(); 776 if (error_) 777 report_error_(s, error_); 778 return arg; 779 } 780 if (next_arg_index_ > 0) { 781 report_error_(s, 782 "cannot switch from automatic to manual argument indexing"); 783 } 784 next_arg_index_ = -1; 785 arg_index = parse_nonnegative_int(s, error_); 786 if (error_) 787 report_error_(s, error_); // TODO: don't use report_error_ 788 if (arg_index >= args_.size()) 789 report_error_(s, "argument index is out of range in format"); 790 return args_[arg_index]; 791 } 792 793 template <typename Char> 794 void fmt::BasicFormatter<Char>::check_sign( 795 const Char *&s, const Arg &arg) { 796 char sign = static_cast<char>(*s); 797 if (arg.type > Arg::LAST_NUMERIC_TYPE) { 798 report_error_(s, fmt::format( 799 "format specifier '{}' requires numeric argument", sign).c_str()); 800 } 801 if (arg.type == Arg::UINT || arg.type == Arg::ULONG_LONG) { 802 report_error_(s, fmt::format( 803 "format specifier '{}' requires signed argument", sign).c_str()); 804 } 805 ++s; 806 } 807 808 const Arg &fmt::internal::FormatterBase::next_arg() { 809 if (next_arg_index_ < 0) { 810 if (!error_) 811 error_ = "cannot switch from manual to automatic argument indexing"; 812 return DUMMY_ARG; 813 } 814 unsigned arg_index = next_arg_index_++; 815 if (arg_index < args_.size()) 816 return args_[arg_index]; 817 if (!error_) 818 error_ = "argument index is out of range in format"; 819 return DUMMY_ARG; 820 } 821 822 const Arg &fmt::internal::FormatterBase::handle_arg_index(unsigned arg_index) { 823 if (arg_index != UINT_MAX) { 824 if (next_arg_index_ <= 0) { 825 next_arg_index_ = -1; 826 --arg_index; 827 } else if (!error_) { 828 error_ = "cannot switch from automatic to manual argument indexing"; 829 } 830 if (arg_index < args_.size()) 831 return args_[arg_index]; 832 if (!error_) 833 error_ = "argument index is out of range in format"; 834 return DUMMY_ARG; 835 } 836 return next_arg(); 837 } 838 839 template <typename Char> 840 void fmt::internal::PrintfFormatter<Char>::parse_flags( 841 FormatSpec &spec, const Char *&s) { 842 for (;;) { 843 switch (*s++) { 844 case '-': 845 spec.align_ = ALIGN_LEFT; 846 break; 847 case '+': 848 spec.flags_ |= SIGN_FLAG | PLUS_FLAG; 849 break; 850 case '0': 851 spec.fill_ = '0'; 852 break; 853 case ' ': 854 spec.flags_ |= SIGN_FLAG; 855 break; 856 case '#': 857 spec.flags_ |= HASH_FLAG; 858 break; 859 default: 860 --s; 861 return; 862 } 863 } 864 } 865 866 template <typename Char> 867 unsigned fmt::internal::PrintfFormatter<Char>::parse_header( 868 const Char *&s, FormatSpec &spec) { 869 unsigned arg_index = UINT_MAX; 870 Char c = *s; 871 if (c >= '0' && c <= '9') { 872 // Parse an argument index (if followed by '$') or a width possibly 873 // preceded with '0' flag(s). 874 unsigned value = parse_nonnegative_int(s, error_); 875 if (*s == '$') { // value is an argument index 876 ++s; 877 arg_index = value; 878 } else { 879 if (c == '0') 880 spec.fill_ = '0'; 881 if (value != 0) { 882 // Nonzero value means that we parsed width and don't need to 883 // parse it or flags again, so return now. 884 spec.width_ = value; 885 return arg_index; 886 } 887 } 888 } 889 parse_flags(spec, s); 890 // Parse width. 891 if (*s >= '0' && *s <= '9') { 892 spec.width_ = parse_nonnegative_int(s, error_); 893 } else if (*s == '*') { 894 ++s; 895 spec.width_ = WidthHandler(spec).visit(handle_arg_index(UINT_MAX)); 896 } 897 return arg_index; 898 } 899 900 template <typename Char> 901 void fmt::internal::PrintfFormatter<Char>::format( 902 BasicWriter<Char> &writer, BasicStringRef<Char> format, 903 const ArgList &args) { 904 const Char *start = format.c_str(); 905 args_ = args; 906 next_arg_index_ = 0; 907 const Char *s = start; 908 while (*s) { 909 Char c = *s++; 910 if (c != '%') continue; 911 if (*s == c) { 912 write(writer, start, s); 913 start = ++s; 914 continue; 915 } 916 write(writer, start, s - 1); 917 918 FormatSpec spec; 919 spec.align_ = ALIGN_RIGHT; 920 921 // Reporting errors is delayed till the format specification is 922 // completely parsed. This is done to avoid potentially confusing 923 // error messages for incomplete format strings. For example, in 924 // sprintf("%2$", 42); 925 // the format specification is incomplete. In a naive approach we 926 // would parse 2 as an argument index and report an error that the 927 // index is out of range which would be rather confusing if the 928 // use meant "%2d$" rather than "%2$d". If we delay an error, the 929 // user will get an error that the format string is invalid which 930 // is OK for both cases. 931 932 // Parse argument index, flags and width. 933 unsigned arg_index = parse_header(s, spec); 934 935 // Parse precision. 936 if (*s == '.') { 937 ++s; 938 if ('0' <= *s && *s <= '9') { 939 spec.precision_ = parse_nonnegative_int(s, error_); 940 } else if (*s == '*') { 941 ++s; 942 spec.precision_ = PrecisionHandler().visit(handle_arg_index(UINT_MAX)); 943 } 944 } 945 946 Arg arg = handle_arg_index(arg_index); 947 if (spec.flag(HASH_FLAG) && IsZeroInt().visit(arg)) 948 spec.flags_ &= ~HASH_FLAG; 949 if (spec.fill_ == '0') { 950 if (arg.type <= Arg::LAST_NUMERIC_TYPE) 951 spec.align_ = ALIGN_NUMERIC; 952 else 953 spec.fill_ = ' '; // Ignore '0' flag for non-numeric types. 954 } 955 956 // Parse length and convert the argument to the required type. 957 switch (*s++) { 958 case 'h': 959 if (*s == 'h') 960 ArgConverter<signed char>(arg, *++s).visit(arg); 961 else 962 ArgConverter<short>(arg, *s).visit(arg); 963 break; 964 case 'l': 965 if (*s == 'l') 966 ArgConverter<fmt::LongLong>(arg, *++s).visit(arg); 967 else 968 ArgConverter<long>(arg, *s).visit(arg); 969 break; 970 case 'j': 971 ArgConverter<intmax_t>(arg, *s).visit(arg); 972 break; 973 case 'z': 974 ArgConverter<size_t>(arg, *s).visit(arg); 975 break; 976 case 't': 977 ArgConverter<ptrdiff_t>(arg, *s).visit(arg); 978 break; 979 case 'L': 980 // printf produces garbage when 'L' is omitted for long double, no 981 // need to do the same. 982 break; 983 default: 984 --s; 985 ArgConverter<int>(arg, *s).visit(arg); 986 } 987 988 // Parse type. 989 if (!*s) 990 throw FormatError("invalid format string"); 991 if (error_) 992 throw FormatError(error_); 993 spec.type_ = static_cast<char>(*s++); 994 if (arg.type <= Arg::LAST_INTEGER_TYPE) { 995 // Normalize type. 996 switch (spec.type_) { 997 case 'i': case 'u': 998 spec.type_ = 'd'; 999 break; 1000 case 'c': 1001 // TODO: handle wchar_t 1002 CharConverter(arg).visit(arg); 1003 break; 1004 } 1005 } 1006 1007 start = s; 1008 1009 // Format argument. 1010 switch (arg.type) { 1011 case Arg::INT: 1012 writer.write_int(arg.int_value, spec); 1013 break; 1014 case Arg::UINT: 1015 writer.write_int(arg.uint_value, spec); 1016 break; 1017 case Arg::LONG_LONG: 1018 writer.write_int(arg.long_long_value, spec); 1019 break; 1020 case Arg::ULONG_LONG: 1021 writer.write_int(arg.ulong_long_value, spec); 1022 break; 1023 case Arg::CHAR: { 1024 if (spec.type_ && spec.type_ != 'c') 1025 writer.write_int(arg.int_value, spec); 1026 typedef typename BasicWriter<Char>::CharPtr CharPtr; 1027 CharPtr out = CharPtr(); 1028 if (spec.width_ > 1) { 1029 Char fill = ' '; 1030 out = writer.grow_buffer(spec.width_); 1031 if (spec.align_ != ALIGN_LEFT) { 1032 std::fill_n(out, spec.width_ - 1, fill); 1033 out += spec.width_ - 1; 1034 } else { 1035 std::fill_n(out + 1, spec.width_ - 1, fill); 1036 } 1037 } else { 1038 out = writer.grow_buffer(1); 1039 } 1040 *out = static_cast<Char>(arg.int_value); 1041 break; 1042 } 1043 case Arg::DOUBLE: 1044 writer.write_double(arg.double_value, spec); 1045 break; 1046 case Arg::LONG_DOUBLE: 1047 writer.write_double(arg.long_double_value, spec); 1048 break; 1049 case Arg::STRING: 1050 writer.write_str(arg.string, spec); 1051 break; 1052 case Arg::WSTRING: 1053 writer.write_str(ignore_incompatible_str<Char>(arg.wstring), spec); 1054 break; 1055 case Arg::POINTER: 1056 if (spec.type_ && spec.type_ != 'p') 1057 internal::report_unknown_type(spec.type_, "pointer"); 1058 spec.flags_= HASH_FLAG; 1059 spec.type_ = 'x'; 1060 writer.write_int(reinterpret_cast<uintptr_t>(arg.pointer_value), spec); 1061 break; 1062 case Arg::CUSTOM: 1063 if (spec.type_) 1064 internal::report_unknown_type(spec.type_, "object"); 1065 arg.custom.format(&writer, arg.custom.value, "s"); 1066 break; 1067 default: 1068 assert(false); 1069 break; 1070 } 1071 } 1072 write(writer, start, s); 1073 } 1074 1075 template <typename Char> 1076 const Char *fmt::BasicFormatter<Char>::format( 1077 const Char *format_str, const Arg &arg) { 1078 const Char *s = format_str; 1079 const char *error = 0; 1080 FormatSpec spec; 1081 if (*s == ':') { 1082 if (arg.type == Arg::CUSTOM) { 1083 arg.custom.format(this, arg.custom.value, s); 1084 return find_closing_brace(s) + 1; 1085 } 1086 ++s; 1087 // Parse fill and alignment. 1088 if (Char c = *s) { 1089 const Char *p = s + 1; 1090 spec.align_ = ALIGN_DEFAULT; 1091 do { 1092 switch (*p) { 1093 case '<': 1094 spec.align_ = ALIGN_LEFT; 1095 break; 1096 case '>': 1097 spec.align_ = ALIGN_RIGHT; 1098 break; 1099 case '=': 1100 spec.align_ = ALIGN_NUMERIC; 1101 break; 1102 case '^': 1103 spec.align_ = ALIGN_CENTER; 1104 break; 1105 } 1106 if (spec.align_ != ALIGN_DEFAULT) { 1107 if (p != s) { 1108 if (c == '}') break; 1109 if (c == '{') 1110 report_error_(s, "invalid fill character '{'"); 1111 s += 2; 1112 spec.fill_ = c; 1113 } else ++s; 1114 if (spec.align_ == ALIGN_NUMERIC && arg.type > Arg::LAST_NUMERIC_TYPE) 1115 report_error_(s, "format specifier '=' requires numeric argument"); 1116 break; 1117 } 1118 } while (--p >= s); 1119 } 1120 1121 // Parse sign. 1122 switch (*s) { 1123 case '+': 1124 check_sign(s, arg); 1125 spec.flags_ |= SIGN_FLAG | PLUS_FLAG; 1126 break; 1127 case '-': 1128 check_sign(s, arg); 1129 spec.flags_ |= MINUS_FLAG; 1130 break; 1131 case ' ': 1132 check_sign(s, arg); 1133 spec.flags_ |= SIGN_FLAG; 1134 break; 1135 } 1136 1137 if (*s == '#') { 1138 if (arg.type > Arg::LAST_NUMERIC_TYPE) 1139 report_error_(s, "format specifier '#' requires numeric argument"); 1140 spec.flags_ |= HASH_FLAG; 1141 ++s; 1142 } 1143 1144 // Parse width and zero flag. 1145 if ('0' <= *s && *s <= '9') { 1146 if (*s == '0') { 1147 if (arg.type > Arg::LAST_NUMERIC_TYPE) 1148 report_error_(s, "format specifier '0' requires numeric argument"); 1149 spec.align_ = ALIGN_NUMERIC; 1150 spec.fill_ = '0'; 1151 } 1152 // Zero may be parsed again as a part of the width, but it is simpler 1153 // and more efficient than checking if the next char is a digit. 1154 spec.width_ = parse_nonnegative_int(s, error); 1155 if (error) 1156 report_error_(s, error); 1157 } 1158 1159 // Parse precision. 1160 if (*s == '.') { 1161 ++s; 1162 spec.precision_ = 0; 1163 if ('0' <= *s && *s <= '9') { 1164 spec.precision_ = parse_nonnegative_int(s, error); 1165 if (error) 1166 report_error_(s, error); 1167 } else if (*s == '{') { 1168 ++s; 1169 ++report_error_.num_open_braces; 1170 const Arg &precision_arg = parse_arg_index(s); 1171 ULongLong value = 0; 1172 switch (precision_arg.type) { 1173 case Arg::INT: 1174 if (precision_arg.int_value < 0) 1175 report_error_(s, "negative precision in format"); 1176 value = precision_arg.int_value; 1177 break; 1178 case Arg::UINT: 1179 value = precision_arg.uint_value; 1180 break; 1181 case Arg::LONG_LONG: 1182 if (precision_arg.long_long_value < 0) 1183 report_error_(s, "negative precision in format"); 1184 value = precision_arg.long_long_value; 1185 break; 1186 case Arg::ULONG_LONG: 1187 value = precision_arg.ulong_long_value; 1188 break; 1189 default: 1190 report_error_(s, "precision is not integer"); 1191 } 1192 if (value > INT_MAX) 1193 report_error_(s, "number is too big in format"); 1194 spec.precision_ = static_cast<int>(value); 1195 if (*s++ != '}') 1196 throw FormatError("unmatched '{' in format"); 1197 --report_error_.num_open_braces; 1198 } else { 1199 report_error_(s, "missing precision in format"); 1200 } 1201 if (arg.type != Arg::DOUBLE && arg.type != Arg::LONG_DOUBLE) { 1202 report_error_(s, 1203 "precision specifier requires floating-point argument"); 1204 } 1205 } 1206 1207 // Parse type. 1208 if (*s != '}' && *s) 1209 spec.type_ = static_cast<char>(*s++); 1210 } 1211 1212 if (*s++ != '}') 1213 throw FormatError("unmatched '{' in format"); 1214 start_ = s; 1215 1216 // Format argument. 1217 internal::ArgFormatter<Char>(*this, spec, s - 1).visit(arg); 1218 return s; 1219 } 1220 1221 template <typename Char> 1222 void fmt::BasicFormatter<Char>::format( 1223 BasicStringRef<Char> format_str, const ArgList &args) { 1224 const Char *s = start_ = format_str.c_str(); 1225 args_ = args; 1226 next_arg_index_ = 0; 1227 while (*s) { 1228 Char c = *s++; 1229 if (c != '{' && c != '}') continue; 1230 if (*s == c) { 1231 write(writer_, start_, s); 1232 start_ = ++s; 1233 continue; 1234 } 1235 if (c == '}') 1236 throw FormatError("unmatched '}' in format"); 1237 report_error_.num_open_braces = 1; 1238 write(writer_, start_, s - 1); 1239 Arg arg = parse_arg_index(s); 1240 s = format(s, arg); 1241 } 1242 write(writer_, start_, s); 1243 } 1244 1245 void fmt::report_system_error( 1246 int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { 1247 // FIXME: format_system_error may throw 1248 report_error(internal::format_system_error, error_code, message); 1249 } 1250 1251 #ifdef _WIN32 1252 void fmt::report_windows_error( 1253 int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { 1254 // FIXME: format_windows_error may throw 1255 report_error(internal::format_windows_error, error_code, message); 1256 } 1257 #endif 1258 1259 void fmt::print(std::FILE *f, StringRef format_str, const ArgList &args) { 1260 Writer w; 1261 w.write(format_str, args); 1262 std::fwrite(w.data(), 1, w.size(), f); 1263 } 1264 1265 void fmt::print(std::ostream &os, StringRef format_str, const ArgList &args) { 1266 Writer w; 1267 w.write(format_str, args); 1268 os.write(w.data(), w.size()); 1269 } 1270 1271 void fmt::print_colored(Color c, StringRef format, const ArgList &args) { 1272 char escape[] = "\x1b[30m"; 1273 escape[3] = '0' + static_cast<char>(c); 1274 std::fputs(escape, stdout); 1275 print(format, args); 1276 std::fputs(RESET_COLOR, stdout); 1277 } 1278 1279 int fmt::fprintf(std::FILE *f, StringRef format, const ArgList &args) { 1280 Writer w; 1281 printf(w, format, args); 1282 return std::fwrite(w.data(), 1, w.size(), f); 1283 } 1284 1285 // Explicit instantiations for char. 1286 1287 template fmt::BasicWriter<char>::CharPtr 1288 fmt::BasicWriter<char>::fill_padding(CharPtr buffer, 1289 unsigned total_size, std::size_t content_size, wchar_t fill); 1290 1291 template void fmt::BasicFormatter<char>::format( 1292 BasicStringRef<char> format, const ArgList &args); 1293 1294 template void fmt::internal::PrintfFormatter<char>::format( 1295 BasicWriter<char> &writer, BasicStringRef<char> format, const ArgList &args); 1296 1297 // Explicit instantiations for wchar_t. 1298 1299 template fmt::BasicWriter<wchar_t>::CharPtr 1300 fmt::BasicWriter<wchar_t>::fill_padding(CharPtr buffer, 1301 unsigned total_size, std::size_t content_size, wchar_t fill); 1302 1303 template void fmt::BasicFormatter<wchar_t>::format( 1304 BasicStringRef<wchar_t> format, const ArgList &args); 1305 1306 template void fmt::internal::PrintfFormatter<wchar_t>::format( 1307 BasicWriter<wchar_t> &writer, BasicStringRef<wchar_t> format, 1308 const ArgList &args); 1309 1310 #ifdef _MSC_VER 1311 # pragma warning(pop) 1312 #endif -
new file source/third_party/cppformat/format.h
diff --git a/source/third_party/cppformat/format.h b/source/third_party/cppformat/format.h new file mode 100644 index 0000000..01452d0
- + 1 /* 2 * Slightly modified version of cppformat, by Wildfire Games, for 0 A.D. 3 * Based on cppformat v0.11.0 from https://github.com/cppformat/cppformat 4 */ 5 6 /* 7 Formatting library for C++ 8 9 Copyright (c) 2012 - 2014, Victor Zverovich 10 All rights reserved. 11 12 Redistribution and use in source and binary forms, with or without 13 modification, are permitted provided that the following conditions are met: 14 15 1. Redistributions of source code must retain the above copyright notice, this 16 list of conditions and the following disclaimer. 17 2. Redistributions in binary form must reproduce the above copyright notice, 18 this list of conditions and the following disclaimer in the documentation 19 and/or other materials provided with the distribution. 20 21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 25 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef FMT_FORMAT_H_ 34 #define FMT_FORMAT_H_ 35 36 #include <stdint.h> 37 38 #include <cassert> 39 #include <cstddef> // for std::ptrdiff_t 40 #include <cstdio> 41 #include <algorithm> 42 #include <limits> 43 #include <stdexcept> 44 #include <string> 45 #include <sstream> 46 47 #if defined(_SECURE_SCL) && _SECURE_SCL 48 # include <iterator> 49 #endif 50 51 #ifdef __GNUC__ 52 # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) 53 # define FMT_GCC_EXTENSION __extension__ 54 // Disable warning about "long long" which is sometimes reported even 55 // when using __extension__. 56 # if FMT_GCC_VERSION >= 406 57 # pragma GCC diagnostic push 58 # pragma GCC diagnostic ignored "-Wlong-long" 59 # endif 60 #else 61 # define FMT_GCC_EXTENSION 62 #endif 63 64 #ifdef __GNUC_LIBSTD__ 65 # define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__) 66 #endif 67 68 #ifdef __has_feature 69 # define FMT_HAS_FEATURE(x) __has_feature(x) 70 #else 71 # define FMT_HAS_FEATURE(x) 0 72 #endif 73 74 #ifdef __has_builtin 75 # define FMT_HAS_BUILTIN(x) __has_builtin(x) 76 #else 77 # define FMT_HAS_BUILTIN(x) 0 78 #endif 79 80 #ifndef FMT_USE_VARIADIC_TEMPLATES 81 // Variadic templates are available in GCC since version 4.4 82 // (http://gcc.gnu.org/projects/cxx0x.html) and in Visual C++ 83 // since version 2013. 84 # define FMT_USE_VARIADIC_TEMPLATES \ 85 (FMT_HAS_FEATURE(cxx_variadic_templates) || \ 86 (FMT_GCC_VERSION >= 404 && __cplusplus >= 201103) || (defined(_MSC_VER) && _MSC_VER >= 1800)) 87 #endif 88 89 #ifndef FMT_USE_RVALUE_REFERENCES 90 // Don't use rvalue references when compiling with clang and an old libstdc++ 91 // as the latter doesn't provide std::move. 92 # if defined(FMT_GNUC_LIBSTD_VERSION) && FMT_GNUC_LIBSTD_VERSION <= 402 93 # define FMT_USE_RVALUE_REFERENCES 0 94 # else 95 # define FMT_USE_RVALUE_REFERENCES \ 96 (FMT_HAS_FEATURE(cxx_rvalue_references) || \ 97 (FMT_GCC_VERSION >= 403 && __cplusplus >= 201103) || (defined(_MSC_VER) && _MSC_VER >= 1600)) 98 # endif 99 #endif 100 101 #if FMT_USE_RVALUE_REFERENCES 102 # include <utility> // for std::move 103 #endif 104 105 // Define FMT_USE_NOEXCEPT to make C++ Format use noexcept (C++11 feature). 106 #if (defined(FMT_USE_NOEXPECT) && FMT_USE_NOEXCEPT) || FMT_HAS_FEATURE(cxx_noexcept) || \ 107 (FMT_GCC_VERSION >= 408 && __cplusplus >= 201103) 108 # define FMT_NOEXCEPT(expr) noexcept(expr) 109 #else 110 # define FMT_NOEXCEPT(expr) 111 #endif 112 113 // A macro to disallow the copy constructor and operator= functions 114 // This should be used in the private: declarations for a class 115 #define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \ 116 TypeName(const TypeName&); \ 117 void operator=(const TypeName&) 118 119 namespace fmt { 120 121 // Fix the warning about long long on older versions of GCC 122 // that don't support the diagnostic pragma. 123 FMT_GCC_EXTENSION typedef long long LongLong; 124 FMT_GCC_EXTENSION typedef unsigned long long ULongLong; 125 126 #if FMT_USE_RVALUE_REFERENCES 127 using std::move; 128 #endif 129 130 template <typename Char> 131 class BasicWriter; 132 133 typedef BasicWriter<char> Writer; 134 typedef BasicWriter<wchar_t> WWriter; 135 136 template <typename Char> 137 class BasicFormatter; 138 139 template <typename Char, typename T> 140 void format(BasicFormatter<Char> &f, const Char *format_str, const T &value); 141 142 /** 143 \rst 144 A string reference. It can be constructed from a C string or 145 ``std::string``. 146 147 You can use one of the following typedefs for common character types: 148 149 +------------+-------------------------+ 150 | Type | Definition | 151 +============+=========================+ 152 | StringRef | BasicStringRef<char> | 153 +------------+-------------------------+ 154 | WStringRef | BasicStringRef<wchar_t> | 155 +------------+-------------------------+ 156 157 This class is most useful as a parameter type to allow passing 158 different types of strings to a function, for example:: 159 160 template<typename... Args> 161 std::string format(StringRef format, const Args & ... args); 162 163 format("{}", 42); 164 format(std::string("{}"), 42); 165 \endrst 166 */ 167 template <typename Char> 168 class BasicStringRef { 169 private: 170 const Char *data_; 171 mutable std::size_t size_; 172 173 public: 174 /** 175 Constructs a string reference object from a C string and a size. 176 If *size* is zero, which is the default, the size is computed 177 automatically. 178 */ 179 BasicStringRef(const Char *s, std::size_t size = 0) : data_(s), size_(size) {} 180 181 /** 182 Constructs a string reference from an `std::string` object. 183 */ 184 BasicStringRef(const std::basic_string<Char> &s) 185 : data_(s.c_str()), size_(s.size()) {} 186 187 /** 188 Converts a string reference to an `std::string` object. 189 */ 190 operator std::basic_string<Char>() const { 191 return std::basic_string<Char>(data_, size()); 192 } 193 194 /** 195 Returns the pointer to a C string. 196 */ 197 const Char *c_str() const { return data_; } 198 199 /** 200 Returns the string size. 201 */ 202 std::size_t size() const { 203 if (size_ == 0 && data_) size_ = std::char_traits<Char>::length(data_); 204 return size_; 205 } 206 207 friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) { 208 return lhs.data_ == rhs.data_; 209 } 210 friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) { 211 return lhs.data_ != rhs.data_; 212 } 213 }; 214 215 typedef BasicStringRef<char> StringRef; 216 typedef BasicStringRef<wchar_t> WStringRef; 217 218 /** 219 A formatting error such as invalid format string. 220 */ 221 class FormatError : public std::runtime_error { 222 public: 223 explicit FormatError(const std::string &message) 224 : std::runtime_error(message) {} 225 }; 226 227 namespace internal { 228 229 // The number of characters to store in the Array object, representing the 230 // output buffer, itself to avoid dynamic memory allocation. 231 enum { INLINE_BUFFER_SIZE = 500 }; 232 233 #if defined(_SECURE_SCL) && _SECURE_SCL 234 // Use checked iterator to avoid warnings on MSVC. 235 template <typename T> 236 inline stdext::checked_array_iterator<T*> make_ptr(T *ptr, std::size_t size) { 237 return stdext::checked_array_iterator<T*>(ptr, size); 238 } 239 #else 240 template <typename T> 241 inline T *make_ptr(T *ptr, std::size_t) { return ptr; } 242 #endif 243 244 // A simple array for POD types with the first SIZE elements stored in 245 // the object itself. It supports a subset of std::vector's operations. 246 template <typename T, std::size_t SIZE> 247 class Array { 248 private: 249 std::size_t size_; 250 std::size_t capacity_; 251 T *ptr_; 252 T data_[SIZE]; 253 254 void grow(std::size_t size); 255 256 // Free memory allocated by the array. 257 void free() { 258 if (ptr_ != data_) delete [] ptr_; 259 } 260 261 // Move data from other to this array. 262 void move(Array &other) { 263 size_ = other.size_; 264 capacity_ = other.capacity_; 265 if (other.ptr_ == other.data_) { 266 ptr_ = data_; 267 std::copy(other.data_, other.data_ + size_, make_ptr(data_, capacity_)); 268 } else { 269 ptr_ = other.ptr_; 270 // Set pointer to the inline array so that delete is not called 271 // when freeing. 272 other.ptr_ = other.data_; 273 } 274 } 275 276 FMT_DISALLOW_COPY_AND_ASSIGN(Array); 277 278 public: 279 explicit Array(std::size_t size = 0) 280 : size_(size), capacity_(SIZE), ptr_(data_) {} 281 ~Array() { free(); } 282 283 #if FMT_USE_RVALUE_REFERENCES 284 Array(Array &&other) { 285 move(other); 286 } 287 288 Array& operator=(Array &&other) { 289 assert(this != &other); 290 free(); 291 move(other); 292 return *this; 293 } 294 #endif 295 296 // Returns the size of this array. 297 std::size_t size() const { return size_; } 298 299 // Returns the capacity of this array. 300 std::size_t capacity() const { return capacity_; } 301 302 // Resizes the array. If T is a POD type new elements are not initialized. 303 void resize(std::size_t new_size) { 304 if (new_size > capacity_) 305 grow(new_size); 306 size_ = new_size; 307 } 308 309 // Reserves space to store at least capacity elements. 310 void reserve(std::size_t capacity) { 311 if (capacity > capacity_) 312 grow(capacity); 313 } 314 315 void clear() { size_ = 0; } 316 317 void push_back(const T &value) { 318 if (size_ == capacity_) 319 grow(size_ + 1); 320 ptr_[size_++] = value; 321 } 322 323 // Appends data to the end of the array. 324 void append(const T *begin, const T *end); 325 326 T &operator[](std::size_t index) { return ptr_[index]; } 327 const T &operator[](std::size_t index) const { return ptr_[index]; } 328 }; 329 330 template <typename T, std::size_t SIZE> 331 void Array<T, SIZE>::grow(std::size_t size) { 332 capacity_ = (std::max)(size, capacity_ + capacity_ / 2); 333 T *p = new T[capacity_]; 334 std::copy(ptr_, ptr_ + size_, make_ptr(p, capacity_)); 335 if (ptr_ != data_) 336 delete [] ptr_; 337 ptr_ = p; 338 } 339 340 template <typename T, std::size_t SIZE> 341 void Array<T, SIZE>::append(const T *begin, const T *end) { 342 std::ptrdiff_t num_elements = end - begin; 343 if (size_ + num_elements > capacity_) 344 grow(size_ + num_elements); 345 std::copy(begin, end, make_ptr(ptr_, capacity_) + size_); 346 size_ += num_elements; 347 } 348 349 template <typename Char> 350 class BasicCharTraits { 351 public: 352 #if defined(_SECURE_SCL) && _SECURE_SCL 353 typedef stdext::checked_array_iterator<Char*> CharPtr; 354 #else 355 typedef Char *CharPtr; 356 #endif 357 }; 358 359 template <typename Char> 360 class CharTraits; 361 362 template <> 363 class CharTraits<char> : public BasicCharTraits<char> { 364 private: 365 // Conversion from wchar_t to char is not allowed. 366 static char convert(wchar_t); 367 368 public: 369 typedef const wchar_t *UnsupportedStrType; 370 371 static char convert(char value) { return value; } 372 373 // Formats a floating-point number. 374 template <typename T> 375 static int format_float(char *buffer, std::size_t size, 376 const char *format, unsigned width, int precision, T value); 377 }; 378 379 template <> 380 class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> { 381 public: 382 typedef const char *UnsupportedStrType; 383 384 static wchar_t convert(char value) { return value; } 385 static wchar_t convert(wchar_t value) { return value; } 386 387 template <typename T> 388 static int format_float(wchar_t *buffer, std::size_t size, 389 const wchar_t *format, unsigned width, int precision, T value); 390 }; 391 392 // Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise. 393 template <bool FitsIn32Bits> 394 struct TypeSelector { typedef uint32_t Type; }; 395 396 template <> 397 struct TypeSelector<false> { typedef uint64_t Type; }; 398 399 // Checks if a number is negative - used to avoid warnings. 400 template <bool IsSigned> 401 struct SignChecker { 402 template <typename T> 403 static bool is_negative(T) { return false; } 404 }; 405 406 template <> 407 struct SignChecker<true> { 408 template <typename T> 409 static bool is_negative(T value) { return value < 0; } 410 }; 411 412 // Returns true if value is negative, false otherwise. 413 // Same as (value < 0) but doesn't produce warnings if T is an unsigned type. 414 template <typename T> 415 inline bool is_negative(T value) { 416 return SignChecker<std::numeric_limits<T>::is_signed>::is_negative(value); 417 } 418 419 template <typename T> 420 struct IntTraits { 421 // Smallest of uint32_t and uint64_t that is large enough to represent 422 // all values of T. 423 typedef typename 424 TypeSelector<std::numeric_limits<T>::digits <= 32>::Type MainType; 425 }; 426 427 // MakeUnsigned<T>::Type gives an unsigned type corresponding to integer type T. 428 template <typename T> 429 struct MakeUnsigned { typedef T Type; }; 430 431 #define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \ 432 template <> \ 433 struct MakeUnsigned<T> { typedef U Type; } 434 435 FMT_SPECIALIZE_MAKE_UNSIGNED(char, unsigned char); 436 FMT_SPECIALIZE_MAKE_UNSIGNED(signed char, unsigned char); 437 FMT_SPECIALIZE_MAKE_UNSIGNED(short, unsigned short); 438 FMT_SPECIALIZE_MAKE_UNSIGNED(int, unsigned); 439 FMT_SPECIALIZE_MAKE_UNSIGNED(long, unsigned long); 440 FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong); 441 442 void report_unknown_type(char code, const char *type); 443 444 extern const uint32_t POWERS_OF_10_32[]; 445 extern const uint64_t POWERS_OF_10_64[]; 446 447 #if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll) 448 // Returns the number of decimal digits in n. Leading zeros are not counted 449 // except for n == 0 in which case count_digits returns 1. 450 inline unsigned count_digits(uint64_t n) { 451 // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 452 // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits. 453 unsigned t = (64 - __builtin_clzll(n | 1)) * 1233 >> 12; 454 return t - (n < POWERS_OF_10_64[t]) + 1; 455 } 456 # if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz) 457 // Optional version of count_digits for better performance on 32-bit platforms. 458 inline unsigned count_digits(uint32_t n) { 459 uint32_t t = (32 - __builtin_clz(n | 1)) * 1233 >> 12; 460 return t - (n < POWERS_OF_10_32[t]) + 1; 461 } 462 # endif 463 #else 464 // Slower version of count_digits used when __builtin_clz is not available. 465 inline unsigned count_digits(uint64_t n) { 466 unsigned count = 1; 467 for (;;) { 468 // Integer division is slow so do it for a group of four digits instead 469 // of for every digit. The idea comes from the talk by Alexandrescu 470 // "Three Optimization Tips for C++". See speed-test for a comparison. 471 if (n < 10) return count; 472 if (n < 100) return count + 1; 473 if (n < 1000) return count + 2; 474 if (n < 10000) return count + 3; 475 n /= 10000u; 476 count += 4; 477 } 478 } 479 #endif 480 481 extern const char DIGITS[]; 482 483 // Formats a decimal unsigned integer value writing into buffer. 484 template <typename UInt, typename Char> 485 inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) { 486 --num_digits; 487 while (value >= 100) { 488 // Integer division is slow so do it for a group of two digits instead 489 // of for every digit. The idea comes from the talk by Alexandrescu 490 // "Three Optimization Tips for C++". See speed-test for a comparison. 491 unsigned index = (value % 100) * 2; 492 value /= 100; 493 buffer[num_digits] = DIGITS[index + 1]; 494 buffer[num_digits - 1] = DIGITS[index]; 495 num_digits -= 2; 496 } 497 if (value < 10) { 498 *buffer = static_cast<char>('0' + value); 499 return; 500 } 501 unsigned index = static_cast<unsigned>(value * 2); 502 buffer[1] = DIGITS[index + 1]; 503 buffer[0] = DIGITS[index]; 504 } 505 506 #ifdef _WIN32 507 // A converter from UTF-8 to UTF-16. 508 // It is only provided for Windows since other systems use UTF-8. 509 class UTF8ToUTF16 { 510 private: 511 Array<wchar_t, INLINE_BUFFER_SIZE> buffer_; 512 513 public: 514 explicit UTF8ToUTF16(StringRef s); 515 operator WStringRef() const { return WStringRef(&buffer_[0], size()); } 516 size_t size() const { return buffer_.size() - 1; } 517 const wchar_t *c_str() const { return &buffer_[0]; } 518 std::wstring str() const { return std::wstring(&buffer_[0], size()); } 519 }; 520 521 // A converter from UTF-16 to UTF-8. 522 // It is only provided for Windows since other systems use UTF-8. 523 class UTF16ToUTF8 { 524 private: 525 Array<char, INLINE_BUFFER_SIZE> buffer_; 526 527 public: 528 UTF16ToUTF8() {} 529 explicit UTF16ToUTF8(WStringRef s); 530 operator StringRef() const { return StringRef(&buffer_[0], size()); } 531 size_t size() const { return buffer_.size() - 1; } 532 const char *c_str() const { return &buffer_[0]; } 533 std::string str() const { return std::string(&buffer_[0], size()); } 534 535 // Performs conversion returning a system error code instead of 536 // throwing exception on error. 537 int convert(WStringRef s); 538 }; 539 #endif 540 541 // Portable thread-safe version of strerror. 542 // Sets buffer to point to a string describing the error code. 543 // This can be either a pointer to a string stored in buffer, 544 // or a pointer to some static immutable string. 545 // Returns one of the following values: 546 // 0 - success 547 // ERANGE - buffer is not large enough to store the error message 548 // other - failure 549 // Buffer should be at least of size 1. 550 int safe_strerror(int error_code, 551 char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT(true); 552 553 void format_system_error( 554 fmt::Writer &out, int error_code, fmt::StringRef message); 555 556 #ifdef _WIN32 557 void format_windows_error( 558 fmt::Writer &out, int error_code, fmt::StringRef message); 559 #endif 560 561 // Throws Exception(message) if format contains '}', otherwise throws 562 // FormatError reporting unmatched '{'. The idea is that unmatched '{' 563 // should override other errors. 564 template <typename Char> 565 struct FormatErrorReporter { 566 int num_open_braces; 567 void operator()(const Char *s, fmt::StringRef message) const; 568 }; 569 570 // Computes max(Arg, 1) at compile time. It is used to avoid errors about 571 // allocating an array of 0 size. 572 template <unsigned Arg> 573 struct NonZero { 574 enum { VALUE = Arg }; 575 }; 576 577 template <> 578 struct NonZero<0> { 579 enum { VALUE = 1 }; 580 }; 581 582 // A formatting argument. It is a POD type to allow storage in internal::Array. 583 struct Arg { 584 enum Type { 585 // Integer types should go first, 586 INT, UINT, LONG_LONG, ULONG_LONG, CHAR, LAST_INTEGER_TYPE = CHAR, 587 // followed by floating-point types. 588 DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE, 589 STRING, WSTRING, POINTER, CUSTOM 590 }; 591 Type type; 592 593 template <typename Char> 594 struct StringValue { 595 const Char *value; 596 std::size_t size; 597 }; 598 599 typedef void (*FormatFunc)( 600 void *formatter, const void *arg, const void *format_str); 601 602 struct CustomValue { 603 const void *value; 604 FormatFunc format; 605 }; 606 607 union { 608 int int_value; 609 unsigned uint_value; 610 LongLong long_long_value; 611 ULongLong ulong_long_value; 612 double double_value; 613 long double long_double_value; 614 const void *pointer_value; 615 StringValue<char> string; 616 StringValue<wchar_t> wstring; 617 CustomValue custom; 618 }; 619 }; 620 621 // Makes an Arg object from any type. 622 template <typename Char> 623 class MakeArg : public Arg { 624 private: 625 // The following two methods are private to disallow formatting of 626 // arbitrary pointers. If you want to output a pointer cast it to 627 // "void *" or "const void *". In particular, this forbids formatting 628 // of "[const] volatile char *" which is printed as bool by iostreams. 629 // Do not implement! 630 template <typename T> 631 MakeArg(const T *value); 632 template <typename T> 633 MakeArg(T *value); 634 635 void set_string(StringRef str) { 636 type = STRING; 637 string.value = str.c_str(); 638 string.size = str.size(); 639 } 640 641 void set_string(WStringRef str) { 642 type = WSTRING; 643 CharTraits<Char>::convert(wchar_t()); 644 wstring.value = str.c_str(); 645 wstring.size = str.size(); 646 } 647 648 // Formats an argument of a custom type, such as a user-defined class. 649 template <typename T> 650 static void format_custom_arg( 651 void *formatter, const void *arg, const void *format_str) { 652 format(*static_cast<BasicFormatter<Char>*>(formatter), 653 static_cast<const Char*>(format_str), *static_cast<const T*>(arg)); 654 } 655 656 public: 657 MakeArg() {} 658 MakeArg(bool value) { type = INT; int_value = value; } 659 MakeArg(short value) { type = INT; int_value = value; } 660 MakeArg(unsigned short value) { type = UINT; uint_value = value; } 661 MakeArg(int value) { type = INT; int_value = value; } 662 MakeArg(unsigned value) { type = UINT; uint_value = value; } 663 MakeArg(long value) { 664 // To minimize the number of types we need to deal with, long is 665 // translated either to int or to long long depending on its size. 666 if (sizeof(long) == sizeof(int)) { 667 type = INT; 668 int_value = static_cast<int>(value); 669 } else { 670 type = LONG_LONG; 671 long_long_value = value; 672 } 673 } 674 MakeArg(unsigned long value) { 675 if (sizeof(unsigned long) == sizeof(unsigned)) { 676 type = UINT; 677 uint_value = static_cast<unsigned>(value); 678 } else { 679 type = ULONG_LONG; 680 ulong_long_value = value; 681 } 682 } 683 MakeArg(LongLong value) { type = LONG_LONG; long_long_value = value; } 684 MakeArg(ULongLong value) { type = ULONG_LONG; ulong_long_value = value; } 685 MakeArg(float value) { type = DOUBLE; double_value = value; } 686 MakeArg(double value) { type = DOUBLE; double_value = value; } 687 MakeArg(long double value) { type = LONG_DOUBLE; long_double_value = value; } 688 MakeArg(signed char value) { type = CHAR; int_value = value; } 689 MakeArg(unsigned char value) { type = CHAR; int_value = value; } 690 MakeArg(char value) { type = CHAR; int_value = value; } 691 MakeArg(wchar_t value) { 692 type = CHAR; 693 int_value = internal::CharTraits<Char>::convert(value); 694 } 695 696 MakeArg(char *value) { set_string(value); } 697 MakeArg(const char *value) { set_string(value); } 698 MakeArg(const std::string &value) { set_string(value); } 699 MakeArg(StringRef value) { set_string(value); } 700 701 MakeArg(wchar_t *value) { set_string(value); } 702 MakeArg(const wchar_t *value) { set_string(value); } 703 MakeArg(const std::wstring &value) { set_string(value); } 704 MakeArg(WStringRef value) { set_string(value); } 705 706 MakeArg(void *value) { type = POINTER; pointer_value = value; } 707 MakeArg(const void *value) { type = POINTER; pointer_value = value; } 708 709 #if 0 710 // WFG: Removed this because otherwise you can pass a CStr8 or an enum etc 711 // into fmt::sprintf, and it will be interpreted as a CUSTOM type and then 712 // will throw an exception at runtime, which is terrible behaviour. 713 template <typename T> 714 MakeArg(const T &value) { 715 type = CUSTOM; 716 custom.value = &value; 717 custom.format = &format_custom_arg<T>; 718 } 719 #endif 720 }; 721 722 #define FMT_DISPATCH(call) static_cast<Impl*>(this)->call 723 724 // An argument visitor. 725 // To use ArgVisitor define a subclass that implements some or all of the 726 // visit methods with the same signatures as the methods in ArgVisitor, 727 // for example, visit_int(int). 728 // Specify the subclass name as the Impl template parameter. Then calling 729 // ArgVisitor::visit for some argument will dispatch to a visit method 730 // specific to the argument type. For example, if the argument type is 731 // double then visit_double(double) method of a subclass will be called. 732 // If the subclass doesn't contain a method with this signature, then 733 // a corresponding method of ArgVisitor will be called. 734 // 735 // Example: 736 // class MyArgVisitor : public ArgVisitor<MyArgVisitor, void> { 737 // public: 738 // void visit_int(int value) { print("{}", value); } 739 // void visit_double(double value) { print("{}", value ); } 740 // }; 741 // 742 // ArgVisitor uses the curiously recurring template pattern: 743 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern 744 template <typename Impl, typename Result> 745 class ArgVisitor { 746 public: 747 Result visit_unhandled_arg() { return Result(); } 748 749 Result visit_int(int value) { 750 return FMT_DISPATCH(visit_any_int(value)); 751 } 752 Result visit_long_long(LongLong value) { 753 return FMT_DISPATCH(visit_any_int(value)); 754 } 755 Result visit_uint(unsigned value) { 756 return FMT_DISPATCH(visit_any_int(value)); 757 } 758 Result visit_ulong_long(ULongLong value) { 759 return FMT_DISPATCH(visit_any_int(value)); 760 } 761 Result visit_char(int value) { 762 return FMT_DISPATCH(visit_any_int(value)); 763 } 764 template <typename T> 765 Result visit_any_int(T) { 766 return FMT_DISPATCH(visit_unhandled_arg()); 767 } 768 769 Result visit_double(double value) { 770 return FMT_DISPATCH(visit_any_double(value)); 771 } 772 Result visit_long_double(long double value) { 773 return FMT_DISPATCH(visit_any_double(value)); 774 } 775 template <typename T> 776 Result visit_any_double(T) { 777 return FMT_DISPATCH(visit_unhandled_arg()); 778 } 779 780 Result visit_string(Arg::StringValue<char>) { 781 return FMT_DISPATCH(visit_unhandled_arg()); 782 } 783 Result visit_wstring(Arg::StringValue<wchar_t>) { 784 return FMT_DISPATCH(visit_unhandled_arg()); 785 } 786 Result visit_pointer(const void *) { 787 return FMT_DISPATCH(visit_unhandled_arg()); 788 } 789 Result visit_custom(Arg::CustomValue) { 790 return FMT_DISPATCH(visit_unhandled_arg()); 791 } 792 793 Result visit(const Arg &arg) { 794 switch (arg.type) { 795 default: 796 assert(false); 797 // Fall through. 798 case Arg::INT: 799 return FMT_DISPATCH(visit_int(arg.int_value)); 800 case Arg::UINT: 801 return FMT_DISPATCH(visit_uint(arg.uint_value)); 802 case Arg::LONG_LONG: 803 return FMT_DISPATCH(visit_long_long(arg.long_long_value)); 804 case Arg::ULONG_LONG: 805 return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value)); 806 case Arg::DOUBLE: 807 return FMT_DISPATCH(visit_double(arg.double_value)); 808 case Arg::LONG_DOUBLE: 809 return FMT_DISPATCH(visit_long_double(arg.long_double_value)); 810 case Arg::CHAR: 811 return FMT_DISPATCH(visit_char(arg.int_value)); 812 case Arg::STRING: 813 return FMT_DISPATCH(visit_string(arg.string)); 814 case Arg::WSTRING: 815 return FMT_DISPATCH(visit_wstring(arg.wstring)); 816 case Arg::POINTER: 817 return FMT_DISPATCH(visit_pointer(arg.pointer_value)); 818 case Arg::CUSTOM: 819 return FMT_DISPATCH(visit_custom(arg.custom)); 820 } 821 } 822 }; 823 824 class RuntimeError : public std::runtime_error { 825 protected: 826 RuntimeError() : std::runtime_error("") {} 827 }; 828 829 template <typename Char> 830 class ArgFormatter; 831 } // namespace internal 832 833 /** 834 An argument list. 835 */ 836 class ArgList { 837 private: 838 const internal::Arg *args_; 839 std::size_t size_; 840 841 public: 842 ArgList() : size_(0) {} 843 ArgList(const internal::Arg *args, std::size_t size) 844 : args_(args), size_(size) {} 845 846 /** 847 Returns the list size (the number of arguments). 848 */ 849 std::size_t size() const { return size_; } 850 851 /** 852 Returns the argument at specified index. 853 */ 854 const internal::Arg &operator[](std::size_t index) const { 855 return args_[index]; 856 } 857 }; 858 859 struct FormatSpec; 860 861 namespace internal { 862 863 class FormatterBase { 864 protected: 865 ArgList args_; 866 int next_arg_index_; 867 const char *error_; 868 869 FormatterBase() : error_(0) {} 870 871 const Arg &next_arg(); 872 873 const Arg &handle_arg_index(unsigned arg_index); 874 875 template <typename Char> 876 void write(BasicWriter<Char> &w, const Char *start, const Char *end) { 877 if (start != end) 878 w << BasicStringRef<Char>(start, end - start); 879 } 880 881 // TODO 882 }; 883 884 // A printf formatter. 885 template <typename Char> 886 class PrintfFormatter : private FormatterBase { 887 private: 888 void parse_flags(FormatSpec &spec, const Char *&s); 889 890 // Parses argument index, flags and width and returns the parsed 891 // argument index. 892 unsigned parse_header(const Char *&s, FormatSpec &spec); 893 894 public: 895 void format(BasicWriter<Char> &writer, 896 BasicStringRef<Char> format, const ArgList &args); 897 }; 898 } // namespace internal 899 900 // A formatter. 901 template <typename Char> 902 class BasicFormatter : private internal::FormatterBase { 903 private: 904 BasicWriter<Char> &writer_; 905 const Char *start_; 906 internal::FormatErrorReporter<Char> report_error_; 907 908 // Parses argument index and returns an argument with this index. 909 const internal::Arg &parse_arg_index(const Char *&s); 910 911 void check_sign(const Char *&s, const internal::Arg &arg); 912 913 public: 914 explicit BasicFormatter(BasicWriter<Char> &w) : writer_(w) {} 915 916 BasicWriter<Char> &writer() { return writer_; } 917 918 void format(BasicStringRef<Char> format_str, const ArgList &args); 919 920 const Char *format(const Char *format_str, const internal::Arg &arg); 921 }; 922 923 enum Alignment { 924 ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC 925 }; 926 927 // Flags. 928 enum { 929 SIGN_FLAG = 1, PLUS_FLAG = 2, MINUS_FLAG = 4, HASH_FLAG = 8, 930 CHAR_FLAG = 0x10 // Argument has char type - used in error reporting. 931 }; 932 933 // An empty format specifier. 934 struct EmptySpec {}; 935 936 // A type specifier. 937 template <char TYPE> 938 struct TypeSpec : EmptySpec { 939 Alignment align() const { return ALIGN_DEFAULT; } 940 unsigned width() const { return 0; } 941 int precision() const { return -1; } 942 bool flag(unsigned) const { return false; } 943 char type() const { return TYPE; } 944 char fill() const { return ' '; } 945 }; 946 947 // A width specifier. 948 struct WidthSpec { 949 unsigned width_; 950 // Fill is always wchar_t and cast to char if necessary to avoid having 951 // two specialization of WidthSpec and its subclasses. 952 wchar_t fill_; 953 954 WidthSpec(unsigned width, wchar_t fill) : width_(width), fill_(fill) {} 955 956 unsigned width() const { return width_; } 957 wchar_t fill() const { return fill_; } 958 }; 959 960 // An alignment specifier. 961 struct AlignSpec : WidthSpec { 962 Alignment align_; 963 964 AlignSpec(unsigned width, wchar_t fill, Alignment align = ALIGN_DEFAULT) 965 : WidthSpec(width, fill), align_(align) {} 966 967 Alignment align() const { return align_; } 968 969 int precision() const { return -1; } 970 }; 971 972 // An alignment and type specifier. 973 template <char TYPE> 974 struct AlignTypeSpec : AlignSpec { 975 AlignTypeSpec(unsigned width, wchar_t fill) : AlignSpec(width, fill) {} 976 977 bool flag(unsigned) const { return false; } 978 char type() const { return TYPE; } 979 }; 980 981 // A full format specifier. 982 struct FormatSpec : AlignSpec { 983 unsigned flags_; 984 int precision_; 985 char type_; 986 987 FormatSpec( 988 unsigned width = 0, char type = 0, wchar_t fill = ' ') 989 : AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {} 990 991 bool flag(unsigned f) const { return (flags_ & f) != 0; } 992 int precision() const { return precision_; } 993 char type() const { return type_; } 994 }; 995 996 // An integer format specifier. 997 template <typename T, typename SpecT = TypeSpec<0>, typename Char = char> 998 class IntFormatSpec : public SpecT { 999 private: 1000 T value_; 1001 1002 public: 1003 IntFormatSpec(T value, const SpecT &spec = SpecT()) 1004 : SpecT(spec), value_(value) {} 1005 1006 T value() const { return value_; } 1007 }; 1008 1009 // A string format specifier. 1010 template <typename T> 1011 class StrFormatSpec : public AlignSpec { 1012 private: 1013 const T *str_; 1014 1015 public: 1016 StrFormatSpec(const T *str, unsigned width, wchar_t fill) 1017 : AlignSpec(width, fill), str_(str) {} 1018 1019 const T *str() const { return str_; } 1020 }; 1021 1022 /** 1023 Returns an integer format specifier to format the value in base 2. 1024 */ 1025 IntFormatSpec<int, TypeSpec<'b'> > bin(int value); 1026 1027 /** 1028 Returns an integer format specifier to format the value in base 8. 1029 */ 1030 IntFormatSpec<int, TypeSpec<'o'> > oct(int value); 1031 1032 /** 1033 Returns an integer format specifier to format the value in base 16 using 1034 lower-case letters for the digits above 9. 1035 */ 1036 IntFormatSpec<int, TypeSpec<'x'> > hex(int value); 1037 1038 /** 1039 Returns an integer formatter format specifier to format in base 16 using 1040 upper-case letters for the digits above 9. 1041 */ 1042 IntFormatSpec<int, TypeSpec<'X'> > hexu(int value); 1043 1044 /** 1045 \rst 1046 Returns an integer format specifier to pad the formatted argument with the 1047 fill character to the specified width using the default (right) numeric 1048 alignment. 1049 1050 **Example**:: 1051 1052 Writer out; 1053 out << pad(hex(0xcafe), 8, '0'); 1054 // out.str() == "0000cafe" 1055 1056 \endrst 1057 */ 1058 template <char TYPE_CODE, typename Char> 1059 IntFormatSpec<int, AlignTypeSpec<TYPE_CODE>, Char> pad( 1060 int value, unsigned width, Char fill = ' '); 1061 1062 #define FMT_DEFINE_INT_FORMATTERS(TYPE) \ 1063 inline IntFormatSpec<TYPE, TypeSpec<'b'> > bin(TYPE value) { \ 1064 return IntFormatSpec<TYPE, TypeSpec<'b'> >(value, TypeSpec<'b'>()); \ 1065 } \ 1066 \ 1067 inline IntFormatSpec<TYPE, TypeSpec<'o'> > oct(TYPE value) { \ 1068 return IntFormatSpec<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \ 1069 } \ 1070 \ 1071 inline IntFormatSpec<TYPE, TypeSpec<'x'> > hex(TYPE value) { \ 1072 return IntFormatSpec<TYPE, TypeSpec<'x'> >(value, TypeSpec<'x'>()); \ 1073 } \ 1074 \ 1075 inline IntFormatSpec<TYPE, TypeSpec<'X'> > hexu(TYPE value) { \ 1076 return IntFormatSpec<TYPE, TypeSpec<'X'> >(value, TypeSpec<'X'>()); \ 1077 } \ 1078 \ 1079 template <char TYPE_CODE> \ 1080 inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> > pad( \ 1081 IntFormatSpec<TYPE, TypeSpec<TYPE_CODE> > f, unsigned width) { \ 1082 return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> >( \ 1083 f.value(), AlignTypeSpec<TYPE_CODE>(width, ' ')); \ 1084 } \ 1085 \ 1086 /* For compatibility with older compilers we provide two overloads for pad, */ \ 1087 /* one that takes a fill character and one that doesn't. In the future this */ \ 1088 /* can be replaced with one overload making the template argument Char */ \ 1089 /* default to char (C++11). */ \ 1090 template <char TYPE_CODE, typename Char> \ 1091 inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char> pad( \ 1092 IntFormatSpec<TYPE, TypeSpec<TYPE_CODE>, Char> f, \ 1093 unsigned width, Char fill) { \ 1094 return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char>( \ 1095 f.value(), AlignTypeSpec<TYPE_CODE>(width, fill)); \ 1096 } \ 1097 \ 1098 inline IntFormatSpec<TYPE, AlignTypeSpec<0> > pad( \ 1099 TYPE value, unsigned width) { \ 1100 return IntFormatSpec<TYPE, AlignTypeSpec<0> >( \ 1101 value, AlignTypeSpec<0>(width, ' ')); \ 1102 } \ 1103 \ 1104 template <typename Char> \ 1105 inline IntFormatSpec<TYPE, AlignTypeSpec<0>, Char> pad( \ 1106 TYPE value, unsigned width, Char fill) { \ 1107 return IntFormatSpec<TYPE, AlignTypeSpec<0>, Char>( \ 1108 value, AlignTypeSpec<0>(width, fill)); \ 1109 } 1110 1111 FMT_DEFINE_INT_FORMATTERS(int) 1112 FMT_DEFINE_INT_FORMATTERS(long) 1113 FMT_DEFINE_INT_FORMATTERS(unsigned) 1114 FMT_DEFINE_INT_FORMATTERS(unsigned long) 1115 FMT_DEFINE_INT_FORMATTERS(LongLong) 1116 FMT_DEFINE_INT_FORMATTERS(ULongLong) 1117 1118 /** 1119 \rst 1120 Returns a string formatter that pads the formatted argument with the fill 1121 character to the specified width using the default (left) string alignment. 1122 1123 **Example**:: 1124 1125 std::string s = str(Writer() << pad("abc", 8)); 1126 // s == "abc " 1127 1128 \endrst 1129 */ 1130 template <typename Char> 1131 inline StrFormatSpec<Char> pad( 1132 const Char *str, unsigned width, Char fill = ' ') { 1133 return StrFormatSpec<Char>(str, width, fill); 1134 } 1135 1136 inline StrFormatSpec<wchar_t> pad( 1137 const wchar_t *str, unsigned width, char fill = ' ') { 1138 return StrFormatSpec<wchar_t>(str, width, fill); 1139 } 1140 1141 // Generates a comma-separated list with results of applying f to numbers 0..n-1. 1142 # define FMT_GEN(n, f) FMT_GEN##n(f) 1143 # define FMT_GEN1(f) f(0) 1144 # define FMT_GEN2(f) FMT_GEN1(f), f(1) 1145 # define FMT_GEN3(f) FMT_GEN2(f), f(2) 1146 # define FMT_GEN4(f) FMT_GEN3(f), f(3) 1147 # define FMT_GEN5(f) FMT_GEN4(f), f(4) 1148 # define FMT_GEN6(f) FMT_GEN5(f), f(5) 1149 # define FMT_GEN7(f) FMT_GEN6(f), f(6) 1150 # define FMT_GEN8(f) FMT_GEN7(f), f(7) 1151 # define FMT_GEN9(f) FMT_GEN8(f), f(8) 1152 # define FMT_GEN10(f) FMT_GEN9(f), f(9) 1153 1154 # define FMT_MAKE_TEMPLATE_ARG(n) typename T##n 1155 # define FMT_MAKE_ARG(n) const T##n &v##n 1156 # define FMT_MAKE_REF_char(n) fmt::internal::MakeArg<char>(v##n) 1157 # define FMT_MAKE_REF_wchar_t(n) fmt::internal::MakeArg<wchar_t>(v##n) 1158 1159 #if FMT_USE_VARIADIC_TEMPLATES 1160 // Defines a variadic function returning void. 1161 # define FMT_VARIADIC_VOID(func, arg_type) \ 1162 template<typename... Args> \ 1163 void func(arg_type arg1, const Args & ... args) { \ 1164 using fmt::internal::Arg; \ 1165 const Arg arg_array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \ 1166 fmt::internal::MakeArg<Char>(args)... \ 1167 }; \ 1168 func(arg1, ArgList(arg_array, sizeof...(Args))); \ 1169 } 1170 1171 // Defines a variadic constructor. 1172 # define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \ 1173 template<typename... Args> \ 1174 ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \ 1175 using fmt::internal::Arg; \ 1176 const Arg arg_array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \ 1177 fmt::internal::MakeArg<Char>(args)... \ 1178 }; \ 1179 func(arg0, arg1, ArgList(arg_array, sizeof...(Args))); \ 1180 } 1181 1182 #else 1183 1184 # define FMT_MAKE_REF(n) fmt::internal::MakeArg<Char>(v##n) 1185 // Defines a wrapper for a function taking one argument of type arg_type 1186 // and n additional arguments of arbitrary types. 1187 # define FMT_WRAP1(func, arg_type, n) \ 1188 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \ 1189 inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \ 1190 const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \ 1191 func(arg1, fmt::ArgList(args, sizeof(args) / sizeof(*args))); \ 1192 } 1193 1194 // Emulates a variadic function returning void on a pre-C++11 compiler. 1195 # define FMT_VARIADIC_VOID(func, arg_type) \ 1196 FMT_WRAP1(func, arg_type, 1) FMT_WRAP1(func, arg_type, 2) \ 1197 FMT_WRAP1(func, arg_type, 3) FMT_WRAP1(func, arg_type, 4) \ 1198 FMT_WRAP1(func, arg_type, 5) FMT_WRAP1(func, arg_type, 6) \ 1199 FMT_WRAP1(func, arg_type, 7) FMT_WRAP1(func, arg_type, 8) \ 1200 FMT_WRAP1(func, arg_type, 9) FMT_WRAP1(func, arg_type, 10) 1201 1202 # define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \ 1203 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \ 1204 ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \ 1205 const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \ 1206 func(arg0, arg1, fmt::ArgList(args, sizeof(args) / sizeof(*args))); \ 1207 } 1208 1209 // Emulates a variadic constructor on a pre-C++11 compiler. 1210 # define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \ 1211 FMT_CTOR(ctor, func, arg0_type, arg1_type, 1) \ 1212 FMT_CTOR(ctor, func, arg0_type, arg1_type, 2) \ 1213 FMT_CTOR(ctor, func, arg0_type, arg1_type, 3) \ 1214 FMT_CTOR(ctor, func, arg0_type, arg1_type, 4) \ 1215 FMT_CTOR(ctor, func, arg0_type, arg1_type, 5) \ 1216 FMT_CTOR(ctor, func, arg0_type, arg1_type, 6) \ 1217 FMT_CTOR(ctor, func, arg0_type, arg1_type, 7) \ 1218 FMT_CTOR(ctor, func, arg0_type, arg1_type, 8) \ 1219 FMT_CTOR(ctor, func, arg0_type, arg1_type, 9) \ 1220 FMT_CTOR(ctor, func, arg0_type, arg1_type, 10) 1221 #endif 1222 1223 // Generates a comma-separated list with results of applying f to pairs 1224 // (argument, index). 1225 #define FMT_FOR_EACH1(f, x0) f(x0, 0) 1226 #define FMT_FOR_EACH2(f, x0, x1) \ 1227 FMT_FOR_EACH1(f, x0), f(x1, 1) 1228 #define FMT_FOR_EACH3(f, x0, x1, x2) \ 1229 FMT_FOR_EACH2(f, x0 ,x1), f(x2, 2) 1230 #define FMT_FOR_EACH4(f, x0, x1, x2, x3) \ 1231 FMT_FOR_EACH3(f, x0, x1, x2), f(x3, 3) 1232 #define FMT_FOR_EACH5(f, x0, x1, x2, x3, x4) \ 1233 FMT_FOR_EACH4(f, x0, x1, x2, x3), f(x4, 4) 1234 #define FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5) \ 1235 FMT_FOR_EACH5(f, x0, x1, x2, x3, x4), f(x5, 5) 1236 #define FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6) \ 1237 FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5), f(x6, 6) 1238 #define FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7) \ 1239 FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6), f(x7, 7) 1240 #define FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8) \ 1241 FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7), f(x8, 8) 1242 #define FMT_FOR_EACH10(f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) \ 1243 FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9) 1244 1245 /** 1246 An error returned by an operating system or a language runtime, 1247 for example a file opening error. 1248 */ 1249 class SystemError : public internal::RuntimeError { 1250 private: 1251 void init(int error_code, StringRef format_str, const ArgList &args); 1252 1253 protected: 1254 int error_code_; 1255 1256 typedef char Char; // For FMT_VARIADIC_CTOR. 1257 1258 SystemError() {} 1259 1260 public: 1261 /** 1262 \rst 1263 Constructs a :cpp:class:`fmt::SystemError` object with the description 1264 of the form "*<message>*: *<system-message>*", where *<message>* is the 1265 formatted message and *<system-message>* is the system message corresponding 1266 to the error code. 1267 *error_code* is a system error code as given by ``errno``. 1268 \endrst 1269 */ 1270 SystemError(int error_code, StringRef message) { 1271 init(error_code, message, ArgList()); 1272 } 1273 FMT_VARIADIC_CTOR(SystemError, init, int, StringRef) 1274 1275 int error_code() const { return error_code_; } 1276 }; 1277 1278 /** 1279 \rst 1280 This template provides operations for formatting and writing data into 1281 a character stream. The output is stored in a memory buffer that grows 1282 dynamically. 1283 1284 You can use one of the following typedefs for common character types: 1285 1286 +---------+----------------------+ 1287 | Type | Definition | 1288 +=========+======================+ 1289 | Writer | BasicWriter<char> | 1290 +---------+----------------------+ 1291 | WWriter | BasicWriter<wchar_t> | 1292 +---------+----------------------+ 1293 1294 **Example**:: 1295 1296 Writer out; 1297 out << "The answer is " << 42 << "\n"; 1298 out.write("({:+f}, {:+f})", -3.14, 3.14); 1299 1300 This will write the following output to the ``out`` object: 1301 1302 .. code-block:: none 1303 1304 The answer is 42 1305 (-3.140000, +3.140000) 1306 1307 The output can be converted to an ``std::string`` with ``out.str()`` or 1308 accessed as a C string with ``out.c_str()``. 1309 \endrst 1310 */ 1311 template <typename Char> 1312 class BasicWriter { 1313 private: 1314 // Output buffer. 1315 mutable internal::Array<Char, internal::INLINE_BUFFER_SIZE> buffer_; 1316 1317 typedef typename internal::CharTraits<Char>::CharPtr CharPtr; 1318 1319 #if defined(_SECURE_SCL) && _SECURE_SCL 1320 // Returns pointer value. 1321 static Char *get(CharPtr p) { return p.base(); } 1322 #else 1323 static Char *get(Char *p) { return p; } 1324 #endif 1325 1326 static CharPtr fill_padding(CharPtr buffer, 1327 unsigned total_size, std::size_t content_size, wchar_t fill); 1328 1329 // Grows the buffer by n characters and returns a pointer to the newly 1330 // allocated area. 1331 CharPtr grow_buffer(std::size_t n) { 1332 std::size_t size = buffer_.size(); 1333 buffer_.resize(size + n); 1334 return internal::make_ptr(&buffer_[size], n); 1335 } 1336 1337 // Prepare a buffer for integer formatting. 1338 CharPtr prepare_int_buffer(unsigned num_digits, 1339 const EmptySpec &, const char *prefix, unsigned prefix_size) { 1340 unsigned size = prefix_size + num_digits; 1341 CharPtr p = grow_buffer(size); 1342 std::copy(prefix, prefix + prefix_size, p); 1343 return p + size - 1; 1344 } 1345 1346 template <typename Spec> 1347 CharPtr prepare_int_buffer(unsigned num_digits, 1348 const Spec &spec, const char *prefix, unsigned prefix_size); 1349 1350 // Formats an integer. 1351 template <typename T, typename Spec> 1352 void write_int(T value, const Spec &spec); 1353 1354 // Formats a floating-point number (double or long double). 1355 template <typename T> 1356 void write_double(T value, const FormatSpec &spec); 1357 1358 // Writes a formatted string. 1359 template <typename StrChar> 1360 CharPtr write_str( 1361 const StrChar *s, std::size_t size, const AlignSpec &spec); 1362 1363 template <typename StrChar> 1364 void write_str( 1365 const internal::Arg::StringValue<StrChar> &str, const FormatSpec &spec); 1366 1367 // This method is private to disallow writing a wide string to a 1368 // char stream and vice versa. If you want to print a wide string 1369 // as a pointer as std::ostream does, cast it to const void*. 1370 // Do not implement! 1371 void operator<<(typename internal::CharTraits<Char>::UnsupportedStrType); 1372 1373 friend class internal::ArgFormatter<Char>; 1374 friend class internal::PrintfFormatter<Char>; 1375 1376 public: 1377 /** 1378 Constructs a ``BasicWriter`` object. 1379 */ 1380 BasicWriter() {} 1381 1382 #if FMT_USE_RVALUE_REFERENCES 1383 /** 1384 Constructs a ``BasicWriter`` object moving the content of the other 1385 object to it. 1386 */ 1387 BasicWriter(BasicWriter &&other) : buffer_(std::move(other.buffer_)) {} 1388 1389 /** 1390 Moves the content of the other ``BasicWriter`` object to this one. 1391 */ 1392 BasicWriter& operator=(BasicWriter &&other) { 1393 assert(this != &other); 1394 buffer_ = std::move(other.buffer_); 1395 return *this; 1396 } 1397 #endif 1398 1399 /** 1400 Returns the total number of characters written. 1401 */ 1402 std::size_t size() const { return buffer_.size(); } 1403 1404 /** 1405 Returns a pointer to the output buffer content. No terminating null 1406 character is appended. 1407 */ 1408 const Char *data() const { return &buffer_[0]; } 1409 1410 /** 1411 Returns a pointer to the output buffer content with terminating null 1412 character appended. 1413 */ 1414 const Char *c_str() const { 1415 std::size_t size = buffer_.size(); 1416 buffer_.reserve(size + 1); 1417 buffer_[size] = '\0'; 1418 return &buffer_[0]; 1419 } 1420 1421 /** 1422 Returns the content of the output buffer as an `std::string`. 1423 */ 1424 std::basic_string<Char> str() const { 1425 return std::basic_string<Char>(&buffer_[0], buffer_.size()); 1426 } 1427 1428 /** 1429 \rst 1430 Writes formatted data. 1431 1432 *args* is an argument list representing arbitrary arguments. 1433 1434 **Example**:: 1435 1436 Writer out; 1437 out.write("Current point:\n"); 1438 out.write("({:+f}, {:+f})", -3.14, 3.14); 1439 1440 This will write the following output to the ``out`` object: 1441 1442 .. code-block:: none 1443 1444 Current point: 1445 (-3.140000, +3.140000) 1446 1447 The output can be accessed using :meth:`data`, :meth:`c_str` or :meth:`str` 1448 methods. 1449 1450 See also `Format String Syntax`_. 1451 \endrst 1452 */ 1453 void write(BasicStringRef<Char> format, const ArgList &args) { 1454 BasicFormatter<Char>(*this).format(format, args); 1455 } 1456 FMT_VARIADIC_VOID(write, fmt::BasicStringRef<Char>) 1457 1458 BasicWriter &operator<<(int value) { 1459 return *this << IntFormatSpec<int>(value); 1460 } 1461 BasicWriter &operator<<(unsigned value) { 1462 return *this << IntFormatSpec<unsigned>(value); 1463 } 1464 BasicWriter &operator<<(long value) { 1465 return *this << IntFormatSpec<long>(value); 1466 } 1467 BasicWriter &operator<<(unsigned long value) { 1468 return *this << IntFormatSpec<unsigned long>(value); 1469 } 1470 BasicWriter &operator<<(LongLong value) { 1471 return *this << IntFormatSpec<LongLong>(value); 1472 } 1473 1474 /** 1475 Formats *value* and writes it to the stream. 1476 */ 1477 BasicWriter &operator<<(ULongLong value) { 1478 return *this << IntFormatSpec<ULongLong>(value); 1479 } 1480 1481 BasicWriter &operator<<(double value) { 1482 write_double(value, FormatSpec()); 1483 return *this; 1484 } 1485 1486 /** 1487 Formats *value* using the general format for floating-point numbers 1488 (``'g'``) and writes it to the stream. 1489 */ 1490 BasicWriter &operator<<(long double value) { 1491 write_double(value, FormatSpec()); 1492 return *this; 1493 } 1494 1495 /** 1496 Writes a character to the stream. 1497 */ 1498 BasicWriter &operator<<(char value) { 1499 buffer_.push_back(value); 1500 return *this; 1501 } 1502 1503 BasicWriter &operator<<(wchar_t value) { 1504 buffer_.push_back(internal::CharTraits<Char>::convert(value)); 1505 return *this; 1506 } 1507 1508 /** 1509 Writes *value* to the stream. 1510 */ 1511 BasicWriter &operator<<(fmt::BasicStringRef<Char> value) { 1512 const Char *str = value.c_str(); 1513 buffer_.append(str, str + value.size()); 1514 return *this; 1515 } 1516 1517 template <typename T, typename Spec, typename FillChar> 1518 BasicWriter &operator<<(const IntFormatSpec<T, Spec, FillChar> &spec) { 1519 internal::CharTraits<Char>::convert(FillChar()); 1520 write_int(spec.value(), spec); 1521 return *this; 1522 } 1523 1524 template <typename StrChar> 1525 BasicWriter &operator<<(const StrFormatSpec<StrChar> &spec) { 1526 const StrChar *s = spec.str(); 1527 // TODO: error if fill is not convertible to Char 1528 write_str(s, std::char_traits<Char>::length(s), spec); 1529 return *this; 1530 } 1531 1532 void clear() { buffer_.clear(); } 1533 }; 1534 1535 template <typename Char> 1536 template <typename StrChar> 1537 typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str( 1538 const StrChar *s, std::size_t size, const AlignSpec &spec) { 1539 CharPtr out = CharPtr(); 1540 if (spec.width() > size) { 1541 out = grow_buffer(spec.width()); 1542 Char fill = static_cast<Char>(spec.fill()); 1543 if (spec.align() == ALIGN_RIGHT) { 1544 std::fill_n(out, spec.width() - size, fill); 1545 out += spec.width() - size; 1546 } else if (spec.align() == ALIGN_CENTER) { 1547 out = fill_padding(out, spec.width(), size, fill); 1548 } else { 1549 std::fill_n(out + size, spec.width() - size, fill); 1550 } 1551 } else { 1552 out = grow_buffer(size); 1553 } 1554 std::copy(s, s + size, out); 1555 return out; 1556 } 1557 1558 template <typename Char> 1559 template <typename Spec> 1560 typename fmt::BasicWriter<Char>::CharPtr 1561 fmt::BasicWriter<Char>::prepare_int_buffer( 1562 unsigned num_digits, const Spec &spec, 1563 const char *prefix, unsigned prefix_size) { 1564 unsigned width = spec.width(); 1565 Alignment align = spec.align(); 1566 Char fill = static_cast<Char>(spec.fill()); 1567 if (spec.precision() > static_cast<int>(num_digits)) { 1568 // Octal prefix '0' is counted as a digit, so ignore it if precision 1569 // is specified. 1570 if (prefix_size > 0 && prefix[prefix_size - 1] == '0') 1571 --prefix_size; 1572 unsigned number_size = prefix_size + spec.precision(); 1573 AlignSpec subspec(number_size, '0', ALIGN_NUMERIC); 1574 if (number_size >= width) 1575 return prepare_int_buffer(num_digits, subspec, prefix, prefix_size); 1576 buffer_.reserve(width); 1577 unsigned fill_size = width - number_size; 1578 if (align != ALIGN_LEFT) { 1579 CharPtr p = grow_buffer(fill_size); 1580 std::fill(p, p + fill_size, fill); 1581 } 1582 CharPtr result = prepare_int_buffer( 1583 num_digits, subspec, prefix, prefix_size); 1584 if (align == ALIGN_LEFT) { 1585 CharPtr p = grow_buffer(fill_size); 1586 std::fill(p, p + fill_size, fill); 1587 } 1588 return result; 1589 } 1590 unsigned size = prefix_size + num_digits; 1591 if (width <= size) { 1592 CharPtr p = grow_buffer(size); 1593 std::copy(prefix, prefix + prefix_size, p); 1594 return p + size - 1; 1595 } 1596 CharPtr p = grow_buffer(width); 1597 CharPtr end = p + width; 1598 if (align == ALIGN_LEFT) { 1599 std::copy(prefix, prefix + prefix_size, p); 1600 p += size; 1601 std::fill(p, end, fill); 1602 } else if (align == ALIGN_CENTER) { 1603 p = fill_padding(p, width, size, fill); 1604 std::copy(prefix, prefix + prefix_size, p); 1605 p += size; 1606 } else { 1607 if (align == ALIGN_NUMERIC) { 1608 if (prefix_size != 0) { 1609 p = std::copy(prefix, prefix + prefix_size, p); 1610 size -= prefix_size; 1611 } 1612 } else { 1613 std::copy(prefix, prefix + prefix_size, end - size); 1614 } 1615 std::fill(p, end - size, fill); 1616 p = end; 1617 } 1618 return p - 1; 1619 } 1620 1621 template <typename Char> 1622 template <typename T, typename Spec> 1623 void BasicWriter<Char>::write_int(T value, const Spec &spec) { 1624 unsigned prefix_size = 0; 1625 typedef typename internal::IntTraits<T>::MainType UnsignedType; 1626 UnsignedType abs_value = value; 1627 char prefix[4] = ""; 1628 if (internal::is_negative(value)) { 1629 prefix[0] = '-'; 1630 ++prefix_size; 1631 abs_value = 0 - abs_value; 1632 } else if (spec.flag(SIGN_FLAG)) { 1633 prefix[0] = spec.flag(PLUS_FLAG) ? '+' : ' '; 1634 ++prefix_size; 1635 } 1636 switch (spec.type()) { 1637 case 0: case 'd': { 1638 unsigned num_digits = internal::count_digits(abs_value); 1639 CharPtr p = prepare_int_buffer( 1640 num_digits, spec, prefix, prefix_size) + 1 - num_digits; 1641 internal::format_decimal(get(p), abs_value, num_digits); 1642 break; 1643 } 1644 case 'x': case 'X': { 1645 UnsignedType n = abs_value; 1646 if (spec.flag(HASH_FLAG)) { 1647 prefix[prefix_size++] = '0'; 1648 prefix[prefix_size++] = spec.type(); 1649 } 1650 unsigned num_digits = 0; 1651 do { 1652 ++num_digits; 1653 } while ((n >>= 4) != 0); 1654 Char *p = get(prepare_int_buffer( 1655 num_digits, spec, prefix, prefix_size)); 1656 n = abs_value; 1657 const char *digits = spec.type() == 'x' ? 1658 "0123456789abcdef" : "0123456789ABCDEF"; 1659 do { 1660 *p-- = digits[n & 0xf]; 1661 } while ((n >>= 4) != 0); 1662 break; 1663 } 1664 case 'b': case 'B': { 1665 UnsignedType n = abs_value; 1666 if (spec.flag(HASH_FLAG)) { 1667 prefix[prefix_size++] = '0'; 1668 prefix[prefix_size++] = spec.type(); 1669 } 1670 unsigned num_digits = 0; 1671 do { 1672 ++num_digits; 1673 } while ((n >>= 1) != 0); 1674 Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size)); 1675 n = abs_value; 1676 do { 1677 *p-- = '0' + (n & 1); 1678 } while ((n >>= 1) != 0); 1679 break; 1680 } 1681 case 'o': { 1682 UnsignedType n = abs_value; 1683 if (spec.flag(HASH_FLAG)) 1684 prefix[prefix_size++] = '0'; 1685 unsigned num_digits = 0; 1686 do { 1687 ++num_digits; 1688 } while ((n >>= 3) != 0); 1689 Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size)); 1690 n = abs_value; 1691 do { 1692 *p-- = '0' + (n & 7); 1693 } while ((n >>= 3) != 0); 1694 break; 1695 } 1696 default: 1697 internal::report_unknown_type( 1698 spec.type(), spec.flag(CHAR_FLAG) ? "char" : "integer"); 1699 break; 1700 } 1701 } 1702 1703 // Formats a value. 1704 template <typename Char, typename T> 1705 void format(BasicFormatter<Char> &f, const Char *format_str, const T &value) { 1706 std::basic_ostringstream<Char> os; 1707 os << value; 1708 f.format(format_str, internal::MakeArg<Char>(os.str())); 1709 } 1710 1711 // Reports a system error without throwing an exception. 1712 // Can be used to report errors from destructors. 1713 void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT(true); 1714 1715 #ifdef _WIN32 1716 1717 /** 1718 A Windows error. 1719 */ 1720 class WindowsError : public SystemError { 1721 private: 1722 void init(int error_code, StringRef format_str, const ArgList &args); 1723 1724 public: 1725 /** 1726 \rst 1727 Constructs a :cpp:class:`fmt::WindowsError` object with the description 1728 of the form "*<message>*: *<system-message>*", where *<message>* is the 1729 formatted message and *<system-message>* is the system message corresponding 1730 to the error code. 1731 *error_code* is a Windows error code as given by ``GetLastError``. 1732 \endrst 1733 */ 1734 WindowsError(int error_code, StringRef message) { 1735 init(error_code, message, ArgList()); 1736 } 1737 FMT_VARIADIC_CTOR(WindowsError, init, int, StringRef) 1738 }; 1739 1740 // Reports a Windows error without throwing an exception. 1741 // Can be used to report errors from destructors. 1742 void report_windows_error(int error_code, StringRef message) FMT_NOEXCEPT(true); 1743 1744 #endif 1745 1746 enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE }; 1747 1748 /** 1749 Formats a string and prints it to stdout using ANSI escape sequences 1750 to specify color (experimental). 1751 Example: 1752 PrintColored(fmt::RED, "Elapsed time: {0:.2f} seconds") << 1.23; 1753 */ 1754 void print_colored(Color c, StringRef format, const ArgList &args); 1755 1756 /** 1757 \rst 1758 Formats arguments and returns the result as a string. 1759 1760 **Example**:: 1761 1762 std::string message = format("The answer is {}", 42); 1763 \endrst 1764 */ 1765 inline std::string format(StringRef format_str, const ArgList &args) { 1766 Writer w; 1767 w.write(format_str, args); 1768 return w.str(); 1769 } 1770 1771 inline std::wstring format(WStringRef format_str, const ArgList &args) { 1772 WWriter w; 1773 w.write(format_str, args); 1774 return w.str(); 1775 } 1776 1777 /** 1778 \rst 1779 Prints formatted data to the file *f*. 1780 1781 **Example**:: 1782 1783 print(stderr, "Don't {}!", "panic"); 1784 \endrst 1785 */ 1786 void print(std::FILE *f, StringRef format_str, const ArgList &args); 1787 1788 /** 1789 \rst 1790 Prints formatted data to ``stdout``. 1791 1792 **Example**:: 1793 1794 print("Elapsed time: {0:.2f} seconds", 1.23); 1795 \endrst 1796 */ 1797 inline void print(StringRef format_str, const ArgList &args) { 1798 print(stdout, format_str, args); 1799 } 1800 1801 /** 1802 \rst 1803 Prints formatted data to the stream *os*. 1804 1805 **Example**:: 1806 1807 print(cerr, "Don't {}!", "panic"); 1808 \endrst 1809 */ 1810 void print(std::ostream &os, StringRef format_str, const ArgList &args); 1811 1812 template <typename Char> 1813 void printf(BasicWriter<Char> &w, 1814 BasicStringRef<Char> format, const ArgList &args) { 1815 internal::PrintfFormatter<Char>().format(w, format, args); 1816 } 1817 1818 /** 1819 \rst 1820 Formats arguments and returns the result as a string. 1821 1822 **Example**:: 1823 1824 std::string message = fmt::sprintf("The answer is %d", 42); 1825 \endrst 1826 */ 1827 inline std::string sprintf(StringRef format, const ArgList &args) { 1828 Writer w; 1829 printf(w, format, args); 1830 return w.str(); 1831 } 1832 1833 /** 1834 \rst 1835 Prints formatted data to the file *f*. 1836 1837 **Example**:: 1838 1839 fmt::fprintf(stderr, "Don't %s!", "panic"); 1840 \endrst 1841 */ 1842 int fprintf(std::FILE *f, StringRef format, const ArgList &args); 1843 1844 /** 1845 \rst 1846 Prints formatted data to ``stdout``. 1847 1848 **Example**:: 1849 1850 fmt::printf("Elapsed time: %.2f seconds", 1.23); 1851 \endrst 1852 */ 1853 inline int printf(StringRef format, const ArgList &args) { 1854 return fprintf(stdout, format, args); 1855 } 1856 1857 /** 1858 Fast integer formatter. 1859 */ 1860 class FormatInt { 1861 private: 1862 // Buffer should be large enough to hold all digits (digits10 + 1), 1863 // a sign and a null character. 1864 enum {BUFFER_SIZE = std::numeric_limits<ULongLong>::digits10 + 3}; 1865 mutable char buffer_[BUFFER_SIZE]; 1866 char *str_; 1867 1868 // Formats value in reverse and returns the number of digits. 1869 char *format_decimal(ULongLong value) { 1870 char *buffer_end = buffer_ + BUFFER_SIZE - 1; 1871 while (value >= 100) { 1872 // Integer division is slow so do it for a group of two digits instead 1873 // of for every digit. The idea comes from the talk by Alexandrescu 1874 // "Three Optimization Tips for C++". See speed-test for a comparison. 1875 unsigned index = (value % 100) * 2; 1876 value /= 100; 1877 *--buffer_end = internal::DIGITS[index + 1]; 1878 *--buffer_end = internal::DIGITS[index]; 1879 } 1880 if (value < 10) { 1881 *--buffer_end = static_cast<char>('0' + value); 1882 return buffer_end; 1883 } 1884 unsigned index = static_cast<unsigned>(value * 2); 1885 *--buffer_end = internal::DIGITS[index + 1]; 1886 *--buffer_end = internal::DIGITS[index]; 1887 return buffer_end; 1888 } 1889 1890 void FormatSigned(LongLong value) { 1891 ULongLong abs_value = static_cast<ULongLong>(value); 1892 bool negative = value < 0; 1893 if (negative) 1894 abs_value = 0 - abs_value; 1895 str_ = format_decimal(abs_value); 1896 if (negative) 1897 *--str_ = '-'; 1898 } 1899 1900 public: 1901 explicit FormatInt(int value) { FormatSigned(value); } 1902 explicit FormatInt(long value) { FormatSigned(value); } 1903 explicit FormatInt(LongLong value) { FormatSigned(value); } 1904 explicit FormatInt(unsigned value) : str_(format_decimal(value)) {} 1905 explicit FormatInt(unsigned long value) : str_(format_decimal(value)) {} 1906 explicit FormatInt(ULongLong value) : str_(format_decimal(value)) {} 1907 1908 /** 1909 Returns the number of characters written to the output buffer. 1910 */ 1911 std::size_t size() const { return buffer_ - str_ + BUFFER_SIZE - 1; } 1912 1913 /** 1914 Returns a pointer to the output buffer content. No terminating null 1915 character is appended. 1916 */ 1917 const char *data() const { return str_; } 1918 1919 /** 1920 Returns a pointer to the output buffer content with terminating null 1921 character appended. 1922 */ 1923 const char *c_str() const { 1924 buffer_[BUFFER_SIZE - 1] = '\0'; 1925 return str_; 1926 } 1927 1928 /** 1929 Returns the content of the output buffer as an `std::string`. 1930 */ 1931 std::string str() const { return std::string(str_, size()); } 1932 }; 1933 1934 // Formats a decimal integer value writing into buffer and returns 1935 // a pointer to the end of the formatted string. This function doesn't 1936 // write a terminating null character. 1937 template <typename T> 1938 inline void format_decimal(char *&buffer, T value) { 1939 typename internal::IntTraits<T>::MainType abs_value = value; 1940 if (internal::is_negative(value)) { 1941 *buffer++ = '-'; 1942 abs_value = 0 - abs_value; 1943 } 1944 if (abs_value < 100) { 1945 if (abs_value < 10) { 1946 *buffer++ = static_cast<char>('0' + abs_value); 1947 return; 1948 } 1949 unsigned index = static_cast<unsigned>(abs_value * 2); 1950 *buffer++ = internal::DIGITS[index]; 1951 *buffer++ = internal::DIGITS[index + 1]; 1952 return; 1953 } 1954 unsigned num_digits = internal::count_digits(abs_value); 1955 internal::format_decimal(buffer, abs_value, num_digits); 1956 buffer += num_digits; 1957 } 1958 } 1959 1960 #if FMT_GCC_VERSION 1961 // Use the system_header pragma to suppress warnings about variadic macros 1962 // because suppressing -Wvariadic-macros with the diagnostic pragma doesn't 1963 // work. It is used at the end because we want to suppress as little warnings 1964 // as possible. 1965 # pragma GCC system_header 1966 #endif 1967 1968 // This is used to work around VC++ bugs in handling variadic macros. 1969 #define FMT_EXPAND(args) args 1970 1971 // Returns the number of arguments. 1972 // Based on https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s. 1973 #define FMT_NARG(...) FMT_NARG_(__VA_ARGS__, FMT_RSEQ_N()) 1974 #define FMT_NARG_(...) FMT_EXPAND(FMT_ARG_N(__VA_ARGS__)) 1975 #define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N 1976 #define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 1977 1978 #define FMT_CONCAT(a, b) a##b 1979 #define FMT_FOR_EACH_(N, f, ...) \ 1980 FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__)) 1981 #define FMT_FOR_EACH(f, ...) \ 1982 FMT_EXPAND(FMT_FOR_EACH_(FMT_NARG(__VA_ARGS__), f, __VA_ARGS__)) 1983 1984 #define FMT_ADD_ARG_NAME(type, index) type arg##index 1985 #define FMT_GET_ARG_NAME(type, index) arg##index 1986 1987 #if FMT_USE_VARIADIC_TEMPLATES 1988 # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \ 1989 template<typename... Args> \ 1990 ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ 1991 const Args & ... args) { \ 1992 using fmt::internal::Arg; \ 1993 const Arg array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \ 1994 fmt::internal::MakeArg<Char>(args)... \ 1995 }; \ 1996 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \ 1997 fmt::ArgList(array, sizeof...(Args))); \ 1998 } 1999 #else 2000 // Defines a wrapper for a function taking __VA_ARGS__ arguments 2001 // and n additional arguments of arbitrary types. 2002 # define FMT_WRAP(Char, ReturnType, func, call, n, ...) \ 2003 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \ 2004 inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ 2005 FMT_GEN(n, FMT_MAKE_ARG)) { \ 2006 const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF_##Char)}; \ 2007 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \ 2008 fmt::ArgList(args, sizeof(args) / sizeof(*args))); \ 2009 } 2010 2011 # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \ 2012 inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) { \ 2013 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList()); \ 2014 } \ 2015 FMT_WRAP(Char, ReturnType, func, call, 1, __VA_ARGS__) \ 2016 FMT_WRAP(Char, ReturnType, func, call, 2, __VA_ARGS__) \ 2017 FMT_WRAP(Char, ReturnType, func, call, 3, __VA_ARGS__) \ 2018 FMT_WRAP(Char, ReturnType, func, call, 4, __VA_ARGS__) \ 2019 FMT_WRAP(Char, ReturnType, func, call, 5, __VA_ARGS__) \ 2020 FMT_WRAP(Char, ReturnType, func, call, 6, __VA_ARGS__) \ 2021 FMT_WRAP(Char, ReturnType, func, call, 7, __VA_ARGS__) \ 2022 FMT_WRAP(Char, ReturnType, func, call, 8, __VA_ARGS__) \ 2023 FMT_WRAP(Char, ReturnType, func, call, 9, __VA_ARGS__) \ 2024 FMT_WRAP(Char, ReturnType, func, call, 10, __VA_ARGS__) 2025 #endif // FMT_USE_VARIADIC_TEMPLATES 2026 2027 /** 2028 \rst 2029 Defines a variadic function with the specified return type, function name 2030 and argument types passed as variable arguments to this macro. 2031 2032 **Example**:: 2033 2034 void print_error(const char *file, int line, const char *format, 2035 const fmt::ArgList &args) { 2036 fmt::print("{}: {}: ", file, line); 2037 fmt::print(format, args); 2038 } 2039 FMT_VARIADIC(void, print_error, const char *, int, const char *) 2040 2041 ``FMT_VARIADIC`` is used for compatibility with legacy C++ compilers that 2042 don't implement variadic templates. You don't have to use this macro if 2043 you don't need legacy compiler support and can use variadic templates 2044 directly:: 2045 2046 template<typename... Args> 2047 void print_error(const char *file, int line, const char *format, 2048 const Args & ... args) { 2049 fmt::print("{}: {}: ", file, line); 2050 fmt::print(format, args...); 2051 } 2052 \endrst 2053 */ 2054 #define FMT_VARIADIC(ReturnType, func, ...) \ 2055 FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__) 2056 2057 #define FMT_VARIADIC_W(ReturnType, func, ...) \ 2058 FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__) 2059 2060 namespace fmt { 2061 FMT_VARIADIC(std::string, format, StringRef) 2062 FMT_VARIADIC_W(std::wstring, format, WStringRef) 2063 FMT_VARIADIC(void, print, StringRef) 2064 FMT_VARIADIC(void, print, std::FILE *, StringRef) 2065 FMT_VARIADIC(void, print, std::ostream &, StringRef) 2066 FMT_VARIADIC(void, print_colored, Color, StringRef) 2067 FMT_VARIADIC(std::string, sprintf, StringRef) 2068 FMT_VARIADIC(int, printf, StringRef) 2069 FMT_VARIADIC(int, fprintf, std::FILE *, StringRef) 2070 } 2071 2072 // Restore warnings. 2073 #if FMT_GCC_VERSION >= 406 2074 # pragma GCC diagnostic pop 2075 #endif 2076 2077 #endif // FMT_FORMAT_H_ -
source/tools/atlas/GameInterface/GameLoop.cpp
diff --git a/source/tools/atlas/GameInterface/GameLoop.cpp b/source/tools/atlas/GameInterface/GameLoop.cpp index cc2fa20..342f983 100644
a b static void* RunEngine(void* data) 178 178 debug_warn(L"Unrecognised message"); 179 179 // CLogger might not be initialised, but this error will be sent 180 180 // to the debug output window anyway so people can still see it 181 LOGERROR( L"Unrecognised message (%hs)", name.c_str());181 LOGERROR("Unrecognised message (%s)", name.c_str()); 182 182 } 183 183 184 184 if (msg->GetType() == IMessage::Query) -
source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp
diff --git a/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp index 38060ee..9a7c2e7 100644
a b MESSAGEHANDLER(ImportHeightmap) 176 176 File file; 177 177 if (file.Open(src, O_RDONLY) < 0) 178 178 { 179 LOGERROR( L"Failed to load heightmap.");179 LOGERROR("Failed to load heightmap."); 180 180 return; 181 181 } 182 182 … … MESSAGEHANDLER(ImportHeightmap) 187 187 188 188 if (read(file.Descriptor(), fileData.get(), fileSize) < 0) 189 189 { 190 LOGERROR( L"Failed to read heightmap image.");190 LOGERROR("Failed to read heightmap image."); 191 191 file.Close(); 192 192 return; 193 193 } … … MESSAGEHANDLER(ImportHeightmap) 198 198 Tex tex; 199 199 if (tex.decode(fileData, fileSize) < 0) 200 200 { 201 LOGERROR( L"Failed to decode heightmap.");201 LOGERROR("Failed to decode heightmap."); 202 202 return; 203 203 } 204 204 205 205 // Convert to uncompressed BGRA with no mipmaps 206 206 if (tex.transform_to((tex.m_Flags | TEX_BGR | TEX_ALPHA) & ~(TEX_DXT | TEX_MIPMAPS)) < 0) 207 207 { 208 LOGERROR( L"Failed to transform heightmap.");208 LOGERROR("Failed to transform heightmap."); 209 209 return; 210 210 } 211 211 -
source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp
diff --git a/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp index a366503..368befd 100644
a b BEGIN_COMMAND(DeleteObjects) 930 930 entity_id_t ent = sim.AddEntity(oldObjects[i].templateName.FromUTF8(), oldObjects[i].entityID); 931 931 if (ent == INVALID_ENTITY) 932 932 { 933 LOGERROR( L"Failed to load entity template '%hs'", oldObjects[i].templateName.c_str());933 LOGERROR("Failed to load entity template '%s'", oldObjects[i].templateName.c_str()); 934 934 } 935 935 else 936 936 {