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