1*eda14cbcSMatt Macy /* 2*eda14cbcSMatt Macy * This file and its contents are supplied under the terms of the 3*eda14cbcSMatt Macy * Common Development and Distribution License ("CDDL"), version 1.0. 4*eda14cbcSMatt Macy * You may only use this file in accordance with the terms of version 5*eda14cbcSMatt Macy * 1.0 of the CDDL. 6*eda14cbcSMatt Macy * 7*eda14cbcSMatt Macy * A full copy of the text of the CDDL should have accompanied this 8*eda14cbcSMatt Macy * source. A copy of the CDDL is also available via the Internet at 9*eda14cbcSMatt Macy * http://www.illumos.org/license/CDDL. 10*eda14cbcSMatt Macy */ 11*eda14cbcSMatt Macy /* 12*eda14cbcSMatt Macy * Copyright (c) 2014, Joyent, Inc. 13*eda14cbcSMatt Macy * Copyright (c) 2017 by Delphix. All rights reserved. 14*eda14cbcSMatt Macy */ 15*eda14cbcSMatt Macy 16*eda14cbcSMatt Macy #include <stdio.h> 17*eda14cbcSMatt Macy #include <stdlib.h> 18*eda14cbcSMatt Macy #include <strings.h> 19*eda14cbcSMatt Macy #include <wchar.h> 20*eda14cbcSMatt Macy #include <sys/debug.h> 21*eda14cbcSMatt Macy 22*eda14cbcSMatt Macy #include "libnvpair.h" 23*eda14cbcSMatt Macy 24*eda14cbcSMatt Macy #define FPRINTF(fp, ...) \ 25*eda14cbcSMatt Macy do { \ 26*eda14cbcSMatt Macy if (fprintf(fp, __VA_ARGS__) < 0) \ 27*eda14cbcSMatt Macy return (-1); \ 28*eda14cbcSMatt Macy } while (0) 29*eda14cbcSMatt Macy 30*eda14cbcSMatt Macy /* 31*eda14cbcSMatt Macy * When formatting a string for JSON output we must escape certain characters, 32*eda14cbcSMatt Macy * as described in RFC4627. This applies to both member names and 33*eda14cbcSMatt Macy * DATA_TYPE_STRING values. 34*eda14cbcSMatt Macy * 35*eda14cbcSMatt Macy * This function will only operate correctly if the following conditions are 36*eda14cbcSMatt Macy * met: 37*eda14cbcSMatt Macy * 38*eda14cbcSMatt Macy * 1. The input String is encoded in the current locale. 39*eda14cbcSMatt Macy * 40*eda14cbcSMatt Macy * 2. The current locale includes the Basic Multilingual Plane (plane 0) 41*eda14cbcSMatt Macy * as defined in the Unicode standard. 42*eda14cbcSMatt Macy * 43*eda14cbcSMatt Macy * The output will be entirely 7-bit ASCII (as a subset of UTF-8) with all 44*eda14cbcSMatt Macy * representable Unicode characters included in their escaped numeric form. 45*eda14cbcSMatt Macy */ 46*eda14cbcSMatt Macy static int 47*eda14cbcSMatt Macy nvlist_print_json_string(FILE *fp, const char *input) 48*eda14cbcSMatt Macy { 49*eda14cbcSMatt Macy mbstate_t mbr; 50*eda14cbcSMatt Macy wchar_t c; 51*eda14cbcSMatt Macy size_t sz; 52*eda14cbcSMatt Macy 53*eda14cbcSMatt Macy bzero(&mbr, sizeof (mbr)); 54*eda14cbcSMatt Macy 55*eda14cbcSMatt Macy FPRINTF(fp, "\""); 56*eda14cbcSMatt Macy while ((sz = mbrtowc(&c, input, MB_CUR_MAX, &mbr)) > 0) { 57*eda14cbcSMatt Macy switch (c) { 58*eda14cbcSMatt Macy case '"': 59*eda14cbcSMatt Macy FPRINTF(fp, "\\\""); 60*eda14cbcSMatt Macy break; 61*eda14cbcSMatt Macy case '\n': 62*eda14cbcSMatt Macy FPRINTF(fp, "\\n"); 63*eda14cbcSMatt Macy break; 64*eda14cbcSMatt Macy case '\r': 65*eda14cbcSMatt Macy FPRINTF(fp, "\\r"); 66*eda14cbcSMatt Macy break; 67*eda14cbcSMatt Macy case '\\': 68*eda14cbcSMatt Macy FPRINTF(fp, "\\\\"); 69*eda14cbcSMatt Macy break; 70*eda14cbcSMatt Macy case '\f': 71*eda14cbcSMatt Macy FPRINTF(fp, "\\f"); 72*eda14cbcSMatt Macy break; 73*eda14cbcSMatt Macy case '\t': 74*eda14cbcSMatt Macy FPRINTF(fp, "\\t"); 75*eda14cbcSMatt Macy break; 76*eda14cbcSMatt Macy case '\b': 77*eda14cbcSMatt Macy FPRINTF(fp, "\\b"); 78*eda14cbcSMatt Macy break; 79*eda14cbcSMatt Macy default: 80*eda14cbcSMatt Macy if ((c >= 0x00 && c <= 0x1f) || 81*eda14cbcSMatt Macy (c > 0x7f && c <= 0xffff)) { 82*eda14cbcSMatt Macy /* 83*eda14cbcSMatt Macy * Render both Control Characters and Unicode 84*eda14cbcSMatt Macy * characters in the Basic Multilingual Plane 85*eda14cbcSMatt Macy * as JSON-escaped multibyte characters. 86*eda14cbcSMatt Macy */ 87*eda14cbcSMatt Macy FPRINTF(fp, "\\u%04x", (int)(0xffff & c)); 88*eda14cbcSMatt Macy } else if (c >= 0x20 && c <= 0x7f) { 89*eda14cbcSMatt Macy /* 90*eda14cbcSMatt Macy * Render other 7-bit ASCII characters directly 91*eda14cbcSMatt Macy * and drop other, unrepresentable characters. 92*eda14cbcSMatt Macy */ 93*eda14cbcSMatt Macy FPRINTF(fp, "%c", (int)(0xff & c)); 94*eda14cbcSMatt Macy } 95*eda14cbcSMatt Macy break; 96*eda14cbcSMatt Macy } 97*eda14cbcSMatt Macy input += sz; 98*eda14cbcSMatt Macy } 99*eda14cbcSMatt Macy 100*eda14cbcSMatt Macy if (sz == (size_t)-1 || sz == (size_t)-2) { 101*eda14cbcSMatt Macy /* 102*eda14cbcSMatt Macy * We last read an invalid multibyte character sequence, 103*eda14cbcSMatt Macy * so return an error. 104*eda14cbcSMatt Macy */ 105*eda14cbcSMatt Macy return (-1); 106*eda14cbcSMatt Macy } 107*eda14cbcSMatt Macy 108*eda14cbcSMatt Macy FPRINTF(fp, "\""); 109*eda14cbcSMatt Macy return (0); 110*eda14cbcSMatt Macy } 111*eda14cbcSMatt Macy 112*eda14cbcSMatt Macy /* 113*eda14cbcSMatt Macy * Dump a JSON-formatted representation of an nvlist to the provided FILE *. 114*eda14cbcSMatt Macy * This routine does not output any new-lines or additional whitespace other 115*eda14cbcSMatt Macy * than that contained in strings, nor does it call fflush(3C). 116*eda14cbcSMatt Macy */ 117*eda14cbcSMatt Macy int 118*eda14cbcSMatt Macy nvlist_print_json(FILE *fp, nvlist_t *nvl) 119*eda14cbcSMatt Macy { 120*eda14cbcSMatt Macy nvpair_t *curr; 121*eda14cbcSMatt Macy boolean_t first = B_TRUE; 122*eda14cbcSMatt Macy 123*eda14cbcSMatt Macy FPRINTF(fp, "{"); 124*eda14cbcSMatt Macy 125*eda14cbcSMatt Macy for (curr = nvlist_next_nvpair(nvl, NULL); curr; 126*eda14cbcSMatt Macy curr = nvlist_next_nvpair(nvl, curr)) { 127*eda14cbcSMatt Macy data_type_t type = nvpair_type(curr); 128*eda14cbcSMatt Macy 129*eda14cbcSMatt Macy if (!first) 130*eda14cbcSMatt Macy FPRINTF(fp, ","); 131*eda14cbcSMatt Macy else 132*eda14cbcSMatt Macy first = B_FALSE; 133*eda14cbcSMatt Macy 134*eda14cbcSMatt Macy if (nvlist_print_json_string(fp, nvpair_name(curr)) == -1) 135*eda14cbcSMatt Macy return (-1); 136*eda14cbcSMatt Macy FPRINTF(fp, ":"); 137*eda14cbcSMatt Macy 138*eda14cbcSMatt Macy switch (type) { 139*eda14cbcSMatt Macy case DATA_TYPE_STRING: { 140*eda14cbcSMatt Macy char *string = fnvpair_value_string(curr); 141*eda14cbcSMatt Macy if (nvlist_print_json_string(fp, string) == -1) 142*eda14cbcSMatt Macy return (-1); 143*eda14cbcSMatt Macy break; 144*eda14cbcSMatt Macy } 145*eda14cbcSMatt Macy 146*eda14cbcSMatt Macy case DATA_TYPE_BOOLEAN: { 147*eda14cbcSMatt Macy FPRINTF(fp, "true"); 148*eda14cbcSMatt Macy break; 149*eda14cbcSMatt Macy } 150*eda14cbcSMatt Macy 151*eda14cbcSMatt Macy case DATA_TYPE_BOOLEAN_VALUE: { 152*eda14cbcSMatt Macy FPRINTF(fp, "%s", fnvpair_value_boolean_value(curr) == 153*eda14cbcSMatt Macy B_TRUE ? "true" : "false"); 154*eda14cbcSMatt Macy break; 155*eda14cbcSMatt Macy } 156*eda14cbcSMatt Macy 157*eda14cbcSMatt Macy case DATA_TYPE_BYTE: { 158*eda14cbcSMatt Macy FPRINTF(fp, "%hhu", fnvpair_value_byte(curr)); 159*eda14cbcSMatt Macy break; 160*eda14cbcSMatt Macy } 161*eda14cbcSMatt Macy 162*eda14cbcSMatt Macy case DATA_TYPE_INT8: { 163*eda14cbcSMatt Macy FPRINTF(fp, "%hhd", fnvpair_value_int8(curr)); 164*eda14cbcSMatt Macy break; 165*eda14cbcSMatt Macy } 166*eda14cbcSMatt Macy 167*eda14cbcSMatt Macy case DATA_TYPE_UINT8: { 168*eda14cbcSMatt Macy FPRINTF(fp, "%hhu", fnvpair_value_uint8(curr)); 169*eda14cbcSMatt Macy break; 170*eda14cbcSMatt Macy } 171*eda14cbcSMatt Macy 172*eda14cbcSMatt Macy case DATA_TYPE_INT16: { 173*eda14cbcSMatt Macy FPRINTF(fp, "%hd", fnvpair_value_int16(curr)); 174*eda14cbcSMatt Macy break; 175*eda14cbcSMatt Macy } 176*eda14cbcSMatt Macy 177*eda14cbcSMatt Macy case DATA_TYPE_UINT16: { 178*eda14cbcSMatt Macy FPRINTF(fp, "%hu", fnvpair_value_uint16(curr)); 179*eda14cbcSMatt Macy break; 180*eda14cbcSMatt Macy } 181*eda14cbcSMatt Macy 182*eda14cbcSMatt Macy case DATA_TYPE_INT32: { 183*eda14cbcSMatt Macy FPRINTF(fp, "%d", fnvpair_value_int32(curr)); 184*eda14cbcSMatt Macy break; 185*eda14cbcSMatt Macy } 186*eda14cbcSMatt Macy 187*eda14cbcSMatt Macy case DATA_TYPE_UINT32: { 188*eda14cbcSMatt Macy FPRINTF(fp, "%u", fnvpair_value_uint32(curr)); 189*eda14cbcSMatt Macy break; 190*eda14cbcSMatt Macy } 191*eda14cbcSMatt Macy 192*eda14cbcSMatt Macy case DATA_TYPE_INT64: { 193*eda14cbcSMatt Macy FPRINTF(fp, "%lld", 194*eda14cbcSMatt Macy (long long)fnvpair_value_int64(curr)); 195*eda14cbcSMatt Macy break; 196*eda14cbcSMatt Macy } 197*eda14cbcSMatt Macy 198*eda14cbcSMatt Macy case DATA_TYPE_UINT64: { 199*eda14cbcSMatt Macy FPRINTF(fp, "%llu", 200*eda14cbcSMatt Macy (unsigned long long)fnvpair_value_uint64(curr)); 201*eda14cbcSMatt Macy break; 202*eda14cbcSMatt Macy } 203*eda14cbcSMatt Macy 204*eda14cbcSMatt Macy case DATA_TYPE_HRTIME: { 205*eda14cbcSMatt Macy hrtime_t val; 206*eda14cbcSMatt Macy VERIFY0(nvpair_value_hrtime(curr, &val)); 207*eda14cbcSMatt Macy FPRINTF(fp, "%llu", (unsigned long long)val); 208*eda14cbcSMatt Macy break; 209*eda14cbcSMatt Macy } 210*eda14cbcSMatt Macy 211*eda14cbcSMatt Macy case DATA_TYPE_DOUBLE: { 212*eda14cbcSMatt Macy double val; 213*eda14cbcSMatt Macy VERIFY0(nvpair_value_double(curr, &val)); 214*eda14cbcSMatt Macy FPRINTF(fp, "%f", val); 215*eda14cbcSMatt Macy break; 216*eda14cbcSMatt Macy } 217*eda14cbcSMatt Macy 218*eda14cbcSMatt Macy case DATA_TYPE_NVLIST: { 219*eda14cbcSMatt Macy if (nvlist_print_json(fp, 220*eda14cbcSMatt Macy fnvpair_value_nvlist(curr)) == -1) 221*eda14cbcSMatt Macy return (-1); 222*eda14cbcSMatt Macy break; 223*eda14cbcSMatt Macy } 224*eda14cbcSMatt Macy 225*eda14cbcSMatt Macy case DATA_TYPE_STRING_ARRAY: { 226*eda14cbcSMatt Macy char **val; 227*eda14cbcSMatt Macy uint_t valsz, i; 228*eda14cbcSMatt Macy VERIFY0(nvpair_value_string_array(curr, &val, &valsz)); 229*eda14cbcSMatt Macy FPRINTF(fp, "["); 230*eda14cbcSMatt Macy for (i = 0; i < valsz; i++) { 231*eda14cbcSMatt Macy if (i > 0) 232*eda14cbcSMatt Macy FPRINTF(fp, ","); 233*eda14cbcSMatt Macy if (nvlist_print_json_string(fp, val[i]) == -1) 234*eda14cbcSMatt Macy return (-1); 235*eda14cbcSMatt Macy } 236*eda14cbcSMatt Macy FPRINTF(fp, "]"); 237*eda14cbcSMatt Macy break; 238*eda14cbcSMatt Macy } 239*eda14cbcSMatt Macy 240*eda14cbcSMatt Macy case DATA_TYPE_NVLIST_ARRAY: { 241*eda14cbcSMatt Macy nvlist_t **val; 242*eda14cbcSMatt Macy uint_t valsz, i; 243*eda14cbcSMatt Macy VERIFY0(nvpair_value_nvlist_array(curr, &val, &valsz)); 244*eda14cbcSMatt Macy FPRINTF(fp, "["); 245*eda14cbcSMatt Macy for (i = 0; i < valsz; i++) { 246*eda14cbcSMatt Macy if (i > 0) 247*eda14cbcSMatt Macy FPRINTF(fp, ","); 248*eda14cbcSMatt Macy if (nvlist_print_json(fp, val[i]) == -1) 249*eda14cbcSMatt Macy return (-1); 250*eda14cbcSMatt Macy } 251*eda14cbcSMatt Macy FPRINTF(fp, "]"); 252*eda14cbcSMatt Macy break; 253*eda14cbcSMatt Macy } 254*eda14cbcSMatt Macy 255*eda14cbcSMatt Macy case DATA_TYPE_BOOLEAN_ARRAY: { 256*eda14cbcSMatt Macy boolean_t *val; 257*eda14cbcSMatt Macy uint_t valsz, i; 258*eda14cbcSMatt Macy VERIFY0(nvpair_value_boolean_array(curr, &val, &valsz)); 259*eda14cbcSMatt Macy FPRINTF(fp, "["); 260*eda14cbcSMatt Macy for (i = 0; i < valsz; i++) { 261*eda14cbcSMatt Macy if (i > 0) 262*eda14cbcSMatt Macy FPRINTF(fp, ","); 263*eda14cbcSMatt Macy FPRINTF(fp, val[i] == B_TRUE ? 264*eda14cbcSMatt Macy "true" : "false"); 265*eda14cbcSMatt Macy } 266*eda14cbcSMatt Macy FPRINTF(fp, "]"); 267*eda14cbcSMatt Macy break; 268*eda14cbcSMatt Macy } 269*eda14cbcSMatt Macy 270*eda14cbcSMatt Macy case DATA_TYPE_BYTE_ARRAY: { 271*eda14cbcSMatt Macy uchar_t *val; 272*eda14cbcSMatt Macy uint_t valsz, i; 273*eda14cbcSMatt Macy VERIFY0(nvpair_value_byte_array(curr, &val, &valsz)); 274*eda14cbcSMatt Macy FPRINTF(fp, "["); 275*eda14cbcSMatt Macy for (i = 0; i < valsz; i++) { 276*eda14cbcSMatt Macy if (i > 0) 277*eda14cbcSMatt Macy FPRINTF(fp, ","); 278*eda14cbcSMatt Macy FPRINTF(fp, "%hhu", val[i]); 279*eda14cbcSMatt Macy } 280*eda14cbcSMatt Macy FPRINTF(fp, "]"); 281*eda14cbcSMatt Macy break; 282*eda14cbcSMatt Macy } 283*eda14cbcSMatt Macy 284*eda14cbcSMatt Macy case DATA_TYPE_UINT8_ARRAY: { 285*eda14cbcSMatt Macy uint8_t *val; 286*eda14cbcSMatt Macy uint_t valsz, i; 287*eda14cbcSMatt Macy VERIFY0(nvpair_value_uint8_array(curr, &val, &valsz)); 288*eda14cbcSMatt Macy FPRINTF(fp, "["); 289*eda14cbcSMatt Macy for (i = 0; i < valsz; i++) { 290*eda14cbcSMatt Macy if (i > 0) 291*eda14cbcSMatt Macy FPRINTF(fp, ","); 292*eda14cbcSMatt Macy FPRINTF(fp, "%hhu", val[i]); 293*eda14cbcSMatt Macy } 294*eda14cbcSMatt Macy FPRINTF(fp, "]"); 295*eda14cbcSMatt Macy break; 296*eda14cbcSMatt Macy } 297*eda14cbcSMatt Macy 298*eda14cbcSMatt Macy case DATA_TYPE_INT8_ARRAY: { 299*eda14cbcSMatt Macy int8_t *val; 300*eda14cbcSMatt Macy uint_t valsz, i; 301*eda14cbcSMatt Macy VERIFY0(nvpair_value_int8_array(curr, &val, &valsz)); 302*eda14cbcSMatt Macy FPRINTF(fp, "["); 303*eda14cbcSMatt Macy for (i = 0; i < valsz; i++) { 304*eda14cbcSMatt Macy if (i > 0) 305*eda14cbcSMatt Macy FPRINTF(fp, ","); 306*eda14cbcSMatt Macy FPRINTF(fp, "%hhd", val[i]); 307*eda14cbcSMatt Macy } 308*eda14cbcSMatt Macy FPRINTF(fp, "]"); 309*eda14cbcSMatt Macy break; 310*eda14cbcSMatt Macy } 311*eda14cbcSMatt Macy 312*eda14cbcSMatt Macy case DATA_TYPE_UINT16_ARRAY: { 313*eda14cbcSMatt Macy uint16_t *val; 314*eda14cbcSMatt Macy uint_t valsz, i; 315*eda14cbcSMatt Macy VERIFY0(nvpair_value_uint16_array(curr, &val, &valsz)); 316*eda14cbcSMatt Macy FPRINTF(fp, "["); 317*eda14cbcSMatt Macy for (i = 0; i < valsz; i++) { 318*eda14cbcSMatt Macy if (i > 0) 319*eda14cbcSMatt Macy FPRINTF(fp, ","); 320*eda14cbcSMatt Macy FPRINTF(fp, "%hu", val[i]); 321*eda14cbcSMatt Macy } 322*eda14cbcSMatt Macy FPRINTF(fp, "]"); 323*eda14cbcSMatt Macy break; 324*eda14cbcSMatt Macy } 325*eda14cbcSMatt Macy 326*eda14cbcSMatt Macy case DATA_TYPE_INT16_ARRAY: { 327*eda14cbcSMatt Macy int16_t *val; 328*eda14cbcSMatt Macy uint_t valsz, i; 329*eda14cbcSMatt Macy VERIFY0(nvpair_value_int16_array(curr, &val, &valsz)); 330*eda14cbcSMatt Macy FPRINTF(fp, "["); 331*eda14cbcSMatt Macy for (i = 0; i < valsz; i++) { 332*eda14cbcSMatt Macy if (i > 0) 333*eda14cbcSMatt Macy FPRINTF(fp, ","); 334*eda14cbcSMatt Macy FPRINTF(fp, "%hd", val[i]); 335*eda14cbcSMatt Macy } 336*eda14cbcSMatt Macy FPRINTF(fp, "]"); 337*eda14cbcSMatt Macy break; 338*eda14cbcSMatt Macy } 339*eda14cbcSMatt Macy 340*eda14cbcSMatt Macy case DATA_TYPE_UINT32_ARRAY: { 341*eda14cbcSMatt Macy uint32_t *val; 342*eda14cbcSMatt Macy uint_t valsz, i; 343*eda14cbcSMatt Macy VERIFY0(nvpair_value_uint32_array(curr, &val, &valsz)); 344*eda14cbcSMatt Macy FPRINTF(fp, "["); 345*eda14cbcSMatt Macy for (i = 0; i < valsz; i++) { 346*eda14cbcSMatt Macy if (i > 0) 347*eda14cbcSMatt Macy FPRINTF(fp, ","); 348*eda14cbcSMatt Macy FPRINTF(fp, "%u", val[i]); 349*eda14cbcSMatt Macy } 350*eda14cbcSMatt Macy FPRINTF(fp, "]"); 351*eda14cbcSMatt Macy break; 352*eda14cbcSMatt Macy } 353*eda14cbcSMatt Macy 354*eda14cbcSMatt Macy case DATA_TYPE_INT32_ARRAY: { 355*eda14cbcSMatt Macy int32_t *val; 356*eda14cbcSMatt Macy uint_t valsz, i; 357*eda14cbcSMatt Macy VERIFY0(nvpair_value_int32_array(curr, &val, &valsz)); 358*eda14cbcSMatt Macy FPRINTF(fp, "["); 359*eda14cbcSMatt Macy for (i = 0; i < valsz; i++) { 360*eda14cbcSMatt Macy if (i > 0) 361*eda14cbcSMatt Macy FPRINTF(fp, ","); 362*eda14cbcSMatt Macy FPRINTF(fp, "%d", val[i]); 363*eda14cbcSMatt Macy } 364*eda14cbcSMatt Macy FPRINTF(fp, "]"); 365*eda14cbcSMatt Macy break; 366*eda14cbcSMatt Macy } 367*eda14cbcSMatt Macy 368*eda14cbcSMatt Macy case DATA_TYPE_UINT64_ARRAY: { 369*eda14cbcSMatt Macy uint64_t *val; 370*eda14cbcSMatt Macy uint_t valsz, i; 371*eda14cbcSMatt Macy VERIFY0(nvpair_value_uint64_array(curr, &val, &valsz)); 372*eda14cbcSMatt Macy FPRINTF(fp, "["); 373*eda14cbcSMatt Macy for (i = 0; i < valsz; i++) { 374*eda14cbcSMatt Macy if (i > 0) 375*eda14cbcSMatt Macy FPRINTF(fp, ","); 376*eda14cbcSMatt Macy FPRINTF(fp, "%llu", 377*eda14cbcSMatt Macy (unsigned long long)val[i]); 378*eda14cbcSMatt Macy } 379*eda14cbcSMatt Macy FPRINTF(fp, "]"); 380*eda14cbcSMatt Macy break; 381*eda14cbcSMatt Macy } 382*eda14cbcSMatt Macy 383*eda14cbcSMatt Macy case DATA_TYPE_INT64_ARRAY: { 384*eda14cbcSMatt Macy int64_t *val; 385*eda14cbcSMatt Macy uint_t valsz, i; 386*eda14cbcSMatt Macy VERIFY0(nvpair_value_int64_array(curr, &val, &valsz)); 387*eda14cbcSMatt Macy FPRINTF(fp, "["); 388*eda14cbcSMatt Macy for (i = 0; i < valsz; i++) { 389*eda14cbcSMatt Macy if (i > 0) 390*eda14cbcSMatt Macy FPRINTF(fp, ","); 391*eda14cbcSMatt Macy FPRINTF(fp, "%lld", (long long)val[i]); 392*eda14cbcSMatt Macy } 393*eda14cbcSMatt Macy FPRINTF(fp, "]"); 394*eda14cbcSMatt Macy break; 395*eda14cbcSMatt Macy } 396*eda14cbcSMatt Macy 397*eda14cbcSMatt Macy case DATA_TYPE_UNKNOWN: 398*eda14cbcSMatt Macy case DATA_TYPE_DONTCARE: 399*eda14cbcSMatt Macy return (-1); 400*eda14cbcSMatt Macy } 401*eda14cbcSMatt Macy 402*eda14cbcSMatt Macy } 403*eda14cbcSMatt Macy 404*eda14cbcSMatt Macy FPRINTF(fp, "}"); 405*eda14cbcSMatt Macy return (0); 406*eda14cbcSMatt Macy } 407