xref: /aosp_15_r20/external/virglrenderer/src/mesa/util/u_debug.c (revision bbecb9d118dfdb95f99bd754f8fa9be01f189df3)
1*bbecb9d1SAndroid Build Coastguard Worker /**************************************************************************
2*bbecb9d1SAndroid Build Coastguard Worker  *
3*bbecb9d1SAndroid Build Coastguard Worker  * Copyright 2008 VMware, Inc.
4*bbecb9d1SAndroid Build Coastguard Worker  * Copyright (c) 2008 VMware, Inc.
5*bbecb9d1SAndroid Build Coastguard Worker  * All Rights Reserved.
6*bbecb9d1SAndroid Build Coastguard Worker  *
7*bbecb9d1SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
8*bbecb9d1SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the
9*bbecb9d1SAndroid Build Coastguard Worker  * "Software"), to deal in the Software without restriction, including
10*bbecb9d1SAndroid Build Coastguard Worker  * without limitation the rights to use, copy, modify, merge, publish,
11*bbecb9d1SAndroid Build Coastguard Worker  * distribute, sub license, and/or sell copies of the Software, and to
12*bbecb9d1SAndroid Build Coastguard Worker  * permit persons to whom the Software is furnished to do so, subject to
13*bbecb9d1SAndroid Build Coastguard Worker  * the following conditions:
14*bbecb9d1SAndroid Build Coastguard Worker  *
15*bbecb9d1SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the
16*bbecb9d1SAndroid Build Coastguard Worker  * next paragraph) shall be included in all copies or substantial portions
17*bbecb9d1SAndroid Build Coastguard Worker  * of the Software.
18*bbecb9d1SAndroid Build Coastguard Worker  *
19*bbecb9d1SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20*bbecb9d1SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21*bbecb9d1SAndroid Build Coastguard Worker  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22*bbecb9d1SAndroid Build Coastguard Worker  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
23*bbecb9d1SAndroid Build Coastguard Worker  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24*bbecb9d1SAndroid Build Coastguard Worker  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25*bbecb9d1SAndroid Build Coastguard Worker  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26*bbecb9d1SAndroid Build Coastguard Worker  *
27*bbecb9d1SAndroid Build Coastguard Worker  **************************************************************************/
28*bbecb9d1SAndroid Build Coastguard Worker 
29*bbecb9d1SAndroid Build Coastguard Worker 
30*bbecb9d1SAndroid Build Coastguard Worker /* (virglrenderer) removed includes for p_format.h and p_state.h */
31*bbecb9d1SAndroid Build Coastguard Worker #include "pipe/p_compiler.h"
32*bbecb9d1SAndroid Build Coastguard Worker #include "pipe/p_config.h"
33*bbecb9d1SAndroid Build Coastguard Worker 
34*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_debug.h"
35*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_string.h"
36*bbecb9d1SAndroid Build Coastguard Worker #include <inttypes.h>
37*bbecb9d1SAndroid Build Coastguard Worker 
38*bbecb9d1SAndroid Build Coastguard Worker #include <stdio.h>
39*bbecb9d1SAndroid Build Coastguard Worker #include <limits.h> /* CHAR_BIT */
40*bbecb9d1SAndroid Build Coastguard Worker #include <ctype.h> /* isalnum */
41*bbecb9d1SAndroid Build Coastguard Worker 
42*bbecb9d1SAndroid Build Coastguard Worker #ifdef _WIN32
43*bbecb9d1SAndroid Build Coastguard Worker #include <windows.h>
44*bbecb9d1SAndroid Build Coastguard Worker #include <stdlib.h>
45*bbecb9d1SAndroid Build Coastguard Worker #endif
46*bbecb9d1SAndroid Build Coastguard Worker 
47*bbecb9d1SAndroid Build Coastguard Worker 
48*bbecb9d1SAndroid Build Coastguard Worker void
_debug_vprintf(const char * format,va_list ap)49*bbecb9d1SAndroid Build Coastguard Worker _debug_vprintf(const char *format, va_list ap)
50*bbecb9d1SAndroid Build Coastguard Worker {
51*bbecb9d1SAndroid Build Coastguard Worker    static char buf[4096] = {'\0'};
52*bbecb9d1SAndroid Build Coastguard Worker #if DETECT_OS_WINDOWS || defined(EMBEDDED_DEVICE)
53*bbecb9d1SAndroid Build Coastguard Worker    /* We buffer until we find a newline. */
54*bbecb9d1SAndroid Build Coastguard Worker    size_t len = strlen(buf);
55*bbecb9d1SAndroid Build Coastguard Worker    int ret = vsnprintf(buf + len, sizeof(buf) - len, format, ap);
56*bbecb9d1SAndroid Build Coastguard Worker    if (ret > (int)(sizeof(buf) - len - 1) || strchr(buf + len, '\n')) {
57*bbecb9d1SAndroid Build Coastguard Worker       os_log_message(buf);
58*bbecb9d1SAndroid Build Coastguard Worker       buf[0] = '\0';
59*bbecb9d1SAndroid Build Coastguard Worker    }
60*bbecb9d1SAndroid Build Coastguard Worker #else
61*bbecb9d1SAndroid Build Coastguard Worker    vsnprintf(buf, sizeof(buf), format, ap);
62*bbecb9d1SAndroid Build Coastguard Worker    os_log_message(buf);
63*bbecb9d1SAndroid Build Coastguard Worker #endif
64*bbecb9d1SAndroid Build Coastguard Worker }
65*bbecb9d1SAndroid Build Coastguard Worker 
66*bbecb9d1SAndroid Build Coastguard Worker 
67*bbecb9d1SAndroid Build Coastguard Worker /* (virglrenderer) removed _pipe_debug_message */
68*bbecb9d1SAndroid Build Coastguard Worker 
69*bbecb9d1SAndroid Build Coastguard Worker 
70*bbecb9d1SAndroid Build Coastguard Worker void
debug_disable_error_message_boxes(void)71*bbecb9d1SAndroid Build Coastguard Worker debug_disable_error_message_boxes(void)
72*bbecb9d1SAndroid Build Coastguard Worker {
73*bbecb9d1SAndroid Build Coastguard Worker #ifdef _WIN32
74*bbecb9d1SAndroid Build Coastguard Worker    /* When Windows' error message boxes are disabled for this process (as is
75*bbecb9d1SAndroid Build Coastguard Worker     * typically the case when running tests in an automated fashion) we disable
76*bbecb9d1SAndroid Build Coastguard Worker     * CRT message boxes too.
77*bbecb9d1SAndroid Build Coastguard Worker     */
78*bbecb9d1SAndroid Build Coastguard Worker    UINT uMode = SetErrorMode(0);
79*bbecb9d1SAndroid Build Coastguard Worker    SetErrorMode(uMode);
80*bbecb9d1SAndroid Build Coastguard Worker    if (uMode & SEM_FAILCRITICALERRORS) {
81*bbecb9d1SAndroid Build Coastguard Worker       /* Disable assertion failure message box.
82*bbecb9d1SAndroid Build Coastguard Worker        * http://msdn.microsoft.com/en-us/library/sas1dkb2.aspx
83*bbecb9d1SAndroid Build Coastguard Worker        */
84*bbecb9d1SAndroid Build Coastguard Worker       _set_error_mode(_OUT_TO_STDERR);
85*bbecb9d1SAndroid Build Coastguard Worker #ifdef _MSC_VER
86*bbecb9d1SAndroid Build Coastguard Worker       /* Disable abort message box.
87*bbecb9d1SAndroid Build Coastguard Worker        * http://msdn.microsoft.com/en-us/library/e631wekh.aspx
88*bbecb9d1SAndroid Build Coastguard Worker        */
89*bbecb9d1SAndroid Build Coastguard Worker       _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
90*bbecb9d1SAndroid Build Coastguard Worker #endif
91*bbecb9d1SAndroid Build Coastguard Worker    }
92*bbecb9d1SAndroid Build Coastguard Worker #endif /* _WIN32 */
93*bbecb9d1SAndroid Build Coastguard Worker }
94*bbecb9d1SAndroid Build Coastguard Worker 
95*bbecb9d1SAndroid Build Coastguard Worker 
96*bbecb9d1SAndroid Build Coastguard Worker #ifdef DEBUG
97*bbecb9d1SAndroid Build Coastguard Worker void
debug_print_blob(const char * name,const void * blob,unsigned size)98*bbecb9d1SAndroid Build Coastguard Worker debug_print_blob(const char *name, const void *blob, unsigned size)
99*bbecb9d1SAndroid Build Coastguard Worker {
100*bbecb9d1SAndroid Build Coastguard Worker    const unsigned *ublob = (const unsigned *)blob;
101*bbecb9d1SAndroid Build Coastguard Worker    unsigned i;
102*bbecb9d1SAndroid Build Coastguard Worker 
103*bbecb9d1SAndroid Build Coastguard Worker    debug_printf("%s (%d dwords%s)\n", name, size/4,
104*bbecb9d1SAndroid Build Coastguard Worker                 size%4 ? "... plus a few bytes" : "");
105*bbecb9d1SAndroid Build Coastguard Worker 
106*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < size/4; i++) {
107*bbecb9d1SAndroid Build Coastguard Worker       debug_printf("%d:\t%08x\n", i, ublob[i]);
108*bbecb9d1SAndroid Build Coastguard Worker    }
109*bbecb9d1SAndroid Build Coastguard Worker }
110*bbecb9d1SAndroid Build Coastguard Worker #endif
111*bbecb9d1SAndroid Build Coastguard Worker 
112*bbecb9d1SAndroid Build Coastguard Worker 
113*bbecb9d1SAndroid Build Coastguard Worker static bool
debug_get_option_should_print(void)114*bbecb9d1SAndroid Build Coastguard Worker debug_get_option_should_print(void)
115*bbecb9d1SAndroid Build Coastguard Worker {
116*bbecb9d1SAndroid Build Coastguard Worker    static bool first = true;
117*bbecb9d1SAndroid Build Coastguard Worker    static bool value = false;
118*bbecb9d1SAndroid Build Coastguard Worker 
119*bbecb9d1SAndroid Build Coastguard Worker    if (!first)
120*bbecb9d1SAndroid Build Coastguard Worker       return value;
121*bbecb9d1SAndroid Build Coastguard Worker 
122*bbecb9d1SAndroid Build Coastguard Worker    /* Oh hey this will call into this function,
123*bbecb9d1SAndroid Build Coastguard Worker     * but its cool since we set first to false
124*bbecb9d1SAndroid Build Coastguard Worker     */
125*bbecb9d1SAndroid Build Coastguard Worker    first = false;
126*bbecb9d1SAndroid Build Coastguard Worker    value = debug_get_bool_option("GALLIUM_PRINT_OPTIONS", false);
127*bbecb9d1SAndroid Build Coastguard Worker    /* XXX should we print this option? Currently it wont */
128*bbecb9d1SAndroid Build Coastguard Worker    return value;
129*bbecb9d1SAndroid Build Coastguard Worker }
130*bbecb9d1SAndroid Build Coastguard Worker 
131*bbecb9d1SAndroid Build Coastguard Worker 
132*bbecb9d1SAndroid Build Coastguard Worker const char *
debug_get_option(const char * name,const char * dfault)133*bbecb9d1SAndroid Build Coastguard Worker debug_get_option(const char *name, const char *dfault)
134*bbecb9d1SAndroid Build Coastguard Worker {
135*bbecb9d1SAndroid Build Coastguard Worker    const char *result;
136*bbecb9d1SAndroid Build Coastguard Worker 
137*bbecb9d1SAndroid Build Coastguard Worker    result = os_get_option(name);
138*bbecb9d1SAndroid Build Coastguard Worker    if (!result)
139*bbecb9d1SAndroid Build Coastguard Worker       result = dfault;
140*bbecb9d1SAndroid Build Coastguard Worker 
141*bbecb9d1SAndroid Build Coastguard Worker    if (debug_get_option_should_print())
142*bbecb9d1SAndroid Build Coastguard Worker       debug_printf("%s: %s = %s\n", __FUNCTION__, name,
143*bbecb9d1SAndroid Build Coastguard Worker                    result ? result : "(null)");
144*bbecb9d1SAndroid Build Coastguard Worker 
145*bbecb9d1SAndroid Build Coastguard Worker    return result;
146*bbecb9d1SAndroid Build Coastguard Worker }
147*bbecb9d1SAndroid Build Coastguard Worker 
148*bbecb9d1SAndroid Build Coastguard Worker 
149*bbecb9d1SAndroid Build Coastguard Worker bool
debug_get_bool_option(const char * name,bool dfault)150*bbecb9d1SAndroid Build Coastguard Worker debug_get_bool_option(const char *name, bool dfault)
151*bbecb9d1SAndroid Build Coastguard Worker {
152*bbecb9d1SAndroid Build Coastguard Worker    const char *str = os_get_option(name);
153*bbecb9d1SAndroid Build Coastguard Worker    bool result;
154*bbecb9d1SAndroid Build Coastguard Worker 
155*bbecb9d1SAndroid Build Coastguard Worker    if (str == NULL)
156*bbecb9d1SAndroid Build Coastguard Worker       result = dfault;
157*bbecb9d1SAndroid Build Coastguard Worker    else if (!strcmp(str, "n"))
158*bbecb9d1SAndroid Build Coastguard Worker       result = false;
159*bbecb9d1SAndroid Build Coastguard Worker    else if (!strcmp(str, "no"))
160*bbecb9d1SAndroid Build Coastguard Worker       result = false;
161*bbecb9d1SAndroid Build Coastguard Worker    else if (!strcmp(str, "0"))
162*bbecb9d1SAndroid Build Coastguard Worker       result = false;
163*bbecb9d1SAndroid Build Coastguard Worker    else if (!strcmp(str, "f"))
164*bbecb9d1SAndroid Build Coastguard Worker       result = false;
165*bbecb9d1SAndroid Build Coastguard Worker    else if (!strcmp(str, "F"))
166*bbecb9d1SAndroid Build Coastguard Worker       result = false;
167*bbecb9d1SAndroid Build Coastguard Worker    else if (!strcmp(str, "false"))
168*bbecb9d1SAndroid Build Coastguard Worker       result = false;
169*bbecb9d1SAndroid Build Coastguard Worker    else if (!strcmp(str, "FALSE"))
170*bbecb9d1SAndroid Build Coastguard Worker       result = false;
171*bbecb9d1SAndroid Build Coastguard Worker    else
172*bbecb9d1SAndroid Build Coastguard Worker       result = true;
173*bbecb9d1SAndroid Build Coastguard Worker 
174*bbecb9d1SAndroid Build Coastguard Worker    if (debug_get_option_should_print())
175*bbecb9d1SAndroid Build Coastguard Worker       debug_printf("%s: %s = %s\n", __FUNCTION__, name,
176*bbecb9d1SAndroid Build Coastguard Worker                    result ? "TRUE" : "FALSE");
177*bbecb9d1SAndroid Build Coastguard Worker 
178*bbecb9d1SAndroid Build Coastguard Worker    return result;
179*bbecb9d1SAndroid Build Coastguard Worker }
180*bbecb9d1SAndroid Build Coastguard Worker 
181*bbecb9d1SAndroid Build Coastguard Worker 
182*bbecb9d1SAndroid Build Coastguard Worker long
debug_get_num_option(const char * name,long dfault)183*bbecb9d1SAndroid Build Coastguard Worker debug_get_num_option(const char *name, long dfault)
184*bbecb9d1SAndroid Build Coastguard Worker {
185*bbecb9d1SAndroid Build Coastguard Worker    long result;
186*bbecb9d1SAndroid Build Coastguard Worker    const char *str;
187*bbecb9d1SAndroid Build Coastguard Worker 
188*bbecb9d1SAndroid Build Coastguard Worker    str = os_get_option(name);
189*bbecb9d1SAndroid Build Coastguard Worker    if (!str) {
190*bbecb9d1SAndroid Build Coastguard Worker       result = dfault;
191*bbecb9d1SAndroid Build Coastguard Worker    } else {
192*bbecb9d1SAndroid Build Coastguard Worker       char *endptr;
193*bbecb9d1SAndroid Build Coastguard Worker 
194*bbecb9d1SAndroid Build Coastguard Worker       result = strtol(str, &endptr, 0);
195*bbecb9d1SAndroid Build Coastguard Worker       if (str == endptr) {
196*bbecb9d1SAndroid Build Coastguard Worker          /* Restore the default value when no digits were found. */
197*bbecb9d1SAndroid Build Coastguard Worker          result = dfault;
198*bbecb9d1SAndroid Build Coastguard Worker       }
199*bbecb9d1SAndroid Build Coastguard Worker    }
200*bbecb9d1SAndroid Build Coastguard Worker 
201*bbecb9d1SAndroid Build Coastguard Worker    if (debug_get_option_should_print())
202*bbecb9d1SAndroid Build Coastguard Worker       debug_printf("%s: %s = %li\n", __FUNCTION__, name, result);
203*bbecb9d1SAndroid Build Coastguard Worker 
204*bbecb9d1SAndroid Build Coastguard Worker    return result;
205*bbecb9d1SAndroid Build Coastguard Worker }
206*bbecb9d1SAndroid Build Coastguard Worker 
207*bbecb9d1SAndroid Build Coastguard Worker void
debug_get_version_option(const char * name,unsigned * major,unsigned * minor)208*bbecb9d1SAndroid Build Coastguard Worker debug_get_version_option(const char *name, unsigned *major, unsigned *minor)
209*bbecb9d1SAndroid Build Coastguard Worker {
210*bbecb9d1SAndroid Build Coastguard Worker    const char *str;
211*bbecb9d1SAndroid Build Coastguard Worker 
212*bbecb9d1SAndroid Build Coastguard Worker    str = os_get_option(name);
213*bbecb9d1SAndroid Build Coastguard Worker    if (str) {
214*bbecb9d1SAndroid Build Coastguard Worker       unsigned v_maj, v_min;
215*bbecb9d1SAndroid Build Coastguard Worker       int n;
216*bbecb9d1SAndroid Build Coastguard Worker 
217*bbecb9d1SAndroid Build Coastguard Worker       n = sscanf(str, "%u.%u", &v_maj, &v_min);
218*bbecb9d1SAndroid Build Coastguard Worker       if (n != 2) {
219*bbecb9d1SAndroid Build Coastguard Worker          debug_printf("Illegal version specified for %s : %s\n", name, str);
220*bbecb9d1SAndroid Build Coastguard Worker          return;
221*bbecb9d1SAndroid Build Coastguard Worker       }
222*bbecb9d1SAndroid Build Coastguard Worker       *major = v_maj;
223*bbecb9d1SAndroid Build Coastguard Worker       *minor = v_min;
224*bbecb9d1SAndroid Build Coastguard Worker    }
225*bbecb9d1SAndroid Build Coastguard Worker 
226*bbecb9d1SAndroid Build Coastguard Worker    if (debug_get_option_should_print())
227*bbecb9d1SAndroid Build Coastguard Worker       debug_printf("%s: %s = %u.%u\n", __FUNCTION__, name, *major, *minor);
228*bbecb9d1SAndroid Build Coastguard Worker 
229*bbecb9d1SAndroid Build Coastguard Worker    return;
230*bbecb9d1SAndroid Build Coastguard Worker }
231*bbecb9d1SAndroid Build Coastguard Worker 
232*bbecb9d1SAndroid Build Coastguard Worker static bool
str_has_option(const char * str,const char * name)233*bbecb9d1SAndroid Build Coastguard Worker str_has_option(const char *str, const char *name)
234*bbecb9d1SAndroid Build Coastguard Worker {
235*bbecb9d1SAndroid Build Coastguard Worker    /* Empty string. */
236*bbecb9d1SAndroid Build Coastguard Worker    if (!*str) {
237*bbecb9d1SAndroid Build Coastguard Worker       return false;
238*bbecb9d1SAndroid Build Coastguard Worker    }
239*bbecb9d1SAndroid Build Coastguard Worker 
240*bbecb9d1SAndroid Build Coastguard Worker    /* OPTION=all */
241*bbecb9d1SAndroid Build Coastguard Worker    if (!strcmp(str, "all")) {
242*bbecb9d1SAndroid Build Coastguard Worker       return true;
243*bbecb9d1SAndroid Build Coastguard Worker    }
244*bbecb9d1SAndroid Build Coastguard Worker 
245*bbecb9d1SAndroid Build Coastguard Worker    /* Find 'name' in 'str' surrounded by non-alphanumeric characters. */
246*bbecb9d1SAndroid Build Coastguard Worker    {
247*bbecb9d1SAndroid Build Coastguard Worker       const char *start = str;
248*bbecb9d1SAndroid Build Coastguard Worker       unsigned name_len = strlen(name);
249*bbecb9d1SAndroid Build Coastguard Worker 
250*bbecb9d1SAndroid Build Coastguard Worker       /* 'start' is the beginning of the currently-parsed word,
251*bbecb9d1SAndroid Build Coastguard Worker        * we increment 'str' each iteration.
252*bbecb9d1SAndroid Build Coastguard Worker        * if we find either the end of string or a non-alphanumeric character,
253*bbecb9d1SAndroid Build Coastguard Worker        * we compare 'start' up to 'str-1' with 'name'. */
254*bbecb9d1SAndroid Build Coastguard Worker 
255*bbecb9d1SAndroid Build Coastguard Worker       while (1) {
256*bbecb9d1SAndroid Build Coastguard Worker          if (!*str || !(isalnum(*str) || *str == '_')) {
257*bbecb9d1SAndroid Build Coastguard Worker             if (str-start == name_len &&
258*bbecb9d1SAndroid Build Coastguard Worker                 !memcmp(start, name, name_len)) {
259*bbecb9d1SAndroid Build Coastguard Worker                return true;
260*bbecb9d1SAndroid Build Coastguard Worker             }
261*bbecb9d1SAndroid Build Coastguard Worker 
262*bbecb9d1SAndroid Build Coastguard Worker             if (!*str) {
263*bbecb9d1SAndroid Build Coastguard Worker                return false;
264*bbecb9d1SAndroid Build Coastguard Worker             }
265*bbecb9d1SAndroid Build Coastguard Worker 
266*bbecb9d1SAndroid Build Coastguard Worker             start = str+1;
267*bbecb9d1SAndroid Build Coastguard Worker          }
268*bbecb9d1SAndroid Build Coastguard Worker 
269*bbecb9d1SAndroid Build Coastguard Worker          str++;
270*bbecb9d1SAndroid Build Coastguard Worker       }
271*bbecb9d1SAndroid Build Coastguard Worker    }
272*bbecb9d1SAndroid Build Coastguard Worker 
273*bbecb9d1SAndroid Build Coastguard Worker    return false;
274*bbecb9d1SAndroid Build Coastguard Worker }
275*bbecb9d1SAndroid Build Coastguard Worker 
276*bbecb9d1SAndroid Build Coastguard Worker 
277*bbecb9d1SAndroid Build Coastguard Worker uint64_t
debug_get_flags_option(const char * name,const struct debug_named_value * flags,uint64_t dfault)278*bbecb9d1SAndroid Build Coastguard Worker debug_get_flags_option(const char *name,
279*bbecb9d1SAndroid Build Coastguard Worker                        const struct debug_named_value *flags,
280*bbecb9d1SAndroid Build Coastguard Worker                        uint64_t dfault)
281*bbecb9d1SAndroid Build Coastguard Worker {
282*bbecb9d1SAndroid Build Coastguard Worker    uint64_t result;
283*bbecb9d1SAndroid Build Coastguard Worker    const char *str;
284*bbecb9d1SAndroid Build Coastguard Worker    const struct debug_named_value *orig = flags;
285*bbecb9d1SAndroid Build Coastguard Worker    unsigned namealign = 0;
286*bbecb9d1SAndroid Build Coastguard Worker 
287*bbecb9d1SAndroid Build Coastguard Worker    str = os_get_option(name);
288*bbecb9d1SAndroid Build Coastguard Worker    if (!str)
289*bbecb9d1SAndroid Build Coastguard Worker       result = dfault;
290*bbecb9d1SAndroid Build Coastguard Worker    else if (!strcmp(str, "help")) {
291*bbecb9d1SAndroid Build Coastguard Worker       result = dfault;
292*bbecb9d1SAndroid Build Coastguard Worker       _debug_printf("%s: help for %s:\n", __FUNCTION__, name);
293*bbecb9d1SAndroid Build Coastguard Worker       for (; flags->name; ++flags)
294*bbecb9d1SAndroid Build Coastguard Worker          namealign = MAX2(namealign, strlen(flags->name));
295*bbecb9d1SAndroid Build Coastguard Worker       for (flags = orig; flags->name; ++flags)
296*bbecb9d1SAndroid Build Coastguard Worker          _debug_printf("| %*s [0x%0*"PRIx64"]%s%s\n", namealign, flags->name,
297*bbecb9d1SAndroid Build Coastguard Worker                       (int)sizeof(uint64_t)*CHAR_BIT/4, flags->value,
298*bbecb9d1SAndroid Build Coastguard Worker                       flags->desc ? " " : "", flags->desc ? flags->desc : "");
299*bbecb9d1SAndroid Build Coastguard Worker    }
300*bbecb9d1SAndroid Build Coastguard Worker    else {
301*bbecb9d1SAndroid Build Coastguard Worker       result = 0;
302*bbecb9d1SAndroid Build Coastguard Worker       while (flags->name) {
303*bbecb9d1SAndroid Build Coastguard Worker 	 if (str_has_option(str, flags->name))
304*bbecb9d1SAndroid Build Coastguard Worker 	    result |= flags->value;
305*bbecb9d1SAndroid Build Coastguard Worker 	 ++flags;
306*bbecb9d1SAndroid Build Coastguard Worker       }
307*bbecb9d1SAndroid Build Coastguard Worker    }
308*bbecb9d1SAndroid Build Coastguard Worker 
309*bbecb9d1SAndroid Build Coastguard Worker    if (debug_get_option_should_print()) {
310*bbecb9d1SAndroid Build Coastguard Worker       if (str) {
311*bbecb9d1SAndroid Build Coastguard Worker          debug_printf("%s: %s = 0x%"PRIx64" (%s)\n",
312*bbecb9d1SAndroid Build Coastguard Worker                       __FUNCTION__, name, result, str);
313*bbecb9d1SAndroid Build Coastguard Worker       } else {
314*bbecb9d1SAndroid Build Coastguard Worker          debug_printf("%s: %s = 0x%"PRIx64"\n", __FUNCTION__, name, result);
315*bbecb9d1SAndroid Build Coastguard Worker       }
316*bbecb9d1SAndroid Build Coastguard Worker    }
317*bbecb9d1SAndroid Build Coastguard Worker 
318*bbecb9d1SAndroid Build Coastguard Worker    return result;
319*bbecb9d1SAndroid Build Coastguard Worker }
320*bbecb9d1SAndroid Build Coastguard Worker 
321*bbecb9d1SAndroid Build Coastguard Worker 
322*bbecb9d1SAndroid Build Coastguard Worker void
_debug_assert_fail(const char * expr,const char * file,unsigned line,const char * function)323*bbecb9d1SAndroid Build Coastguard Worker _debug_assert_fail(const char *expr, const char *file, unsigned line,
324*bbecb9d1SAndroid Build Coastguard Worker                    const char *function)
325*bbecb9d1SAndroid Build Coastguard Worker {
326*bbecb9d1SAndroid Build Coastguard Worker    _debug_printf("%s:%u:%s: Assertion `%s' failed.\n",
327*bbecb9d1SAndroid Build Coastguard Worker                  file, line, function, expr);
328*bbecb9d1SAndroid Build Coastguard Worker    os_abort();
329*bbecb9d1SAndroid Build Coastguard Worker }
330*bbecb9d1SAndroid Build Coastguard Worker 
331*bbecb9d1SAndroid Build Coastguard Worker 
332*bbecb9d1SAndroid Build Coastguard Worker const char *
debug_dump_enum(const struct debug_named_value * names,unsigned long value)333*bbecb9d1SAndroid Build Coastguard Worker debug_dump_enum(const struct debug_named_value *names,
334*bbecb9d1SAndroid Build Coastguard Worker                 unsigned long value)
335*bbecb9d1SAndroid Build Coastguard Worker {
336*bbecb9d1SAndroid Build Coastguard Worker    static char rest[64];
337*bbecb9d1SAndroid Build Coastguard Worker 
338*bbecb9d1SAndroid Build Coastguard Worker    while (names->name) {
339*bbecb9d1SAndroid Build Coastguard Worker       if (names->value == value)
340*bbecb9d1SAndroid Build Coastguard Worker 	 return names->name;
341*bbecb9d1SAndroid Build Coastguard Worker       ++names;
342*bbecb9d1SAndroid Build Coastguard Worker    }
343*bbecb9d1SAndroid Build Coastguard Worker 
344*bbecb9d1SAndroid Build Coastguard Worker    snprintf(rest, sizeof(rest), "0x%08lx", value);
345*bbecb9d1SAndroid Build Coastguard Worker    return rest;
346*bbecb9d1SAndroid Build Coastguard Worker }
347*bbecb9d1SAndroid Build Coastguard Worker 
348*bbecb9d1SAndroid Build Coastguard Worker 
349*bbecb9d1SAndroid Build Coastguard Worker const char *
debug_dump_enum_noprefix(const struct debug_named_value * names,const char * prefix,unsigned long value)350*bbecb9d1SAndroid Build Coastguard Worker debug_dump_enum_noprefix(const struct debug_named_value *names,
351*bbecb9d1SAndroid Build Coastguard Worker                          const char *prefix,
352*bbecb9d1SAndroid Build Coastguard Worker                          unsigned long value)
353*bbecb9d1SAndroid Build Coastguard Worker {
354*bbecb9d1SAndroid Build Coastguard Worker    static char rest[64];
355*bbecb9d1SAndroid Build Coastguard Worker 
356*bbecb9d1SAndroid Build Coastguard Worker    while (names->name) {
357*bbecb9d1SAndroid Build Coastguard Worker       if (names->value == value) {
358*bbecb9d1SAndroid Build Coastguard Worker          const char *name = names->name;
359*bbecb9d1SAndroid Build Coastguard Worker          while (*name == *prefix) {
360*bbecb9d1SAndroid Build Coastguard Worker             name++;
361*bbecb9d1SAndroid Build Coastguard Worker             prefix++;
362*bbecb9d1SAndroid Build Coastguard Worker          }
363*bbecb9d1SAndroid Build Coastguard Worker          return name;
364*bbecb9d1SAndroid Build Coastguard Worker       }
365*bbecb9d1SAndroid Build Coastguard Worker       ++names;
366*bbecb9d1SAndroid Build Coastguard Worker    }
367*bbecb9d1SAndroid Build Coastguard Worker 
368*bbecb9d1SAndroid Build Coastguard Worker    snprintf(rest, sizeof(rest), "0x%08lx", value);
369*bbecb9d1SAndroid Build Coastguard Worker    return rest;
370*bbecb9d1SAndroid Build Coastguard Worker }
371*bbecb9d1SAndroid Build Coastguard Worker 
372*bbecb9d1SAndroid Build Coastguard Worker 
373*bbecb9d1SAndroid Build Coastguard Worker const char *
debug_dump_flags(const struct debug_named_value * names,unsigned long value)374*bbecb9d1SAndroid Build Coastguard Worker debug_dump_flags(const struct debug_named_value *names, unsigned long value)
375*bbecb9d1SAndroid Build Coastguard Worker {
376*bbecb9d1SAndroid Build Coastguard Worker    static char output[4096];
377*bbecb9d1SAndroid Build Coastguard Worker    static char rest[256];
378*bbecb9d1SAndroid Build Coastguard Worker    int first = 1;
379*bbecb9d1SAndroid Build Coastguard Worker 
380*bbecb9d1SAndroid Build Coastguard Worker    output[0] = '\0';
381*bbecb9d1SAndroid Build Coastguard Worker 
382*bbecb9d1SAndroid Build Coastguard Worker    while (names->name) {
383*bbecb9d1SAndroid Build Coastguard Worker       if ((names->value & value) == names->value) {
384*bbecb9d1SAndroid Build Coastguard Worker 	 if (!first)
385*bbecb9d1SAndroid Build Coastguard Worker 	    strncat(output, "|", sizeof(output) - strlen(output) - 1);
386*bbecb9d1SAndroid Build Coastguard Worker 	 else
387*bbecb9d1SAndroid Build Coastguard Worker 	    first = 0;
388*bbecb9d1SAndroid Build Coastguard Worker 	 strncat(output, names->name, sizeof(output) - strlen(output) - 1);
389*bbecb9d1SAndroid Build Coastguard Worker 	 output[sizeof(output) - 1] = '\0';
390*bbecb9d1SAndroid Build Coastguard Worker 	 value &= ~names->value;
391*bbecb9d1SAndroid Build Coastguard Worker       }
392*bbecb9d1SAndroid Build Coastguard Worker       ++names;
393*bbecb9d1SAndroid Build Coastguard Worker    }
394*bbecb9d1SAndroid Build Coastguard Worker 
395*bbecb9d1SAndroid Build Coastguard Worker    if (value) {
396*bbecb9d1SAndroid Build Coastguard Worker       if (!first)
397*bbecb9d1SAndroid Build Coastguard Worker 	 strncat(output, "|", sizeof(output) - strlen(output) - 1);
398*bbecb9d1SAndroid Build Coastguard Worker       else
399*bbecb9d1SAndroid Build Coastguard Worker 	 first = 0;
400*bbecb9d1SAndroid Build Coastguard Worker 
401*bbecb9d1SAndroid Build Coastguard Worker       snprintf(rest, sizeof(rest), "0x%08lx", value);
402*bbecb9d1SAndroid Build Coastguard Worker       strncat(output, rest, sizeof(output) - strlen(output) - 1);
403*bbecb9d1SAndroid Build Coastguard Worker       output[sizeof(output) - 1] = '\0';
404*bbecb9d1SAndroid Build Coastguard Worker    }
405*bbecb9d1SAndroid Build Coastguard Worker 
406*bbecb9d1SAndroid Build Coastguard Worker    if (first)
407*bbecb9d1SAndroid Build Coastguard Worker       return "0";
408*bbecb9d1SAndroid Build Coastguard Worker 
409*bbecb9d1SAndroid Build Coastguard Worker    return output;
410*bbecb9d1SAndroid Build Coastguard Worker }
411*bbecb9d1SAndroid Build Coastguard Worker 
412*bbecb9d1SAndroid Build Coastguard Worker 
413*bbecb9d1SAndroid Build Coastguard Worker 
414*bbecb9d1SAndroid Build Coastguard Worker #ifdef DEBUG
415*bbecb9d1SAndroid Build Coastguard Worker int fl_indent = 0;
416*bbecb9d1SAndroid Build Coastguard Worker const char* fl_function[1024];
417*bbecb9d1SAndroid Build Coastguard Worker 
418*bbecb9d1SAndroid Build Coastguard Worker int
debug_funclog_enter(const char * f,UNUSED const int line,UNUSED const char * file)419*bbecb9d1SAndroid Build Coastguard Worker debug_funclog_enter(const char* f, UNUSED const int line,
420*bbecb9d1SAndroid Build Coastguard Worker                     UNUSED const char* file)
421*bbecb9d1SAndroid Build Coastguard Worker {
422*bbecb9d1SAndroid Build Coastguard Worker    int i;
423*bbecb9d1SAndroid Build Coastguard Worker 
424*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < fl_indent; i++)
425*bbecb9d1SAndroid Build Coastguard Worker       debug_printf("  ");
426*bbecb9d1SAndroid Build Coastguard Worker    debug_printf("%s\n", f);
427*bbecb9d1SAndroid Build Coastguard Worker 
428*bbecb9d1SAndroid Build Coastguard Worker    assert(fl_indent < 1023);
429*bbecb9d1SAndroid Build Coastguard Worker    fl_function[fl_indent++] = f;
430*bbecb9d1SAndroid Build Coastguard Worker 
431*bbecb9d1SAndroid Build Coastguard Worker    return 0;
432*bbecb9d1SAndroid Build Coastguard Worker }
433*bbecb9d1SAndroid Build Coastguard Worker 
434*bbecb9d1SAndroid Build Coastguard Worker void
debug_funclog_exit(const char * f,UNUSED const int line,UNUSED const char * file)435*bbecb9d1SAndroid Build Coastguard Worker debug_funclog_exit(const char* f, UNUSED const int line,
436*bbecb9d1SAndroid Build Coastguard Worker                    UNUSED const char* file)
437*bbecb9d1SAndroid Build Coastguard Worker {
438*bbecb9d1SAndroid Build Coastguard Worker    --fl_indent;
439*bbecb9d1SAndroid Build Coastguard Worker    assert(fl_indent >= 0);
440*bbecb9d1SAndroid Build Coastguard Worker    assert(fl_function[fl_indent] == f);
441*bbecb9d1SAndroid Build Coastguard Worker }
442*bbecb9d1SAndroid Build Coastguard Worker 
443*bbecb9d1SAndroid Build Coastguard Worker void
debug_funclog_enter_exit(const char * f,UNUSED const int line,UNUSED const char * file)444*bbecb9d1SAndroid Build Coastguard Worker debug_funclog_enter_exit(const char* f, UNUSED const int line,
445*bbecb9d1SAndroid Build Coastguard Worker                          UNUSED const char* file)
446*bbecb9d1SAndroid Build Coastguard Worker {
447*bbecb9d1SAndroid Build Coastguard Worker    int i;
448*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < fl_indent; i++)
449*bbecb9d1SAndroid Build Coastguard Worker       debug_printf("  ");
450*bbecb9d1SAndroid Build Coastguard Worker    debug_printf("%s\n", f);
451*bbecb9d1SAndroid Build Coastguard Worker }
452*bbecb9d1SAndroid Build Coastguard Worker #endif
453