| ||
#pragma once
//---------------------------------------
//Minimum sample program:
// #include "ut.h"
//
// UTDLLMAIN()
//
// TEST(1)
// {
// utxBoolAssert(true);
// utxassert(1, 0);
// }
//---------------------------------------
//#define _WIN32_WINNT 0x0501
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
#include <sstream>
#include <algorithm>
#ifndef T
#include <tchar.h>
#endif
using std::transform;
#ifdef UNICODE
using std::wstring;
#define tstring std::wstring
#else
using std::string;
#define tstring std::string
#endif
//----
#ifdef _DEBUG
#include <crtdbg.h>
#ifdef CRTMEMDEBUG
#define UTDEBUGNEW new(_NORMAL_BLOCK,__FILE__,__LINE__)
#define new UTDEBUGNEW
#endif
#define UTX_ATTACH(stopValue) \
static _CrtMemState before; \
_CrtMemCheckpoint(&before); \
_CrtSetBreakAlloc(stopValue)
#define UTX_DETACH() \
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); \
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); \
_CrtMemState after; \
_CrtMemState diff; \
_CrtMemCheckpoint(&after); \
_CrtMemDifference(&diff, &before, &after); \
if (diff.lCounts[1]) \
{ \
_RPT1(_CRT_WARN, "-----Memory Leaks in %s\n", __FILE__); \
_CrtMemDumpAllObjectsSince(&diff); \
_RPT1(_CRT_WARN, "-----end of Memory Leaks in %s\n", __FILE__); \
} \
else \
_RPT1(_CRT_WARN, "----- No Memory Leaks in %s\n", __FILE__);
#else
#define UTX_ATTACH(stopvalue)
#define UTX_DETACH()
#endif
#define UTXDLLMAIN() BOOL APIENTRY DllMain( HANDLE, DWORD, LPVOID) {return TRUE; }
#define UTXDLLMAIN_CHECKLEAKS(stopValue) \
BOOL APIENTRY DllMain( HANDLE , DWORD ul_reason_for_call, LPVOID ) \
{ switch (ul_reason_for_call) \
{ case DLL_PROCESS_ATTACH: UTX_ATTACH(stopValue); break; \
case DLL_THREAD_ATTACH: break; \
case DLL_THREAD_DETACH: break; \
case DLL_PROCESS_DETACH: UTX_DETACH(); break; \
} return TRUE; }
//helper functions
#ifdef UNICODE
inline std::string _utxToNarrowString(const wstring& s)
{
std::string narrowstr;
narrowstr.resize(s.size() + 1);
transform(s.begin(), s.end(), narrowstr.begin(), wctob);
return narrowstr;
}
#else
#define _utxToNarrowString(s) (s)
#endif
//----
#define TEST(t) __declspec(dllexport) void __stdcall test##t(void)
typedef void (*__UTXFUNCTIONPTR) (bool, const char*, const char*, const char*, const long);
#ifdef UNICODE
#define _UTXFUNCNAME ((LPCWSTR) L"UTXASSERTFUNC")
#else
#define _UTXFUNCNAME ((LPCSTR) "UTXASSERTFUNC")
#endif
inline __UTXFUNCTIONPTR _utxGetFunction()
{
HANDLE mMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // max. object size
sizeof(__UTXFUNCTIONPTR), // buffer size
_UTXFUNCNAME); // name of mapping object
LPTSTR mBuf = (LPTSTR) MapViewOfFile(mMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
sizeof(__UTXFUNCTIONPTR));
__UTXFUNCTIONPTR fp;
memcpy((void*)&fp, (void*) mBuf, sizeof(__UTXFUNCTIONPTR));
UnmapViewOfFile(mBuf);
CloseHandle(mMapFile);
return fp;
}
//for testing utx only. DO NOT USE!
#ifdef DEFINEUTXTEST
#ifdef DEFINENEXTASSERTFAILS
bool _gutxAssertNextAssertFails = false;
#else
extern bool _gutxAssertNextAssertFails;
#endif
inline void _utxAssertNextAssertFails()
{
_gutxAssertNextAssertFails = true;
}
inline bool _utxCheckMissingFailure(__UTXFUNCTIONPTR fp, bool c, const tstring& cAsString, const char* fname, const long lineno, const tstring& msg)
{
if (!_gutxAssertNextAssertFails) return false;
_gutxAssertNextAssertFails = false;
if (!c) return true;
fp(false,
_utxToNarrowString(_T("Expected a failure: ") + cAsString).c_str(),
_utxToNarrowString(msg).c_str(),
fname, lineno);
return true;
}
#else
inline bool _utxCheckMissingFailure(__UTXFUNCTIONPTR /*fp*/, bool /*c*/, const string& /*cAsString*/, const char* /*fname*/, const long /*lineno*/, const string& /*msg*/)
{
return false;
}
#endif
//base level calls
inline void _utxAssertBase(bool c, const tstring& cAsString, const char* fname, const long lineno, const tstring& msg)
{
__UTXFUNCTIONPTR fp = _utxGetFunction();
if (_utxCheckMissingFailure(fp, c, cAsString, fname, lineno, msg)) return;
fp(c, _utxToNarrowString(cAsString).c_str(), _utxToNarrowString(msg).c_str(), fname, lineno);
}
//inline void _utxAssertBase(bool c, const wstring& cAsString, char* fname, const long lineno, const wstring& msg)
// {
// _utxAssertBase(c, _utxToNarrowString(cAsString), fname, lineno, _utxToNarrowString(msg));
// }
//inline void _utxAssertBase(bool c, const string& cAsString, char* fname, const long lineno, const wstring& msg)
// {
// _utxAssertBase(c, cAsString, fname, lineno, _utxToNarrowString(msg));
// }
//pointer check
inline bool _utxCheckNulls(const void *actual, const void* expected, const char* fname, const long lineno)
{
if (actual == 0 && expected == 0) return false; //do not continue
if (actual != 0 && expected != 0) return true; //ok to continue
_utxAssertBase(false, tstring(_T("actual=")) + (actual == 0 ? _T("null") : _T("non-null")) + tstring(_T(" expected=")) + (expected == 0 ? _T("null") : _T("non-null")), fname, lineno, tstring());
return false;
}
inline bool _utxCheckNullsNot(const void *actual, const void* expected, const char* fname, const long lineno)
{
if (actual == 0 && expected != 0) return false; //do not continue
if (actual != 0 && expected == 0) return false; //do not continue
if (actual != 0 && expected != 0) return true; //ok to continue
_utxAssertBase(false, tstring(_T("actual=")) + (actual == 0 ? _T("null") : _T("non-null")) + tstring(_T(" expected=")) + (expected == 0 ? _T("null") : _T("non-null")), fname, lineno, tstring());
return false;
}
//output string formatting routines
#define DefineFormatMsgFunc(type, format) \
inline tstring _utxFormatMsg(const tstring& t, type p1, type p2) \
{ TCHAR desc[100]; \
_stprintf(desc, _T(format), p1, t.c_str(), p2); \
return tstring(desc); }
#pragma warning (disable:4996)
DefineFormatMsgFunc(const void*, "actual=0x%p expected%s0x%p")
DefineFormatMsgFunc(int, "actual=%d expected%s%d")
DefineFormatMsgFunc(unsigned int, "actual=%u expected%s%u")
DefineFormatMsgFunc(long, "actual=%ld expected%s%ld")
DefineFormatMsgFunc(unsigned long, "actual=%lu expected%s%lu")
//DefineFormatMsgFunc(__int64, "actual=%I64d expected%s%I64d")
DefineFormatMsgFunc(long long, "actual=%lld expected%s%lld")
//#pragma warning (disable:4996)
inline tstring _utxFormatMsg(const tstring& type, double n1, double n2, double epsilon)
{
TCHAR desc[100];
_stprintf(desc, _T("actual=%f expected%s%f (epsilon=%f)"), n1, type.c_str(), n2, epsilon);
return tstring(desc);
}
inline tstring _utxFormatMsg(const tstring& type, const tstring& actual, const tstring& expected)
{
return _T("actual='") + actual + _T("' expected") + type + _T("'") + expected + _T("'");
}
inline tstring _utxFormatMsg(const tstring& type, bool actual, bool expected)
{
tstring t(_T("true"));
tstring f(_T("false"));
return _T("actual='") + (actual ? t : f) + _T("' expected") + type + _T("'") + (expected ? t : f) + _T("'");
}
inline tstring _utxFormatContainsMsg(const tstring& type, const tstring& actual, const tstring& expected)
{
return _T("'") + actual + _T("' ") + type + _T(" contain '") + expected + _T("'");
}
//inline string _utxFormatContainsMsg(const string& type, const wstring& actual, const wstring& expected)
// {
// return _utxFormatContainsMsg(type, _utxToNarrowString(actual), _utxToNarrowString(expected));
// }
//inline string _utxFormatMsg(const string& type, const wstring& actual, const wstring& expected)
// {
// return _utxFormatMsg(type, _utxToNarrowString(actual), _utxToNarrowString(expected));
// }
inline tstring _utxFormatMsg(const tstring& type, const TCHAR* actual, const TCHAR* expected)
{
return _utxFormatMsg(type, tstring(actual), tstring(expected));
}
//inline string _utxFormatMsg(const string& type, const wchar_t* actual, const wchar_t* expected)
// {
// return _utxFormatMsg(type, wstring(actual), wstring(expected));
// }
//helper macros
#define DefineCharArrayWithMsg(type, casttype, msgtype) \
inline void _utxAssert2(type actual, type expected, const char* fname, const long lineno, const msgtype& msg) \
{ if (!_utxCheckNulls(actual, expected, fname, lineno)) return; \
_utxAssert2(casttype(actual), casttype(expected), fname, lineno, msg); }
#define DefineCharArrayNoMsg(type, msgtype) \
inline void _utxAssert(type actual, type expected, const char* fname, const long lineno) \
{ _utxAssert2(actual, expected, fname, lineno, msgtype()); }
#define DefineCharArrayWithMsgNot(type, casttype, msgtype) \
inline void _utxAssertNot2(type actual, type expected, const char* fname, const long lineno, const msgtype& msg) \
{ if (!_utxCheckNullsNot(actual, expected, fname, lineno)) return; \
_utxAssertBase(casttype(actual) != casttype(expected), _utxFormatMsg(_T(" !="), actual, expected), fname, lineno, msg); }
#define DefineCharArrayNoMsgNot(type, msgtype) \
inline void _utxAssertNot(type actual, type expected, const char* fname, const long lineno) \
{ _utxAssertNot2(actual, expected, fname, lineno, msgtype()); }
#define DefineFuncWithMsg(type, msgtype) \
inline void _utxAssert2(type actual, type expected, const char* fname, const long lineno, const msgtype& msg) \
{ _utxAssertBase(actual == expected, _utxFormatMsg(_T("="), actual, expected), fname, lineno, msg); }
#define DefineFuncNoMsg(type, msgtype) \
inline void _utxAssert(type actual, type expected, const char* fname, const long lineno) \
{ _utxAssert2(actual, expected, fname, lineno, msgtype()); }
#define DefineFuncWithMsgNot(type, msgtype) \
inline void _utxAssertNot2(type actual, type expected, const char* fname, const long lineno, const msgtype& msg) \
{ _utxAssertBase(actual != expected, _utxFormatMsg(_T(" !="), actual, expected), fname, lineno, msg); }
#define DefineFuncNoMsgNot(type, msgtype) \
inline void _utxAssertNot(type actual, type expected, const char* fname, const long lineno) \
{ _utxAssertNot2(actual, expected, fname, lineno, msgtype()); }
#define DefineSubStringFuncWithMsg(type, msgtype) \
inline void _utxAssertStringContains2(type actual, type expected, const char* fname, const long lineno, const msgtype& msg) \
{ _utxAssertBase((actual).find(expected) != tstring::npos, _utxFormatContainsMsg(_T("does not"), actual, expected), fname, lineno, msg); }
#define DefineSubStringFuncNoMsg(type, msgtype) \
inline void _utxAssertStringContains(type actual, type expected, const char* fname, const long lineno) \
{ _utxAssertStringContains2(actual, expected, fname, lineno, msgtype()); }
#define DefineSubStringFuncWithMsgNot(type, msgtype) \
inline void _utxAssertStringContainsNot2(type actual, type expected, const char* fname, const long lineno, const msgtype& msg) \
{ _utxAssertBase((actual).find(expected) == tstring::npos, _utxFormatContainsMsg(_T("should not"), actual, expected), fname, lineno, msg); }
#define DefineSubStringFuncNoMsgNot(type, msgtype) \
inline void _utxAssertStringContainsNot(type actual, type expected, const char* fname, const long lineno) \
{ _utxAssertStringContainsNot2(actual, expected, fname, lineno, msgtype()); }
//bool
inline void _utxAssert2(bool actual, const tstring& cAsString, const char* fname, const long lineno, const tstring& msg)
{
tstring m = (msg.empty() ? _T("") : msg + _T(": ")) + _utxFormatMsg(_T("="), false, true);
_utxAssertBase(actual, cAsString, fname, lineno, m);
}
//inline void _utxAssert2(bool actual, const string& cAsString, char* fname, const long lineno, const wstring& msg)
// {
// _utxAssertBase(actual, cAsString, fname, lineno, msg);
// }
inline void _utxAssert(bool actual, const tstring& cAsString, const char* fname, const long lineno)
{
_utxAssert2(actual, cAsString, fname, lineno, tstring());
}
inline void _utxAssertNot2(bool actual, const tstring& cAsString, const char* fname, const long lineno, const tstring& msg)
{
tstring m = (msg.empty() ? _T("") : msg + _T(": ")) + _utxFormatMsg(_T(" !="), true, true);
_utxAssertBase(!actual, cAsString, fname, lineno, m);
}
//inline void _utxAssertNot2(bool actual, const string& cAsString, char* fname, const long lineno, const wstring& msg)
// {
// _utxAssertNot2(actual, cAsString, fname, lineno, _utxToNarrowString(msg));
// }
inline void _utxAssertNot(bool actual, const tstring& cAsString, const char* fname, const long lineno)
{
_utxAssertNot2(actual, cAsString, fname, lineno, tstring());
}
//void*
inline void _utxAssert2(const void* actual, const char* fname, const long lineno, const tstring& msg)
{
_utxAssertBase(actual == 0, _utxFormatMsg(_T("="), actual, 0), fname, lineno, msg);
}
inline void _utxAssert(const void* actual, const char* fname, const long lineno)
{
_utxAssert2(actual, fname, lineno, tstring());
}
inline void _utxAssertNot2(const void* actual, const char* fname, const long lineno, const tstring& msg)
{
_utxAssertBase(actual != 0, _utxFormatMsg(_T(" !="), actual, 0), fname, lineno, msg);
}
inline void _utxAssertNot(const void* actual, const char* fname, const long lineno)
{
_utxAssertNot2(actual, fname, lineno, tstring());
}
//-- all string types go here -----
//string
DefineFuncWithMsg(const tstring&, tstring)
DefineFuncNoMsg(const tstring&, tstring)
DefineFuncWithMsgNot(const tstring&, tstring)
DefineFuncNoMsgNot(const tstring&, tstring)
////wstring
//DefineFuncWithMsg(const wstring&, string)
//DefineFuncWithMsg(const wstring&, wstring)
//DefineFuncNoMsg(const wstring&, string)
//DefineFuncWithMsgNot(const wstring&, wstring)
//DefineFuncWithMsgNot(const wstring&, string)
//DefineFuncNoMsgNot(const wstring&, wstring)
//substring
DefineSubStringFuncWithMsg(const tstring&, tstring)
DefineSubStringFuncNoMsg(const tstring&, tstring)
DefineSubStringFuncWithMsgNot(const tstring&, tstring)
DefineSubStringFuncNoMsgNot(const tstring&, tstring)
////wsubstring
//DefineSubStringFuncWithMsg(const wstring&, wstring)
//DefineSubStringFuncNoMsg(const wstring&, wstring)
//DefineSubStringFuncWithMsgNot(const wstring&, wstring)
//DefineSubStringFuncNoMsgNot(const wstring&, wstring)
//string + char*
inline void _utxAssert2(const tstring& actual, const TCHAR* expected, const char* fname, const long lineno, const tstring& msg)
{
_utxAssertBase(actual == tstring(expected), _utxFormatMsg(_T("="), actual, expected), fname, lineno, msg);
}
inline void _utxAssert(const tstring& actual, const TCHAR* expected, const char* fname, const long lineno)
{
_utxAssert2(actual, tstring(expected), fname, lineno, tstring());
}
inline void _utxAssertNot2(const tstring& actual, const TCHAR* expected, const char* fname, const long lineno, const tstring& msg)
{
_utxAssertBase(actual != tstring(expected), _utxFormatMsg(_T(" !="), actual, expected), fname, lineno, msg);
}
inline void _utxAssertNot(const tstring& actual, const TCHAR* expected, const char* fname, const long lineno)
{
_utxAssertNot2(actual, expected, fname, lineno, tstring());
}
//-- all char* types go here -----
//char*
DefineCharArrayWithMsg(const TCHAR*, tstring, tstring)
DefineCharArrayNoMsg(const TCHAR*, tstring)
DefineCharArrayWithMsgNot(const TCHAR*, tstring, tstring)
DefineCharArrayNoMsgNot(const TCHAR*, tstring)
////wchar_t
//DefineCharArrayWithMsg(const wchar_t*, wstring, string)
//DefineCharArrayWithMsg(const wchar_t*, wstring, wstring)
//DefineCharArrayNoMsg(const wchar_t*, string)
//DefineCharArrayWithMsgNot(const wchar_t*, wstring, wstring)
//DefineCharArrayNoMsgNot(const wchar_t*, wstring)
//-- all real types go here -----
//double
//inline void _utxAssert2(double actual, double expected, double epsilon, char* fname, const long lineno, const wstring& msg)
// {
// _utxAssertBase((actual > expected - epsilon && actual < expected + epsilon), _utxFormatMsg("=", actual, expected, epsilon), fname, lineno, msg);
// }
inline void _utxAssert2(double actual, double expected, double epsilon, const char* fname, const long lineno, const tstring& msg)
{
_utxAssertBase((actual > expected - epsilon && actual < expected + epsilon), _utxFormatMsg(_T("="), actual, expected, epsilon), fname, lineno, msg);
}
inline void _utxAssert(double actual, double expected, double epsilon, const char* fname, const long lineno)
{
_utxAssert2(actual, expected, epsilon, fname, lineno, tstring());
}
//inline void _utxAssertNot2(double actual, double expected, double epsilon, char* fname, const long lineno, const wstring& msg)
// {
// _utxAssertBase((actual <= expected - epsilon || actual >= expected + epsilon), _utxFormatMsg(" !=", actual, expected, epsilon), fname, lineno, msg);
// }
inline void _utxAssertNot2(double actual, double expected, double epsilon, const char* fname, const long lineno, const tstring& msg)
{
_utxAssertBase((actual <= expected - epsilon || actual >= expected + epsilon), _utxFormatMsg(_T(" !="), actual, expected, epsilon), fname, lineno, msg);
}
inline void _utxAssertNot(double actual, double expected, double epsilon, const char* fname, const long lineno)
{
_utxAssertNot2(actual, expected, epsilon, fname, lineno, tstring());
}
//-- all integral types go here -----
//long
//DefineFuncWithMsg (long, wstring)
DefineFuncWithMsg (long, tstring)
DefineFuncNoMsg (long, tstring)
//DefineFuncWithMsgNot(long, wstring)
DefineFuncWithMsgNot(long, tstring)
DefineFuncNoMsgNot (long, tstring)
//unsigned long
//DefineFuncWithMsg (unsigned long, wstring)
DefineFuncWithMsg (unsigned long, tstring)
DefineFuncNoMsg (unsigned long, tstring)
//DefineFuncWithMsgNot(unsigned long, wstring)
DefineFuncWithMsgNot(unsigned long, tstring)
DefineFuncNoMsgNot (unsigned long, tstring)
//int
//DefineFuncWithMsg (int, wstring)
DefineFuncWithMsg (int, tstring)
DefineFuncNoMsg (int, tstring)
//DefineFuncWithMsgNot(int, wstring)
DefineFuncWithMsgNot(int, tstring)
DefineFuncNoMsgNot (int, tstring)
//unsigned int
//DefineFuncWithMsg (unsigned int, wstring)
DefineFuncWithMsg (unsigned int, tstring)
DefineFuncNoMsg (unsigned int, tstring)
//DefineFuncWithMsgNot(unsigned int, wstring)
DefineFuncWithMsgNot(unsigned int, tstring)
DefineFuncNoMsgNot (unsigned int, tstring)
//__int64
//DefineFuncWithMsg (__int64, wstring)
//DefineFuncWithMsg (__int64, string)
//DefineFuncNoMsg (__int64, string)
//DefineFuncWithMsgNot(__int64, wstring)
//DefineFuncWithMsgNot(__int64, string)
//DefineFuncNoMsgNot (__int64, string)
//DefineFuncWithMsg (__int64, wstring)
DefineFuncWithMsg (long long, tstring)
DefineFuncNoMsg (long long, tstring)
//DefineFuncWithMsgNot(__int64, wstring)
DefineFuncWithMsgNot(long long, tstring)
DefineFuncNoMsgNot (long long, tstring)
//gather the file and lineno info
#define utxBoolAssert(c) _utxAssert((c), tstring(_T(#c)), __FILE__,__LINE__)
#define utxBoolAssert2(c, msg) _utxAssert2((c), tstring(_T(#c)), __FILE__,__LINE__, tstring(msg))
#define utxBoolAssertNot(c) _utxAssertNot((c), tstring(_T(#c)), __FILE__,__LINE__)
#define utxBoolAssertNot2(c, msg) _utxAssertNot2((c), tstring(_T(#c)), __FILE__,__LINE__, tstring(msg))
#define utxAssertPtrIsNull(p) _utxAssert((p), __FILE__,__LINE__)
#define utxAssertPtrIsNull2(p, msg) _utxAssert2((p), __FILE__,__LINE__, tstring(msg))
#define utxAssertPtrIsNotNull(p) _utxAssertNot((p), __FILE__,__LINE__)
#define utxAssertPtrIsNotNull2(p, msg) _utxAssertNot2((p), __FILE__,__LINE__, tstring(msg))
#define utxDoubleAssert(actual, expected, epsilon) _utxAssert((actual), (expected), (epsilon),__FILE__, __LINE__)
#define utxDoubleAssert2(actual, expected, epsilon, msg) _utxAssert2((actual), (expected), (epsilon), __FILE__, __LINE__, tstring(msg))
#define utxDoubleAssertNot(actual, expected, epsilon) _utxAssertNot((actual), (expected), (epsilon),__FILE__, __LINE__)
#define utxDoubleAssertNot2(actual, expected, epsilon, msg) _utxAssertNot2((actual), (expected), (epsilon), __FILE__, __LINE__, tstring(msg))
#define utxassert(actual, expected) _utxAssert((actual), (expected), __FILE__, __LINE__)
#define utxassert2(actual, expected, msg) _utxAssert2((actual), (expected), __FILE__,__LINE__, tstring(msg))
#define utxassertnot(actual, expected) _utxAssertNot((actual), (expected), __FILE__, __LINE__)
#define utxassertnot2(actual, expected, msg) _utxAssertNot2((actual), (expected), __FILE__, __LINE__, tstring(msg))
#define utxAssertStringContains(actual, expected) _utxAssertStringContains((actual), (expected), __FILE__, __LINE__)
#define utxAssertStringContains2(actual, expected, msg) _utxAssertStringContains2((actual), (expected), __FILE__, __LINE__, tstring(msg))
#define utxAssertStringContainsNot(actual, expected) _utxAssertStringContainsNot((actual), (expected), __FILE__, __LINE__)
#define utxAssertStringContainsNot2(actual, expected, msg) _utxAssertStringContainsNot2((actual), (expected), __FILE__, __LINE__, tstring(msg))
| ||
| ||
#pragma once
#include <comdef.h>
inline bool _utxCheckNulls(const _bstr_t& actual, const _bstr_t& expected, char* fname, const long lineno)
{
return _utxCheckNulls((char*)actual, (char*)expected, fname, lineno);
}
inline bool _utxCheckNullsNot(const _bstr_t& actual, const _bstr_t& expected, char* fname, const long lineno)
{
return _utxCheckNullsNot((char*) actual, (char*) expected, fname, lineno);
}
inline string _utxFormatMsg(const string& type, const _bstr_t& actual, const _bstr_t& expected)
{
return _utxFormatMsg(type, (wchar_t*) actual, (wchar_t*) expected);
}
//bstr_t
inline void _utxAssert2(const _bstr_t& actual, const _bstr_t& expected, char* fname, const long lineno, const char* msg)
{
if (!_utxCheckNulls(actual, expected, fname, lineno)) return;
_utxAssertBase(actual == expected, "actual='" + string((char*) actual) + "' expected='" + string((char*) expected) + "'", fname, lineno, msg);
}
inline void _utxAssert(const _bstr_t& actual, const _bstr_t& expected, char* fname, const long lineno)
{
_utxAssert2(actual, expected, fname, lineno, "");
}
inline void _utxAssertNot2(const _bstr_t& actual, const _bstr_t& expected, char* fname, const long lineno, const string& msg)
{
if (!_utxCheckNullsNot(actual, expected, fname, lineno)) return;
_utxAssertBase(actual != expected, "actual='" + string((char*) actual) + "' expected='" + string((char*) expected) + "'", fname, lineno, msg);
}
inline void _utxAssertNot(const _bstr_t& actual, const _bstr_t& expected, char* fname, const long lineno)
{
_utxAssertNot2(actual, expected, fname, lineno, "");
}
//BSTR
inline void _utxAssert2(const BSTR actual, const BSTR expected, char* fname, const long lineno, const char* msg)
{
_utxAssert2(_bstr_t(actual), _bstr_t(expected), fname, lineno, msg);
}
inline void _utxAssert(const BSTR actual, const BSTR expected, char* fname, const long lineno)
{
_utxAssert2(actual, expected, fname, lineno, "");
}
inline void _utxAssertNot2(const BSTR actual, const BSTR expected, char* fname, const long lineno, const string& msg)
{
_utxAssertNot2(_bstr_t(actual), _bstr_t(expected), fname, lineno, msg);
}
inline void _utxAssertNot(const BSTR actual, const BSTR expected, char* fname, const long lineno)
{
_utxAssertNot2(actual, expected, fname, lineno, "");
}
//BSTR & _bstr_t mix
inline void _utxAssert2(const _bstr_t& actual, const BSTR expected, char* fname, const long lineno, const char* msg)
{
_utxAssert2(actual, _bstr_t(expected), fname, lineno, msg);
}
inline void _utxAssert(const _bstr_t& actual, const BSTR expected, char* fname, const long lineno)
{
_utxAssert2(actual, expected, fname, lineno, "");
}
inline void _utxAssertNot2(const _bstr_t& actual, const BSTR expected, char* fname, const long lineno, const string& msg)
{
_utxAssertNot2(actual, _bstr_t(expected), fname, lineno, msg);
}
inline void _utxAssertNot(const _bstr_t& actual, const BSTR expected, char* fname, const long lineno)
{
_utxAssertNot2(actual, expected, fname, lineno, "");
}
//----------------------------------
#ifdef USECOMSPY
#include "\projects\src\jcomheap\jcomheap.h"
#pragma comment(lib, "c:\\projects\\debug\\jcomheap\\jcomheap.lib")
#define STARTCOMSPY(breaknum) \
jComHeap* _comheap = new jComHeap(); \
_comheap->Init(); \
_comheap->BreakOnAllocNumber(breaknum)
#define ENDCOMSPY() \
_comheap->Report(__FILE__, __LINE__); \
delete _comheap; \
_comheap = 0
#define UTXCOMDLLMAIN_CHECKLEAKS(stopValue) \
BOOL APIENTRY DllMain( HANDLE , DWORD ul_reason_for_call, LPVOID ) \
{ static jComHeap* _comheap = new jComHeap(); \
switch (ul_reason_for_call) \
{ case DLL_PROCESS_ATTACH: \
_RPT1(_CRT_WARN, "----- Attach Here! %s\n", __FILE__); \
_comheap->Init(); \
_comheap->BreakOnAllocNumber(stopValue); \
break; \
case DLL_THREAD_ATTACH: break; \
case DLL_THREAD_DETACH: break; \
case DLL_PROCESS_DETACH: \
_RPT1(_CRT_WARN, "----- Detach START Here! %s\n", __FILE__); \
CoFreeUnusedLibraries(); \
_comheap->Report(__FILE__, __LINE__); \
delete _comheap; \
_comheap = 0; \
_RPT1(_CRT_WARN, "----- Detach DONE Here! %s\n", __FILE__); \
break; \
} return TRUE; }
#else
#define STARTCOMSPY(breaknum)
#define ENDCOMSPY()
#define UTXCOMDLLMAIN_CHECKLEAKS(stopValue)
#endif
#define STARTCOM() \
HRESULT hr; \
hr = CoInitialize(0); \
{
#define CREATECOM(clazz, vrbl, coclass) \
clazz vrbl; \
hr = vrbl##.CreateInstance(__uuidof(coclass)); \
utxassert(hr, S_OK)
#define ENDCOM() \
} \
CoUninitialize()
#define UTXCOMDLLMAIN() BOOL APIENTRY DllMain( HANDLE, DWORD, LPVOID) {return TRUE; }
| ||
| ||
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include "utxCommon.h"
#include "utx.h"
#include "App.h"
#include "ImageFile.h"
//-----------------------------------------------------
//all lowercase!
string cUTFilePrefix = "";
string cUTFileSuffix = "_utest.dll";
string cUTMethodPrefix = "test";
string cUTMethodSuffix = "";
//-----------------------------------------------------
char HelpText[] =
"usage: utx [switches] [dir or file]\n"
"\n"
"switches:\n"
" -h display this help screen\n"
" -? display this help screen\n"
" -v display version and exit\n"
"\n"
" -test:<pattern>\n"
" -file:<pattern>\n"
" defaults:\n"
" -file:*_utest\n"
" -test:test*\n"
" where <pattern> is a series of characters\n"
" there can be zero or one asterisk '*' in it\n"
" can be empty before or after the asterisk or both\n"
" don't use file extension (.dll, .class) etc.\n"
" examples:\n"
" -file:ut_* all dll's and classes starting with 'ut_'\n"
" -file:ut_abc the files 'ut_abc.dll', 'ut_abc.class' etc.\n"
" -test:case* all functions with signatures like 'void casexxx()'\n"
"\n"
" if no file name or directory given, defaults to '.'\n";
//-----------------------------------------------------
template<typename _Ty>
inline bool startswith(const _Ty& _F, const _Ty& _PFX)
{
typename _Ty::const_iterator it = _PFX.begin();
typename _Ty::const_iterator it2 = _F.begin();
for ( ; it != _PFX.end() && it2 != _F.end(); ++it, ++it2)
{
if (*it != *it2)
return false;
}
return it == _PFX.end();
}
template<typename _Ty>
inline bool endswith(const _Ty& _F, const _Ty& _SFX)
{
typename _Ty::const_reverse_iterator it = _SFX.rbegin();
typename _Ty::const_reverse_iterator it2 = _F.rbegin();
for ( ; it != _SFX.rend() && it2 != _F.rend(); ++it, ++it2)
{
if (*it != *it2)
return false;
}
return it == _SFX.rend();
}
//-----------------------------------------------------
static bool isMatch(const string& f)
{
return startswith(f, cUTFilePrefix) && endswith(f, cUTFileSuffix);
}
//-----------------------------------------------------
class App::AssertFunction
{
public:
//----------
void Set(__UTXFUNCTIONPTR fp)
{
mMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // max. object size
BUF_SIZE, // buffer size
"UTXASSERTFUNC"); // name of mapping object
checkInternalError(mMapFile == 0 || mMapFile == INVALID_HANDLE_VALUE, "Can't crate file mapping");
mBuf = (LPTSTR) MapViewOfFile(mMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);
checkInternalError(mBuf == 0, "Can't map view of file");
memcpy((void*)mBuf, (void*) &fp, BUF_SIZE);
}
//----------
void Close()
{
if (mMapFile != INVALID_HANDLE_VALUE)
{
UnmapViewOfFile(mBuf);
mBuf = 0;
CloseHandle(mMapFile);
mMapFile = INVALID_HANDLE_VALUE;
}
}
private:
//-----------------------------------------------------
void checkInternalError(bool condition, const char* s)
{
if (condition)
{
char buf[512];
sprintf(buf, "Internal error: %s: gle=%lX", s, ::GetLastError());
throw string(buf);
}
}
private:
enum { BUF_SIZE = sizeof(__UTXFUNCTIONPTR) };
HANDLE mMapFile;
LPTSTR mBuf;
} ;
//-----------------------------------------------------
App::App()
: mFunc(* new App::AssertFunction), m_files(isMatch)
{
}
//-----------------------------------------------------
App::~App()
{
delete &mFunc;
}
//-----------------------------------------------------
void App::Init(int argc, char** argv)
{
initDebugRoutines();
try
{
processCommandLine(argc, argv);
setAssertFunction();
//todo: how does g++ handle system exceptions?
//_set_se_translator(translate_exceptions);
m_files.get(m_argpath);
}
catch (const string& s)
{
cout << s << endl << endl;
cout << HelpText;
throw 1;
}
catch (const char* s)
{
cout << s << endl << endl;
cout << HelpText;
throw 1;
}
catch(int n)
{
throw n;
}
}
//-----------------------------------------------------
void App::Run()
{
stats.numfiles = m_files.size();
for(FileList::iterator it = m_files.begin(); it != m_files.end(); ++it)
{
ImageFile img;
img.Run(*it);
}
}
//-----------------------------------------------------
void App::utxAssertImpl(bool cond, const char* condstr, const char* msg, const char* fn, const long line)
{
stats.numasserts++;
if (cond) return;
if (strcmp(msg, "") == 0)
cout << fn << "(" << line << "): FAILED: " << condstr << endl;
else
cout << fn << "(" << line << "): FAILED: " << msg << ": " << condstr << endl;
stats.numerrors++;
}
//-----------------------------------------------------
void App::setAssertFunction()
{
__UTXFUNCTIONPTR fp = utxAssertImpl;
mFunc.Set(fp);
}
void App::closeAssertFunction()
{
mFunc.Close();
}
//-----------------------------------------------------
void App::translate_exceptions(unsigned int u, EXCEPTION_POINTERS* pExp)
{
SE_Exception se;
se.ex = u;
throw se;
}
//-----------------------------------------------------
bool App::isSwitch(char* arg)
{
return arg[0] == '-' || arg[0] == '/';
}
//-----------------------------------------------------
void App::processCommandLine(int argc, char** argv)
{
for (int i=1; i < argc; i++ )
{
strlwr(argv[i]);
if (isSwitch(argv[i]) )
handleSwitch(&argv[i][1]);
else if (m_argpath != "")
throw "already have a filename or directory to scan";
else
m_argpath = argv[i];
}
if (m_argpath == "")
m_argpath = ".";
}
//-----------------------------------------------------
void App::handleSwitch(char* s)
{
string arg = s;
if (arg == "h" || arg == "?")
throw "";
if (arg == "v")
{
cout << "utx V0.9" << endl;
throw 2;
}
if (strncmp(s, "test:", 5) == 0)
{
handlePattern(&s[5], cUTMethodPrefix, cUTMethodSuffix);
}
else if (strncmp(s, "file:", 5) == 0)
{
handlePattern(&s[5], cUTFilePrefix, cUTFileSuffix);
cUTFileSuffix += ".dll";
}
else
{
char buf[200];
sprintf(buf, "unknown switch: %s", s);
throw buf;
}
}
//-----------------------------------------------------
void App::handlePattern(const string& pattern, string& prefix, string& suffix)
{
int starcount = count(pattern.begin(), pattern.end(), '*');
if (starcount > 1)
throw "Only zero or one asterisk allowed!";
string::size_type idx = pattern.find('*');
prefix = pattern.substr(0, idx);
suffix = idx == string::npos ? "" : pattern.substr(idx+1);
}
//-----------------------------------------------------
void App::initDebugRoutines()
{
// _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
// _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
// _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
}
| ||
| ||
//-----------------------------------------------------
#pragma once
#include <string>
using std::string;
#include "FileList.h"
class App
{
public:
App();
~App();
void Init(int argc, char** argv);
void Run();
private:
static void utxAssertImpl(bool cond, const char* msg, const char* condstr, const char* fn, const long line);
void setAssertFunction();
void closeAssertFunction();
static void translate_exceptions(unsigned int u, EXCEPTION_POINTERS* pExp);
void processCommandLine(int argc, char** argv);
void initDebugRoutines();
bool isSwitch(char* arg);
void handleSwitch(char* s);
void handlePattern(const string& pattern, string& prefix, string& suffix);
private:
class AssertFunction;
AssertFunction& mFunc;
FileList m_files;
string m_argpath;
} ;
| ||
| ||
#include <string>
#include <algorithm>
using namespace std;
#include "utxCommon.h"
#include "FileFind.h"
#include "NTHandles.h"
static string toDosPath(const string& path)
{
struct LocalFunc
{
static bool isForwardSlash(char c) { return c == '/'; }
} ;
string s = path;
replace_if(s.begin(), s.end(), LocalFunc::isForwardSlash, '\\');
return s;
}
//-----------------------------------------------------
class FileFind::Private
{
public:
Private(const string& dir)
{
mRootdir = toDosPath(dir);
filefindData.first = mRootdir + "\\*.*";
filefindData.second = &fdata;
resetFilename();
}
bool findFirst()
{
resetFilename();
return hFileFind.create(filefindData);
}
bool findnext()
{
resetFilename();
return hFileFind.next(filefindData);
}
const string filename()
{
if (mFilename == "")
setFilename(strlwr(fdata.cFileName));
return mFilename;
}
const string fullpath()
{
if (mFullpath == "")
mFullpath = string(mRootdir + "\\" + filename());
return mFullpath;
}
bool isDir()
{
return (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
}
private:
void resetFilename()
{
setFilename("");
}
void setFilename(const char* fn)
{
mFilename = string(fn);
mFullpath = "";
}
private:
string mRootdir;
string mFilename;
string mFullpath;
WIN32_FIND_DATA fdata;
FileFindPair filefindData;
NtFileFindHandle hFileFind;
} ;
//-----------------------------------------------------
FileFind::FileFind(const string& dir)
: mimpl (* new FileFind::Private(dir))
{
}
//-----------------------------------------------------
FileFind::~FileFind()
{
delete &mimpl;
}
//-----------------------------------------------------
bool FileFind::getFirst()
{
if (!mimpl.findFirst())
return false;
for(;;)
{
if (!isDotDir())
return true;
if (!getNext())
return false;
}
}
//-----------------------------------------------------
bool FileFind::getNext()
{
return mimpl.findnext();
}
//-----------------------------------------------------
bool FileFind::isDotDir()
{
return fileName() == string(".") || fileName() == string("..");
}
//-----------------------------------------------------
bool FileFind::isDir()
{
return mimpl.isDir();
}
//-----------------------------------------------------
const string FileFind::fullPath()
{
return mimpl.fullpath();
}
//-----------------------------------------------------
const string FileFind::fileName()
{
return mimpl.filename();
}
| ||
| ||
#pragma once
#include <string>
class FileFind
{
public:
FileFind(const std::string& dir);
~FileFind();
bool getFirst();
bool getNext();
bool isDotDir();
bool isDir();
const std::string fullPath();
const std::string fileName();
private:
class Private;
Private& mimpl;
};
| ||
| ||
#include <string>
using namespace std;
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX 1
#include <windows.h>
#include "utxCommon.h"
#include "FileList.h"
#include "FileFind.h"
//-----------------------------------------------------
FileList::FileList(isMatchFunc p)
: matchfunc(p)
{
}
//-----------------------------------------------------
void FileList::get(const std::string& path)
{
m_argpath = path;
if (! isArgAFile())
argIsDirectory();
if (empty())
throw "No files were found to scan";
}
//-----------------------------------------------------
void FileList::argIsDirectory()
{
Paths dirs;
dirs.push(m_argpath);
while(!dirs.empty())
{
string dir = dirs.top();
dirs.pop();
searchDir(dir, dirs);
}
}
//-----------------------------------------------------
void FileList::searchDir(const string& dir, Paths& dirs)
{
FileFind ff(dir);
for (bool rc = ff.getFirst(); rc; rc = ff.getNext())
{
if (ff.isDir())
dirs.push(ff.fullPath());
else if (matchfunc(ff.fileName()))
push_back(ff.fullPath());
}
}
//-----------------------------------------------------
bool FileList::isArgAFile()
{
DWORD fattr = GetFileAttributes(m_argpath.c_str());
if (fattr == 0xFFFFFFFF)
{
char buf[200];
sprintf(buf, "Could not find the file or directory '%s'", m_argpath.c_str());
throw buf;
}
if ((fattr & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
push_back(m_argpath);
return true;
}
return false;
}
| ||
| ||
#pragma once
#include <algorithm>
#include <string>
#include <list>
#include <stack>
typedef bool (* isMatchFunc) (const std::string& f);
class FileList : public std::list<std::string>
{
public:
FileList(isMatchFunc p);
void get(const std::string& path);
private:
FileList();
typedef std::stack<std::string> Paths;
void searchDir(const std::string& dir, Paths& dirs);
bool isArgAFile();
void argIsDirectory();
private:
isMatchFunc matchfunc;
std::string m_argpath;
} ;
| ||
| ||
#include <string>
#include <iostream>
using namespace std;
#include "utxCommon.h"
#include "Library.h"
#include "ImageFile.h"
#include "ImageFileWrapper.h"
//------------------------------------------------------
class ImageFile::Private
{
public:
bool Load(const std::string& fn);
void invokeUnitTests();
private:
bool isOkUnitTest(char* p);
ostream& operator << (ostream& os);
void AssertFailed(const char* s);
void ThrewException(const unsigned int ex);
void ThrewUnknownException();
private:
string FQFileName;
ImageFileWrapper ifw;
char undecoratedName[512];
} ;
//------------------------------------------------------
ImageFile::ImageFile()
: m_impl(* new Private())
{
}
//------------------------------------------------------
ImageFile::~ImageFile()
{
delete &m_impl;
}
//------------------------------------------------------
void ImageFile::Run(const string& fn)
{
if (m_impl.Load(fn))
m_impl.invokeUnitTests();
}
//------------------------------------------------------
ostream& ImageFile::Private::operator << (ostream& os)
{
os << FQFileName << ": " << undecoratedName << " : ";
return os;
}
//------------------------------------------------------
void ImageFile::Private::AssertFailed(const char* s)
{
operator << (cout);
cout << "utxassert failed '" << s << "'" << endl;
}
//------------------------------------------------------
void ImageFile::Private::ThrewException(const unsigned int ex)
{
operator << (cout);
cout << "threw an exception: 0x" << hex << ex << dec << endl;
}
//------------------------------------------------------
void ImageFile::Private::ThrewUnknownException()
{
operator << (cout);
cout << "threw an unknown exception" << endl;
}
//------------------------------------------------------
bool ImageFile::Private::Load(const string& fn)
{
FQFileName = fn;
ifw.Load(FQFileName);
if (!ifw.isValid())
return false;
return ifw.loadExportTable();
}
//-----------------------------------------------------
void ImageFile::Private::invokeUnitTests()
{
Library lib(FQFileName);
for(ifw.reset(); !ifw.done(); ifw.next())
{
if (!isOkUnitTest(ifw.getDecoratedName()))
continue;
try
{
stats.numtestcases++;
lib.invokeFunctionAt(ifw.getOrdinal());
}
catch(char* s)
{
AssertFailed(s);
stats.numerrors++;
}
catch(unsigned int ex)
{
ThrewException(ex);
stats.numexcps++;
}
catch(int ex)
{
ThrewException(ex);
stats.numexcps++;
}
catch(SE_Exception& se)
{
ThrewException(se.ex);
stats.numexcps++;
}
catch(...)
{
ThrewUnknownException();
stats.numexcps++;
}
}
}
//-------------------------
int toint(const char* s)
{
int n;
for(n = 0; *s; ++s)
{
n = n * 10 + *s - '0';
}
return n;
}
////-------------------------
////must have a signature like:
//// void __stdcall f(void) => _Z5testfv@0
//// using namespace nmsp { void __stdcall f(void) } => _ZN4nmsp5testfEv@0
//bool ImageFile::Private::isOkUnitTest(char *p)
// {
// unsigned int i = 0;
// unsigned int j = 0;
//
//// if (p[i] != '_')
//// return false; //invalid or unknown decorated name
// //++i;
// //if (p[i] != 'Z')
// // return false; //invalid or unknown decorated name
// if (p[i] != '?')
// return false; //invalid or unknown decorated name
//
//
// char nlen[256];
// char nsname[256];
// ++i;
// if (p[i] == 'N') //it's a namespace
// {
// ++i;
// for (j = 0; isdigit(p[i]); ++i, ++j)
// {
// nlen[j] = p[i];
// }
// nlen[j] = 0;
// int n = toint(nlen);
// for (j = 0; n > 0; --n, ++i)
// {
// nsname[j] = p[i];
// }
// nsname[j] = 0;
// }
//
// //we're at the name
// for (j = 0; isdigit(p[i]); ++i, ++j)
// {
// nlen[j] = p[i];
// }
// nlen[j] = 0;
// int n = toint(nlen);
// for (j = 0; j < sizeof(undecoratedName) && n > 0; --n, ++i, ++j)
// {
// undecoratedName[j] = p[i];
// }
// undecoratedName[j] = 0;
//
// if (j >= sizeof(undecoratedName))
// return false; //func name > buf size... possible invalid or unknown decorated name
//
// if (strncmp(undecoratedName, cUTMethodPrefix.c_str(), cUTMethodPrefix.length()) != 0)
// return false;
//
// cout << "here: " << (char*) &p[i] << " : " << undecoratedName << "\n";
//
//// if (p[i] == 0)
//// return false; //invalid or unknown decorated name
////
//// ++i;
//// if (p[i] != 'Y')
//// return false; //invalid or unknown function type; if p[i] == 'Q' then it's a class
////
//// ++i;
//// if (p[i] != 'G')
//// return false; //not __stdcall calling convention
////
//// ++i;
//// if (p[i] != 'X')
//// return false; //not a void return call
////
//// ++i;
//// if (p[i] != 'X')
//// return false; //not a void parameter list
////
// return true;
// }
bool ImageFile::Private::isOkUnitTest(char *p)
{
unsigned int i = 0;
unsigned int j = 0;
if (p[0] != '?')
return false; //invalid or unknown decorated name
for(j = 0, ++i; j < sizeof(undecoratedName) && p[i] && p[i] != '@'; ++i, ++j)
{
undecoratedName[j] = p[i];
}
if (j >= sizeof(undecoratedName))
return false; //func name > buf size... possible invalid or unknown decorated name
if (strncmp(undecoratedName, cUTMethodPrefix.c_str(), cUTMethodPrefix.length()) != 0)
return false;
if (p[i] == 0)
return false; //invalid or unknown decorated name
undecoratedName[j] = 0;
++i; //skip @
//it can be a class name or a namespace here...
//if (p[i] && p[i] != '@')
// {
// return false; //it's a class method
// }
char nsname[256];
nsname[0] = 0;
if (p[i] && p[i] != '@')
{
//it's a class or a namespace...
for(j = 0, ++i; j < sizeof(nsname) && p[i] && p[i] != '@'; ++i, ++j)
{
nsname[j] = p[i];
}
nsname[j] = 0;
i++; //skip '@'
//return false; //it's a class method
}
++i;
if (p[i] != 'Y')
return false; //invalid or unknown function type; if p[i] == 'Q' then it's a class
++i;
if (p[i] != 'G')
return false; //not __stdcall calling convention
++i;
if (p[i] != 'X')
return false; //not a void return call
++i;
if (p[i] != 'X')
return false; //not a void parameter list
//++i;
//if (p[i] != 'Z')
// return false; //last char is a 'Z'
return true;
}
| ||
| ||
#pragma once
#include <string>
//-----------------------------------------------------
class SE_Exception
{
public:
unsigned int ex;
} ;
//------------------------------------------------------
class ImageFile
{
public:
ImageFile();
~ImageFile();
void Run(const std::string& fn);
private:
class Private;
Private& m_impl;
} ;
| ||
| ||
#include <iostream>
using std::cout;
using std::endl;
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX 1
#include <windows.h>
#include "utxCommon.h"
#include "ImageFileWrapper.h"
#include "MemoryMappedImageFile.h"
//-----------------------------------------------------
class SectionHeader
{
public:
//-----------------------------------------------------
SectionHeader& operator = (PIMAGE_SECTION_HEADER h)
{
header = h;
return *this;
}
//-----------------------------------------------------
bool isNull()
{
return header == 0;
}
//-----------------------------------------------------
DWORD getOffset(DWORD base)
{
return base - getDelta();
}
//-----------------------------------------------------
DWORD getDelta()
{
return (DWORD) (header->VirtualAddress - header->PointerToRawData);
}
//-----------------------------------------------------
PIMAGE_EXPORT_DIRECTORY getExportDir(DWORD base)
{
return MakePtr(PIMAGE_EXPORT_DIRECTORY, base, header->PointerToRawData);
}
//-----------------------------------------------------
PIMAGE_EXPORT_DIRECTORY getExportDir(DWORD base, DWORD tableVA)
{
return (PIMAGE_EXPORT_DIRECTORY) (base + tableVA - getDelta());
}
private:
PIMAGE_SECTION_HEADER header;
} ;
//-----------------------------------------------------
class DosHeaderPtr
{
public:
//-----------------------------------------------------
DosHeaderPtr()
: header(0)
{
}
//-----------------------------------------------------
PIMAGE_NT_HEADERS getNtHeader()
{
return MakePtr( PIMAGE_NT_HEADERS, header, header->e_lfanew );
}
//-----------------------------------------------------
operator DWORD()
{
return (DWORD) header;
}
//-----------------------------------------------------
DosHeaderPtr& operator = (PIMAGE_DOS_HEADER h)
{
header = h;
return *this;
}
//-----------------------------------------------------
bool isValidImage()
{
return !isNull() && isDosSignature();
}
private:
//-----------------------------------------------------
bool isNull()
{
return header == 0;
}
//-----------------------------------------------------
bool isDosSignature()
{
return header->e_magic == IMAGE_DOS_SIGNATURE;
}
private:
PIMAGE_DOS_HEADER header;
} ;
//-----------------------------------------------------
class NtHeaderPtr
{
public:
//-----------------------------------------------------
NtHeaderPtr() : header(0)
{
}
//-----------------------------------------------------
NtHeaderPtr& operator =(DosHeaderPtr& p)
{
header = p.getNtHeader();
return *this;
}
//-----------------------------------------------------
bool findExportTable(DWORD base, PIMAGE_EXPORT_DIRECTORY& exportDir, DWORD& offset)
{
SectionHeader sHeader;
sHeader = getSectionHeader(".edata");
if (!sHeader.isNull())
{
exportDir = sHeader.getExportDir(base);
offset = sHeader.getOffset(base);
return true;
}
DWORD tableVA = getExportTableVA();
if (tableVA == 0)
return false;
sHeader = getSectionHeader();
exportDir = sHeader.getExportDir(base, tableVA);
offset = sHeader.getOffset(base);
return true;
}
//-----------------------------------------------------
bool isValidSignature()
{
return !IsBadReadPtr(header, sizeof(IMAGE_NT_HEADERS)) && isNtSignature();
}
//-----------------------------------------------------
bool isValidExecutable()
{
return isCharacteristic(IMAGE_FILE_EXECUTABLE_IMAGE);
};
//-----------------------------------------------------
bool isValidDll()
{
return isCharacteristic(IMAGE_FILE_DLL);
}
private:
//-----------------------------------------------------
bool isCharacteristic(WORD ch)
{
PIMAGE_FILE_HEADER pImageFileHeader = (PIMAGE_FILE_HEADER)&header->FileHeader;
return (pImageFileHeader->Characteristics & ch) != 0;
};
//-----------------------------------------------------
DWORD getExportTableVA()
{
PIMAGE_OPTIONAL_HEADER optionalHeader = (PIMAGE_OPTIONAL_HEADER)&header->OptionalHeader;
return optionalHeader->DataDirectory[0].VirtualAddress;
}
//-----------------------------------------------------
PIMAGE_SECTION_HEADER getSectionHeader()
{
return getEnclosingSectionHeader(getExportTableVA());
}
//-----------------------------------------------------
static int icmp(const char* s1, const char* s2, int len)
{
for (int i = 0; i < len; ++i, ++s1, ++s2)
{
if (*s1 == 0 && *s2 == 0) return 0;
if (*s1 == 0) return -1;
if (*s2 == 0) return 1;
if (*s1 == *s2) continue;
if (*s1 < *s2) return -1;
return 1;
}
return 0;
}
//-----------------------------------------------------
PIMAGE_SECTION_HEADER getSectionHeader(PSTR name)
{
PIMAGE_SECTION_HEADER section = (PIMAGE_SECTION_HEADER)(header+1);
for (unsigned int i = 0; i < header->FileHeader.NumberOfSections; i++, section++ )
{
if ( icmp((const char*) section->Name, name, IMAGE_SIZEOF_SHORT_NAME) == 0 )
return section;
}
return 0;
}
//-----------------------------------------------------
PIMAGE_SECTION_HEADER getEnclosingSectionHeader(DWORD rva)
{
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(header);
for (unsigned i=0; i < header->FileHeader.NumberOfSections; i++, section++ )
{
// Is the RVA within this section?
if ( (rva >= section->VirtualAddress) &&
(rva < (section->VirtualAddress + section->Misc.VirtualSize)))
return section;
}
return 0;
}
//-----------------------------------------------------
bool isNtSignature()
{
return header->Signature == IMAGE_NT_SIGNATURE ;
}
private:
PIMAGE_NT_HEADERS header;
} ;
//-----------------------------------------------------
class ExportTable
{
public:
//-----------------------------------------------------
ExportTable()
: pDirectory(0), offset(0), functions(0), ordinals(0), name(0)
{
}
//-----------------------------------------------------
bool done()
{
return current >= pDirectory->NumberOfNames;
}
//-----------------------------------------------------
void reset()
{
current = 0;
}
//-----------------------------------------------------
void next()
{
current++;
name++; // Bump each pointer to the next array element
ordinals++;
functions++;
}
//-----------------------------------------------------
DWORD getOrdinal()
{
return *ordinals + pDirectory->Base;
}
//-----------------------------------------------------
char * getDecoratedName()
{
return *name + offset;
}
//-----------------------------------------------------
bool Load(NtHeaderPtr& ntHeader, DosHeaderPtr& dosHeader)
{
if (! ntHeader.findExportTable(dosHeader, pDirectory, offset))
return false;
functions = (PDWORD)((DWORD)pDirectory->AddressOfFunctions + offset);
ordinals = (PWORD)((DWORD)pDirectory->AddressOfNameOrdinals + offset);
name = (PSTR*)((DWORD)pDirectory->AddressOfNames + offset);
return true;
}
private:
PIMAGE_EXPORT_DIRECTORY pDirectory;
DWORD offset;
PDWORD functions;
PWORD ordinals;
PSTR* name;
DWORD current;
} ;
//-----------------------------------------------------
class ImageFileWrapper::Private
{
public:
ExportTable exportTable;
MemoryMappedImageFile mmifile;
//-----------------------------------------------------
bool loadExportTable()
{
return exportTable.Load(pNtHeader, pDosHeader);
}
//-----------------------------------------------------
void setHeaders()
{
pDosHeader = mmifile.getHeader();
pNtHeader = pDosHeader;
}
//-----------------------------------------------------
bool isValid()
{
if (!pDosHeader.isValidImage())
{
cout << "Unrecognized file format, expecting a DLL" << endl;
return false;
}
if (!pNtHeader.isValidSignature())
{
cout << "Unhandled EXE type, or invalid .EXE" << endl;
return false;
}
if (!pNtHeader.isValidExecutable())
{
cout << "File is not an executable image!" << endl;
return false;
}
if (!pNtHeader.isValidDll())
{
cout << "File is not a DLL!" << endl;
return false;
}
return true;
}
private:
DosHeaderPtr pDosHeader;
NtHeaderPtr pNtHeader;
} ;
//-----------------------------------------------------
ImageFileWrapper::ImageFileWrapper()
: pimpl(* new Private)
{
}
//-----------------------------------------------------
ImageFileWrapper::~ImageFileWrapper()
{
delete &pimpl;
}
//-----------------------------------------------------
bool ImageFileWrapper::loadExportTable()
{
return pimpl.loadExportTable();
}
//-----------------------------------------------------
void ImageFileWrapper::Load(const string& fn)
{
if (!pimpl.mmifile.Load(fn))
return;
cout << "Loading file " << fn << "..." << endl;;
pimpl.setHeaders();
}
//-----------------------------------------------------
bool ImageFileWrapper::isValid()
{
return pimpl.isValid();
}
//-----------------------------------------------------
void ImageFileWrapper::reset()
{
pimpl.exportTable.reset();
}
//-----------------------------------------------------
bool ImageFileWrapper::done()
{
return pimpl.exportTable.done();
}
//-----------------------------------------------------
void ImageFileWrapper::next()
{
pimpl.exportTable.next();
}
//-----------------------------------------------------
char* ImageFileWrapper::getDecoratedName()
{
return pimpl.exportTable.getDecoratedName();
}
//-----------------------------------------------------
DWORD ImageFileWrapper::getOrdinal()
{
return pimpl.exportTable.getOrdinal();
}
| ||
| ||
#pragma once
#include <string>
using std::string;
//------------------------------------------------------
class ImageFileWrapper
{
public:
ImageFileWrapper();
~ImageFileWrapper();
bool loadExportTable();
void Load(const string& fn);
bool isValid();
void reset();
bool done();
void next();
char * getDecoratedName();
DWORD getOrdinal();
private:
class Private;
Private& pimpl;
} ;
| ||
| ||
#include <string>
#include <iostream>
using namespace std;
#include "utxCommon.h"
#include "Library.h"
//-----------------------------------------------------
Library::Library(const string& fn)
: m_fileName(fn)
{
}
//-----------------------------------------------------
Library::~Library()
{
}
//-----------------------------------------------------
void Library::invokeFunctionAt(DWORD ordinal)
{
typedef void (*VVFUNCP)();
VVFUNCP fp = (VVFUNCP) getAddress(ordinal);
if (fp)
fp();
}
//-----------------------------------------------------
FARPROC Library::getAddress(DWORD ordinal)
{
if (!m_handle.create(m_fileName))
{
cout << "here " << m_fileName << " : " << ordinal << " : " << ::GetLastError() << "\n";
return 0;
}
return ::GetProcAddress(m_handle, (LPCSTR) (0x0000FFFF & ordinal));
}
| ||
| ||
#pragma once
#include <string>
#include "NtHandles.h"
//-----------------------------------------------------
class Library
{
public:
Library(const std::string& fn);
~Library();
void invokeFunctionAt(DWORD ordinal);
private:
Library();
FARPROC getAddress(DWORD ordinal);
private:
NtLibraryHandle m_handle;
std::string m_fileName;
} ;
| ||
| ||
#include <string>
#include <iostream>
using namespace std;
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX 1
#include <windows.h>
#include "utxCommon.h"
#include "MemoryMappedImageFile.h"
#include "NtHandles.h"
//-----------------------------------------------------
class MemoryMappedImageFile::Private
{
public:
NtFileHandle hFile;
NtFileMappingHandle hFileMapping;
NtMappedFileViewHandle hFileView;
} ;
//-----------------------------------------------------
MemoryMappedImageFile::MemoryMappedImageFile()
: m_impl(* new Private())
{
}
//-----------------------------------------------------
MemoryMappedImageFile::~MemoryMappedImageFile()
{
delete &m_impl;
}
//------------------------------------------------------
bool MemoryMappedImageFile::Load(const string& fn)
{
if (!m_impl.hFile.create(fn.c_str()))
{
cout << "Couldn't open file with CreateFile(), gle=" << GetLastError() << " : " << fn.c_str() << endl;
return false;
}
if (!m_impl.hFileMapping.create(m_impl.hFile))
{
cout << "Couldn't open file mapping with CreateFileMapping()" << endl;
return false;
}
if (!m_impl.hFileView.create(m_impl.hFileMapping))
{
cout << "Couldn't map view of file with MapViewOfFile()" << endl;
return false;
}
return true;
}
//-----------------------------------------------------
PIMAGE_DOS_HEADER MemoryMappedImageFile::getHeader()
{
return (PIMAGE_DOS_HEADER) (LPVOID) m_impl.hFileView;
}
| ||
| ||
#pragma once
#include <string>
using std::string;
//-----------------------------------------------------
class MemoryMappedImageFile
{
public:
MemoryMappedImageFile();
~MemoryMappedImageFile();
bool Load(const std::string& fn);
PIMAGE_DOS_HEADER getHeader();
private:
class Private;
Private& m_impl;
} ;
| ||
| ||
#pragma once
#include <windows.h>
//-----------------------------------------------------
template <typename tTrait>
class NtHandleImpl
{
protected:
typename tTrait::HandleType h;
bool isInvalid() { return h == tTrait::BadValue(); }
public:
NtHandleImpl()
: h(tTrait::BadValue())
{
}
~NtHandleImpl()
{
if (isInvalid())
return;
tTrait::Cleanup(h);
h = tTrait::BadValue();
}
bool create(typename tTrait::CreateParmType p)
{
if (isInvalid())
h = tTrait::create(p);
return !isInvalid();
}
operator typename tTrait::HandleType()
{
return h;
}
} ;
//------------------------------------------------------
//-- Used for Nt Files in general
class NtFileHandleTrait
{
public:
typedef HANDLE HandleType;
typedef string CreateParmType;
static HandleType BadValue() { return INVALID_HANDLE_VALUE; }
static void Cleanup(HandleType h) { CloseHandle(h); }
static HandleType create(CreateParmType& fn)
{
return ::CreateFile(fn.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
}
} ;
typedef NtHandleImpl<NtFileHandleTrait> NtFileHandle;
//------------------------------------------------------
//-- Used for Nt Memory Mapped Files
class NtFileMappingHandleTrait
{
public:
typedef HANDLE HandleType;
typedef HANDLE CreateParmType;
static HandleType BadValue() { return 0; }
static void Cleanup(HandleType h) { CloseHandle(h); }
static HandleType create(CreateParmType& hfile)
{
return ::CreateFileMapping(hfile, NULL, PAGE_READONLY, 0, 0, NULL);
}
} ;
typedef NtHandleImpl<NtFileMappingHandleTrait> NtFileMappingHandle;
//------------------------------------------------------
//-- Used for Nt Memory Mapped Files
class NtMappedFileViewHandleTrait
{
public:
typedef LPVOID HandleType;
typedef HANDLE CreateParmType;
static HandleType BadValue() { return 0; }
static void Cleanup(HandleType h) { UnmapViewOfFile(h); }
static HandleType create(CreateParmType& hfilemap)
{
return ::MapViewOfFile(hfilemap, FILE_MAP_READ, 0, 0, 0);
}
} ;
typedef NtHandleImpl<NtMappedFileViewHandleTrait> NtMappedFileViewHandle;
//------------------------------------------------------
//-- Used for Nt FileFind operations
typedef pair<string, WIN32_FIND_DATA*> FileFindPair;
class NtFileFindHandleTrait
{
public:
typedef HANDLE HandleType;
typedef FileFindPair CreateParmType;
static HandleType BadValue() { return INVALID_HANDLE_VALUE; }
static void Cleanup(HandleType h) { FindClose(h); }
static HandleType create(CreateParmType& cpt)
{
return ::FindFirstFile(cpt.first.c_str(), cpt.second);
}
} ;
class NtFileFindHandle : public NtHandleImpl<NtFileFindHandleTrait>
{
public:
bool next(NtFileFindHandleTrait::CreateParmType& cpt)
{
return ::FindNextFile(h, cpt.second) == TRUE;
}
} ;
//------------------------------------------------------
//-- Used for Nt DLL Libraries
class NtLibraryHandleTrait
{
public:
typedef HMODULE HandleType;
typedef string CreateParmType;
static HandleType BadValue() { return 0; }
static void Cleanup(HandleType h) { ::FreeLibrary(h); }
static HandleType create(CreateParmType& fn)
{
return ::LoadLibrary(fn.c_str());
}
} ;
typedef NtHandleImpl<NtLibraryHandleTrait> NtLibraryHandle;
| ||
| ||
#include "utxCommon.h"
#include <iostream>
using namespace std;
//--------------------------------------------
Statistics::Statistics()
{
numfiles = 0;
numtestcases = 0;
numasserts = 0;
numerrors = 0;
numexcps = 0;
}
//--------------------------------------------
void Statistics::dump()
{
cout << endl
<< "Number of unit tests : " << numfiles << endl
<< "Number of test methods : " << numtestcases << endl
<< "Number of assert calls : " << numasserts << endl
<< "Number of errors : " << numerrors << endl
<< "Number of exceptions : " << numexcps << endl;
if (numerrors != 0 || numexcps != 0)
cout << "************* FAILED *** FAILED *** FAILED *************" << endl;
}
| ||
| ||
#pragma once
class Statistics
{
public:
int numfiles;
int numtestcases;
int numasserts;
int numerrors;
int numexcps;
Statistics();
void dump();
} ;
| ||
| ||
UTXASSERTFUNC RCDATA BEGIN "XXXX" END | ||
| ||
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX 1
#include <windows.h>
#include "utxCommon.h"
#include "App.h"
Statistics stats;
//-----------------------------------------------------
int main(int argc, char *argv[])
{
int rc = 0;
try
{
App theApp;
theApp.Init(argc, argv);
theApp.Run();
stats.dump();
rc = stats.numerrors + stats.numexcps;
}
catch (int badrc)
{
rc = badrc;
}
return rc;
}
| ||
| ||
#pragma once #include "Statistics.h" #define MakePtr( cast, ptr, addValue ) ((cast)( (DWORD)(ptr) + (DWORD)(addValue) )) extern Statistics stats; #include <string> using std::string; extern string cUTFilePrefix; extern string cUTFileSuffix; extern string cUTMethodPrefix; extern string cUTMethodSuffix; | ||
| ||
#define DEFINEUTXTEST
#include "\projects\include\utx.h"
//once with ansi
namespace ns_ansi
{
#include "testunicodebase.cpp"
}
__declspec(dllexport) class xxbob2
{
public:
TEST(unicode_normal_notsubstring_vrbl)
{
utxBoolAssert(false);
}
} ;
| ||
| ||
//#define DEFINEUTXTEST
//#include "\projects\include\utx.h"
//#include "\projects\include\utxcom.h"
//
////BSTR
//TEST(normal_bstr_vrbl)
// {
// BSTR v1 = SysAllocString(L"abc");
// BSTR v2 = SysAllocString(L"abc");
// BSTR v3 = SysAllocString(L"abcx");
// utxassert(v1, v2);
// utxassert2(v1, v2, "with a message");
//
// _utxAssertNextAssertFails();
// utxassert(v1, v3);
// _utxAssertNextAssertFails();
// utxassert2(v1, v3, "with a message");
//
// SysFreeString(v1);
// SysFreeString(v2);
// SysFreeString(v3);
// }
//
//TEST(normal_notbstr_vrbl)
//{
// BSTR v1 = SysAllocString(L"abc");
// BSTR v2 = SysAllocString(L"abcx");
// BSTR v3 = SysAllocString(L"abc");
//
// utxassertnot(v1, v2);
// utxassertnot2(v1, v2, "with a message");
//
// _utxAssertNextAssertFails();
// utxassertnot(v1, v3);
// _utxAssertNextAssertFails();
// utxassertnot2(v1, v3, "with a message");
// SysFreeString(v1);
// SysFreeString(v2);
// SysFreeString(v3);
// }
//
//TEST(normal_bstr_t_vrbl)
// {
// _bstr_t v1 = "abc";
// _bstr_t v2 = "abc";
// _bstr_t v3 = "abcx";
// utxassert(v1, v2);
// utxassert2(v1, v2, "with a message");
//
// _utxAssertNextAssertFails();
// utxassert(v1, v3);
// _utxAssertNextAssertFails();
// utxassert2(v1, v3, "with a message");
// }
//
| ||
| ||
#define DEFINEUTXTEST
#define UNICODE 1
#define _UNICODE 1
#include "\projects\include\utx.h"
//once with unicode
namespace ns_unicode
{
#include "testunicodebase.cpp"
}
class xxbob
{
public:
TEST(unicode_normal_notsubstring_vrbl)
{
utxBoolAssert(false);
}
} ;
| ||
| ||
//NO #PRAGMA ONCE!
//bool ------------------------------------------------------------------
TEST(bool_literal)
{
utxBoolAssert(true || true);
utxBoolAssert2(true || false, _T("with a message"));
_utxAssertNextAssertFails();
utxBoolAssert(false || false);
_utxAssertNextAssertFails();
utxBoolAssert2(false && true, _T("with a message"));
}
TEST(notbool_literal)
{
utxBoolAssertNot(false && true);
utxBoolAssertNot2(false && false, _T("with a message"));
_utxAssertNextAssertFails();
utxBoolAssertNot(true || true);
_utxAssertNextAssertFails();
utxBoolAssertNot2(true || false, _T("with a message"));
}
TEST(bool_vrbl)
{
bool v1 = true;
bool v2 = false;
utxBoolAssert(v1);
utxBoolAssert2(v1, _T("with a message"));
_utxAssertNextAssertFails();
utxBoolAssert(v2);
_utxAssertNextAssertFails();
utxBoolAssert2(v2, _T("with a message"));
_utxAssertNextAssertFails();
utxBoolAssert2(v1 && v2, _T("with a message"));
}
TEST(notbool_vrbl)
{
bool v1 = false;
bool v2 = true;
utxBoolAssertNot(v1);
utxBoolAssertNot2(v1, _T("with a message"));
_utxAssertNextAssertFails();
utxBoolAssertNot(v2);
_utxAssertNextAssertFails();
utxBoolAssertNot2(v2, _T("with a message"));
_utxAssertNextAssertFails();
utxBoolAssertNot2(v1 || v2, _T("with a message"));
}
//TCHAR* ------------------------------------------------------------------
TEST(charstar_literal)
{
utxassert(_T("abc"), _T("abc"));
utxassert2(_T("abc"), _T("abc"), _T("with a message"));
//utxassert2(_T("abc"), _T("abc"), "with a message");
_utxAssertNextAssertFails();
utxassert(_T("abc"), _T("abcx"));
_utxAssertNextAssertFails();
utxassert2(_T("abc"), _T("abcx"), _T("with a message"));
}
TEST(notcharstar_literal)
{
utxassertnot(_T("abc"), _T("abcx"));
utxassertnot2(_T("abc"), _T("abcx"), _T("with a message"));
_utxAssertNextAssertFails();
utxassertnot(_T("abc"), _T("abc"));
_utxAssertNextAssertFails();
utxassertnot2(_T("abc"), _T("abc"), _T("with a message"));
}
TEST(charstar_vrbl)
{
TCHAR* v1 = _T("abc");
TCHAR* v2 = _T("abc");
TCHAR* v3 = _T("abcx");
utxassert(v1, v2);
utxassert2(v1, v2, _T("with a message"));
_utxAssertNextAssertFails();
utxassert(v1, v3);
_utxAssertNextAssertFails();
utxassert2(v1, v3, _T("with a message"));
}
TEST(notcharstar_vrbl)
{
TCHAR* v1 = _T("abc");
TCHAR* v2 = _T("abcx");
TCHAR* v3 = _T("abc");
utxassertnot(v1, v2);
utxassertnot2(v1, v2, _T("with a message"));
_utxAssertNextAssertFails();
utxassertnot(v1, v3);
_utxAssertNextAssertFails();
utxassertnot2(v1, v3, _T("with a message"));
}
//tchar[] ------------------------------------------------------------------
TEST(charbuf_vrbl)
{
TCHAR v1[] = _T("abc");
TCHAR v2[] = _T("abc");
TCHAR v3[] = _T("abcx");
utxassert(v1, v2);
utxassert2(v1, v2, _T("with a message"));
_utxAssertNextAssertFails();
utxassert(v1, v3);
_utxAssertNextAssertFails();
utxassert2(v1, v3, _T("with a message"));
}
TEST(notcharbuf_vrbl)
{
TCHAR v1[] = _T("abc");
TCHAR v2[] = _T("abcx");
TCHAR v3[] = _T("abc");
utxassertnot(v1, v2);
utxassertnot2(v1, v2, _T("with a message"));
_utxAssertNextAssertFails();
utxassertnot(v1, v3);
_utxAssertNextAssertFails();
utxassertnot2(v1, v3, _T("with a message"));
}
//substring ------------------------------------------------------------------
TEST(substring_literal)
{
utxAssertStringContains(_T("abcd"), _T("bc"));
utxAssertStringContains2(_T("abcd"), _T("bc"), _T("with a message"));
utxAssertStringContains(_T("abcd"), _T("a"));
utxAssertStringContains(_T("abcd"), _T("d"));
utxAssertStringContains(_T("abcd"), _T("")); //every string contains the empty string
utxAssertStringContains(_T("abcd"), _T("abcd")); //every string contains itself
_utxAssertNextAssertFails();
utxAssertStringContains(_T("abcd"), _T("x"));
_utxAssertNextAssertFails();
utxAssertStringContains2(_T("abcd"), _T("x"), _T("with a message"));
_utxAssertNextAssertFails();
utxAssertStringContains(_T("abcd"), _T("xabcdx"));
}
TEST(notsubstring_literal)
{
utxAssertStringContainsNot(_T("abcd"), _T("bx"));
utxAssertStringContainsNot2(_T("abcd"), _T("bx"), _T("with a message"));
utxAssertStringContainsNot(_T("abcd"), _T("x"));
utxAssertStringContainsNot(_T("abcd"), _T("x"));
_utxAssertNextAssertFails();
utxAssertStringContainsNot(_T("abcd"), _T("bc"));
_utxAssertNextAssertFails();
utxAssertStringContainsNot2(_T("abcd"), _T("bc"), _T("with a message"));
_utxAssertNextAssertFails();
utxAssertStringContainsNot(_T("abcd"), _T(""));
_utxAssertNextAssertFails();
utxAssertStringContainsNot(_T("abcd"), _T("abcd"));
}
TEST(substring_vrbl)
{
tstring v1 = _T("abcd");
tstring v2 = _T("bc");
utxAssertStringContains(v1, v2);
utxAssertStringContains2(v1, v2, _T("with a message"));
tstring v3 = _T("a");
tstring v4 = _T("d");
utxAssertStringContains(v1, v3);
utxAssertStringContains(v1, v4);
tstring v5 = _T("");
utxAssertStringContains(v1, v5); //every string contains the empty string
tstring v6;
utxAssertStringContains(v1, v6); //every string contains the empty string
tstring v7 = v1;
utxAssertStringContains(v1, v7); //every string contains itself
tstring v8 = _T("x");
_utxAssertNextAssertFails();
utxAssertStringContains(v1, v8);
_utxAssertNextAssertFails();
utxAssertStringContains2(v1, v8, _T("with a message"));
_utxAssertNextAssertFails();
tstring v9 = _T("xabcdx");
utxAssertStringContains(v1, v9);
}
TEST(notsubstring_vrbl)
{
tstring v1 = _T("abcd");
tstring v2 = _T("bx");
utxAssertStringContainsNot(v1, v2);
utxAssertStringContainsNot2(v1, v2, _T("with a message"));
tstring v3 = _T("x");
utxAssertStringContainsNot(v1, v3);
tstring v9 = _T("xabcdx");
utxAssertStringContainsNot(v1, v9);
tstring v8 = _T("b");
_utxAssertNextAssertFails();
utxAssertStringContainsNot(v1, v8);
_utxAssertNextAssertFails();
utxAssertStringContainsNot2(v1, v8, _T("with a message"));
_utxAssertNextAssertFails();
tstring v5 = _T("");
utxAssertStringContainsNot(v1, v5); //every string contains the empty string
_utxAssertNextAssertFails();
tstring v6;
utxAssertStringContainsNot(v1, v6); //every string contains the empty string
_utxAssertNextAssertFails();
tstring v7 = v1;
utxAssertStringContainsNot(v1, v7); //every string contains itself
}
//tstring ------------------------------------------------------------------
TEST(tstring_literal)
{
utxassert(tstring(_T("abc")), tstring(_T("abc")));
utxassert2(tstring(_T("abc")), tstring(_T("abc")), _T("with a message"));
_utxAssertNextAssertFails();
utxassert(tstring(_T("abc")), tstring(_T("abcx")));
_utxAssertNextAssertFails();
utxassert2(tstring(_T("abc")), tstring(_T("abcx")), _T("with a message"));
}
TEST(nottstring_literal)
{
utxassertnot(tstring(_T("abc")), tstring(_T("abcx")));
utxassertnot2(tstring(_T("abc")), tstring(_T("abcx")), _T("with a message"));
_utxAssertNextAssertFails();
utxassertnot(tstring(_T("abc")), tstring(_T("abc")));
_utxAssertNextAssertFails();
utxassertnot2(tstring(_T("abc")), tstring(_T("abc")), _T("with a message"));
}
TEST(tstring_vrbl)
{
tstring v1 = _T("abc");
tstring v2 = _T("abc");
tstring v3 = _T("abcx");
utxassert(v1, v2);
utxassert2(v1, v2, _T("with a message"));
_utxAssertNextAssertFails();
utxassert(v1, v3);
_utxAssertNextAssertFails();
utxassert2(v1, v3, _T("with a message"));
}
TEST(nottstring_vrbl)
{
tstring v1 = _T("abc");
tstring v2 = _T("abcx");
tstring v3 = _T("abc");
utxassertnot(v1, v2);
utxassertnot2(v1, v2, _T("with a message"));
_utxAssertNextAssertFails();
utxassertnot(v1, v3);
_utxAssertNextAssertFails();
utxassertnot2(v1, v3, _T("with a message"));
}
//integral types ------------------------------------------------------------------
#define TEST1_INTEGRALTYPE(name, type, val1, val2) \
TEST(name##_literal) \
{ \
utxassert((type) val1, (type) val1); \
utxassert2((type) val1, (type) val1, _T("with a message")); \
_utxAssertNextAssertFails(); \
utxassert((type) val1, (type) val2); \
_utxAssertNextAssertFails(); \
utxassert2((type) val1, (type) val2, _T("with a message")); \
}
#define TEST2_INTEGRALTYPE(name, type, val1, val2) \
TEST(name##_literal_not) \
{ \
utxassertnot((type) val1, (type) val2); \
utxassertnot2((type) val1, (type) val2, _T("with a message")); \
_utxAssertNextAssertFails(); \
utxassertnot((type) val1, (type) val1); \
_utxAssertNextAssertFails(); \
utxassertnot2((type) val1, (type) val1, _T("with a message")); \
}
#define TEST3_INTEGRALTYPE(name, type, val1, val2) \
TEST(name##_vrbl) \
{ \
type v1 = (type) val1; \
type v2 = (type) val1; \
type v3 = (type) val2; \
utxassert(v1, v2); \
utxassert2(v1, v2, _T("with a message")); \
_utxAssertNextAssertFails(); \
utxassert(v1, v3); \
_utxAssertNextAssertFails(); \
utxassert2(v1, v3, _T("with a message")); \
}
#define TEST4_INTEGRALTYPE(name, type, val1, val2) \
TEST(name##_vrbl_not) \
{ \
type v1 = (type) val1; \
type v2 = (type) val2; \
type v3 = (type) val1; \
utxassertnot(v1, v2); \
utxassertnot2(v1, v2, _T("with a message")); \
_utxAssertNextAssertFails(); \
utxassertnot(v1, v3); \
_utxAssertNextAssertFails(); \
utxassertnot2(v1, v3, _T("with a message")); \
}
//long ------------------------------------------------------------------
TEST1_INTEGRALTYPE(slong, long, 0x7FFFFFF, 0x7FFFFFE);
TEST2_INTEGRALTYPE(slong, long, -1, -2);
TEST3_INTEGRALTYPE(slong, long, 0xFFFFFFFF, 0xFFFFFFFE);
TEST4_INTEGRALTYPE(slong, long, 0xFFFFFFFF, 0xFFFFFFFE);
//unsigned long ------------------------------------------------------------------
TEST1_INTEGRALTYPE(ulong, unsigned long, 0x7FFFFFF, 0x7FFFFFE);
TEST2_INTEGRALTYPE(ulong, unsigned long, 0xFFFFFFF, 0xFFFFFFE);
TEST3_INTEGRALTYPE(ulong, unsigned long, -1, -2);
TEST4_INTEGRALTYPE(ulong, unsigned long, 23, 24);
//int ------------------------------------------------------------------
TEST1_INTEGRALTYPE(sint, int, 0x7FFFFFF, 0x7FFFFFE);
TEST2_INTEGRALTYPE(sint, int, -1, -2);
TEST3_INTEGRALTYPE(sint, int, 0xFFFFFFFF, 0xFFFFFFFE);
TEST4_INTEGRALTYPE(sint, int, 0xFFFFFFFF, 0xFFFFFFFE);
//unsigned int ------------------------------------------------------------------
TEST1_INTEGRALTYPE(uint, unsigned int, 0x7FFFFFF, 0x7FFFFFE);
TEST2_INTEGRALTYPE(uint, unsigned int, 0xFFFFFFF, 0xFFFFFFE);
TEST3_INTEGRALTYPE(uint, unsigned int, -1, -2);
TEST4_INTEGRALTYPE(uint, unsigned int, 23, 24);
//short ------------------------------------------------------------------
TEST1_INTEGRALTYPE(sshort, short, 0x7FFF, 0x7FFE);
TEST2_INTEGRALTYPE(sshort, short, -1, -2);
TEST3_INTEGRALTYPE(sshort, short, 0x7FFF, 0x7FFE);
TEST4_INTEGRALTYPE(sshort, short, 0x7FFF, 0x7FFE);
//unsigned short ------------------------------------------------------------------
TEST1_INTEGRALTYPE(ushort, unsigned short, 0x7FFF, 0x7FFE);
TEST2_INTEGRALTYPE(ushort, unsigned short, 0xFFFF, 0xFFFE);
TEST3_INTEGRALTYPE(ushort, unsigned short, -1, -2);
TEST4_INTEGRALTYPE(ushort, unsigned short, 23, 24);
////__int64 ------------------------------------------------------------------
//TEST1_INTEGRALTYPE(i64, __int64, 0x7FFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFE);
TEST2_INTEGRALTYPE(i64, __int64, 0xFFFFFFF, 0xFFFFFFE);
TEST3_INTEGRALTYPE(i64, __int64, -1, -2);
TEST4_INTEGRALTYPE(i64, __int64, 23, 24);
////long long ------------------------------------------------------------------
//TEST1_INTEGRALTYPE(i64, long long int, 0x7FFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFE);
//TEST2_INTEGRALTYPE(i64, long long, 0xFFFFFFF, 0xFFFFFFE);
//TEST3_INTEGRALTYPE(i64, long long, -1, -2);
//TEST4_INTEGRALTYPE(i64, long long, 23, 24);
//double ------------------------------------------------------------------
TEST(double_literal)
{
utxDoubleAssert(23.0, 23.0, 0.001);
utxDoubleAssert2(23.0, 23.0, 0.001, _T("with a message"));
_utxAssertNextAssertFails();
utxDoubleAssert(23.0, 24.0, 0.001);
_utxAssertNextAssertFails();
utxDoubleAssert2(23.0, 24.0, 0.001, _T("with a message"));
utxDoubleAssert(23.0009, 23.0, 0.001);
_utxAssertNextAssertFails();
utxDoubleAssert(23.0009, 23.0, 0.0001);
}
TEST(notdouble_literal)
{
utxDoubleAssertNot(23.0, 24.0, 0.001);
utxDoubleAssertNot2(23.0, 24.0, 0.001, _T("with a message"));
_utxAssertNextAssertFails();
utxDoubleAssertNot(23.0, 23.0, 0.001);
_utxAssertNextAssertFails();
utxDoubleAssertNot2(23.0, 23.0, 0.001, _T("with a message"));
utxDoubleAssertNot(23.0009, 23.0, 0.0001);
_utxAssertNextAssertFails();
utxDoubleAssertNot(23.0009, 23.0, 0.001);
}
TEST(double_vrbl)
{
double v1 = 23.0;
double v2 = 23.0;
double v3 = 24.0;
double v4 = 23.0009;
utxDoubleAssert(v1, v2, 0.001);
utxDoubleAssert2(v1, v2, 0.001, _T("with a message"));
_utxAssertNextAssertFails();
utxDoubleAssert(v1, v3, 0.001);
_utxAssertNextAssertFails();
utxDoubleAssert2(v1, v3, 0.001, _T("with a message"));
utxDoubleAssert(v4, v1, 0.001);
_utxAssertNextAssertFails();
utxDoubleAssert(v4, v1, 0.0001);
}
TEST(notdouble_vrbl)
{
double v1 = 23.0;
double v2 = 24.0;
double v3 = 23.0;
double v4 = 23.0009;
utxDoubleAssertNot(v1, v2, 0.001);
utxDoubleAssertNot2(v1, v2, 0.001, _T("with a message"));
_utxAssertNextAssertFails();
utxDoubleAssertNot(v1, v3, 0.001);
_utxAssertNextAssertFails();
utxDoubleAssertNot2(v1, v3, 0.001, _T("with a message"));
utxDoubleAssertNot(v4, v1, 0.0001);
_utxAssertNextAssertFails();
utxDoubleAssertNot(v4, v1, 0.001);
}
| ||
| ||
#define DEFINEUTXTEST
#define DEFINENEXTASSERTFAILS
#define CRTMEMDEBUG
#include "d:/projects/include/utx.h"
#if defined(UNICODE) || defined(_UNICODE)
#error "Turn off UNICODE!"
#endif
UTXDLLMAIN_CHECKLEAKS(-1);
TEST(crt_leaks)
{
int* x = new int;
x = 0;
//you will see a report on standard output
}
//void*
TEST(ptr)
{
void* p = 0;
utxAssertPtrIsNull(p);
utxAssertPtrIsNull2(p, "a message");
p = (void*) 1;
_utxAssertNextAssertFails();
utxAssertPtrIsNull(p);
_utxAssertNextAssertFails();
utxAssertPtrIsNull2(p, "a message");
}
TEST(ptr_not)
{
void* p = (void*) 1;
utxAssertPtrIsNotNull(p);
utxAssertPtrIsNotNull2(p, "a message");
p = 0;
_utxAssertNextAssertFails();
utxAssertPtrIsNotNull(p);
_utxAssertNextAssertFails();
utxAssertPtrIsNotNull2(p, "a message");
}
|
| Contact me about content on this page using john_web-at-arrizza-dot-com |
| For Web Master or site problems contact: webadmin-at-arrizza-dot-com |
| Copyright John Arrizza (c) 2001,2002,2003,2004,2005,2006,2007 |