]>
Commit | Line | Data |
---|---|---|
34dc7c2f BB |
1 | /* |
2 | * CDDL HEADER START | |
3 | * | |
4 | * The contents of this file are subject to the terms of the | |
b128c09f BB |
5 | * Common Development and Distribution License (the "License"). |
6 | * You may not use this file except in compliance with the License. | |
34dc7c2f BB |
7 | * |
8 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
9 | * or http://www.opensolaris.org/os/licensing. | |
10 | * See the License for the specific language governing permissions | |
11 | * and limitations under the License. | |
12 | * | |
13 | * When distributing Covered Code, include this CDDL HEADER in each | |
14 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
15 | * If applicable, add the following below this CDDL HEADER, with the | |
16 | * fields enclosed by brackets "[]" replaced with your own identifying | |
17 | * information: Portions Copyright [yyyy] [name of copyright owner] | |
18 | * | |
19 | * CDDL HEADER END | |
20 | */ | |
21 | /* | |
572e2857 | 22 | * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. |
34dc7c2f BB |
23 | */ |
24 | ||
34dc7c2f BB |
25 | #include <unistd.h> |
26 | #include <strings.h> | |
428870ff | 27 | #include <libintl.h> |
b128c09f BB |
28 | #include <sys/types.h> |
29 | #include <sys/inttypes.h> | |
572e2857 BB |
30 | #include <stdarg.h> |
31 | #include <note.h> | |
34dc7c2f BB |
32 | #include "libnvpair.h" |
33 | ||
34 | /* | |
35 | * libnvpair - A tools library for manipulating <name, value> pairs. | |
36 | * | |
37 | * This library provides routines packing an unpacking nv pairs | |
38 | * for transporting data across process boundaries, transporting | |
39 | * between kernel and userland, and possibly saving onto disk files. | |
40 | */ | |
41 | ||
572e2857 BB |
42 | /* |
43 | * Print control structure. | |
44 | */ | |
45 | ||
46 | #define DEFINEOP(opname, vtype) \ | |
47 | struct { \ | |
48 | int (*op)(struct nvlist_prtctl *, void *, nvlist_t *, \ | |
49 | const char *, vtype); \ | |
50 | void *arg; \ | |
51 | } opname | |
52 | ||
53 | #define DEFINEARROP(opname, vtype) \ | |
54 | struct { \ | |
55 | int (*op)(struct nvlist_prtctl *, void *, nvlist_t *, \ | |
56 | const char *, vtype, uint_t); \ | |
57 | void *arg; \ | |
58 | } opname | |
59 | ||
60 | struct nvlist_printops { | |
61 | DEFINEOP(print_boolean, int); | |
62 | DEFINEOP(print_boolean_value, boolean_t); | |
63 | DEFINEOP(print_byte, uchar_t); | |
64 | DEFINEOP(print_int8, int8_t); | |
65 | DEFINEOP(print_uint8, uint8_t); | |
66 | DEFINEOP(print_int16, int16_t); | |
67 | DEFINEOP(print_uint16, uint16_t); | |
68 | DEFINEOP(print_int32, int32_t); | |
69 | DEFINEOP(print_uint32, uint32_t); | |
70 | DEFINEOP(print_int64, int64_t); | |
71 | DEFINEOP(print_uint64, uint64_t); | |
72 | DEFINEOP(print_double, double); | |
73 | DEFINEOP(print_string, char *); | |
74 | DEFINEOP(print_hrtime, hrtime_t); | |
75 | DEFINEOP(print_nvlist, nvlist_t *); | |
76 | DEFINEARROP(print_boolean_array, boolean_t *); | |
77 | DEFINEARROP(print_byte_array, uchar_t *); | |
78 | DEFINEARROP(print_int8_array, int8_t *); | |
79 | DEFINEARROP(print_uint8_array, uint8_t *); | |
80 | DEFINEARROP(print_int16_array, int16_t *); | |
81 | DEFINEARROP(print_uint16_array, uint16_t *); | |
82 | DEFINEARROP(print_int32_array, int32_t *); | |
83 | DEFINEARROP(print_uint32_array, uint32_t *); | |
84 | DEFINEARROP(print_int64_array, int64_t *); | |
85 | DEFINEARROP(print_uint64_array, uint64_t *); | |
86 | DEFINEARROP(print_string_array, char **); | |
87 | DEFINEARROP(print_nvlist_array, nvlist_t **); | |
88 | }; | |
89 | ||
90 | struct nvlist_prtctl { | |
91 | FILE *nvprt_fp; /* output destination */ | |
92 | enum nvlist_indent_mode nvprt_indent_mode; /* see above */ | |
93 | int nvprt_indent; /* absolute indent, or tab depth */ | |
94 | int nvprt_indentinc; /* indent or tab increment */ | |
95 | const char *nvprt_nmfmt; /* member name format, max one %s */ | |
96 | const char *nvprt_eomfmt; /* after member format, e.g. "\n" */ | |
97 | const char *nvprt_btwnarrfmt; /* between array members */ | |
98 | int nvprt_btwnarrfmt_nl; /* nvprt_eoamfmt includes newline? */ | |
99 | struct nvlist_printops *nvprt_dfltops; | |
100 | struct nvlist_printops *nvprt_custops; | |
101 | }; | |
102 | ||
103 | #define DFLTPRTOP(pctl, type) \ | |
104 | ((pctl)->nvprt_dfltops->print_##type.op) | |
105 | ||
106 | #define DFLTPRTOPARG(pctl, type) \ | |
107 | ((pctl)->nvprt_dfltops->print_##type.arg) | |
108 | ||
109 | #define CUSTPRTOP(pctl, type) \ | |
110 | ((pctl)->nvprt_custops->print_##type.op) | |
111 | ||
112 | #define CUSTPRTOPARG(pctl, type) \ | |
113 | ((pctl)->nvprt_custops->print_##type.arg) | |
114 | ||
115 | #define RENDER(pctl, type, nvl, name, val) \ | |
116 | { \ | |
117 | int done = 0; \ | |
118 | if ((pctl)->nvprt_custops && CUSTPRTOP(pctl, type)) { \ | |
119 | done = CUSTPRTOP(pctl, type)(pctl, \ | |
120 | CUSTPRTOPARG(pctl, type), nvl, name, val); \ | |
121 | } \ | |
122 | if (!done) { \ | |
123 | (void) DFLTPRTOP(pctl, type)(pctl, \ | |
124 | DFLTPRTOPARG(pctl, type), nvl, name, val); \ | |
125 | } \ | |
8ec8000f | 126 | (void) fprintf(pctl->nvprt_fp, "%s", pctl->nvprt_eomfmt); \ |
572e2857 BB |
127 | } |
128 | ||
129 | #define ARENDER(pctl, type, nvl, name, arrp, count) \ | |
130 | { \ | |
131 | int done = 0; \ | |
132 | if ((pctl)->nvprt_custops && CUSTPRTOP(pctl, type)) { \ | |
133 | done = CUSTPRTOP(pctl, type)(pctl, \ | |
134 | CUSTPRTOPARG(pctl, type), nvl, name, arrp, count); \ | |
135 | } \ | |
136 | if (!done) { \ | |
137 | (void) DFLTPRTOP(pctl, type)(pctl, \ | |
138 | DFLTPRTOPARG(pctl, type), nvl, name, arrp, count); \ | |
139 | } \ | |
8ec8000f | 140 | (void) fprintf(pctl->nvprt_fp, "%s", pctl->nvprt_eomfmt); \ |
572e2857 BB |
141 | } |
142 | ||
143 | static void nvlist_print_with_indent(nvlist_t *, nvlist_prtctl_t); | |
144 | ||
145 | /* | |
146 | * ====================================================================== | |
147 | * | | | |
148 | * | Indentation | | |
149 | * | | | |
150 | * ====================================================================== | |
151 | */ | |
152 | ||
34dc7c2f | 153 | static void |
572e2857 | 154 | indent(nvlist_prtctl_t pctl, int onemore) |
34dc7c2f | 155 | { |
572e2857 BB |
156 | int depth; |
157 | ||
158 | switch (pctl->nvprt_indent_mode) { | |
159 | case NVLIST_INDENT_ABS: | |
160 | (void) fprintf(pctl->nvprt_fp, "%*s", | |
161 | pctl->nvprt_indent + onemore * pctl->nvprt_indentinc, ""); | |
162 | break; | |
163 | ||
164 | case NVLIST_INDENT_TABBED: | |
165 | depth = pctl->nvprt_indent + onemore; | |
166 | while (depth-- > 0) | |
167 | (void) fprintf(pctl->nvprt_fp, "\t"); | |
168 | } | |
34dc7c2f BB |
169 | } |
170 | ||
171 | /* | |
572e2857 BB |
172 | * ====================================================================== |
173 | * | | | |
174 | * | Default nvlist member rendering functions. | | |
175 | * | | | |
176 | * ====================================================================== | |
177 | */ | |
178 | ||
179 | /* | |
180 | * Generate functions to print single-valued nvlist members. | |
181 | * | |
182 | * type_and_variant - suffix to form function name | |
183 | * vtype - C type for the member value | |
184 | * ptype - C type to cast value to for printing | |
185 | * vfmt - format string for pair value, e.g "%d" or "0x%llx" | |
186 | */ | |
187 | ||
188 | #define NVLIST_PRTFUNC(type_and_variant, vtype, ptype, vfmt) \ | |
189 | static int \ | |
190 | nvprint_##type_and_variant(nvlist_prtctl_t pctl, void *private, \ | |
191 | nvlist_t *nvl, const char *name, vtype value) \ | |
192 | { \ | |
193 | FILE *fp = pctl->nvprt_fp; \ | |
194 | NOTE(ARGUNUSED(private)) \ | |
195 | NOTE(ARGUNUSED(nvl)) \ | |
196 | indent(pctl, 1); \ | |
197 | (void) fprintf(fp, pctl->nvprt_nmfmt, name); \ | |
198 | (void) fprintf(fp, vfmt, (ptype)value); \ | |
199 | return (1); \ | |
200 | } | |
201 | ||
202 | NVLIST_PRTFUNC(boolean, int, int, "%d") | |
203 | NVLIST_PRTFUNC(boolean_value, boolean_t, int, "%d") | |
204 | NVLIST_PRTFUNC(byte, uchar_t, uchar_t, "0x%2.2x") | |
205 | NVLIST_PRTFUNC(int8, int8_t, int, "%d") | |
206 | NVLIST_PRTFUNC(uint8, uint8_t, uint8_t, "0x%x") | |
207 | NVLIST_PRTFUNC(int16, int16_t, int16_t, "%d") | |
208 | NVLIST_PRTFUNC(uint16, uint16_t, uint16_t, "0x%x") | |
209 | NVLIST_PRTFUNC(int32, int32_t, int32_t, "%d") | |
210 | NVLIST_PRTFUNC(uint32, uint32_t, uint32_t, "0x%x") | |
211 | NVLIST_PRTFUNC(int64, int64_t, longlong_t, "%lld") | |
212 | NVLIST_PRTFUNC(uint64, uint64_t, u_longlong_t, "0x%llx") | |
b8864a23 | 213 | NVLIST_PRTFUNC(double, double, double, "0x%f") |
572e2857 BB |
214 | NVLIST_PRTFUNC(string, char *, char *, "%s") |
215 | NVLIST_PRTFUNC(hrtime, hrtime_t, hrtime_t, "0x%llx") | |
216 | ||
217 | /* | |
218 | * Generate functions to print array-valued nvlist members. | |
219 | */ | |
220 | ||
221 | #define NVLIST_ARRPRTFUNC(type_and_variant, vtype, ptype, vfmt) \ | |
222 | static int \ | |
223 | nvaprint_##type_and_variant(nvlist_prtctl_t pctl, void *private, \ | |
224 | nvlist_t *nvl, const char *name, vtype *valuep, uint_t count) \ | |
225 | { \ | |
226 | FILE *fp = pctl->nvprt_fp; \ | |
227 | uint_t i; \ | |
228 | NOTE(ARGUNUSED(private)) \ | |
229 | NOTE(ARGUNUSED(nvl)) \ | |
230 | for (i = 0; i < count; i++) { \ | |
231 | if (i == 0 || pctl->nvprt_btwnarrfmt_nl) { \ | |
232 | indent(pctl, 1); \ | |
233 | (void) fprintf(fp, pctl->nvprt_nmfmt, name); \ | |
234 | if (pctl->nvprt_btwnarrfmt_nl) \ | |
235 | (void) fprintf(fp, "[%d]: ", i); \ | |
236 | } \ | |
237 | if (i != 0) \ | |
8ec8000f | 238 | (void) fprintf(fp, "%s", pctl->nvprt_btwnarrfmt); \ |
572e2857 BB |
239 | (void) fprintf(fp, vfmt, (ptype)valuep[i]); \ |
240 | } \ | |
241 | return (1); \ | |
242 | } | |
243 | ||
244 | NVLIST_ARRPRTFUNC(boolean_array, boolean_t, boolean_t, "%d") | |
245 | NVLIST_ARRPRTFUNC(byte_array, uchar_t, uchar_t, "0x%2.2x") | |
246 | NVLIST_ARRPRTFUNC(int8_array, int8_t, int8_t, "%d") | |
247 | NVLIST_ARRPRTFUNC(uint8_array, uint8_t, uint8_t, "0x%x") | |
248 | NVLIST_ARRPRTFUNC(int16_array, int16_t, int16_t, "%d") | |
249 | NVLIST_ARRPRTFUNC(uint16_array, uint16_t, uint16_t, "0x%x") | |
250 | NVLIST_ARRPRTFUNC(int32_array, int32_t, int32_t, "%d") | |
251 | NVLIST_ARRPRTFUNC(uint32_array, uint32_t, uint32_t, "0x%x") | |
252 | NVLIST_ARRPRTFUNC(int64_array, int64_t, longlong_t, "%lld") | |
253 | NVLIST_ARRPRTFUNC(uint64_array, uint64_t, u_longlong_t, "0x%llx") | |
254 | NVLIST_ARRPRTFUNC(string_array, char *, char *, "%s") | |
255 | ||
256 | /*ARGSUSED*/ | |
257 | static int | |
258 | nvprint_nvlist(nvlist_prtctl_t pctl, void *private, | |
259 | nvlist_t *nvl, const char *name, nvlist_t *value) | |
260 | { | |
261 | FILE *fp = pctl->nvprt_fp; | |
262 | ||
263 | indent(pctl, 1); | |
264 | (void) fprintf(fp, "%s = (embedded nvlist)\n", name); | |
265 | ||
266 | pctl->nvprt_indent += pctl->nvprt_indentinc; | |
267 | nvlist_print_with_indent(value, pctl); | |
268 | pctl->nvprt_indent -= pctl->nvprt_indentinc; | |
269 | ||
270 | indent(pctl, 1); | |
271 | (void) fprintf(fp, "(end %s)\n", name); | |
272 | ||
273 | return (1); | |
274 | } | |
275 | ||
276 | /*ARGSUSED*/ | |
277 | static int | |
278 | nvaprint_nvlist_array(nvlist_prtctl_t pctl, void *private, | |
279 | nvlist_t *nvl, const char *name, nvlist_t **valuep, uint_t count) | |
280 | { | |
281 | FILE *fp = pctl->nvprt_fp; | |
282 | uint_t i; | |
283 | ||
284 | indent(pctl, 1); | |
285 | (void) fprintf(fp, "%s = (array of embedded nvlists)\n", name); | |
286 | ||
287 | for (i = 0; i < count; i++) { | |
288 | indent(pctl, 1); | |
289 | (void) fprintf(fp, "(start %s[%d])\n", name, i); | |
290 | ||
291 | pctl->nvprt_indent += pctl->nvprt_indentinc; | |
292 | nvlist_print_with_indent(valuep[i], pctl); | |
293 | pctl->nvprt_indent -= pctl->nvprt_indentinc; | |
294 | ||
295 | indent(pctl, 1); | |
296 | (void) fprintf(fp, "(end %s[%d])\n", name, i); | |
297 | } | |
298 | ||
299 | return (1); | |
300 | } | |
301 | ||
302 | /* | |
303 | * ====================================================================== | |
304 | * | | | |
305 | * | Interfaces that allow control over formatting. | | |
306 | * | | | |
307 | * ====================================================================== | |
308 | */ | |
309 | ||
310 | void | |
311 | nvlist_prtctl_setdest(nvlist_prtctl_t pctl, FILE *fp) | |
312 | { | |
313 | pctl->nvprt_fp = fp; | |
314 | } | |
315 | ||
316 | FILE * | |
317 | nvlist_prtctl_getdest(nvlist_prtctl_t pctl) | |
318 | { | |
319 | return (pctl->nvprt_fp); | |
320 | } | |
321 | ||
322 | ||
323 | void | |
324 | nvlist_prtctl_setindent(nvlist_prtctl_t pctl, enum nvlist_indent_mode mode, | |
325 | int start, int inc) | |
326 | { | |
327 | if (mode < NVLIST_INDENT_ABS || mode > NVLIST_INDENT_TABBED) | |
328 | mode = NVLIST_INDENT_TABBED; | |
329 | ||
330 | if (start < 0) | |
331 | start = 0; | |
332 | ||
333 | if (inc < 0) | |
334 | inc = 1; | |
335 | ||
336 | pctl->nvprt_indent_mode = mode; | |
337 | pctl->nvprt_indent = start; | |
338 | pctl->nvprt_indentinc = inc; | |
339 | } | |
340 | ||
341 | void | |
342 | nvlist_prtctl_doindent(nvlist_prtctl_t pctl, int onemore) | |
343 | { | |
344 | indent(pctl, onemore); | |
345 | } | |
346 | ||
347 | ||
348 | void | |
349 | nvlist_prtctl_setfmt(nvlist_prtctl_t pctl, enum nvlist_prtctl_fmt which, | |
350 | const char *fmt) | |
351 | { | |
352 | switch (which) { | |
353 | case NVLIST_FMT_MEMBER_NAME: | |
354 | if (fmt == NULL) | |
355 | fmt = "%s = "; | |
356 | pctl->nvprt_nmfmt = fmt; | |
357 | break; | |
358 | ||
359 | case NVLIST_FMT_MEMBER_POSTAMBLE: | |
360 | if (fmt == NULL) | |
361 | fmt = "\n"; | |
362 | pctl->nvprt_eomfmt = fmt; | |
363 | break; | |
364 | ||
365 | case NVLIST_FMT_BTWN_ARRAY: | |
366 | if (fmt == NULL) { | |
367 | pctl->nvprt_btwnarrfmt = " "; | |
368 | pctl->nvprt_btwnarrfmt_nl = 0; | |
369 | } else { | |
370 | pctl->nvprt_btwnarrfmt = fmt; | |
371 | pctl->nvprt_btwnarrfmt_nl = (strstr(fmt, "\n") != NULL); | |
372 | } | |
373 | break; | |
374 | ||
375 | default: | |
376 | break; | |
377 | } | |
378 | } | |
379 | ||
380 | ||
381 | void | |
382 | nvlist_prtctl_dofmt(nvlist_prtctl_t pctl, enum nvlist_prtctl_fmt which, ...) | |
383 | { | |
384 | FILE *fp = pctl->nvprt_fp; | |
385 | va_list ap; | |
386 | char *name; | |
387 | ||
388 | va_start(ap, which); | |
389 | ||
390 | switch (which) { | |
391 | case NVLIST_FMT_MEMBER_NAME: | |
392 | name = va_arg(ap, char *); | |
393 | (void) fprintf(fp, pctl->nvprt_nmfmt, name); | |
394 | break; | |
395 | ||
396 | case NVLIST_FMT_MEMBER_POSTAMBLE: | |
8ec8000f | 397 | (void) fprintf(fp, "%s", pctl->nvprt_eomfmt); |
572e2857 BB |
398 | break; |
399 | ||
400 | case NVLIST_FMT_BTWN_ARRAY: | |
8ec8000f | 401 | (void) fprintf(fp, "%s", pctl->nvprt_btwnarrfmt); |
572e2857 BB |
402 | break; |
403 | ||
404 | default: | |
405 | break; | |
406 | } | |
407 | ||
408 | va_end(ap); | |
409 | } | |
410 | ||
411 | /* | |
412 | * ====================================================================== | |
413 | * | | | |
414 | * | Interfaces to allow appointment of replacement rendering functions.| | |
415 | * | | | |
416 | * ====================================================================== | |
417 | */ | |
418 | ||
419 | #define NVLIST_PRINTCTL_REPLACE(type, vtype) \ | |
420 | void \ | |
421 | nvlist_prtctlop_##type(nvlist_prtctl_t pctl, \ | |
422 | int (*func)(nvlist_prtctl_t, void *, nvlist_t *, const char *, vtype), \ | |
423 | void *private) \ | |
424 | { \ | |
425 | CUSTPRTOP(pctl, type) = func; \ | |
426 | CUSTPRTOPARG(pctl, type) = private; \ | |
427 | } | |
428 | ||
429 | NVLIST_PRINTCTL_REPLACE(boolean, int) | |
430 | NVLIST_PRINTCTL_REPLACE(boolean_value, boolean_t) | |
431 | NVLIST_PRINTCTL_REPLACE(byte, uchar_t) | |
432 | NVLIST_PRINTCTL_REPLACE(int8, int8_t) | |
433 | NVLIST_PRINTCTL_REPLACE(uint8, uint8_t) | |
434 | NVLIST_PRINTCTL_REPLACE(int16, int16_t) | |
435 | NVLIST_PRINTCTL_REPLACE(uint16, uint16_t) | |
436 | NVLIST_PRINTCTL_REPLACE(int32, int32_t) | |
437 | NVLIST_PRINTCTL_REPLACE(uint32, uint32_t) | |
438 | NVLIST_PRINTCTL_REPLACE(int64, int64_t) | |
439 | NVLIST_PRINTCTL_REPLACE(uint64, uint64_t) | |
440 | NVLIST_PRINTCTL_REPLACE(double, double) | |
441 | NVLIST_PRINTCTL_REPLACE(string, char *) | |
442 | NVLIST_PRINTCTL_REPLACE(hrtime, hrtime_t) | |
443 | NVLIST_PRINTCTL_REPLACE(nvlist, nvlist_t *) | |
444 | ||
445 | #define NVLIST_PRINTCTL_AREPLACE(type, vtype) \ | |
446 | void \ | |
447 | nvlist_prtctlop_##type(nvlist_prtctl_t pctl, \ | |
448 | int (*func)(nvlist_prtctl_t, void *, nvlist_t *, const char *, vtype, \ | |
449 | uint_t), void *private) \ | |
450 | { \ | |
451 | CUSTPRTOP(pctl, type) = func; \ | |
452 | CUSTPRTOPARG(pctl, type) = private; \ | |
453 | } | |
454 | ||
455 | NVLIST_PRINTCTL_AREPLACE(boolean_array, boolean_t *) | |
456 | NVLIST_PRINTCTL_AREPLACE(byte_array, uchar_t *) | |
457 | NVLIST_PRINTCTL_AREPLACE(int8_array, int8_t *) | |
458 | NVLIST_PRINTCTL_AREPLACE(uint8_array, uint8_t *) | |
459 | NVLIST_PRINTCTL_AREPLACE(int16_array, int16_t *) | |
460 | NVLIST_PRINTCTL_AREPLACE(uint16_array, uint16_t *) | |
461 | NVLIST_PRINTCTL_AREPLACE(int32_array, int32_t *) | |
462 | NVLIST_PRINTCTL_AREPLACE(uint32_array, uint32_t *) | |
463 | NVLIST_PRINTCTL_AREPLACE(int64_array, int64_t *) | |
464 | NVLIST_PRINTCTL_AREPLACE(uint64_array, uint64_t *) | |
465 | NVLIST_PRINTCTL_AREPLACE(string_array, char **) | |
466 | NVLIST_PRINTCTL_AREPLACE(nvlist_array, nvlist_t **) | |
467 | ||
468 | /* | |
469 | * ====================================================================== | |
470 | * | | | |
471 | * | Interfaces to manage nvlist_prtctl_t cookies. | | |
472 | * | | | |
473 | * ====================================================================== | |
34dc7c2f | 474 | */ |
572e2857 BB |
475 | |
476 | ||
477 | static const struct nvlist_printops defprtops = { | |
478 | { nvprint_boolean, NULL }, | |
479 | { nvprint_boolean_value, NULL }, | |
480 | { nvprint_byte, NULL }, | |
481 | { nvprint_int8, NULL }, | |
482 | { nvprint_uint8, NULL }, | |
483 | { nvprint_int16, NULL }, | |
484 | { nvprint_uint16, NULL }, | |
485 | { nvprint_int32, NULL }, | |
486 | { nvprint_uint32, NULL }, | |
487 | { nvprint_int64, NULL }, | |
488 | { nvprint_uint64, NULL }, | |
489 | { nvprint_double, NULL }, | |
490 | { nvprint_string, NULL }, | |
491 | { nvprint_hrtime, NULL }, | |
492 | { nvprint_nvlist, NULL }, | |
493 | { nvaprint_boolean_array, NULL }, | |
494 | { nvaprint_byte_array, NULL }, | |
495 | { nvaprint_int8_array, NULL }, | |
496 | { nvaprint_uint8_array, NULL }, | |
497 | { nvaprint_int16_array, NULL }, | |
498 | { nvaprint_uint16_array, NULL }, | |
499 | { nvaprint_int32_array, NULL }, | |
500 | { nvaprint_uint32_array, NULL }, | |
501 | { nvaprint_int64_array, NULL }, | |
502 | { nvaprint_uint64_array, NULL }, | |
503 | { nvaprint_string_array, NULL }, | |
504 | { nvaprint_nvlist_array, NULL }, | |
505 | }; | |
506 | ||
507 | static void | |
508 | prtctl_defaults(FILE *fp, struct nvlist_prtctl *pctl, | |
509 | struct nvlist_printops *ops) | |
510 | { | |
511 | pctl->nvprt_fp = fp; | |
512 | pctl->nvprt_indent_mode = NVLIST_INDENT_TABBED; | |
513 | pctl->nvprt_indent = 0; | |
514 | pctl->nvprt_indentinc = 1; | |
515 | pctl->nvprt_nmfmt = "%s = "; | |
516 | pctl->nvprt_eomfmt = "\n"; | |
517 | pctl->nvprt_btwnarrfmt = " "; | |
518 | pctl->nvprt_btwnarrfmt_nl = 0; | |
519 | ||
520 | pctl->nvprt_dfltops = (struct nvlist_printops *)&defprtops; | |
521 | pctl->nvprt_custops = ops; | |
522 | } | |
523 | ||
524 | nvlist_prtctl_t | |
525 | nvlist_prtctl_alloc(void) | |
526 | { | |
527 | struct nvlist_prtctl *pctl; | |
528 | struct nvlist_printops *ops; | |
529 | ||
530 | if ((pctl = malloc(sizeof (*pctl))) == NULL) | |
531 | return (NULL); | |
532 | ||
533 | if ((ops = calloc(1, sizeof (*ops))) == NULL) { | |
534 | free(pctl); | |
535 | return (NULL); | |
536 | } | |
537 | ||
538 | prtctl_defaults(stdout, pctl, ops); | |
539 | ||
540 | return (pctl); | |
541 | } | |
542 | ||
34dc7c2f | 543 | void |
572e2857 | 544 | nvlist_prtctl_free(nvlist_prtctl_t pctl) |
34dc7c2f | 545 | { |
572e2857 BB |
546 | if (pctl != NULL) { |
547 | free(pctl->nvprt_custops); | |
548 | free(pctl); | |
549 | } | |
550 | } | |
551 | ||
552 | /* | |
553 | * ====================================================================== | |
554 | * | | | |
555 | * | Top-level print request interfaces. | | |
556 | * | | | |
557 | * ====================================================================== | |
558 | */ | |
559 | ||
560 | /* | |
561 | * nvlist_print - Prints elements in an event buffer | |
562 | */ | |
563 | static void | |
564 | nvlist_print_with_indent(nvlist_t *nvl, nvlist_prtctl_t pctl) | |
565 | { | |
566 | FILE *fp = pctl->nvprt_fp; | |
34dc7c2f BB |
567 | char *name; |
568 | uint_t nelem; | |
569 | nvpair_t *nvp; | |
570 | ||
571 | if (nvl == NULL) | |
572 | return; | |
573 | ||
572e2857 | 574 | indent(pctl, 0); |
34dc7c2f BB |
575 | (void) fprintf(fp, "nvlist version: %d\n", NVL_VERSION(nvl)); |
576 | ||
577 | nvp = nvlist_next_nvpair(nvl, NULL); | |
578 | ||
579 | while (nvp) { | |
580 | data_type_t type = nvpair_type(nvp); | |
581 | ||
34dc7c2f | 582 | name = nvpair_name(nvp); |
34dc7c2f | 583 | nelem = 0; |
572e2857 | 584 | |
34dc7c2f BB |
585 | switch (type) { |
586 | case DATA_TYPE_BOOLEAN: { | |
572e2857 | 587 | RENDER(pctl, boolean, nvl, name, 1); |
34dc7c2f BB |
588 | break; |
589 | } | |
590 | case DATA_TYPE_BOOLEAN_VALUE: { | |
591 | boolean_t val; | |
592 | (void) nvpair_value_boolean_value(nvp, &val); | |
572e2857 | 593 | RENDER(pctl, boolean_value, nvl, name, val); |
34dc7c2f BB |
594 | break; |
595 | } | |
596 | case DATA_TYPE_BYTE: { | |
597 | uchar_t val; | |
598 | (void) nvpair_value_byte(nvp, &val); | |
572e2857 | 599 | RENDER(pctl, byte, nvl, name, val); |
34dc7c2f BB |
600 | break; |
601 | } | |
602 | case DATA_TYPE_INT8: { | |
603 | int8_t val; | |
604 | (void) nvpair_value_int8(nvp, &val); | |
572e2857 | 605 | RENDER(pctl, int8, nvl, name, val); |
34dc7c2f BB |
606 | break; |
607 | } | |
608 | case DATA_TYPE_UINT8: { | |
609 | uint8_t val; | |
610 | (void) nvpair_value_uint8(nvp, &val); | |
572e2857 | 611 | RENDER(pctl, uint8, nvl, name, val); |
34dc7c2f BB |
612 | break; |
613 | } | |
614 | case DATA_TYPE_INT16: { | |
615 | int16_t val; | |
616 | (void) nvpair_value_int16(nvp, &val); | |
572e2857 | 617 | RENDER(pctl, int16, nvl, name, val); |
34dc7c2f BB |
618 | break; |
619 | } | |
620 | case DATA_TYPE_UINT16: { | |
621 | uint16_t val; | |
622 | (void) nvpair_value_uint16(nvp, &val); | |
572e2857 | 623 | RENDER(pctl, uint16, nvl, name, val); |
34dc7c2f BB |
624 | break; |
625 | } | |
626 | case DATA_TYPE_INT32: { | |
627 | int32_t val; | |
628 | (void) nvpair_value_int32(nvp, &val); | |
572e2857 | 629 | RENDER(pctl, int32, nvl, name, val); |
34dc7c2f BB |
630 | break; |
631 | } | |
632 | case DATA_TYPE_UINT32: { | |
633 | uint32_t val; | |
634 | (void) nvpair_value_uint32(nvp, &val); | |
572e2857 | 635 | RENDER(pctl, uint32, nvl, name, val); |
34dc7c2f BB |
636 | break; |
637 | } | |
638 | case DATA_TYPE_INT64: { | |
639 | int64_t val; | |
640 | (void) nvpair_value_int64(nvp, &val); | |
572e2857 | 641 | RENDER(pctl, int64, nvl, name, val); |
34dc7c2f BB |
642 | break; |
643 | } | |
644 | case DATA_TYPE_UINT64: { | |
645 | uint64_t val; | |
646 | (void) nvpair_value_uint64(nvp, &val); | |
572e2857 | 647 | RENDER(pctl, uint64, nvl, name, val); |
34dc7c2f BB |
648 | break; |
649 | } | |
b128c09f BB |
650 | case DATA_TYPE_DOUBLE: { |
651 | double val; | |
652 | (void) nvpair_value_double(nvp, &val); | |
572e2857 | 653 | RENDER(pctl, double, nvl, name, val); |
b128c09f BB |
654 | break; |
655 | } | |
34dc7c2f BB |
656 | case DATA_TYPE_STRING: { |
657 | char *val; | |
658 | (void) nvpair_value_string(nvp, &val); | |
572e2857 | 659 | RENDER(pctl, string, nvl, name, val); |
34dc7c2f BB |
660 | break; |
661 | } | |
662 | case DATA_TYPE_BOOLEAN_ARRAY: { | |
663 | boolean_t *val; | |
664 | (void) nvpair_value_boolean_array(nvp, &val, &nelem); | |
572e2857 | 665 | ARENDER(pctl, boolean_array, nvl, name, val, nelem); |
34dc7c2f BB |
666 | break; |
667 | } | |
668 | case DATA_TYPE_BYTE_ARRAY: { | |
669 | uchar_t *val; | |
670 | (void) nvpair_value_byte_array(nvp, &val, &nelem); | |
572e2857 | 671 | ARENDER(pctl, byte_array, nvl, name, val, nelem); |
34dc7c2f BB |
672 | break; |
673 | } | |
674 | case DATA_TYPE_INT8_ARRAY: { | |
675 | int8_t *val; | |
676 | (void) nvpair_value_int8_array(nvp, &val, &nelem); | |
572e2857 | 677 | ARENDER(pctl, int8_array, nvl, name, val, nelem); |
34dc7c2f BB |
678 | break; |
679 | } | |
680 | case DATA_TYPE_UINT8_ARRAY: { | |
681 | uint8_t *val; | |
682 | (void) nvpair_value_uint8_array(nvp, &val, &nelem); | |
572e2857 | 683 | ARENDER(pctl, uint8_array, nvl, name, val, nelem); |
34dc7c2f BB |
684 | break; |
685 | } | |
686 | case DATA_TYPE_INT16_ARRAY: { | |
687 | int16_t *val; | |
688 | (void) nvpair_value_int16_array(nvp, &val, &nelem); | |
572e2857 | 689 | ARENDER(pctl, int16_array, nvl, name, val, nelem); |
34dc7c2f BB |
690 | break; |
691 | } | |
692 | case DATA_TYPE_UINT16_ARRAY: { | |
693 | uint16_t *val; | |
694 | (void) nvpair_value_uint16_array(nvp, &val, &nelem); | |
572e2857 | 695 | ARENDER(pctl, uint16_array, nvl, name, val, nelem); |
34dc7c2f BB |
696 | break; |
697 | } | |
698 | case DATA_TYPE_INT32_ARRAY: { | |
699 | int32_t *val; | |
700 | (void) nvpair_value_int32_array(nvp, &val, &nelem); | |
572e2857 | 701 | ARENDER(pctl, int32_array, nvl, name, val, nelem); |
34dc7c2f BB |
702 | break; |
703 | } | |
704 | case DATA_TYPE_UINT32_ARRAY: { | |
705 | uint32_t *val; | |
706 | (void) nvpair_value_uint32_array(nvp, &val, &nelem); | |
572e2857 | 707 | ARENDER(pctl, uint32_array, nvl, name, val, nelem); |
34dc7c2f BB |
708 | break; |
709 | } | |
710 | case DATA_TYPE_INT64_ARRAY: { | |
711 | int64_t *val; | |
712 | (void) nvpair_value_int64_array(nvp, &val, &nelem); | |
572e2857 | 713 | ARENDER(pctl, int64_array, nvl, name, val, nelem); |
34dc7c2f BB |
714 | break; |
715 | } | |
716 | case DATA_TYPE_UINT64_ARRAY: { | |
717 | uint64_t *val; | |
718 | (void) nvpair_value_uint64_array(nvp, &val, &nelem); | |
572e2857 | 719 | ARENDER(pctl, uint64_array, nvl, name, val, nelem); |
34dc7c2f BB |
720 | break; |
721 | } | |
722 | case DATA_TYPE_STRING_ARRAY: { | |
723 | char **val; | |
724 | (void) nvpair_value_string_array(nvp, &val, &nelem); | |
572e2857 | 725 | ARENDER(pctl, string_array, nvl, name, val, nelem); |
34dc7c2f BB |
726 | break; |
727 | } | |
728 | case DATA_TYPE_HRTIME: { | |
729 | hrtime_t val; | |
730 | (void) nvpair_value_hrtime(nvp, &val); | |
572e2857 | 731 | RENDER(pctl, hrtime, nvl, name, val); |
34dc7c2f BB |
732 | break; |
733 | } | |
734 | case DATA_TYPE_NVLIST: { | |
735 | nvlist_t *val; | |
736 | (void) nvpair_value_nvlist(nvp, &val); | |
572e2857 | 737 | RENDER(pctl, nvlist, nvl, name, val); |
34dc7c2f BB |
738 | break; |
739 | } | |
740 | case DATA_TYPE_NVLIST_ARRAY: { | |
741 | nvlist_t **val; | |
742 | (void) nvpair_value_nvlist_array(nvp, &val, &nelem); | |
572e2857 | 743 | ARENDER(pctl, nvlist_array, nvl, name, val, nelem); |
34dc7c2f BB |
744 | break; |
745 | } | |
746 | default: | |
747 | (void) fprintf(fp, " unknown data type (%d)", type); | |
748 | break; | |
749 | } | |
34dc7c2f BB |
750 | nvp = nvlist_next_nvpair(nvl, nvp); |
751 | } | |
752 | } | |
753 | ||
754 | void | |
755 | nvlist_print(FILE *fp, nvlist_t *nvl) | |
756 | { | |
572e2857 BB |
757 | struct nvlist_prtctl pc; |
758 | ||
759 | prtctl_defaults(fp, &pc, NULL); | |
760 | nvlist_print_with_indent(nvl, &pc); | |
34dc7c2f | 761 | } |
b128c09f | 762 | |
572e2857 BB |
763 | void |
764 | nvlist_prt(nvlist_t *nvl, nvlist_prtctl_t pctl) | |
765 | { | |
766 | nvlist_print_with_indent(nvl, pctl); | |
767 | } | |
428870ff BB |
768 | |
769 | #define NVP(elem, type, vtype, ptype, format) { \ | |
770 | vtype value; \ | |
771 | \ | |
772 | (void) nvpair_value_##type(elem, &value); \ | |
773 | (void) printf("%*s%s: " format "\n", indent, "", \ | |
774 | nvpair_name(elem), (ptype)value); \ | |
775 | } | |
776 | ||
777 | #define NVPA(elem, type, vtype, ptype, format) { \ | |
778 | uint_t i, count; \ | |
779 | vtype *value; \ | |
780 | \ | |
781 | (void) nvpair_value_##type(elem, &value, &count); \ | |
782 | for (i = 0; i < count; i++) { \ | |
783 | (void) printf("%*s%s[%d]: " format "\n", indent, "", \ | |
784 | nvpair_name(elem), i, (ptype)value[i]); \ | |
785 | } \ | |
786 | } | |
787 | ||
788 | /* | |
789 | * Similar to nvlist_print() but handles arrays slightly differently. | |
790 | */ | |
791 | void | |
792 | dump_nvlist(nvlist_t *list, int indent) | |
793 | { | |
794 | nvpair_t *elem = NULL; | |
795 | boolean_t bool_value; | |
796 | nvlist_t *nvlist_value; | |
797 | nvlist_t **nvlist_array_value; | |
798 | uint_t i, count; | |
799 | ||
800 | if (list == NULL) { | |
801 | return; | |
802 | } | |
803 | ||
804 | while ((elem = nvlist_next_nvpair(list, elem)) != NULL) { | |
805 | switch (nvpair_type(elem)) { | |
806 | case DATA_TYPE_BOOLEAN_VALUE: | |
807 | (void) nvpair_value_boolean_value(elem, &bool_value); | |
808 | (void) printf("%*s%s: %s\n", indent, "", | |
809 | nvpair_name(elem), bool_value ? "true" : "false"); | |
810 | break; | |
811 | ||
812 | case DATA_TYPE_BYTE: | |
813 | NVP(elem, byte, uchar_t, int, "%u"); | |
814 | break; | |
815 | ||
816 | case DATA_TYPE_INT8: | |
817 | NVP(elem, int8, int8_t, int, "%d"); | |
818 | break; | |
819 | ||
820 | case DATA_TYPE_UINT8: | |
821 | NVP(elem, uint8, uint8_t, int, "%u"); | |
822 | break; | |
823 | ||
824 | case DATA_TYPE_INT16: | |
825 | NVP(elem, int16, int16_t, int, "%d"); | |
826 | break; | |
827 | ||
828 | case DATA_TYPE_UINT16: | |
829 | NVP(elem, uint16, uint16_t, int, "%u"); | |
830 | break; | |
831 | ||
832 | case DATA_TYPE_INT32: | |
833 | NVP(elem, int32, int32_t, long, "%ld"); | |
834 | break; | |
835 | ||
836 | case DATA_TYPE_UINT32: | |
837 | NVP(elem, uint32, uint32_t, ulong_t, "%lu"); | |
838 | break; | |
839 | ||
840 | case DATA_TYPE_INT64: | |
841 | NVP(elem, int64, int64_t, longlong_t, "%lld"); | |
842 | break; | |
843 | ||
844 | case DATA_TYPE_UINT64: | |
845 | NVP(elem, uint64, uint64_t, u_longlong_t, "%llu"); | |
846 | break; | |
847 | ||
848 | case DATA_TYPE_STRING: | |
849 | NVP(elem, string, char *, char *, "'%s'"); | |
850 | break; | |
851 | ||
852 | case DATA_TYPE_BYTE_ARRAY: | |
853 | NVPA(elem, byte_array, uchar_t, int, "%u"); | |
854 | break; | |
855 | ||
856 | case DATA_TYPE_INT8_ARRAY: | |
857 | NVPA(elem, int8_array, int8_t, int, "%d"); | |
858 | break; | |
859 | ||
860 | case DATA_TYPE_UINT8_ARRAY: | |
861 | NVPA(elem, uint8_array, uint8_t, int, "%u"); | |
862 | break; | |
863 | ||
864 | case DATA_TYPE_INT16_ARRAY: | |
865 | NVPA(elem, int16_array, int16_t, int, "%d"); | |
866 | break; | |
867 | ||
868 | case DATA_TYPE_UINT16_ARRAY: | |
869 | NVPA(elem, uint16_array, uint16_t, int, "%u"); | |
870 | break; | |
871 | ||
872 | case DATA_TYPE_INT32_ARRAY: | |
873 | NVPA(elem, int32_array, int32_t, long, "%ld"); | |
874 | break; | |
875 | ||
876 | case DATA_TYPE_UINT32_ARRAY: | |
877 | NVPA(elem, uint32_array, uint32_t, ulong_t, "%lu"); | |
878 | break; | |
879 | ||
880 | case DATA_TYPE_INT64_ARRAY: | |
881 | NVPA(elem, int64_array, int64_t, longlong_t, "%lld"); | |
882 | break; | |
883 | ||
884 | case DATA_TYPE_UINT64_ARRAY: | |
885 | NVPA(elem, uint64_array, uint64_t, u_longlong_t, | |
886 | "%llu"); | |
887 | break; | |
888 | ||
889 | case DATA_TYPE_STRING_ARRAY: | |
890 | NVPA(elem, string_array, char *, char *, "'%s'"); | |
891 | break; | |
892 | ||
893 | case DATA_TYPE_NVLIST: | |
894 | (void) nvpair_value_nvlist(elem, &nvlist_value); | |
895 | (void) printf("%*s%s:\n", indent, "", | |
896 | nvpair_name(elem)); | |
897 | dump_nvlist(nvlist_value, indent + 4); | |
898 | break; | |
899 | ||
900 | case DATA_TYPE_NVLIST_ARRAY: | |
901 | (void) nvpair_value_nvlist_array(elem, | |
902 | &nvlist_array_value, &count); | |
903 | for (i = 0; i < count; i++) { | |
904 | (void) printf("%*s%s[%u]:\n", indent, "", | |
905 | nvpair_name(elem), i); | |
906 | dump_nvlist(nvlist_array_value[i], indent + 4); | |
907 | } | |
908 | break; | |
909 | ||
910 | default: | |
911 | (void) printf(dgettext(TEXT_DOMAIN, "bad config type " | |
912 | "%d for %s\n"), nvpair_type(elem), | |
913 | nvpair_name(elem)); | |
914 | } | |
915 | } | |
916 | } | |
917 | ||
572e2857 BB |
918 | /* |
919 | * ====================================================================== | |
920 | * | | | |
921 | * | Misc private interface. | | |
922 | * | | | |
923 | * ====================================================================== | |
924 | */ | |
925 | ||
b128c09f BB |
926 | /* |
927 | * Determine if string 'value' matches 'nvp' value. The 'value' string is | |
928 | * converted, depending on the type of 'nvp', prior to match. For numeric | |
929 | * types, a radix independent sscanf conversion of 'value' is used. If 'nvp' | |
930 | * is an array type, 'ai' is the index into the array against which we are | |
931 | * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass | |
932 | * in a regex_t compilation of value in 'value_regex' to trigger regular | |
933 | * expression string match instead of simple strcmp(). | |
934 | * | |
935 | * Return 1 on match, 0 on no-match, and -1 on error. If the error is | |
936 | * related to value syntax error and 'ep' is non-NULL, *ep will point into | |
937 | * the 'value' string at the location where the error exists. | |
938 | * | |
939 | * NOTE: It may be possible to move the non-regex_t version of this into | |
940 | * common code used by library/kernel/boot. | |
941 | */ | |
942 | int | |
943 | nvpair_value_match_regex(nvpair_t *nvp, int ai, | |
944 | char *value, regex_t *value_regex, char **ep) | |
945 | { | |
946 | char *evalue; | |
947 | uint_t a_len; | |
948 | int sr; | |
949 | ||
950 | if (ep) | |
951 | *ep = NULL; | |
952 | ||
953 | if ((nvp == NULL) || (value == NULL)) | |
954 | return (-1); /* error fail match - invalid args */ | |
955 | ||
956 | /* make sure array and index combination make sense */ | |
957 | if ((nvpair_type_is_array(nvp) && (ai < 0)) || | |
958 | (!nvpair_type_is_array(nvp) && (ai >= 0))) | |
959 | return (-1); /* error fail match - bad index */ | |
960 | ||
961 | /* non-string values should be single 'chunk' */ | |
962 | if ((nvpair_type(nvp) != DATA_TYPE_STRING) && | |
963 | (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) { | |
964 | value += strspn(value, " \t"); | |
965 | evalue = value + strcspn(value, " \t"); | |
966 | if (*evalue) { | |
967 | if (ep) | |
968 | *ep = evalue; | |
969 | return (-1); /* error fail match - syntax */ | |
970 | } | |
971 | } | |
972 | ||
973 | sr = EOF; | |
974 | switch (nvpair_type(nvp)) { | |
975 | case DATA_TYPE_STRING: { | |
976 | char *val; | |
977 | ||
978 | /* check string value for match */ | |
979 | if (nvpair_value_string(nvp, &val) == 0) { | |
980 | if (value_regex) { | |
981 | if (regexec(value_regex, val, | |
982 | (size_t)0, NULL, 0) == 0) | |
983 | return (1); /* match */ | |
984 | } else { | |
985 | if (strcmp(value, val) == 0) | |
986 | return (1); /* match */ | |
987 | } | |
988 | } | |
989 | break; | |
990 | } | |
991 | case DATA_TYPE_STRING_ARRAY: { | |
992 | char **val_array; | |
993 | ||
994 | /* check indexed string value of array for match */ | |
995 | if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) && | |
996 | (ai < a_len)) { | |
997 | if (value_regex) { | |
998 | if (regexec(value_regex, val_array[ai], | |
999 | (size_t)0, NULL, 0) == 0) | |
1000 | return (1); | |
1001 | } else { | |
1002 | if (strcmp(value, val_array[ai]) == 0) | |
1003 | return (1); | |
1004 | } | |
1005 | } | |
1006 | break; | |
1007 | } | |
1008 | case DATA_TYPE_BYTE: { | |
1009 | uchar_t val, val_arg; | |
1010 | ||
1011 | /* scanf uchar_t from value and check for match */ | |
1012 | sr = sscanf(value, "%c", &val_arg); | |
1013 | if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) && | |
1014 | (val == val_arg)) | |
1015 | return (1); | |
1016 | break; | |
1017 | } | |
1018 | case DATA_TYPE_BYTE_ARRAY: { | |
1019 | uchar_t *val_array, val_arg; | |
1020 | ||
1021 | ||
1022 | /* check indexed value of array for match */ | |
1023 | sr = sscanf(value, "%c", &val_arg); | |
1024 | if ((sr == 1) && | |
1025 | (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) && | |
1026 | (ai < a_len) && | |
1027 | (val_array[ai] == val_arg)) | |
1028 | return (1); | |
1029 | break; | |
1030 | } | |
1031 | case DATA_TYPE_INT8: { | |
1032 | int8_t val, val_arg; | |
1033 | ||
1034 | /* scanf int8_t from value and check for match */ | |
1035 | sr = sscanf(value, "%"SCNi8, &val_arg); | |
1036 | if ((sr == 1) && | |
1037 | (nvpair_value_int8(nvp, &val) == 0) && | |
1038 | (val == val_arg)) | |
1039 | return (1); | |
1040 | break; | |
1041 | } | |
1042 | case DATA_TYPE_INT8_ARRAY: { | |
1043 | int8_t *val_array, val_arg; | |
1044 | ||
1045 | /* check indexed value of array for match */ | |
1046 | sr = sscanf(value, "%"SCNi8, &val_arg); | |
1047 | if ((sr == 1) && | |
1048 | (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) && | |
1049 | (ai < a_len) && | |
1050 | (val_array[ai] == val_arg)) | |
1051 | return (1); | |
1052 | break; | |
1053 | } | |
1054 | case DATA_TYPE_UINT8: { | |
1055 | uint8_t val, val_arg; | |
1056 | ||
1057 | /* scanf uint8_t from value and check for match */ | |
1058 | sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg); | |
1059 | if ((sr == 1) && | |
1060 | (nvpair_value_uint8(nvp, &val) == 0) && | |
1061 | (val == val_arg)) | |
1062 | return (1); | |
1063 | break; | |
1064 | } | |
1065 | case DATA_TYPE_UINT8_ARRAY: { | |
1066 | uint8_t *val_array, val_arg; | |
1067 | ||
1068 | /* check indexed value of array for match */ | |
1069 | sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg); | |
1070 | if ((sr == 1) && | |
1071 | (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) && | |
1072 | (ai < a_len) && | |
1073 | (val_array[ai] == val_arg)) | |
1074 | return (1); | |
1075 | break; | |
1076 | } | |
1077 | case DATA_TYPE_INT16: { | |
1078 | int16_t val, val_arg; | |
1079 | ||
1080 | /* scanf int16_t from value and check for match */ | |
1081 | sr = sscanf(value, "%"SCNi16, &val_arg); | |
1082 | if ((sr == 1) && | |
1083 | (nvpair_value_int16(nvp, &val) == 0) && | |
1084 | (val == val_arg)) | |
1085 | return (1); | |
1086 | break; | |
1087 | } | |
1088 | case DATA_TYPE_INT16_ARRAY: { | |
1089 | int16_t *val_array, val_arg; | |
1090 | ||
1091 | /* check indexed value of array for match */ | |
1092 | sr = sscanf(value, "%"SCNi16, &val_arg); | |
1093 | if ((sr == 1) && | |
1094 | (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) && | |
1095 | (ai < a_len) && | |
1096 | (val_array[ai] == val_arg)) | |
1097 | return (1); | |
1098 | break; | |
1099 | } | |
1100 | case DATA_TYPE_UINT16: { | |
1101 | uint16_t val, val_arg; | |
1102 | ||
1103 | /* scanf uint16_t from value and check for match */ | |
1104 | sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg); | |
1105 | if ((sr == 1) && | |
1106 | (nvpair_value_uint16(nvp, &val) == 0) && | |
1107 | (val == val_arg)) | |
1108 | return (1); | |
1109 | break; | |
1110 | } | |
1111 | case DATA_TYPE_UINT16_ARRAY: { | |
1112 | uint16_t *val_array, val_arg; | |
1113 | ||
1114 | /* check indexed value of array for match */ | |
1115 | sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg); | |
1116 | if ((sr == 1) && | |
1117 | (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) && | |
1118 | (ai < a_len) && | |
1119 | (val_array[ai] == val_arg)) | |
1120 | return (1); | |
1121 | break; | |
1122 | } | |
1123 | case DATA_TYPE_INT32: { | |
1124 | int32_t val, val_arg; | |
1125 | ||
1126 | /* scanf int32_t from value and check for match */ | |
1127 | sr = sscanf(value, "%"SCNi32, &val_arg); | |
1128 | if ((sr == 1) && | |
1129 | (nvpair_value_int32(nvp, &val) == 0) && | |
1130 | (val == val_arg)) | |
1131 | return (1); | |
1132 | break; | |
1133 | } | |
1134 | case DATA_TYPE_INT32_ARRAY: { | |
1135 | int32_t *val_array, val_arg; | |
1136 | ||
1137 | /* check indexed value of array for match */ | |
1138 | sr = sscanf(value, "%"SCNi32, &val_arg); | |
1139 | if ((sr == 1) && | |
1140 | (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) && | |
1141 | (ai < a_len) && | |
1142 | (val_array[ai] == val_arg)) | |
1143 | return (1); | |
1144 | break; | |
1145 | } | |
1146 | case DATA_TYPE_UINT32: { | |
1147 | uint32_t val, val_arg; | |
1148 | ||
1149 | /* scanf uint32_t from value and check for match */ | |
1150 | sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg); | |
1151 | if ((sr == 1) && | |
1152 | (nvpair_value_uint32(nvp, &val) == 0) && | |
1153 | (val == val_arg)) | |
1154 | return (1); | |
1155 | break; | |
1156 | } | |
1157 | case DATA_TYPE_UINT32_ARRAY: { | |
1158 | uint32_t *val_array, val_arg; | |
1159 | ||
1160 | /* check indexed value of array for match */ | |
1161 | sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg); | |
1162 | if ((sr == 1) && | |
1163 | (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) && | |
1164 | (ai < a_len) && | |
1165 | (val_array[ai] == val_arg)) | |
1166 | return (1); | |
1167 | break; | |
1168 | } | |
1169 | case DATA_TYPE_INT64: { | |
1170 | int64_t val, val_arg; | |
1171 | ||
1172 | /* scanf int64_t from value and check for match */ | |
1173 | sr = sscanf(value, "%"SCNi64, &val_arg); | |
1174 | if ((sr == 1) && | |
1175 | (nvpair_value_int64(nvp, &val) == 0) && | |
1176 | (val == val_arg)) | |
1177 | return (1); | |
1178 | break; | |
1179 | } | |
1180 | case DATA_TYPE_INT64_ARRAY: { | |
1181 | int64_t *val_array, val_arg; | |
1182 | ||
1183 | /* check indexed value of array for match */ | |
1184 | sr = sscanf(value, "%"SCNi64, &val_arg); | |
1185 | if ((sr == 1) && | |
1186 | (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) && | |
1187 | (ai < a_len) && | |
1188 | (val_array[ai] == val_arg)) | |
1189 | return (1); | |
1190 | break; | |
1191 | } | |
1192 | case DATA_TYPE_UINT64: { | |
1193 | uint64_t val_arg, val; | |
1194 | ||
1195 | /* scanf uint64_t from value and check for match */ | |
1196 | sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg); | |
1197 | if ((sr == 1) && | |
1198 | (nvpair_value_uint64(nvp, &val) == 0) && | |
1199 | (val == val_arg)) | |
1200 | return (1); | |
1201 | break; | |
1202 | } | |
1203 | case DATA_TYPE_UINT64_ARRAY: { | |
1204 | uint64_t *val_array, val_arg; | |
1205 | ||
1206 | /* check indexed value of array for match */ | |
1207 | sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg); | |
1208 | if ((sr == 1) && | |
1209 | (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) && | |
1210 | (ai < a_len) && | |
1211 | (val_array[ai] == val_arg)) | |
1212 | return (1); | |
1213 | break; | |
1214 | } | |
1215 | case DATA_TYPE_BOOLEAN_VALUE: { | |
1216 | boolean_t val, val_arg; | |
1217 | ||
1218 | /* scanf boolean_t from value and check for match */ | |
b8864a23 | 1219 | sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg); |
b128c09f BB |
1220 | if ((sr == 1) && |
1221 | (nvpair_value_boolean_value(nvp, &val) == 0) && | |
1222 | (val == val_arg)) | |
1223 | return (1); | |
1224 | break; | |
1225 | } | |
1226 | case DATA_TYPE_BOOLEAN_ARRAY: { | |
1227 | boolean_t *val_array, val_arg; | |
1228 | ||
1229 | /* check indexed value of array for match */ | |
b8864a23 | 1230 | sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg); |
b128c09f BB |
1231 | if ((sr == 1) && |
1232 | (nvpair_value_boolean_array(nvp, | |
1233 | &val_array, &a_len) == 0) && | |
1234 | (ai < a_len) && | |
1235 | (val_array[ai] == val_arg)) | |
1236 | return (1); | |
1237 | break; | |
1238 | } | |
1239 | case DATA_TYPE_HRTIME: | |
1240 | case DATA_TYPE_NVLIST: | |
1241 | case DATA_TYPE_NVLIST_ARRAY: | |
1242 | case DATA_TYPE_BOOLEAN: | |
1243 | case DATA_TYPE_DOUBLE: | |
1244 | case DATA_TYPE_UNKNOWN: | |
1245 | default: | |
1246 | /* | |
1247 | * unknown/unsupported data type | |
1248 | */ | |
1249 | return (-1); /* error fail match */ | |
1250 | } | |
1251 | ||
1252 | /* | |
1253 | * check to see if sscanf failed conversion, return approximate | |
1254 | * pointer to problem | |
1255 | */ | |
1256 | if (sr != 1) { | |
1257 | if (ep) | |
1258 | *ep = value; | |
1259 | return (-1); /* error fail match - syntax */ | |
1260 | } | |
1261 | ||
1262 | return (0); /* fail match */ | |
1263 | } | |
1264 | ||
1265 | int | |
1266 | nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep) | |
1267 | { | |
1268 | return (nvpair_value_match_regex(nvp, ai, value, NULL, ep)); | |
1269 | } |