swr: [rasterizer] Fix Coverity issues reported by Mesa developers.
[mesa.git] / src / gallium / drivers / swr / rasterizer / common / swr_assert.cpp
1 /****************************************************************************
2 * Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 ****************************************************************************/
23
24 #include "common/os.h"
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <assert.h>
28
29 #if SWR_ENABLE_ASSERTS || SWR_ENABLE_REL_ASSERTS
30
31 #if defined(_WIN32)
32 #pragma comment(lib, "user32.lib")
33 #endif // _WIN32
34
35 enum TextColor
36 {
37 TEXT_BLACK = 0,
38 TEXT_RED = 1,
39 TEXT_GREEN = 2,
40 TEXT_BLUE = 4,
41 TEXT_PURPLE = TEXT_RED | TEXT_BLUE,
42 TEXT_CYAN = TEXT_GREEN | TEXT_BLUE,
43 TEXT_YELLOW = TEXT_RED | TEXT_GREEN,
44 TEXT_WHITE = TEXT_RED | TEXT_GREEN | TEXT_BLUE,
45 };
46
47 enum TextStyle
48 {
49 TEXT_NORMAL = 0,
50 TEXT_INTENSITY = 1,
51 };
52
53 void SetTextColor(FILE* stream, TextColor color = TEXT_WHITE, TextStyle style = TEXT_NORMAL)
54 {
55 #if defined(_WIN32)
56
57 HANDLE hConsoleHandle = nullptr;
58 if (stream == stderr)
59 {
60 hConsoleHandle = GetStdHandle(STD_ERROR_HANDLE);
61 }
62 else if (stream == stdout)
63 {
64 hConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
65 }
66 else
67 {
68 // Not a console stream, do nothing
69 return;
70 }
71
72 WORD textAttributes = 0;
73 if (color & TEXT_RED)
74 {
75 textAttributes |= FOREGROUND_RED;
76 }
77 if (color & TEXT_GREEN)
78 {
79 textAttributes |= FOREGROUND_GREEN;
80 }
81 if (color & TEXT_BLUE)
82 {
83 textAttributes |= FOREGROUND_BLUE;
84 }
85 if (style & TEXT_INTENSITY)
86 {
87 textAttributes |= FOREGROUND_INTENSITY;
88 }
89 SetConsoleTextAttribute(hConsoleHandle, textAttributes);
90
91 #else // !_WIN32
92
93 // Print ANSI codes
94 uint32_t cc = 30 + (style ? 60 : 0) + color;
95 fprintf(stream, "\033[0m\033[%d;%dm", style, cc);
96
97 #endif
98 }
99
100 void ResetTextColor(FILE* stream)
101 {
102 #if defined(_WIN32)
103
104 SetTextColor(stream);
105
106 #else // !_WIN32
107
108 // Print ANSI codes
109 fprintf(stream, "\033[0m");
110
111 #endif
112 }
113
114 bool SwrAssert(
115 bool chkDebugger,
116 bool& enabled,
117 const char* pExpression,
118 const char* pFileName,
119 uint32_t lineNum,
120 const char* pFunction,
121 const char* pFmtString /* = nullptr */,
122 ...)
123 {
124 if (!enabled) return false;
125
126 SetTextColor(stderr, TEXT_CYAN, TEXT_NORMAL);
127
128 fprintf(stderr, "%s(%d): ", pFileName, lineNum);
129
130 SetTextColor(stderr, TEXT_RED, TEXT_INTENSITY);
131
132 fprintf(stderr, "ASSERT: %s\n", pExpression);
133
134 SetTextColor(stderr, TEXT_CYAN, TEXT_INTENSITY);
135 fprintf(stderr, "\t%s\n", pFunction);
136
137 if (pFmtString)
138 {
139 SetTextColor(stderr, TEXT_YELLOW, TEXT_INTENSITY);
140 fprintf(stderr, "\t");
141 va_list args;
142 va_start(args, pFmtString);
143 vfprintf(stderr, pFmtString, args);
144 va_end(args);
145 fprintf(stderr, "\n");
146 }
147 ResetTextColor(stderr);
148 fflush(stderr);
149
150 #if defined(_WIN32)
151 static const int MAX_MESSAGE_LEN = 2048;
152 char msgBuf[MAX_MESSAGE_LEN];
153
154 sprintf_s(msgBuf, "%s(%d): ASSERT: %s\n", pFileName, lineNum, pExpression);
155 msgBuf[MAX_MESSAGE_LEN - 2] = '\n';
156 msgBuf[MAX_MESSAGE_LEN - 1] = 0;
157 OutputDebugStringA(msgBuf);
158
159 sprintf_s(msgBuf, "\t%s\n", pFunction);
160 msgBuf[MAX_MESSAGE_LEN - 2] = '\n';
161 msgBuf[MAX_MESSAGE_LEN - 1] = 0;
162 OutputDebugStringA(msgBuf);
163
164 int offset = 0;
165
166 if (pFmtString)
167 {
168 va_list args;
169 va_start(args, pFmtString);
170 offset = _vsnprintf_s(
171 msgBuf,
172 sizeof(msgBuf),
173 sizeof(msgBuf),
174 pFmtString,
175 args);
176 va_end(args);
177
178 if (offset < 0) { return true; }
179
180 OutputDebugStringA("\t");
181 OutputDebugStringA(msgBuf);
182 OutputDebugStringA("\n");
183 }
184
185 if (KNOB_ENABLE_ASSERT_DIALOGS)
186 {
187 int retval = sprintf_s(
188 &msgBuf[offset],
189 MAX_MESSAGE_LEN - offset,
190 "\n\n"
191 "File: %s\n"
192 "Line: %d\n"
193 "\n"
194 "Expression: %s\n\n"
195 "Cancel: Disable this assert for the remainder of the process\n"
196 "Try Again: Break into the debugger\n"
197 "Continue: Continue execution (but leave assert enabled)",
198 pFileName,
199 lineNum,
200 pExpression);
201
202 if (retval < 0) { return true; }
203
204 offset += retval;
205
206 if (!IsDebuggerPresent())
207 {
208 sprintf_s(
209 &msgBuf[offset],
210 MAX_MESSAGE_LEN - offset,
211 "\n\n*** NO DEBUGGER DETECTED ***\n\nPressing \"Try Again\" will cause a program crash!");
212 }
213
214 retval = MessageBoxA(nullptr, msgBuf, "Assert Failed", MB_CANCELTRYCONTINUE | MB_ICONEXCLAMATION);
215
216 switch (retval)
217 {
218 case IDCANCEL:
219 enabled = false;
220 return false;
221
222 case IDTRYAGAIN:
223 return true;
224
225 case IDCONTINUE:
226 return false;
227 }
228 }
229 else
230 {
231 return IsDebuggerPresent() || !chkDebugger;
232 }
233 #endif // _WIN32
234
235 return true;
236 }
237
238 #endif // SWR_ENABLE_ASSERTS