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,12 +29,30 @@ static void _print_stack_trace() { | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| void _Noreturn _assert( | ||||
| void _assert( | ||||
|     char const *cond, | ||||
|     char const *func, | ||||
|     char const *file, | ||||
|     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("  Function: %s\n", func); | ||||
|         printf("  File: %s\n", file); | ||||
|  | @ -39,4 +60,5 @@ void _Noreturn _assert( | |||
|         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