/** * @file kyassert.cpp * @brief アサーションモジュール * @author Nomura Kei * @copyright 2003 - 2017 Nomura Kei * License: New BSD License (3-cclause BSD license) */ #include <iostream> #include <sstream> #include <string> #include <cstring> #include <cerrno> #include <kyassert.hpp> #undef assertEquals #undef assertTrue #undef assertFalse #undef assertNull #undef assertNotNull #undef fail namespace ky { //////////////////////////////////////////////////////////////////////////////// // // AssertError // /** * 最後に発生したエラーメッセージを持つ AssertError を構築します. * エラーメッセージを取得できない場合, 空文字がメッセージに設定されます. */ AssertError::AssertError() throw() : message(""), fileName("unknown"), lineNumber(0), functionName("unknown") { message = std::strerror(errno); } /** * コピーコンストラクタ * * @param e コピー元 */ AssertError::AssertError(const AssertError& e) throw() : message(e.message), fileName(e.fileName), lineNumber(e.lineNumber), functionName(e.functionName) { // NOP } /** * 指定されたメッセージを持つ AssertError を構築します. * * @param msg メッセージ */ AssertError::AssertError(const std::string& msg) throw() : message(msg), fileName("unknown"), lineNumber(0), functionName("unknown") { // NOP } /** * 指定されたメッセージを持つ AssertError を構築します. * * @param msg メッセージ * @param file AssertError 発生ソースファイル名 * @param line AssertError 発生ソース行番号 * @param func AssertError 発生関数名 * */ AssertError::AssertError(const std::string& msg, const char* file, int line, const char* func) throw() : message(msg), fileName(file), lineNumber(line), functionName(func) { // NOP } /** * デストラクタ. */ AssertError::~AssertError() throw() { // NOP } /** * AssertError が throw されたファイル名を取得します. * * @return ファイル名 */ const std::string& AssertError::getFileName() const throw() { return fileName; } /** * AssertError が throw された行番号を取得します. * * @return 行番号 */ int AssertError::getLineNumber() const throw() { return lineNumber; } /** * AssertError が throw された関数名を取得します. * * @return 関数名 */ const std::string& AssertError::getFunctionName() const throw() { return functionName; } /** * エラーメッセージを返します. * * @return エラーメッセージ */ const char* AssertError::what() const throw() { return message.c_str(); } namespace Assertion { /** * bool 型の値比較. * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください. * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します. * * @param expected 比較対象1 * @param actual 比較対象2 * @param file ファイル * @param line 行番号 * @param func 関数 */ void assertEquals(bool expected, bool actual, const char* file, int line, const char* func) throw(AssertError) { if (expected != actual) { if (expected) { throw AssertError("expected:<true> but was:<false>", file, line, func); } else { throw AssertError("expected:<true> but was:<false>", file, line, func); } } } /** * char 型の値比較. * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください. * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します. * * @param expected 比較対象1 * @param actual 比較対象2 * @param file ファイル * @param line 行番号 * @param func 関数 */ void assertEquals(char expected, char actual, const char* file, int line, const char* func) throw(AssertError) { if (expected != actual) { std::ostringstream msg; msg << "expected <" << expected << "> but was:<" << actual << ">"; throw AssertError(msg.str(), file, line, func); } } /** * double 型の値比較. * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください. * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します. * * @param expected 比較対象1 * @param actual 比較対象2 * @param file ファイル * @param line 行番号 * @param func 関数 */ void assertEquals(double expected, double actual, const char* file, int line, const char* func) throw(AssertError) { if (expected != actual) { std::ostringstream msg; msg << "expected <" << expected << "> but was:<" << actual << ">"; throw AssertError(msg.str(), file, line, func); } } /** * float 型の値比較. * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください. * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します. * * @param expected 比較対象1 * @param actual 比較対象2 * @param file ファイル * @param line 行番号 * @param func 関数 */ void assertEquals(float expected, float actual, const char* file, int line, const char* func) throw(AssertError) { if (expected != actual) { std::ostringstream msg; msg << "expected <" << expected << "> but was:<" << actual << ">"; throw AssertError(msg.str(), file, line, func); } } /** * int 型の値比較. * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください. * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します. * * @param expected 比較対象1 * @param actual 比較対象2 * @param file ファイル * @param line 行番号 * @param func 関数 */ void assertEquals(int expected, int actual, const char* file, int line, const char* func) throw(AssertError) { if (expected != actual) { std::ostringstream msg; msg << "expected <" << expected << "> but was:<" << actual << ">"; throw AssertError(msg.str(), file, line, func); } } /** * long 型の値比較. * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください. * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します. * * @param expected 比較対象1 * @param actual 比較対象2 * @param file ファイル * @param line 行番号 * @param func 関数 */ void assertEquals(long expected, long actual, const char* file, int line, const char* func) throw(AssertError) { if (expected != actual) { std::ostringstream msg; msg << "expected <" << expected << "> but was:<" << actual << ">"; throw AssertError(msg.str(), file, line, func); } } /** * 文字列 (string) 型の値比較. * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください. * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します. * * @param expected 比較対象1 * @param actual 比較対象2 * @param file ファイル * @param line 行番号 * @param func 関数 */ void assertEquals(const std::string& expected, const std::string& actual, const char* file, int line, const char* func) throw(AssertError) { if (expected != actual) { std::ostringstream msg; msg << "expected <" << expected << "> but was:<" << actual << ">"; throw AssertError(msg.str(), file, line, func); } } /** * 文字列型 (const char*) の値比較. * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください. * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します. * * @param expected 比較対象1 * @param actual 比較対象2 * @param file ファイル * @param line 行番号 * @param func 関数 */ void assertEquals(const char* expected, const char* actual, const char* file, int line, const char* func) throw(AssertError) { std::string expectedStr = expected; std::string actualStr = actual; assertEquals(expectedStr, actualStr, file, line, func); } /** * 文字列型 (const char*, string) の値比較. * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください. * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します. * * @param expected 比較対象1 * @param actual 比較対象2 * @param file ファイル * @param line 行番号 * @param func 関数 */ void assertEquals(const char* expected, const std::string& actual, const char* file, int line, const char* func) throw(AssertError) { std::string expectedStr = expected; assertEquals(expectedStr, actual, file, line, func); } /** * 文字列型 (string, const char*) の値比較. * 通常, 本メソッドを直接使用せず, assertEquals(expected, actual) マクロを使用してください. * 指定された excepted と actual が同じか否かを判定し, 不一致の場合 AssertError を throw します. * * @param expected 比較対象1 * @param actual 比較対象2 * @param file ファイル * @param line 行番号 * @param func 関数 */ void assertEquals(const std::string& expected, const char* actual, const char* file, int line, const char* func) throw(AssertError) { std::string actualStr = actual; assertEquals(expected, actualStr, file, line, func); } /** * 指定された値 condition が true であるか判定し, true でない場合 AssertError を throw します. * 通常, 本メソッドを直接使用せず, assertTrue(condition) マクロを使用してください. * * @param condition 判定する bool * @param file ファイル * @param line 行番号 * @param func 関数 */ void assertTrue(bool condition, const char* file, int line, const char* func) throw(AssertError) { if (!condition) { throw AssertError("", file, line, func); } } /** * 指定された値 condition が false であるか判定し, false でない場合 AssertError を throw します. * 通常, 本メソッドを直接使用せず, assertFalse(condition) マクロを使用してください. * * @param condition 判定する bool * @param file ファイル * @param line 行番号 * @param func 関数 */ void assertFalse(bool condition, const char* file, int line, const char* func) throw(AssertError) { if (condition) { throw AssertError("", file, line, func); } } /** * 指定された値 condition が null であるか判定し, null でない場合 AssertError を throw します. * 通常, 本メソッドを直接使用せず, assertNull(obj) マクロを使用してください. * * @param obj null か否か判定するオブジェクト * @param file ファイル * @param line 行番号 * @param func 関数 */ void assertNull(void* obj, const char* file, int line, const char* func) throw(AssertError) { if (obj != 0) { throw AssertError("", file, line, func); } } /** * 指定された値 condition が null でないか判定し, null の場合 AssertError を throw します. * 通常, 本メソッドを直接使用せず, assertNotNull(obj) マクロを使用してください. * * @param obj nullでないか確認するオブジェクト * @param file ファイル * @param line 行番号 * @param func 関数 */ void assertNotNull(void* obj, const char* file, int line, const char* func) throw(AssertError) { if (obj == 0) { throw AssertError("", file, line, func); } } /** * AssertError を throw します. * 通常, 本メソッドを直接使用せず, fail() マクロを使用してください. * * @param file ファイル * @param line 行番号 * @param func 関数 */ void fail(const char* file, int line, const char* func) throw(AssertError) { throw AssertError("", file, line, func); } } // namespace Assertion } // namespace ky