The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/lib/libnvpair/libnvpair.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: b4a5996e2f59115710cc2ea527617c0a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.