1// tAssert.cpp 
2// 
3// Tacent asserts and warnings. 
4// 
5// Copyright (c) 2004-2006, 2015, 2017, 2022, 2023 Tristan Grimmer. 
6// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby 
7// granted, provided that the above copyright notice and this permission notice appear in all copies. 
8// 
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 
10// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
11// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
12// AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
13// PERFORMANCE OF THIS SOFTWARE. 
14 
15#include <stdio.h> 
16#include "Foundation/tPlatform.h" 
17#ifdef TACENT_UTF16_API_CALLS 
18#include "Foundation/tStandard.h" 
19#endif 
20#include <signal.h> 
21#ifdef PLATFORM_WINDOWS 
22#include <Windows.h> 
23#endif 
24 
25 
26void tAbort() 
27
28 // Note the use of stdio printf here to reduce dependencies. 
29 printf(format: "%s(%d) Tacent Abort\n", __FILE__, __LINE__); 
30 abort(); 
31
32 
33 
34void tAssertPrintBreak(const char* expr, const char* fileName, int lineNum, const char* msg
35
36 const int assertMessageSize = 4*1024
37 char message[assertMessageSize]; 
38 
39 snprintf 
40
41 s: message, maxlen: assertMessageSize
42 format: "Tacent Assert Failed.\n\n" 
43 "Expr: [%s]\n" 
44 "File: [%s]\n" 
45 "Line: [%d]\n" 
46 "Msg : [%s]\n\n" 
47 #ifdef PLATFORM_WINDOWS 
48 "Press 'Abort' to abort the program completely.\n" 
49 "Press 'Retry' to start debugging.\n" 
50 "Press 'Ignore' to try and move past this assert and continue running.\n" 
51 #endif 
52
53 expr, fileName, lineNum, msg ? msg : "None" 
54 ); 
55 printf(format: "%s", message); 
56 
57 #ifdef PLATFORM_WINDOWS 
58 // In windows we bring up a message box. 
59 
60 #ifdef TACENT_UTF16_API_CALLS 
61 // @todo Using more stack than is needed for the UTF-16 string. 
62 char16_t utfmsg[assertMessageSize]; 
63 tStd::tUTF16s(utfmsg, (char8_t*)message); 
64 int retCode = ::MessageBox 
65
66 0, LPWSTR(utfmsg), LPWSTR(u"Tacent Assert"), 
67 MB_ABORTRETRYIGNORE | MB_ICONHAND | MB_SETFOREGROUND | MB_TASKMODAL 
68 ); 
69 #else 
70 int retCode = ::MessageBox 
71
72 0, message, "Tacent Assert"
73 MB_ABORTRETRYIGNORE | MB_ICONHAND | MB_SETFOREGROUND | MB_TASKMODAL 
74 ); 
75 #endif 
76 
77 switch (retCode) 
78
79 case IDABORT: 
80 // Exit ungracefully. 
81 raise(SIGABRT); 
82 _exit(200); 
83 break
84 
85 case IDRETRY: 
86 // Attempt break to debugger. 
87 __debugbreak(); 
88 return
89 
90 case IDIGNORE: 
91 return
92
93 #endif 
94 
95 #ifdef PLATFORM_LINUX 
96 raise(SIGTRAP); 
97 #endif 
98
99