|
// A very-very basic CRT lib.
#include "MiniCRT.h"
#if MINICRT_ENABLED
#include <intrin.h>
#pragma intrinsic(__movsb)
int __cdecl printf(const char* format, ...)
{
int len, max_len;
DWORD written;
char buf[0x100];
va_list args;
va_start(args, format);
len = wvsprintfA(buf, format, args);
va_end(args);
max_len = (int)sizeof(buf)-1;
len = len < max_len ? len : max_len;
buf[len] = 0;
WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), buf, (DWORD)len, &written, NULL);
return len;
}
void* __cdecl operator new(size_t size)
{
void* p = LocalAlloc(LMEM_FIXED, (SIZE_T)size);
ASSERT(p);
return p;
}
void __cdecl operator delete(void* p)
{
if (p)
VERIFY_FALSE(LocalFree((HLOCAL)p));
}
#pragma section(".CRT$XCA",long,read)
#pragma data_seg(push, crtxc, ".CRT$XCA")
CrtInitFunc __static_init_func_array_begin[] = { 0 };
#pragma data_seg(pop, crtxc)
#pragma section(".CRT$XCZ",long,read)
#pragma data_seg(push, crtxc, ".CRT$XCZ")
CrtInitFunc __static_init_func_array_end[] = { 0 };
#pragma data_seg(pop, crtxc)
static void StaticInitialization()
{
for (CrtInitFunc* pinit_func=__static_init_func_array_begin+1; pinit_func<__static_init_func_array_end; ++pinit_func)
{
if (*pinit_func)
(*pinit_func)();
}
}
// TODO
static CrtInitFunc* g_AtExit = NULL;
static size_t g_AtExitCapacity = 0;
static size_t g_AtExitCount = 0;
static void StaticDeinitialization()
{
for (size_t i=g_AtExitCount; i--; )
g_AtExit[i]();
delete[] g_AtExit;
}
int __cdecl atexit(CrtInitFunc func)
{
if (!func)
return 0;
if (g_AtExitCount >= g_AtExitCapacity)
{
g_AtExitCapacity = g_AtExitCapacity ? g_AtExitCapacity*2 : 1;
CrtInitFunc* new_atexits = new CrtInitFunc[g_AtExitCapacity];
if (g_AtExitCount)
{
__movsb((unsigned char*)new_atexits, (unsigned char*)g_AtExit, g_AtExitCount*sizeof(CrtInitFunc));
delete[] g_AtExit;
}
g_AtExit = new_atexits;
}
g_AtExit[g_AtExitCount++] = func;
return 0;
}
#if ASSERT_ACTIVE
void __assert(const char* condition, const char* file, int line, const char* function)
{
printf("%s(%d) in function %s: ASSERTION FAILED: %s\n", file, line, function, condition);
char buf[0x100];
wsprintfA(buf, "file: %s\nline: %d\nfunction: %s\n\nASSERT(%s)\n\nYes==break No==Continue", file, line, function, condition);
if (IDYES == MessageBoxA(NULL, buf, "ASSERTION FAILED!", MB_YESNO|MB_ICONEXCLAMATION))
__debugbreak();
}
#endif
int __cdecl _purecall()
{
printf("Pure virtual function call!\n");
MessageBoxA(NULL, "Pure virtual function call!", "Runtime error!", MB_OK|MB_ICONEXCLAMATION);
__debugbreak();
ExitProcess(1);
}
void __cdecl MiniCRTStartup()
{
StaticInitialization();
}
void __cdecl MiniCRTCleanup()
{
StaticDeinitialization();
}
BOOL WINAPI MiniCRTDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
// With manual DLL loading you can not use DLL_THREAD_ATTACH and DLL_THREAD_DETACH.
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
MiniCRTStartup();
break;
case DLL_PROCESS_DETACH:
MiniCRTCleanup();
break;
default:
break;
}
return TRUE;
}
#endif
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.