1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 00:37:15 +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 <cerrno>
#include <cstdio>
#include <cstring>
#include <cstdarg>
#include <algorithm>
// ------------------------------------------------------------------------------------------------
#ifdef SQMOD_OS_WINDOWS
#include <windows.h>
#endif // SQMOD_OS_WINDOWS
// ------------------------------------------------------------------------------------------------
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)
{

View File

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

View File

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