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
|
||||
|
||||
#if !defined(__func__)
|
||||
#define __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define _Noreturn
|
||||
#endif
|
||||
|
||||
void _Noreturn _assert(
|
||||
void _assert(
|
||||
char const *cond,
|
||||
char const *func,
|
||||
char const *file,
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#pragma comment(lib, "user32.lib")
|
||||
#pragma comment(lib, "DbgHelp.lib")
|
||||
|
||||
static void _print_stack_trace() {
|
||||
HANDLE process = GetCurrentProcess();
|
||||
SymInitialize(process, NULL, TRUE);
|
||||
|
@ -26,17 +29,36 @@ static void _print_stack_trace() {
|
|||
}
|
||||
|
||||
|
||||
void _Noreturn _assert(
|
||||
void _assert(
|
||||
char const *cond,
|
||||
char const *func,
|
||||
char const *file,
|
||||
int line
|
||||
) {
|
||||
printf("Assertion failed: %s\n", cond);
|
||||
printf(" Function: %s\n", func);
|
||||
printf(" File: %s\n", file);
|
||||
printf(" Line: %d\n", line);
|
||||
printf("Trace:\n");
|
||||
_print_stack_trace();
|
||||
abort();
|
||||
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(" Function: %s\n", func);
|
||||
printf(" File: %s\n", file);
|
||||
printf(" Line: %d\n", line);
|
||||
printf("Trace:\n");
|
||||
_print_stack_trace();
|
||||
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
|
||||
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, "DbgHelp.lib")
|
||||
|
||||
// Exit routines
|
||||
#define ATEXIT_FUNC_COUNT 64
|
||||
|
@ -18,27 +14,6 @@ static int atqexit_func_count;
|
|||
|
||||
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) {
|
||||
ExitProcess(status);
|
||||
#if defined(_MSC_VER)
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#include "_win/win.h"
|
||||
#include "_win/assert.c"
|
||||
#include "_win/cmdline.c"
|
||||
#include "_win/entry.c"
|
||||
#include "_win/environment.c"
|
||||
#include "_win/heap.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;
|
||||
uint64_t m2;
|
||||
if (ieeeExponent == 0) {
|
||||
|
|
|
@ -6,4 +6,4 @@ typedef struct {
|
|||
int32_t exponent;
|
||||
} 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 pfx
|
||||
|
||||
|
||||
static int fprintfcb(void *ctx, char ch) {
|
||||
FILE *f = ctx;
|
||||
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) {
|
||||
return vprintfcb(stream, fprintfcb, fmt, args);
|
||||
}
|
||||
|
@ -39,3 +63,33 @@ int printf(const char *fmt, ...) {
|
|||
va_end(args);
|
||||
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;
|
||||
}
|
||||
else {
|
||||
decfloat_t f = todecfloat(m2, e2);
|
||||
decfloat_t f = dtodecfloat(m2, e2);
|
||||
E = f.exponent;
|
||||
}
|
||||
}
|
||||
|
@ -321,15 +321,15 @@ static int pfx(vprintfcb)(
|
|||
out(wstr[i]);
|
||||
}
|
||||
else {
|
||||
char utf8[5];
|
||||
char *s = utf8;
|
||||
size_t r = c16rtomb(s, wstr[i], &ps);
|
||||
if(r == (size_t)(-1)) return -1;
|
||||
if(r != 0) {
|
||||
while(*s != 0) {
|
||||
out(*s++);
|
||||
}
|
||||
}
|
||||
// char utf8[5];
|
||||
// char *s = utf8;
|
||||
// size_t r = c16rtomb(s, wstr[i], &ps);
|
||||
// if(r == (size_t)(-1)) return -1;
|
||||
// if(r != 0) {
|
||||
// while(*s != 0) {
|
||||
// out(*s++);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
// Print right-pad
|
||||
|
@ -697,7 +697,7 @@ static inline int pfx(_dtoa)(
|
|||
exp = 0;
|
||||
}
|
||||
else {
|
||||
decfloat_t f = todecfloat(m2, e2);
|
||||
decfloat_t f = dtodecfloat(m2, e2);
|
||||
mant = f.mantissa;
|
||||
exp = f.exponent;
|
||||
}
|
||||
|
@ -822,7 +822,7 @@ static inline int pfx(_etoa)(
|
|||
exp = 0;
|
||||
}
|
||||
else {
|
||||
decfloat_t f = todecfloat(m2, e2);
|
||||
decfloat_t f = dtodecfloat(m2, e2);
|
||||
mant = f.mantissa;
|
||||
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