mirror of https://github.com/flysand7/ciabatta.git
GUI assert + WinMain handling
This commit is contained in:
parent
33719988c4
commit
b349443f8a
|
@ -1,15 +1,11 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if !defined(__func__)
|
|
||||||
#define __func__ __FUNCTION__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
#define _Noreturn
|
#define _Noreturn
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void _Noreturn _assert(
|
void _assert(
|
||||||
char const *cond,
|
char const *cond,
|
||||||
char const *func,
|
char const *func,
|
||||||
char const *file,
|
char const *file,
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#pragma comment(lib, "user32.lib")
|
||||||
|
#pragma comment(lib, "DbgHelp.lib")
|
||||||
|
|
||||||
static void _print_stack_trace() {
|
static void _print_stack_trace() {
|
||||||
HANDLE process = GetCurrentProcess();
|
HANDLE process = GetCurrentProcess();
|
||||||
SymInitialize(process, NULL, TRUE);
|
SymInitialize(process, NULL, TRUE);
|
||||||
|
@ -26,12 +29,30 @@ static void _print_stack_trace() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _Noreturn _assert(
|
void _assert(
|
||||||
char const *cond,
|
char const *cond,
|
||||||
char const *func,
|
char const *func,
|
||||||
char const *file,
|
char const *file,
|
||||||
int line
|
int line
|
||||||
) {
|
) {
|
||||||
|
if(GetConsoleWindow() == NULL) {
|
||||||
|
// For GUI application we display the info into a messagebox
|
||||||
|
char buf[1024];
|
||||||
|
int i = 0;
|
||||||
|
i += snprintf(buf+i, sizeof buf-i, "Assertion failed: %s\n", cond);
|
||||||
|
i += snprintf(buf+i, sizeof buf-i, " Function: %s\n", func);
|
||||||
|
i += snprintf(buf+i, sizeof buf-i, " File: %s\n", file);
|
||||||
|
i += snprintf(buf+i, sizeof buf-i, " Line: %d\n", line);
|
||||||
|
display_msg:
|
||||||
|
int reaction = MessageBoxA(NULL, buf, "Assertion Failed", 0x00000032L);
|
||||||
|
switch(reaction) {
|
||||||
|
case IDABORT: abort();
|
||||||
|
case IDRETRY: goto display_msg;
|
||||||
|
case IDCONTINUE: return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// For console application we print the info to console
|
||||||
printf("Assertion failed: %s\n", cond);
|
printf("Assertion failed: %s\n", cond);
|
||||||
printf(" Function: %s\n", func);
|
printf(" Function: %s\n", func);
|
||||||
printf(" File: %s\n", file);
|
printf(" File: %s\n", file);
|
||||||
|
@ -40,3 +61,4 @@ void _Noreturn _assert(
|
||||||
_print_stack_trace();
|
_print_stack_trace();
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
#pragma weak main
|
||||||
|
#pragma weak wmain
|
||||||
|
#pragma weak WinMain
|
||||||
|
|
||||||
|
int main(int argc, char** argv);
|
||||||
|
int wmain(int argc, wchar_t** argv, wchar_t **envp);
|
||||||
|
int WinMain(HINSTANCE inst, HINSTANCE pinst, LPSTR cmdline, int showcmd);
|
||||||
|
|
||||||
|
_Noreturn void mainCRTStartup() {
|
||||||
|
_setup_eh();
|
||||||
|
_setup_heap();
|
||||||
|
_setup_timer();
|
||||||
|
_setup_io();
|
||||||
|
|
||||||
|
srand(0);
|
||||||
|
setlocale(LC_ALL, "C");
|
||||||
|
|
||||||
|
int argc;
|
||||||
|
char **args = get_command_args(&argc);
|
||||||
|
int exit_code = main(argc, args);
|
||||||
|
|
||||||
|
exit(exit_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
_Noreturn void WinMainCRTStartup() {
|
||||||
|
_setup_eh();
|
||||||
|
_setup_heap();
|
||||||
|
_setup_timer();
|
||||||
|
_setup_io();
|
||||||
|
|
||||||
|
srand(0);
|
||||||
|
setlocale(LC_ALL, "C");
|
||||||
|
|
||||||
|
HINSTANCE inst = GetModuleHandle(NULL);
|
||||||
|
LPSTR cmdline = GetCommandLineA();
|
||||||
|
int exit_code = WinMain(inst, 0, cmdline, SW_SHOWDEFAULT);
|
||||||
|
|
||||||
|
exit(exit_code);
|
||||||
|
}
|
|
@ -2,11 +2,7 @@
|
||||||
// Windows symbols because windows
|
// Windows symbols because windows
|
||||||
int _fltused=0;
|
int _fltused=0;
|
||||||
|
|
||||||
extern int main(int argc, char** argv);
|
|
||||||
extern int wmain(int argc, wchar_t** argv, wchar_t **envp);
|
|
||||||
|
|
||||||
#pragma comment(lib, "kernel32.lib")
|
#pragma comment(lib, "kernel32.lib")
|
||||||
#pragma comment(lib, "DbgHelp.lib")
|
|
||||||
|
|
||||||
// Exit routines
|
// Exit routines
|
||||||
#define ATEXIT_FUNC_COUNT 64
|
#define ATEXIT_FUNC_COUNT 64
|
||||||
|
@ -18,27 +14,6 @@ static int atqexit_func_count;
|
||||||
|
|
||||||
static char **get_command_args(int *argc_ptr);
|
static char **get_command_args(int *argc_ptr);
|
||||||
|
|
||||||
_Noreturn void mainCRTStartup() {
|
|
||||||
// Set-up some platform stuff
|
|
||||||
_setup_eh();
|
|
||||||
_setup_heap();
|
|
||||||
_setup_timer();
|
|
||||||
_setup_io();
|
|
||||||
|
|
||||||
// Set-up CRT stuff
|
|
||||||
srand(0);
|
|
||||||
setlocale(LC_ALL, "C");
|
|
||||||
|
|
||||||
// Parse command-line arguments
|
|
||||||
int argc;
|
|
||||||
char **args = get_command_args(&argc);
|
|
||||||
int exit_code = main(argc, args);
|
|
||||||
|
|
||||||
// we call exit because we want atexit routines run
|
|
||||||
// and all the file handles to be freed
|
|
||||||
exit(exit_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
_Noreturn void _Exit(int status) {
|
_Noreturn void _Exit(int status) {
|
||||||
ExitProcess(status);
|
ExitProcess(status);
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
#include "_win/win.h"
|
#include "_win/win.h"
|
||||||
#include "_win/assert.c"
|
#include "_win/assert.c"
|
||||||
#include "_win/cmdline.c"
|
#include "_win/cmdline.c"
|
||||||
|
#include "_win/entry.c"
|
||||||
#include "_win/environment.c"
|
#include "_win/environment.c"
|
||||||
#include "_win/heap.c"
|
#include "_win/heap.c"
|
||||||
#include "_win/signal.c"
|
#include "_win/signal.c"
|
||||||
|
|
|
@ -135,7 +135,7 @@ static inline uint64_t div1e8(const uint64_t x) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
decfloat_t dtodecfloat(const uint64_t ieeeMantissa, const uint32_t ieeeExponent) {
|
static decfloat_t dtodecfloat(const uint64_t ieeeMantissa, const uint32_t ieeeExponent) {
|
||||||
int32_t e2;
|
int32_t e2;
|
||||||
uint64_t m2;
|
uint64_t m2;
|
||||||
if (ieeeExponent == 0) {
|
if (ieeeExponent == 0) {
|
||||||
|
|
|
@ -6,4 +6,4 @@ typedef struct {
|
||||||
int32_t exponent;
|
int32_t exponent;
|
||||||
} decfloat_t;
|
} decfloat_t;
|
||||||
|
|
||||||
decfloat_t todecfloat(const uint64_t ieeeMant, const uint32_t ieeeExp);
|
static decfloat_t todecfloat(const uint64_t ieeeMant, const uint32_t ieeeExp);
|
||||||
|
|
|
@ -11,11 +11,35 @@
|
||||||
#undef ctype
|
#undef ctype
|
||||||
#undef pfx
|
#undef pfx
|
||||||
|
|
||||||
|
|
||||||
static int fprintfcb(void *ctx, char ch) {
|
static int fprintfcb(void *ctx, char ch) {
|
||||||
FILE *f = ctx;
|
FILE *f = ctx;
|
||||||
return fputc(ch, f) != EOF;
|
return fputc(ch, f) != EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct str_ctx_t typedef str_ctx_t;
|
||||||
|
struct str_ctx_t {
|
||||||
|
char *str;
|
||||||
|
size_t n;
|
||||||
|
size_t i;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int sprintfcb(void *ctx, char ch) {
|
||||||
|
str_ctx_t *stream = ctx;
|
||||||
|
stream->str[stream->i++] = ch;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int snprintfcb(void *ctx, char ch) {
|
||||||
|
str_ctx_t *stream = ctx;
|
||||||
|
if(stream->i >= stream->n) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
stream->str[stream->i++] = ch;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int vfprintf(FILE *stream, const char *fmt, va_list args) {
|
int vfprintf(FILE *stream, const char *fmt, va_list args) {
|
||||||
return vprintfcb(stream, fprintfcb, fmt, args);
|
return vprintfcb(stream, fprintfcb, fmt, args);
|
||||||
}
|
}
|
||||||
|
@ -39,3 +63,33 @@ int printf(const char *fmt, ...) {
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int vsprintf(char *buf, char const *fmt, va_list args) {
|
||||||
|
str_ctx_t ctx = {0};
|
||||||
|
ctx.str = buf;
|
||||||
|
return vprintfcb(&ctx, sprintfcb, fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
int vsnprintf(char *buf, size_t sz, char const *fmt, va_list args) {
|
||||||
|
str_ctx_t ctx = {0};
|
||||||
|
ctx.str = buf;
|
||||||
|
ctx.n = sz;
|
||||||
|
return vprintfcb(&ctx, snprintfcb, fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sprintf(char *buf, char const *fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
int len = vsprintf(buf, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snprintf(char *buf, size_t sz, char const *fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
int len = vsnprintf(buf, sz, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
|
@ -270,7 +270,7 @@ static int pfx(vprintfcb)(
|
||||||
E = 0;
|
E = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
decfloat_t f = todecfloat(m2, e2);
|
decfloat_t f = dtodecfloat(m2, e2);
|
||||||
E = f.exponent;
|
E = f.exponent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -321,15 +321,15 @@ static int pfx(vprintfcb)(
|
||||||
out(wstr[i]);
|
out(wstr[i]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char utf8[5];
|
// char utf8[5];
|
||||||
char *s = utf8;
|
// char *s = utf8;
|
||||||
size_t r = c16rtomb(s, wstr[i], &ps);
|
// size_t r = c16rtomb(s, wstr[i], &ps);
|
||||||
if(r == (size_t)(-1)) return -1;
|
// if(r == (size_t)(-1)) return -1;
|
||||||
if(r != 0) {
|
// if(r != 0) {
|
||||||
while(*s != 0) {
|
// while(*s != 0) {
|
||||||
out(*s++);
|
// out(*s++);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Print right-pad
|
// Print right-pad
|
||||||
|
@ -697,7 +697,7 @@ static inline int pfx(_dtoa)(
|
||||||
exp = 0;
|
exp = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
decfloat_t f = todecfloat(m2, e2);
|
decfloat_t f = dtodecfloat(m2, e2);
|
||||||
mant = f.mantissa;
|
mant = f.mantissa;
|
||||||
exp = f.exponent;
|
exp = f.exponent;
|
||||||
}
|
}
|
||||||
|
@ -822,7 +822,7 @@ static inline int pfx(_etoa)(
|
||||||
exp = 0;
|
exp = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
decfloat_t f = todecfloat(m2, e2);
|
decfloat_t f = dtodecfloat(m2, e2);
|
||||||
mant = f.mantissa;
|
mant = f.mantissa;
|
||||||
exp = f.exponent;
|
exp = f.exponent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE p, LPSTR pCmdLine, int nCmdShow) {
|
||||||
|
const char CLASS_NAME[] = "Sample Window Class";
|
||||||
|
assert(0);
|
||||||
|
WNDCLASS wc = {
|
||||||
|
.lpfnWndProc = WindowProc,
|
||||||
|
.hInstance = hInstance,
|
||||||
|
.lpszClassName = CLASS_NAME,
|
||||||
|
};
|
||||||
|
RegisterClass(&wc);
|
||||||
|
HWND hwnd = CreateWindowEx(
|
||||||
|
0,
|
||||||
|
CLASS_NAME,
|
||||||
|
"Learn to Program Windows",
|
||||||
|
WS_OVERLAPPEDWINDOW,
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
hInstance,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if (hwnd == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ShowWindow(hwnd, nCmdShow);
|
||||||
|
MSG msg;
|
||||||
|
while (GetMessage(&msg, NULL, 0, 0)) {
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_DESTROY:
|
||||||
|
PostQuitMessage(0);
|
||||||
|
return 0;
|
||||||
|
case WM_PAINT:
|
||||||
|
{
|
||||||
|
PAINTSTRUCT ps;
|
||||||
|
HDC hdc = BeginPaint(hwnd, &ps);
|
||||||
|
|
||||||
|
// All painting occurs here, between BeginPaint and EndPaint.
|
||||||
|
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
|
||||||
|
EndPaint(hwnd, &ps);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||||
|
}
|
Loading…
Reference in New Issue