1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-02-22 12:47:13 +01:00

Add a helper function to obtain the last system error as a string and throw it.

This commit is contained in:
Sandu Liviu Catalin 2016-06-18 20:27:23 +03:00
parent 4be562c926
commit fe70560234
3 changed files with 57 additions and 0 deletions

View File

@ -7,9 +7,17 @@
#include "Library/String.hpp" #include "Library/String.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include <cerrno>
#include <cstdio>
#include <cstring> #include <cstring>
#include <cstdarg>
#include <algorithm> #include <algorithm>
// ------------------------------------------------------------------------------------------------
#ifdef SQMOD_OS_WINDOWS
#include <windows.h>
#endif // SQMOD_OS_WINDOWS
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
namespace SqMod { namespace SqMod {
@ -813,6 +821,48 @@ Color3 GetColor(CSStr name)
} }
} }
// ------------------------------------------------------------------------------------------------
void SqThrowLastF(CSStr msg, ...)
{
// Acquire a moderately sized buffer
Buffer b(128);
// Prepare the arguments list
va_list args;
va_start (args, msg);
// Attempt to run the specified format
if (b.WriteF(0, msg, args) == 0)
{
b.At(0) = '\0'; // Make sure the string is null terminated
}
// Finalize the argument list
va_end(args);
#ifdef SQMOD_OS_WINDOWS
// Get the error message, if any.
const DWORD error_num = ::GetLastError();
// Was there an error recorded?
if(error_num == 0)
{
// Invoker is responsible for making sure this doesn't happen!
SqThrowF("%s [Unknown error]", b.Data());
}
// The resulted message buffer
LPSTR msg_buff = nullptr;
// Attempt to obtain the error message
const std::size_t size = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, error_num, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast< LPSTR >(&msg_buff), 0, nullptr);
// Copy the message buffer before freeing it
std::string message(msg_buff, size);
//Free the message buffer
LocalFree(msg_buff);
// Now it's safe to throw the error
SqThrowF("%s [%s]", b.Data(), message.c_str());
#else
SqThrowF("%s [%s]", b.Data(), std::strerror(errno));
#endif // SQMOD_OS_WINDOWS
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static SQInteger SqPackRGB(SQInteger r, SQInteger g, SQInteger b) static SQInteger SqPackRGB(SQInteger r, SQInteger g, SQInteger b)
{ {

View File

@ -172,6 +172,11 @@ const Color3 & GetRandomColor();
*/ */
Color3 GetColor(CSStr name); Color3 GetColor(CSStr name);
/* ------------------------------------------------------------------------------------------------
* Throw the last system error as an exception.
*/
void SqThrowLastF(CSStr msg, ...);
} // Namespace:: SqMod } // Namespace:: SqMod
#endif // _BASE_SHARED_HPP_ #endif // _BASE_SHARED_HPP_

View File

@ -528,9 +528,11 @@ enum CmdError
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) #if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
#define STHROW(e, m, ...) throw e(m " =>[" __FILE__ ":" SQMOD_STRINGIZEWRAP(__LINE__) "] ", ##__VA_ARGS__) #define STHROW(e, m, ...) throw e(m " =>[" __FILE__ ":" SQMOD_STRINGIZEWRAP(__LINE__) "] ", ##__VA_ARGS__)
#define STHROWF(m, ...) SqThrowF(m " =>[" __FILE__ ":" SQMOD_STRINGIZEWRAP(__LINE__) "] ", ##__VA_ARGS__) #define STHROWF(m, ...) SqThrowF(m " =>[" __FILE__ ":" SQMOD_STRINGIZEWRAP(__LINE__) "] ", ##__VA_ARGS__)
#define STHROWLASTF(m, ...) SqThrowLastF(m " =>[" __FILE__ ":" SQMOD_STRINGIZEWRAP(__LINE__) "] ", ##__VA_ARGS__)
#else #else
#define STHROW(e, m, ...) throw e(m, ##__VA_ARGS__) #define STHROW(e, m, ...) throw e(m, ##__VA_ARGS__)
#define STHROWF(m, ...) SqThrowF(m, ##__VA_ARGS__) #define STHROWF(m, ...) SqThrowF(m, ##__VA_ARGS__)
#define STHROWLASTF(m, ...) SqThrowLastF(m, ##__VA_ARGS__)
#endif // _DEBUG #endif // _DEBUG
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------