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