Newer
Older
c-interpreter / modules / libkcpp / src / kcpp_throwable.cpp
////////////////////////////////////////////////////////////////////////////////
//
// Throwable
//

#include <cstring>
#include <cerrno>

#include <kcpp_throwable.hpp>

#ifndef MAXMSG
#define MAXMSG (256)
#endif

namespace kcpp
{

    /**
     * 最後に発生したエラーメッセージを持つ Throwable を構築します。
     * エラーメッセージを取得できない場合、空文字がメッセージに設定されます。
     */
    Throwable::Throwable() noexcept : message("")
    {
#if (KCPP_IS_WINDOWS)
        // Window の場合
        int errnum = GetLastError();
        LPVOID lpMsgBuf;
        int ret = FormatMessage(
                  FORMAT_MESSAGE_ALLOCATE_BUFFER             // 動作フラグ
                | FORMAT_MESSAGE_FROM_SYSTEM
                | FORMAT_MESSAGE_IGNORE_TNSERTS,
                0,                                          // メッセージ定義位置
                errnum,                                     // エラーコード
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),  // 言語ID
                (LPSTR) &lpMsgBuf,                          // バッファアドレス
                0,                                          // バッファサイズ
                0);                                         // 挿入句
        if (ret != 0)
        {
            message = static_cast<const char*>(lpMsgBuf);
        }
        localFree(lpMsgBuf);
#elif ((_POSIX_C_SOURCE >= 200112L || __XOPEN_SOURCE >= 600) && ! _GNU_SOURCE)
        // XSI準拠 strerror_r が提供されている
        char buf[MAXMSG];
        int ret = stderror_r(errno, buf, sizeof(buf));
        if (ret == 0)
        {
            message = buf;
        }
#else
        // ANSI 準拠 streror を利用
        char* errMsg = strerror(errno);
        message = errMsg;
#endif
    }


    /**
     * コピーコンストラクタ。
     *
     * @param t コピー元
     */
    Throwable::Throwable(const Throwable& t) noexcept : message(t.message)
    {
        // NOP
    }


    /**
     * 指定されたメッセージを持つ Throwable を構築します。
     *
     * @param msg メッセージ
     */
    Throwable::Throwable(const std::string& msg) noexcept : message(msg)
    {
        // NOP
    }


    /**
     * デストラクタ。
     */
    Throwable::~Throwable() noexcept
    {
        // NOP
    }


    /**
     * エラーメッセージを返します。
     *
     * @return エラーメッセージ
     */
	const char* Throwable::what() const noexcept
    {
        return message.c_str();
    }

}