1 /**************************************************************************
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
39 #include "pipe/p_compiler.h"
40 #include "pipe/p_util.h"
41 #include "pipe/p_debug.h"
46 rpl_EngDebugPrint(const char *format
, ...)
50 EngDebugPrint("", (PCHAR
)format
, ap
);
54 int rpl_vsnprintf(char *, size_t, const char *, va_list);
55 int rpl_snprintf(char *str
, size_t size
, const char *format
, ...);
56 #define vsnprintf rpl_vsnprintf
57 #define snprintf rpl_snprintf
61 void _debug_vprintf(const char *format
, va_list ap
)
65 /* EngDebugPrint does not handle float point arguments, so we need to use
66 * our own vsnprintf implementation */
68 rpl_vsnprintf(buf
, sizeof(buf
), format
, ap
);
69 rpl_EngDebugPrint("%s", buf
);
71 /* TODO: Implement debug print for WINCE */
74 vfprintf(stderr
, format
, ap
);
80 void debug_print_blob( const char *name
,
84 const unsigned *ublob
= (const unsigned *)blob
;
87 debug_printf("%s (%d dwords%s)\n", name
, size
/4,
88 size
%4 ? "... plus a few bytes" : "");
90 for (i
= 0; i
< size
/4; i
++) {
91 debug_printf("%d:\t%08x\n", i
, ublob
[i
]);
97 void _debug_break(void)
99 #if (defined(__i386__) || defined(__386__)) && defined(__GNUC__)
101 #elif (defined(__i386__) || defined(__386__)) && defined(__MSC__)
103 #elif defined(WIN32) && !defined(WINCE)
113 find(const char *start
, const char *end
, char c
)
116 for(p
= start
; !end
|| p
!= end
; ++p
) {
126 compare(const char *start
, const char *end
, const char *s
)
129 for(p
= start
, q
= s
; p
!= end
&& *q
!= '\0'; ++p
, ++q
) {
133 return p
== end
&& *q
== '\0';
137 copy(char *dst
, const char *start
, const char *end
, size_t n
)
141 for(p
= start
, q
= dst
, n
= n
- 1; p
!= end
&& n
; ++p
, ++q
, --n
)
149 debug_get_option(const char *name
, const char *dfault
)
154 const void *pMap
= NULL
;
155 const char *sol
, *eol
, *sep
;
156 static char output
[1024];
158 pMap
= EngMapFile(L
"\\??\\c:\\gallium.cfg", 0, &iFile
);
162 sol
= (const char *)pMap
;
164 /* TODO: handle LF line endings */
165 eol
= find(sol
, NULL
, '\r');
166 if(!eol
|| eol
== sol
)
168 sep
= find(sol
, eol
, '=');
171 if(compare(sol
, sep
, name
)) {
172 copy(output
, sep
+ 1, eol
, sizeof(output
));
182 result
= getenv(name
);
188 debug_printf("%s: %s = %s\n", __FUNCTION__
, name
, result
);
190 debug_printf("%s: %s = (null)\n", __FUNCTION__
, name
);
196 debug_get_bool_option(const char *name
, boolean dfault
)
198 const char *str
= debug_get_option(name
, NULL
);
203 else if(!strcmp(str
, "no"))
205 else if(!strcmp(str
, "0"))
207 else if(!strcmp(str
, "f"))
209 else if(!strcmp(str
, "false"))
214 debug_printf("%s: %s = %s\n", __FUNCTION__
, name
, result
? "TRUE" : "FALSE");
221 debug_get_num_option(const char *name
, long dfault
)
229 debug_get_flags_option(const char *name
,
230 const struct debug_named_value
*flags
,
231 unsigned long dfault
)
233 unsigned long result
;
236 str
= debug_get_option(name
, NULL
);
241 while( flags
->name
) {
242 if (!strcmp(str
, "all") || strstr(str
, flags
->name
))
243 result
|= flags
->value
;
248 debug_printf("%s: %s = 0x%lx\n", __FUNCTION__
, name
, result
);
255 ULONG_PTR debug_config_file
= 0;
256 void *mapped_config_file
= 0;
259 eAssertAbortEn
= 0x1,
262 /* Check for aborts enabled. */
263 static unsigned abort_en(void)
265 if (!mapped_config_file
)
267 /* Open an 8 byte file for configuration data. */
268 mapped_config_file
= EngMapFile(L
"\\??\\c:\\gaDebug.cfg", 8, &debug_config_file
);
271 /* A value of "0" (ascii) in the configuration file will clear the
272 * first 8 bits in the test byte.
274 * A value of "1" (ascii) in the configuration file will set the
275 * first bit in the test byte.
277 * A value of "2" (ascii) in the configuration file will set the
278 * second bit in the test byte.
280 * Currently the only interesting values are 0 and 1, which clear
281 * and set abort-on-assert behaviour respectively.
283 return ((((char *)mapped_config_file
)[0]) - 0x30) & eAssertAbortEn
;
286 static unsigned abort_en(void)
288 return !GETENV("GALLIUM_ABORT_ON_ASSERT");
292 void _debug_assert_fail(const char *expr
,
295 const char *function
)
297 _debug_printf("%s:%u:%s: Assertion `%s' failed.\n", file
, line
, function
, expr
);
303 _debug_printf("continuing...\n");
309 debug_dump_enum(const struct debug_named_value
*names
,
312 static char rest
[256];
315 if(names
->value
== value
)
320 snprintf(rest
, sizeof(rest
), "0x%08lx", value
);
326 debug_dump_flags(const struct debug_named_value
*names
,
329 static char output
[4096];
330 static char rest
[256];
336 if((names
->value
& value
) == names
->value
) {
338 strncat(output
, "|", sizeof(output
));
341 strncat(output
, names
->name
, sizeof(output
));
342 value
&= ~names
->value
;
349 strncat(output
, "|", sizeof(output
));
353 snprintf(rest
, sizeof(rest
), "0x%08lx", value
);
354 strncat(output
, rest
, sizeof(output
));