1*cf84ac9aSAndroid Build Coastguard Worker /*
2*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 1991, 1992 Paul Kranenburg <[email protected]>
3*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 1993 Branko Lankester <[email protected]>
4*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <[email protected]>
5*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 1996-1999 Wichert Akkerman <[email protected]>
6*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 1999-2018 The strace developers.
7*cf84ac9aSAndroid Build Coastguard Worker * All rights reserved.
8*cf84ac9aSAndroid Build Coastguard Worker *
9*cf84ac9aSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
10*cf84ac9aSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
11*cf84ac9aSAndroid Build Coastguard Worker * are met:
12*cf84ac9aSAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
13*cf84ac9aSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
14*cf84ac9aSAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
15*cf84ac9aSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
16*cf84ac9aSAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
17*cf84ac9aSAndroid Build Coastguard Worker * 3. The name of the author may not be used to endorse or promote products
18*cf84ac9aSAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
19*cf84ac9aSAndroid Build Coastguard Worker *
20*cf84ac9aSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21*cf84ac9aSAndroid Build Coastguard Worker * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22*cf84ac9aSAndroid Build Coastguard Worker * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23*cf84ac9aSAndroid Build Coastguard Worker * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24*cf84ac9aSAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25*cf84ac9aSAndroid Build Coastguard Worker * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26*cf84ac9aSAndroid Build Coastguard Worker * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27*cf84ac9aSAndroid Build Coastguard Worker * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28*cf84ac9aSAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29*cf84ac9aSAndroid Build Coastguard Worker * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*cf84ac9aSAndroid Build Coastguard Worker */
31*cf84ac9aSAndroid Build Coastguard Worker
32*cf84ac9aSAndroid Build Coastguard Worker #include "defs.h"
33*cf84ac9aSAndroid Build Coastguard Worker #include "xstring.h"
34*cf84ac9aSAndroid Build Coastguard Worker #include <stdarg.h>
35*cf84ac9aSAndroid Build Coastguard Worker
36*cf84ac9aSAndroid Build Coastguard Worker static inline enum xlat_style
get_xlat_style(enum xlat_style style)37*cf84ac9aSAndroid Build Coastguard Worker get_xlat_style(enum xlat_style style)
38*cf84ac9aSAndroid Build Coastguard Worker {
39*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) == XLAT_STYLE_DEFAULT)
40*cf84ac9aSAndroid Build Coastguard Worker return style | xlat_verbosity;
41*cf84ac9aSAndroid Build Coastguard Worker
42*cf84ac9aSAndroid Build Coastguard Worker return style;
43*cf84ac9aSAndroid Build Coastguard Worker }
44*cf84ac9aSAndroid Build Coastguard Worker
45*cf84ac9aSAndroid Build Coastguard Worker static inline const char *
sprint_xlat_val(uint64_t val,enum xlat_style style)46*cf84ac9aSAndroid Build Coastguard Worker sprint_xlat_val(uint64_t val, enum xlat_style style)
47*cf84ac9aSAndroid Build Coastguard Worker {
48*cf84ac9aSAndroid Build Coastguard Worker static char buf[sizeof(val) * 3];
49*cf84ac9aSAndroid Build Coastguard Worker
50*cf84ac9aSAndroid Build Coastguard Worker switch (xlat_format(style)) {
51*cf84ac9aSAndroid Build Coastguard Worker case XLAT_STYLE_FMT_D:
52*cf84ac9aSAndroid Build Coastguard Worker xsprintf(buf, "%" PRId64, val);
53*cf84ac9aSAndroid Build Coastguard Worker break;
54*cf84ac9aSAndroid Build Coastguard Worker
55*cf84ac9aSAndroid Build Coastguard Worker case XLAT_STYLE_FMT_U:
56*cf84ac9aSAndroid Build Coastguard Worker xsprintf(buf, "%" PRIu64, val);
57*cf84ac9aSAndroid Build Coastguard Worker break;
58*cf84ac9aSAndroid Build Coastguard Worker
59*cf84ac9aSAndroid Build Coastguard Worker case XLAT_STYLE_FMT_X:
60*cf84ac9aSAndroid Build Coastguard Worker xsprintf(buf, "%#" PRIx64, val);
61*cf84ac9aSAndroid Build Coastguard Worker break;
62*cf84ac9aSAndroid Build Coastguard Worker }
63*cf84ac9aSAndroid Build Coastguard Worker
64*cf84ac9aSAndroid Build Coastguard Worker return buf;
65*cf84ac9aSAndroid Build Coastguard Worker }
66*cf84ac9aSAndroid Build Coastguard Worker
67*cf84ac9aSAndroid Build Coastguard Worker static inline void
print_xlat_val(uint64_t val,enum xlat_style style)68*cf84ac9aSAndroid Build Coastguard Worker print_xlat_val(uint64_t val, enum xlat_style style)
69*cf84ac9aSAndroid Build Coastguard Worker {
70*cf84ac9aSAndroid Build Coastguard Worker tprints(sprint_xlat_val(val, style));
71*cf84ac9aSAndroid Build Coastguard Worker }
72*cf84ac9aSAndroid Build Coastguard Worker
73*cf84ac9aSAndroid Build Coastguard Worker const char *
xlookup(const struct xlat * xlat,const uint64_t val)74*cf84ac9aSAndroid Build Coastguard Worker xlookup(const struct xlat *xlat, const uint64_t val)
75*cf84ac9aSAndroid Build Coastguard Worker {
76*cf84ac9aSAndroid Build Coastguard Worker static const struct xlat *pos;
77*cf84ac9aSAndroid Build Coastguard Worker
78*cf84ac9aSAndroid Build Coastguard Worker if (xlat)
79*cf84ac9aSAndroid Build Coastguard Worker pos = xlat;
80*cf84ac9aSAndroid Build Coastguard Worker
81*cf84ac9aSAndroid Build Coastguard Worker for (; pos->str != NULL; pos++)
82*cf84ac9aSAndroid Build Coastguard Worker if (pos->val == val)
83*cf84ac9aSAndroid Build Coastguard Worker return pos->str;
84*cf84ac9aSAndroid Build Coastguard Worker return NULL;
85*cf84ac9aSAndroid Build Coastguard Worker }
86*cf84ac9aSAndroid Build Coastguard Worker
87*cf84ac9aSAndroid Build Coastguard Worker static int
xlat_bsearch_compare(const void * a,const void * b)88*cf84ac9aSAndroid Build Coastguard Worker xlat_bsearch_compare(const void *a, const void *b)
89*cf84ac9aSAndroid Build Coastguard Worker {
90*cf84ac9aSAndroid Build Coastguard Worker const uint64_t val1 = *(const uint64_t *) a;
91*cf84ac9aSAndroid Build Coastguard Worker const uint64_t val2 = ((const struct xlat *) b)->val;
92*cf84ac9aSAndroid Build Coastguard Worker return (val1 > val2) ? 1 : (val1 < val2) ? -1 : 0;
93*cf84ac9aSAndroid Build Coastguard Worker }
94*cf84ac9aSAndroid Build Coastguard Worker
95*cf84ac9aSAndroid Build Coastguard Worker const char *
xlat_search(const struct xlat * xlat,const size_t nmemb,const uint64_t val)96*cf84ac9aSAndroid Build Coastguard Worker xlat_search(const struct xlat *xlat, const size_t nmemb, const uint64_t val)
97*cf84ac9aSAndroid Build Coastguard Worker {
98*cf84ac9aSAndroid Build Coastguard Worker static const struct xlat *pos;
99*cf84ac9aSAndroid Build Coastguard Worker static size_t memb_left;
100*cf84ac9aSAndroid Build Coastguard Worker
101*cf84ac9aSAndroid Build Coastguard Worker if (xlat) {
102*cf84ac9aSAndroid Build Coastguard Worker pos = xlat;
103*cf84ac9aSAndroid Build Coastguard Worker memb_left = nmemb;
104*cf84ac9aSAndroid Build Coastguard Worker }
105*cf84ac9aSAndroid Build Coastguard Worker
106*cf84ac9aSAndroid Build Coastguard Worker const struct xlat *e =
107*cf84ac9aSAndroid Build Coastguard Worker bsearch((const void *) &val,
108*cf84ac9aSAndroid Build Coastguard Worker pos, memb_left, sizeof(*pos), xlat_bsearch_compare);
109*cf84ac9aSAndroid Build Coastguard Worker
110*cf84ac9aSAndroid Build Coastguard Worker if (e) {
111*cf84ac9aSAndroid Build Coastguard Worker memb_left -= e - pos;
112*cf84ac9aSAndroid Build Coastguard Worker return e->str;
113*cf84ac9aSAndroid Build Coastguard Worker } else {
114*cf84ac9aSAndroid Build Coastguard Worker return NULL;
115*cf84ac9aSAndroid Build Coastguard Worker }
116*cf84ac9aSAndroid Build Coastguard Worker }
117*cf84ac9aSAndroid Build Coastguard Worker
118*cf84ac9aSAndroid Build Coastguard Worker /**
119*cf84ac9aSAndroid Build Coastguard Worker * Print entry in struct xlat table, if there.
120*cf84ac9aSAndroid Build Coastguard Worker *
121*cf84ac9aSAndroid Build Coastguard Worker * @param val Value to search a literal representation for.
122*cf84ac9aSAndroid Build Coastguard Worker * @param dflt String (abbreviated in comment syntax) which should be emitted
123*cf84ac9aSAndroid Build Coastguard Worker * if no appropriate xlat value has been found.
124*cf84ac9aSAndroid Build Coastguard Worker * @param style Style in which xlat value should be printed.
125*cf84ac9aSAndroid Build Coastguard Worker * @param xlat (And the following arguments) Pointers to arrays of xlat values.
126*cf84ac9aSAndroid Build Coastguard Worker * The last argument should be NULL.
127*cf84ac9aSAndroid Build Coastguard Worker * @return 1 if appropriate xlat value has been found, 0 otherwise.
128*cf84ac9aSAndroid Build Coastguard Worker */
129*cf84ac9aSAndroid Build Coastguard Worker int
printxvals_ex(const uint64_t val,const char * dflt,enum xlat_style style,const struct xlat * xlat,...)130*cf84ac9aSAndroid Build Coastguard Worker printxvals_ex(const uint64_t val, const char *dflt, enum xlat_style style,
131*cf84ac9aSAndroid Build Coastguard Worker const struct xlat *xlat, ...)
132*cf84ac9aSAndroid Build Coastguard Worker {
133*cf84ac9aSAndroid Build Coastguard Worker static const struct xlat *last;
134*cf84ac9aSAndroid Build Coastguard Worker
135*cf84ac9aSAndroid Build Coastguard Worker style = get_xlat_style(style);
136*cf84ac9aSAndroid Build Coastguard Worker
137*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) == XLAT_STYLE_RAW) {
138*cf84ac9aSAndroid Build Coastguard Worker print_xlat_val(val, style);
139*cf84ac9aSAndroid Build Coastguard Worker return 0;
140*cf84ac9aSAndroid Build Coastguard Worker }
141*cf84ac9aSAndroid Build Coastguard Worker
142*cf84ac9aSAndroid Build Coastguard Worker const char *str = NULL;
143*cf84ac9aSAndroid Build Coastguard Worker va_list args;
144*cf84ac9aSAndroid Build Coastguard Worker
145*cf84ac9aSAndroid Build Coastguard Worker va_start(args, xlat);
146*cf84ac9aSAndroid Build Coastguard Worker
147*cf84ac9aSAndroid Build Coastguard Worker if (!xlat)
148*cf84ac9aSAndroid Build Coastguard Worker xlat = last;
149*cf84ac9aSAndroid Build Coastguard Worker
150*cf84ac9aSAndroid Build Coastguard Worker for (; xlat; xlat = va_arg(args, const struct xlat *)) {
151*cf84ac9aSAndroid Build Coastguard Worker last = xlat;
152*cf84ac9aSAndroid Build Coastguard Worker
153*cf84ac9aSAndroid Build Coastguard Worker str = xlookup(xlat, val);
154*cf84ac9aSAndroid Build Coastguard Worker
155*cf84ac9aSAndroid Build Coastguard Worker if (str) {
156*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
157*cf84ac9aSAndroid Build Coastguard Worker print_xlat_val(val, style);
158*cf84ac9aSAndroid Build Coastguard Worker tprints_comment(str);
159*cf84ac9aSAndroid Build Coastguard Worker } else {
160*cf84ac9aSAndroid Build Coastguard Worker tprints(str);
161*cf84ac9aSAndroid Build Coastguard Worker }
162*cf84ac9aSAndroid Build Coastguard Worker
163*cf84ac9aSAndroid Build Coastguard Worker goto printxvals_ex_end;
164*cf84ac9aSAndroid Build Coastguard Worker }
165*cf84ac9aSAndroid Build Coastguard Worker }
166*cf84ac9aSAndroid Build Coastguard Worker
167*cf84ac9aSAndroid Build Coastguard Worker /* No hits -- print raw # instead. */
168*cf84ac9aSAndroid Build Coastguard Worker print_xlat_val(val, style);
169*cf84ac9aSAndroid Build Coastguard Worker tprints_comment(dflt);
170*cf84ac9aSAndroid Build Coastguard Worker
171*cf84ac9aSAndroid Build Coastguard Worker printxvals_ex_end:
172*cf84ac9aSAndroid Build Coastguard Worker va_end(args);
173*cf84ac9aSAndroid Build Coastguard Worker
174*cf84ac9aSAndroid Build Coastguard Worker return !!str;
175*cf84ac9aSAndroid Build Coastguard Worker }
176*cf84ac9aSAndroid Build Coastguard Worker
177*cf84ac9aSAndroid Build Coastguard Worker int
sprintxval_ex(char * const buf,const size_t size,const struct xlat * const x,const unsigned int val,const char * const dflt,enum xlat_style style)178*cf84ac9aSAndroid Build Coastguard Worker sprintxval_ex(char *const buf, const size_t size, const struct xlat *const x,
179*cf84ac9aSAndroid Build Coastguard Worker const unsigned int val, const char *const dflt,
180*cf84ac9aSAndroid Build Coastguard Worker enum xlat_style style)
181*cf84ac9aSAndroid Build Coastguard Worker {
182*cf84ac9aSAndroid Build Coastguard Worker style = get_xlat_style(style);
183*cf84ac9aSAndroid Build Coastguard Worker
184*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) == XLAT_STYLE_RAW)
185*cf84ac9aSAndroid Build Coastguard Worker return xsnprintf(buf, size, "%s", sprint_xlat_val(val, style));
186*cf84ac9aSAndroid Build Coastguard Worker
187*cf84ac9aSAndroid Build Coastguard Worker const char *const str = xlookup(x, val);
188*cf84ac9aSAndroid Build Coastguard Worker
189*cf84ac9aSAndroid Build Coastguard Worker if (str) {
190*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) == XLAT_STYLE_VERBOSE)
191*cf84ac9aSAndroid Build Coastguard Worker return xsnprintf(buf, size, "%s /* %s */",
192*cf84ac9aSAndroid Build Coastguard Worker sprint_xlat_val(val, style), str);
193*cf84ac9aSAndroid Build Coastguard Worker else
194*cf84ac9aSAndroid Build Coastguard Worker return xsnprintf(buf, size, "%s", str);
195*cf84ac9aSAndroid Build Coastguard Worker }
196*cf84ac9aSAndroid Build Coastguard Worker if (dflt)
197*cf84ac9aSAndroid Build Coastguard Worker return xsnprintf(buf, size, "%s /* %s */",
198*cf84ac9aSAndroid Build Coastguard Worker sprint_xlat_val(val, style), dflt);
199*cf84ac9aSAndroid Build Coastguard Worker
200*cf84ac9aSAndroid Build Coastguard Worker return xsnprintf(buf, size, "%s", sprint_xlat_val(val, style));
201*cf84ac9aSAndroid Build Coastguard Worker }
202*cf84ac9aSAndroid Build Coastguard Worker
203*cf84ac9aSAndroid Build Coastguard Worker /**
204*cf84ac9aSAndroid Build Coastguard Worker * Print entry in sorted struct xlat table, if it is there.
205*cf84ac9aSAndroid Build Coastguard Worker *
206*cf84ac9aSAndroid Build Coastguard Worker * @param xlat Pointer to an array of xlat values (not terminated with
207*cf84ac9aSAndroid Build Coastguard Worker * XLAT_END).
208*cf84ac9aSAndroid Build Coastguard Worker * @param xlat_size Number of xlat elements present in array (usually ARRAY_SIZE
209*cf84ac9aSAndroid Build Coastguard Worker * if array is declared in the unit's scope and not
210*cf84ac9aSAndroid Build Coastguard Worker * terminated with XLAT_END).
211*cf84ac9aSAndroid Build Coastguard Worker * @param val Value to search literal representation for.
212*cf84ac9aSAndroid Build Coastguard Worker * @param dflt String (abbreviated in comment syntax) which should be
213*cf84ac9aSAndroid Build Coastguard Worker * emitted if no appropriate xlat value has been found.
214*cf84ac9aSAndroid Build Coastguard Worker * @param style Style in which xlat value should be printed.
215*cf84ac9aSAndroid Build Coastguard Worker * @param fn Search function.
216*cf84ac9aSAndroid Build Coastguard Worker * @return 1 if appropriate xlat value has been found, 0
217*cf84ac9aSAndroid Build Coastguard Worker * otherwise.
218*cf84ac9aSAndroid Build Coastguard Worker */
219*cf84ac9aSAndroid Build Coastguard Worker static int
printxval_sized(const struct xlat * xlat,size_t xlat_size,uint64_t val,const char * dflt,enum xlat_style style,const char * (* fn)(const struct xlat *,size_t,uint64_t))220*cf84ac9aSAndroid Build Coastguard Worker printxval_sized(const struct xlat *xlat, size_t xlat_size, uint64_t val,
221*cf84ac9aSAndroid Build Coastguard Worker const char *dflt, enum xlat_style style,
222*cf84ac9aSAndroid Build Coastguard Worker const char *(* fn)(const struct xlat *, size_t, uint64_t))
223*cf84ac9aSAndroid Build Coastguard Worker {
224*cf84ac9aSAndroid Build Coastguard Worker style = get_xlat_style(style);
225*cf84ac9aSAndroid Build Coastguard Worker
226*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) == XLAT_STYLE_RAW) {
227*cf84ac9aSAndroid Build Coastguard Worker print_xlat_val(val, style);
228*cf84ac9aSAndroid Build Coastguard Worker return 0;
229*cf84ac9aSAndroid Build Coastguard Worker }
230*cf84ac9aSAndroid Build Coastguard Worker
231*cf84ac9aSAndroid Build Coastguard Worker const char *s = fn(xlat, xlat_size, val);
232*cf84ac9aSAndroid Build Coastguard Worker
233*cf84ac9aSAndroid Build Coastguard Worker if (s) {
234*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
235*cf84ac9aSAndroid Build Coastguard Worker print_xlat_val(val, style);
236*cf84ac9aSAndroid Build Coastguard Worker tprints_comment(s);
237*cf84ac9aSAndroid Build Coastguard Worker } else {
238*cf84ac9aSAndroid Build Coastguard Worker tprints(s);
239*cf84ac9aSAndroid Build Coastguard Worker }
240*cf84ac9aSAndroid Build Coastguard Worker return 1;
241*cf84ac9aSAndroid Build Coastguard Worker }
242*cf84ac9aSAndroid Build Coastguard Worker
243*cf84ac9aSAndroid Build Coastguard Worker print_xlat_val(val, style);
244*cf84ac9aSAndroid Build Coastguard Worker tprints_comment(dflt);
245*cf84ac9aSAndroid Build Coastguard Worker
246*cf84ac9aSAndroid Build Coastguard Worker return 0;
247*cf84ac9aSAndroid Build Coastguard Worker }
248*cf84ac9aSAndroid Build Coastguard Worker
249*cf84ac9aSAndroid Build Coastguard Worker int
printxval_searchn_ex(const struct xlat * xlat,size_t xlat_size,uint64_t val,const char * dflt,enum xlat_style style)250*cf84ac9aSAndroid Build Coastguard Worker printxval_searchn_ex(const struct xlat *xlat, size_t xlat_size, uint64_t val,
251*cf84ac9aSAndroid Build Coastguard Worker const char *dflt, enum xlat_style style)
252*cf84ac9aSAndroid Build Coastguard Worker {
253*cf84ac9aSAndroid Build Coastguard Worker return printxval_sized(xlat, xlat_size, val, dflt, style,
254*cf84ac9aSAndroid Build Coastguard Worker xlat_search);
255*cf84ac9aSAndroid Build Coastguard Worker }
256*cf84ac9aSAndroid Build Coastguard Worker
257*cf84ac9aSAndroid Build Coastguard Worker const char *
xlat_idx(const struct xlat * xlat,size_t nmemb,uint64_t val)258*cf84ac9aSAndroid Build Coastguard Worker xlat_idx(const struct xlat *xlat, size_t nmemb, uint64_t val)
259*cf84ac9aSAndroid Build Coastguard Worker {
260*cf84ac9aSAndroid Build Coastguard Worker static const struct xlat *pos;
261*cf84ac9aSAndroid Build Coastguard Worker static size_t memb_left;
262*cf84ac9aSAndroid Build Coastguard Worker
263*cf84ac9aSAndroid Build Coastguard Worker if (xlat) {
264*cf84ac9aSAndroid Build Coastguard Worker pos = xlat;
265*cf84ac9aSAndroid Build Coastguard Worker memb_left = nmemb;
266*cf84ac9aSAndroid Build Coastguard Worker }
267*cf84ac9aSAndroid Build Coastguard Worker
268*cf84ac9aSAndroid Build Coastguard Worker if (val >= memb_left)
269*cf84ac9aSAndroid Build Coastguard Worker return NULL;
270*cf84ac9aSAndroid Build Coastguard Worker
271*cf84ac9aSAndroid Build Coastguard Worker if (val != pos[val].val) {
272*cf84ac9aSAndroid Build Coastguard Worker error_func_msg("Unexpected xlat value %" PRIu64
273*cf84ac9aSAndroid Build Coastguard Worker " at index %" PRIu64,
274*cf84ac9aSAndroid Build Coastguard Worker pos[val].val, val);
275*cf84ac9aSAndroid Build Coastguard Worker return NULL;
276*cf84ac9aSAndroid Build Coastguard Worker }
277*cf84ac9aSAndroid Build Coastguard Worker
278*cf84ac9aSAndroid Build Coastguard Worker return pos[val].str;
279*cf84ac9aSAndroid Build Coastguard Worker }
280*cf84ac9aSAndroid Build Coastguard Worker
281*cf84ac9aSAndroid Build Coastguard Worker int
printxval_indexn_ex(const struct xlat * xlat,size_t xlat_size,uint64_t val,const char * dflt,enum xlat_style style)282*cf84ac9aSAndroid Build Coastguard Worker printxval_indexn_ex(const struct xlat *xlat, size_t xlat_size, uint64_t val,
283*cf84ac9aSAndroid Build Coastguard Worker const char *dflt, enum xlat_style style)
284*cf84ac9aSAndroid Build Coastguard Worker {
285*cf84ac9aSAndroid Build Coastguard Worker return printxval_sized(xlat, xlat_size, val, dflt, style, xlat_idx);
286*cf84ac9aSAndroid Build Coastguard Worker }
287*cf84ac9aSAndroid Build Coastguard Worker
288*cf84ac9aSAndroid Build Coastguard Worker /*
289*cf84ac9aSAndroid Build Coastguard Worker * Interpret `xlat' as an array of flags.
290*cf84ac9aSAndroid Build Coastguard Worker * Print to static string the entries whose bits are on in `flags'
291*cf84ac9aSAndroid Build Coastguard Worker * Return static string. If 0 is provided as flags, and there is no flag that
292*cf84ac9aSAndroid Build Coastguard Worker * has the value of 0 (it should be the first in xlat table), return NULL.
293*cf84ac9aSAndroid Build Coastguard Worker *
294*cf84ac9aSAndroid Build Coastguard Worker * Expected output:
295*cf84ac9aSAndroid Build Coastguard Worker * +------------+------------+---------+------------+
296*cf84ac9aSAndroid Build Coastguard Worker * | flags != 0 | xlat found | style | output |
297*cf84ac9aSAndroid Build Coastguard Worker * +------------+------------+---------+------------+
298*cf84ac9aSAndroid Build Coastguard Worker * | false | (any) | raw | <none> |
299*cf84ac9aSAndroid Build Coastguard Worker * | true | (any) | raw | VAL |
300*cf84ac9aSAndroid Build Coastguard Worker * +------------+------------+---------+------------+
301*cf84ac9aSAndroid Build Coastguard Worker * | false | false | abbrev | <none> |
302*cf84ac9aSAndroid Build Coastguard Worker * | true | false | abbrev | VAL |
303*cf84ac9aSAndroid Build Coastguard Worker * | (any) | true | abbrev | XLAT |
304*cf84ac9aSAndroid Build Coastguard Worker * +------------+------------+---------+------------+
305*cf84ac9aSAndroid Build Coastguard Worker * | false | false | verbose | <none> |
306*cf84ac9aSAndroid Build Coastguard Worker * | true | false | verbose | VAL |
307*cf84ac9aSAndroid Build Coastguard Worker * | (any) | true | verbose | VAL (XLAT) |
308*cf84ac9aSAndroid Build Coastguard Worker * +------------+------------+---------+------------+
309*cf84ac9aSAndroid Build Coastguard Worker */
310*cf84ac9aSAndroid Build Coastguard Worker const char *
sprintflags_ex(const char * prefix,const struct xlat * xlat,uint64_t flags,enum xlat_style style)311*cf84ac9aSAndroid Build Coastguard Worker sprintflags_ex(const char *prefix, const struct xlat *xlat, uint64_t flags,
312*cf84ac9aSAndroid Build Coastguard Worker enum xlat_style style)
313*cf84ac9aSAndroid Build Coastguard Worker {
314*cf84ac9aSAndroid Build Coastguard Worker static char outstr[1024];
315*cf84ac9aSAndroid Build Coastguard Worker char *outptr;
316*cf84ac9aSAndroid Build Coastguard Worker int found = 0;
317*cf84ac9aSAndroid Build Coastguard Worker
318*cf84ac9aSAndroid Build Coastguard Worker outptr = stpcpy(outstr, prefix);
319*cf84ac9aSAndroid Build Coastguard Worker style = get_xlat_style(style);
320*cf84ac9aSAndroid Build Coastguard Worker
321*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) == XLAT_STYLE_RAW) {
322*cf84ac9aSAndroid Build Coastguard Worker if (!flags)
323*cf84ac9aSAndroid Build Coastguard Worker return NULL;
324*cf84ac9aSAndroid Build Coastguard Worker
325*cf84ac9aSAndroid Build Coastguard Worker outptr = xappendstr(outstr, outptr, "%s",
326*cf84ac9aSAndroid Build Coastguard Worker sprint_xlat_val(flags, style));
327*cf84ac9aSAndroid Build Coastguard Worker
328*cf84ac9aSAndroid Build Coastguard Worker return outstr;
329*cf84ac9aSAndroid Build Coastguard Worker }
330*cf84ac9aSAndroid Build Coastguard Worker
331*cf84ac9aSAndroid Build Coastguard Worker if (flags == 0 && xlat->val == 0 && xlat->str) {
332*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
333*cf84ac9aSAndroid Build Coastguard Worker outptr = xappendstr(outstr, outptr, "0 /* %s */",
334*cf84ac9aSAndroid Build Coastguard Worker xlat->str);
335*cf84ac9aSAndroid Build Coastguard Worker } else {
336*cf84ac9aSAndroid Build Coastguard Worker strcpy(outptr, xlat->str);
337*cf84ac9aSAndroid Build Coastguard Worker }
338*cf84ac9aSAndroid Build Coastguard Worker
339*cf84ac9aSAndroid Build Coastguard Worker return outstr;
340*cf84ac9aSAndroid Build Coastguard Worker }
341*cf84ac9aSAndroid Build Coastguard Worker
342*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) == XLAT_STYLE_VERBOSE && flags)
343*cf84ac9aSAndroid Build Coastguard Worker outptr = xappendstr(outstr, outptr, "%s",
344*cf84ac9aSAndroid Build Coastguard Worker sprint_xlat_val(flags, style));
345*cf84ac9aSAndroid Build Coastguard Worker
346*cf84ac9aSAndroid Build Coastguard Worker for (; flags && xlat->str; xlat++) {
347*cf84ac9aSAndroid Build Coastguard Worker if (xlat->val && (flags & xlat->val) == xlat->val) {
348*cf84ac9aSAndroid Build Coastguard Worker if (found)
349*cf84ac9aSAndroid Build Coastguard Worker *outptr++ = '|';
350*cf84ac9aSAndroid Build Coastguard Worker else if (xlat_verbose(style) == XLAT_STYLE_VERBOSE)
351*cf84ac9aSAndroid Build Coastguard Worker outptr = stpcpy(outptr, " /* ");
352*cf84ac9aSAndroid Build Coastguard Worker
353*cf84ac9aSAndroid Build Coastguard Worker outptr = stpcpy(outptr, xlat->str);
354*cf84ac9aSAndroid Build Coastguard Worker found = 1;
355*cf84ac9aSAndroid Build Coastguard Worker flags &= ~xlat->val;
356*cf84ac9aSAndroid Build Coastguard Worker }
357*cf84ac9aSAndroid Build Coastguard Worker }
358*cf84ac9aSAndroid Build Coastguard Worker
359*cf84ac9aSAndroid Build Coastguard Worker if (flags) {
360*cf84ac9aSAndroid Build Coastguard Worker if (found)
361*cf84ac9aSAndroid Build Coastguard Worker *outptr++ = '|';
362*cf84ac9aSAndroid Build Coastguard Worker if (found || xlat_verbose(style) != XLAT_STYLE_VERBOSE)
363*cf84ac9aSAndroid Build Coastguard Worker outptr = xappendstr(outstr, outptr, "%s",
364*cf84ac9aSAndroid Build Coastguard Worker sprint_xlat_val(flags, style));
365*cf84ac9aSAndroid Build Coastguard Worker } else {
366*cf84ac9aSAndroid Build Coastguard Worker if (!found)
367*cf84ac9aSAndroid Build Coastguard Worker return NULL;
368*cf84ac9aSAndroid Build Coastguard Worker }
369*cf84ac9aSAndroid Build Coastguard Worker
370*cf84ac9aSAndroid Build Coastguard Worker if (found && xlat_verbose(style) == XLAT_STYLE_VERBOSE)
371*cf84ac9aSAndroid Build Coastguard Worker outptr = stpcpy(outptr, " */");
372*cf84ac9aSAndroid Build Coastguard Worker
373*cf84ac9aSAndroid Build Coastguard Worker return outstr;
374*cf84ac9aSAndroid Build Coastguard Worker }
375*cf84ac9aSAndroid Build Coastguard Worker
376*cf84ac9aSAndroid Build Coastguard Worker /**
377*cf84ac9aSAndroid Build Coastguard Worker * Print flags from multiple xlat tables.
378*cf84ac9aSAndroid Build Coastguard Worker *
379*cf84ac9aSAndroid Build Coastguard Worker * Expected output:
380*cf84ac9aSAndroid Build Coastguard Worker * +------------+--------------+------------+---------+------------+
381*cf84ac9aSAndroid Build Coastguard Worker * | flags != 0 | dflt != NULL | xlat found | style | output |
382*cf84ac9aSAndroid Build Coastguard Worker * +------------+--------------+------------+---------+------------+
383*cf84ac9aSAndroid Build Coastguard Worker * | false | false | (any) | raw | <none> |
384*cf84ac9aSAndroid Build Coastguard Worker * | false | true | (any) | raw | VAL |
385*cf84ac9aSAndroid Build Coastguard Worker * | true | (any) | (any) | raw | VAL |
386*cf84ac9aSAndroid Build Coastguard Worker * +------------+--------------+------------+---------+------------+
387*cf84ac9aSAndroid Build Coastguard Worker * | false | false | false | abbrev | <none> |
388*cf84ac9aSAndroid Build Coastguard Worker * | false | true | false | abbrev | VAL |
389*cf84ac9aSAndroid Build Coastguard Worker * | true | false | false | abbrev | VAL |
390*cf84ac9aSAndroid Build Coastguard Worker * | true | true | false | abbrev | VAL (DFLT) |
391*cf84ac9aSAndroid Build Coastguard Worker * | (any) | (any) | true | abbrev | XLAT |
392*cf84ac9aSAndroid Build Coastguard Worker * +------------+--------------+------------+---------+------------+
393*cf84ac9aSAndroid Build Coastguard Worker * | false | false | false | verbose | <none> |
394*cf84ac9aSAndroid Build Coastguard Worker * | false | true | false | verbose | VAL |
395*cf84ac9aSAndroid Build Coastguard Worker * | true | false | false | verbose | VAL |
396*cf84ac9aSAndroid Build Coastguard Worker * | true | true | false | verbose | VAL (DFLT) |
397*cf84ac9aSAndroid Build Coastguard Worker * | (any) | (any) | true | verbose | VAL (XLAT) |
398*cf84ac9aSAndroid Build Coastguard Worker * +------------+--------------+------------+---------+------------+
399*cf84ac9aSAndroid Build Coastguard Worker */
400*cf84ac9aSAndroid Build Coastguard Worker int
printflags_ex(uint64_t flags,const char * dflt,enum xlat_style style,const struct xlat * xlat,...)401*cf84ac9aSAndroid Build Coastguard Worker printflags_ex(uint64_t flags, const char *dflt, enum xlat_style style,
402*cf84ac9aSAndroid Build Coastguard Worker const struct xlat *xlat, ...)
403*cf84ac9aSAndroid Build Coastguard Worker {
404*cf84ac9aSAndroid Build Coastguard Worker style = get_xlat_style(style);
405*cf84ac9aSAndroid Build Coastguard Worker
406*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) == XLAT_STYLE_RAW) {
407*cf84ac9aSAndroid Build Coastguard Worker if (flags || dflt) {
408*cf84ac9aSAndroid Build Coastguard Worker print_xlat_val(flags, style);
409*cf84ac9aSAndroid Build Coastguard Worker return 1;
410*cf84ac9aSAndroid Build Coastguard Worker }
411*cf84ac9aSAndroid Build Coastguard Worker
412*cf84ac9aSAndroid Build Coastguard Worker return 0;
413*cf84ac9aSAndroid Build Coastguard Worker }
414*cf84ac9aSAndroid Build Coastguard Worker
415*cf84ac9aSAndroid Build Coastguard Worker const char *init_sep = "";
416*cf84ac9aSAndroid Build Coastguard Worker unsigned int n = 0;
417*cf84ac9aSAndroid Build Coastguard Worker va_list args;
418*cf84ac9aSAndroid Build Coastguard Worker
419*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
420*cf84ac9aSAndroid Build Coastguard Worker init_sep = " /* ";
421*cf84ac9aSAndroid Build Coastguard Worker if (flags)
422*cf84ac9aSAndroid Build Coastguard Worker print_xlat_val(flags, style);
423*cf84ac9aSAndroid Build Coastguard Worker }
424*cf84ac9aSAndroid Build Coastguard Worker
425*cf84ac9aSAndroid Build Coastguard Worker va_start(args, xlat);
426*cf84ac9aSAndroid Build Coastguard Worker for (; xlat; xlat = va_arg(args, const struct xlat *)) {
427*cf84ac9aSAndroid Build Coastguard Worker for (; (flags || !n) && xlat->str; ++xlat) {
428*cf84ac9aSAndroid Build Coastguard Worker if ((flags == xlat->val) ||
429*cf84ac9aSAndroid Build Coastguard Worker (xlat->val && (flags & xlat->val) == xlat->val)) {
430*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) == XLAT_STYLE_VERBOSE
431*cf84ac9aSAndroid Build Coastguard Worker && !flags)
432*cf84ac9aSAndroid Build Coastguard Worker tprints("0");
433*cf84ac9aSAndroid Build Coastguard Worker tprintf("%s%s",
434*cf84ac9aSAndroid Build Coastguard Worker (n++ ? "|" : init_sep), xlat->str);
435*cf84ac9aSAndroid Build Coastguard Worker flags &= ~xlat->val;
436*cf84ac9aSAndroid Build Coastguard Worker }
437*cf84ac9aSAndroid Build Coastguard Worker if (!flags)
438*cf84ac9aSAndroid Build Coastguard Worker break;
439*cf84ac9aSAndroid Build Coastguard Worker }
440*cf84ac9aSAndroid Build Coastguard Worker }
441*cf84ac9aSAndroid Build Coastguard Worker va_end(args);
442*cf84ac9aSAndroid Build Coastguard Worker
443*cf84ac9aSAndroid Build Coastguard Worker if (n) {
444*cf84ac9aSAndroid Build Coastguard Worker if (flags) {
445*cf84ac9aSAndroid Build Coastguard Worker tprints("|");
446*cf84ac9aSAndroid Build Coastguard Worker print_xlat_val(flags, style);
447*cf84ac9aSAndroid Build Coastguard Worker n++;
448*cf84ac9aSAndroid Build Coastguard Worker }
449*cf84ac9aSAndroid Build Coastguard Worker
450*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) == XLAT_STYLE_VERBOSE)
451*cf84ac9aSAndroid Build Coastguard Worker tprints(" */");
452*cf84ac9aSAndroid Build Coastguard Worker } else {
453*cf84ac9aSAndroid Build Coastguard Worker if (flags) {
454*cf84ac9aSAndroid Build Coastguard Worker if (xlat_verbose(style) != XLAT_STYLE_VERBOSE)
455*cf84ac9aSAndroid Build Coastguard Worker print_xlat_val(flags, style);
456*cf84ac9aSAndroid Build Coastguard Worker tprints_comment(dflt);
457*cf84ac9aSAndroid Build Coastguard Worker } else {
458*cf84ac9aSAndroid Build Coastguard Worker if (dflt)
459*cf84ac9aSAndroid Build Coastguard Worker tprints("0");
460*cf84ac9aSAndroid Build Coastguard Worker }
461*cf84ac9aSAndroid Build Coastguard Worker }
462*cf84ac9aSAndroid Build Coastguard Worker
463*cf84ac9aSAndroid Build Coastguard Worker return n;
464*cf84ac9aSAndroid Build Coastguard Worker }
465*cf84ac9aSAndroid Build Coastguard Worker
466*cf84ac9aSAndroid Build Coastguard Worker void
print_xlat_ex(const uint64_t val,const char * str,enum xlat_style style)467*cf84ac9aSAndroid Build Coastguard Worker print_xlat_ex(const uint64_t val, const char *str, enum xlat_style style)
468*cf84ac9aSAndroid Build Coastguard Worker {
469*cf84ac9aSAndroid Build Coastguard Worker bool default_str = style & PXF_DEFAULT_STR;
470*cf84ac9aSAndroid Build Coastguard Worker style = get_xlat_style(style);
471*cf84ac9aSAndroid Build Coastguard Worker
472*cf84ac9aSAndroid Build Coastguard Worker switch (xlat_verbose(style)) {
473*cf84ac9aSAndroid Build Coastguard Worker case XLAT_STYLE_ABBREV:
474*cf84ac9aSAndroid Build Coastguard Worker if (str) {
475*cf84ac9aSAndroid Build Coastguard Worker if (default_str) {
476*cf84ac9aSAndroid Build Coastguard Worker print_xlat_val(val, style);
477*cf84ac9aSAndroid Build Coastguard Worker tprints_comment(str);
478*cf84ac9aSAndroid Build Coastguard Worker } else {
479*cf84ac9aSAndroid Build Coastguard Worker tprints(str);
480*cf84ac9aSAndroid Build Coastguard Worker }
481*cf84ac9aSAndroid Build Coastguard Worker break;
482*cf84ac9aSAndroid Build Coastguard Worker }
483*cf84ac9aSAndroid Build Coastguard Worker ATTRIBUTE_FALLTHROUGH;
484*cf84ac9aSAndroid Build Coastguard Worker
485*cf84ac9aSAndroid Build Coastguard Worker case XLAT_STYLE_RAW:
486*cf84ac9aSAndroid Build Coastguard Worker print_xlat_val(val, style);
487*cf84ac9aSAndroid Build Coastguard Worker break;
488*cf84ac9aSAndroid Build Coastguard Worker
489*cf84ac9aSAndroid Build Coastguard Worker default:
490*cf84ac9aSAndroid Build Coastguard Worker error_func_msg("Unexpected style value of %#x", style);
491*cf84ac9aSAndroid Build Coastguard Worker ATTRIBUTE_FALLTHROUGH;
492*cf84ac9aSAndroid Build Coastguard Worker
493*cf84ac9aSAndroid Build Coastguard Worker case XLAT_STYLE_VERBOSE:
494*cf84ac9aSAndroid Build Coastguard Worker print_xlat_val(val, style);
495*cf84ac9aSAndroid Build Coastguard Worker tprints_comment(str);
496*cf84ac9aSAndroid Build Coastguard Worker }
497*cf84ac9aSAndroid Build Coastguard Worker }
498*cf84ac9aSAndroid Build Coastguard Worker
499*cf84ac9aSAndroid Build Coastguard Worker void
printxval_dispatch_ex(const struct xlat * xlat,size_t xlat_size,uint64_t val,const char * dflt,enum xlat_type xt,enum xlat_style style)500*cf84ac9aSAndroid Build Coastguard Worker printxval_dispatch_ex(const struct xlat *xlat, size_t xlat_size, uint64_t val,
501*cf84ac9aSAndroid Build Coastguard Worker const char *dflt, enum xlat_type xt,
502*cf84ac9aSAndroid Build Coastguard Worker enum xlat_style style)
503*cf84ac9aSAndroid Build Coastguard Worker {
504*cf84ac9aSAndroid Build Coastguard Worker switch (xt) {
505*cf84ac9aSAndroid Build Coastguard Worker case XT_NORMAL:
506*cf84ac9aSAndroid Build Coastguard Worker printxvals_ex(val, dflt, style, xlat, NULL);
507*cf84ac9aSAndroid Build Coastguard Worker break;
508*cf84ac9aSAndroid Build Coastguard Worker
509*cf84ac9aSAndroid Build Coastguard Worker case XT_SORTED:
510*cf84ac9aSAndroid Build Coastguard Worker printxval_searchn_ex(xlat, xlat_size, val, dflt, style);
511*cf84ac9aSAndroid Build Coastguard Worker break;
512*cf84ac9aSAndroid Build Coastguard Worker
513*cf84ac9aSAndroid Build Coastguard Worker case XT_INDEXED:
514*cf84ac9aSAndroid Build Coastguard Worker printxval_indexn_ex(xlat, xlat_size, val, dflt, style);
515*cf84ac9aSAndroid Build Coastguard Worker break;
516*cf84ac9aSAndroid Build Coastguard Worker }
517*cf84ac9aSAndroid Build Coastguard Worker }
518