Home | History | Annotate | Download | only in ltrace
      1 /*
      2  * This file is part of ltrace.
      3  * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc.
      4  * Copyright (C) 1998,2004,2007,2008,2009 Juan Cespedes
      5  * Copyright (C) 2006 Ian Wienand
      6  * Copyright (C) 2006 Steve Fink
      7  *
      8  * This program is free software; you can redistribute it and/or
      9  * modify it under the terms of the GNU General Public License as
     10  * published by the Free Software Foundation; either version 2 of the
     11  * License, or (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful, but
     14  * WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16  * General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License
     19  * along with this program; if not, write to the Free Software
     20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
     21  * 02110-1301 USA
     22  */
     23 
     24 #define _XOPEN_SOURCE /* For wcwidth from wchar.h.  */
     25 
     26 #include <ctype.h>
     27 #include <stdlib.h>
     28 #include <assert.h>
     29 #include <inttypes.h>
     30 #include <stdarg.h>
     31 #include <stdio.h>
     32 #include <string.h>
     33 #include <wchar.h>
     34 
     35 #include "bits.h"
     36 #include "expr.h"
     37 #include "lens_default.h"
     38 #include "options.h"
     39 #include "output.h"
     40 #include "type.h"
     41 #include "value.h"
     42 #include "zero.h"
     43 
     44 #define READER(NAME, TYPE)						\
     45 	static int							\
     46 	NAME(struct value *value, TYPE *ret, struct value_dict *arguments) \
     47 	{								\
     48 		union {							\
     49 			TYPE val;					\
     50 			unsigned char buf[0];				\
     51 		} u;							\
     52 		if (value_extract_buf(value, u.buf, arguments) < 0)	\
     53 			return -1;					\
     54 		*ret = u.val;						\
     55 		return 0;						\
     56 	}
     57 
     58 READER(read_float, float)
     59 READER(read_double, double)
     60 
     61 #undef READER
     62 
     63 #define HANDLE_WIDTH(BITS)						\
     64 	do {								\
     65 		long l;							\
     66 		if (value_extract_word(value, &l, arguments) < 0)	\
     67 			return -1;					\
     68 		int##BITS##_t i = l;					\
     69 		uint64_t v = (uint64_t)(uint##BITS##_t)i;		\
     70 		switch (format) {					\
     71 		case INT_FMT_unknown:					\
     72 			if (l < -10000 || l > 10000)			\
     73 		case INT_FMT_x:						\
     74 			return fprintf(stream, "%#"PRIx64, v);		\
     75 		case INT_FMT_i:						\
     76 		case INT_FMT_default:					\
     77 			return fprintf(stream, "%"PRIi##BITS, i);	\
     78 		case INT_FMT_u:						\
     79 			return fprintf(stream, "%"PRIu64, v);		\
     80 		case INT_FMT_o:						\
     81 			return fprintf(stream, "0%"PRIo64, v);		\
     82 		}							\
     83 	} while (0)
     84 
     85 enum int_fmt_t
     86 {
     87 	INT_FMT_i,
     88 	INT_FMT_u,
     89 	INT_FMT_o,
     90 	INT_FMT_x,
     91 	INT_FMT_unknown,
     92 	INT_FMT_default,
     93 };
     94 
     95 static int
     96 format_integer(FILE *stream, struct value *value, enum int_fmt_t format,
     97 	       struct value_dict *arguments)
     98 {
     99 	switch (type_sizeof(value->inferior, value->type)) {
    100 
    101 	case 1: HANDLE_WIDTH(8);
    102 	case 2: HANDLE_WIDTH(16);
    103 	case 4: HANDLE_WIDTH(32);
    104 	case 8: HANDLE_WIDTH(64);
    105 
    106 	default:
    107 		assert(!"unsupported integer width");
    108 		abort();
    109 
    110 	case -1:
    111 		return -1;
    112 	}
    113 }
    114 
    115 #undef HANDLE_WIDTH
    116 
    117 static int
    118 acc_fprintf(int *countp, FILE *stream, const char *format, ...)
    119 {
    120 	va_list pa;
    121 	va_start(pa, format);
    122 	int i = account_output(countp, vfprintf(stream, format, pa));
    123 	va_end(pa);
    124 
    125 	return i;
    126 }
    127 
    128 static int
    129 print_char(FILE *stream, int c)
    130 {
    131 	const char *fmt;
    132 	switch (c) {
    133 	case -1:
    134 		fmt = "EOF";
    135 		break;
    136 	case 0:
    137 		fmt = "\\0";
    138 		break;
    139 	case '\a':
    140 		fmt = "\\a";
    141 		break;
    142 	case '\b':
    143 		fmt = "\\b";
    144 		break;
    145 	case '\t':
    146 		fmt = "\\t";
    147 		break;
    148 	case '\n':
    149 		fmt = "\\n";
    150 		break;
    151 	case '\v':
    152 		fmt = "\\v";
    153 		break;
    154 	case '\f':
    155 		fmt = "\\f";
    156 		break;
    157 	case '\r':
    158 		fmt = "\\r";
    159 		break;
    160 	case '\\':
    161 		fmt = "\\\\";
    162 		break;
    163 	default:
    164 		if (isprint(c) || c == ' ')
    165 			fmt = "%c";
    166 		else
    167 			fmt = "\\%03o";
    168 	}
    169 
    170 	return fprintf(stream, fmt, c);
    171 }
    172 
    173 static int
    174 format_char(FILE *stream, struct value *value, struct value_dict *arguments)
    175 {
    176 	long lc;
    177 	if (value_extract_word(value, &lc, arguments) < 0)
    178 		return -1;
    179 	return print_char(stream, (int) lc);
    180 }
    181 
    182 static int
    183 format_naked(FILE *stream, struct value *value,
    184 	     struct value_dict *arguments,
    185 	     int (*what)(FILE *, struct value *, struct value_dict *))
    186 {
    187 	int written = 0;
    188 	if (acc_fprintf(&written, stream, "'") < 0
    189 	    || account_output(&written,
    190 			      what(stream, value, arguments)) < 0
    191 	    || acc_fprintf(&written, stream, "'") < 0)
    192 		return -1;
    193 
    194 	return written;
    195 }
    196 
    197 static int
    198 format_double(FILE *stream, double value, enum int_fmt_t format)
    199 {
    200 	if (format == INT_FMT_x)
    201 		return fprintf(stream, "%a", value);
    202 	else
    203 		return fprintf(stream, "%f", value);
    204 }
    205 
    206 static int
    207 format_floating(FILE *stream, struct value *value, struct value_dict *arguments,
    208 		enum int_fmt_t format)
    209 {
    210 	switch (value->type->type) {
    211 		float f;
    212 		double d;
    213 	case ARGTYPE_FLOAT:
    214 		if (read_float(value, &f, arguments) < 0)
    215 			return -1;
    216 		return format_double(stream, f, format);
    217 	case ARGTYPE_DOUBLE:
    218 		if (read_double(value, &d, arguments) < 0)
    219 			return -1;
    220 		return format_double(stream, d, format);
    221 	default:
    222 		abort();
    223 	}
    224 }
    225 
    226 struct format_argument_data
    227 {
    228 	struct value *value;
    229 	struct value_dict *arguments;
    230 };
    231 
    232 static int
    233 format_argument_cb(FILE *stream, void *ptr)
    234 {
    235 	struct format_argument_data *data = ptr;
    236 	return format_argument(stream, data->value, data->arguments);
    237 }
    238 
    239 static int
    240 format_struct(FILE *stream, struct value *value, struct value_dict *arguments)
    241 {
    242 	int written = 0;
    243 	if (acc_fprintf(&written, stream, "{ ") < 0)
    244 		return -1;
    245 
    246 	int need_delim = 0;
    247 	size_t i;
    248 	for (i = 0; i < type_struct_size(value->type); ++i) {
    249 		struct value element;
    250 		if (value_init_element(&element, value, i) < 0)
    251 			return -1;
    252 
    253 		struct format_argument_data data = { &element, arguments };
    254 		int o = delim_output(stream, &need_delim,
    255 				     format_argument_cb, &data);
    256 		value_destroy(&element);
    257 		if (o < 0)
    258 			return -1;
    259 
    260 		written += o;
    261 	}
    262 	if (acc_fprintf(&written, stream, " }") < 0)
    263 		return -1;
    264 	return written;
    265 }
    266 
    267 static const char null_message[] = "nil";
    268 int
    269 format_pointer(FILE *stream, struct value *value, struct value_dict *arguments)
    270 {
    271 	if (value_is_zero(value, arguments))
    272 		return fprintf(stream, null_message);
    273 
    274 	/* The following is for detecting recursion.  We keep track of
    275 	 * the values that were already displayed.  Each time a
    276 	 * pointer should be dereferenced, we compare its value to the
    277 	 * value of each of the pointers dereferenced so far.  If one
    278 	 * of them matches, instead of recursing, we just printf which
    279 	 * superstructure this pointer recurses to.  */
    280 	static struct vect pointers = {};
    281 	if (pointers.elt_size == 0)
    282 		VECT_INIT(&pointers, struct value *);
    283 
    284 	/* Trim number of expanded structures of the same type.  Even
    285 	 * for non-recursive structure, we don't want to expand all of
    286 	 * it if it's huge.  */
    287 	size_t i;
    288 	size_t len = vect_size(&pointers);
    289 	assert(value->type->type == ARGTYPE_POINTER);
    290 	struct arg_type_info *pointee = value->type->u.ptr_info.info;
    291 	if (pointee->type == ARGTYPE_STRUCT) {
    292 		size_t depth = 0;
    293 		for (i = 0; i < len; ++i) {
    294 			struct value *old
    295 				= *VECT_ELEMENT(&pointers, struct value *, i);
    296 			assert(old->type->type == ARGTYPE_POINTER);
    297 			struct arg_type_info *old_pointee
    298 				= old->type->u.ptr_info.info;
    299 			if (old_pointee == pointee)
    300 				depth++;
    301 		}
    302 		if (depth >= options.arraylen)
    303 			return fprintf(stream, "...");
    304 	}
    305 
    306 	for (i = len; i-- > 0 ;) {
    307 		struct value **old = VECT_ELEMENT(&pointers, struct value *, i);
    308 		int rc = value_equal(value, *old, arguments);
    309 		if (rc < 0)
    310 			return -1;
    311 		if (rc > 0) {
    312 			size_t reclevel = len - i - 1;
    313 			char buf[reclevel + 1];
    314 			memset(buf, '^', sizeof buf);
    315 			buf[reclevel] = 0;
    316 			return fprintf(stream, "recurse%s", buf);
    317 		}
    318 	}
    319 
    320 	/* OK, not a recursion.  Remember this value for tracking.  */
    321 	if (VECT_PUSHBACK(&pointers, &value) < 0)
    322 		return -1;
    323 
    324 	struct value element;
    325 	int o;
    326 	if (value_init_deref(&element, value) < 0) {
    327 		o = -1;
    328 		goto done;
    329 	}
    330 	o = format_argument(stream, &element, arguments);
    331 	value_destroy(&element);
    332 
    333 done:
    334 	VECT_POPBACK(&pointers, struct value *, NULL, NULL);
    335 	return o;
    336 }
    337 
    338 /*
    339  * LENGTH is an expression whose evaluation will yield the actual
    340  *    length of the array.
    341  *
    342  * MAXLEN is the actual maximum length that we care about
    343  *
    344  * BEFORE if LENGTH>MAXLEN, we display ellipsis.  We display it before
    345  *    the closing parenthesis if BEFORE, otherwise after it.
    346  *
    347  * OPEN, CLOSE, DELIM are opening and closing parenthesis and element
    348  *    delimiter.
    349  */
    350 static int
    351 format_array(FILE *stream, struct value *value, struct value_dict *arguments,
    352 	     struct expr_node *length, size_t maxlen, int before,
    353 	     const char *open, const char *close, const char *delim)
    354 {
    355 	/* We need "long" to be long enough to cover the whole address
    356 	 * space.  */
    357 	(void)sizeof(char[1 - 2*(sizeof(long) < sizeof(void *))]);
    358 	long l;
    359 	if (expr_eval_word(length, value, arguments, &l) < 0)
    360 		return -1;
    361 	size_t len = (size_t)l;
    362 
    363 	int written = 0;
    364 	if (acc_fprintf(&written, stream, "%s", open) < 0)
    365 		return -1;
    366 
    367 	size_t i;
    368 	for (i = 0; i < len && i <= maxlen; ++i) {
    369 		if (i == maxlen) {
    370 			if (before && acc_fprintf(&written, stream, "...") < 0)
    371 				return -1;
    372 			break;
    373 		}
    374 
    375 		if (i > 0 && acc_fprintf(&written, stream, "%s", delim) < 0)
    376 			return -1;
    377 
    378 		struct value element;
    379 		if (value_init_element(&element, value, i) < 0)
    380 			return -1;
    381 		int o = format_argument(stream, &element, arguments);
    382 		value_destroy(&element);
    383 		if (o < 0)
    384 			return -1;
    385 		written += o;
    386 	}
    387 	if (acc_fprintf(&written, stream, "%s", close) < 0)
    388 		return -1;
    389 	if (i == maxlen && !before && acc_fprintf(&written, stream, "...") < 0)
    390 		return -1;
    391 
    392 	return written;
    393 }
    394 
    395 static int
    396 toplevel_format_lens(struct lens *lens, FILE *stream,
    397 		     struct value *value, struct value_dict *arguments,
    398 		     enum int_fmt_t int_fmt)
    399 {
    400 	switch (value->type->type) {
    401 	case ARGTYPE_VOID:
    402 		return fprintf(stream, "<void>");
    403 
    404 	case ARGTYPE_SHORT:
    405 	case ARGTYPE_INT:
    406 	case ARGTYPE_LONG:
    407 		return format_integer(stream, value, int_fmt, arguments);
    408 
    409 	case ARGTYPE_USHORT:
    410 	case ARGTYPE_UINT:
    411 	case ARGTYPE_ULONG:
    412 		if (int_fmt == INT_FMT_i || int_fmt == INT_FMT_default)
    413 			int_fmt = INT_FMT_u;
    414 		return format_integer(stream, value, int_fmt, arguments);
    415 
    416 	case ARGTYPE_CHAR:
    417 		if (int_fmt == INT_FMT_default)
    418 			return format_naked(stream, value, arguments,
    419 					    &format_char);
    420 		return format_integer(stream, value, int_fmt, arguments);
    421 
    422 	case ARGTYPE_FLOAT:
    423 	case ARGTYPE_DOUBLE:
    424 		return format_floating(stream, value, arguments, int_fmt);
    425 
    426 	case ARGTYPE_STRUCT:
    427 		return format_struct(stream, value, arguments);
    428 
    429 	case ARGTYPE_POINTER:
    430 		if (value_is_zero(value, arguments))
    431 			return fprintf(stream, null_message);
    432 		if (value->type->u.array_info.elt_type->type != ARGTYPE_VOID)
    433 			return format_pointer(stream, value, arguments);
    434 		return format_integer(stream, value, INT_FMT_x, arguments);
    435 
    436 	case ARGTYPE_ARRAY:
    437 		return format_array(stream, value, arguments,
    438 				    value->type->u.array_info.length,
    439 				    options.arraylen, 1, "[ ", " ]", ", ");
    440 	}
    441 	abort();
    442 }
    443 
    444 static int
    445 default_lens_format_cb(struct lens *lens, FILE *stream,
    446 		       struct value *value, struct value_dict *arguments)
    447 {
    448 	return toplevel_format_lens(lens, stream, value, arguments,
    449 				    INT_FMT_default);
    450 }
    451 
    452 struct lens default_lens = {
    453 	.format_cb = default_lens_format_cb,
    454 };
    455 
    456 
    457 static int
    458 blind_lens_format_cb(struct lens *lens, FILE *stream,
    459 		     struct value *value, struct value_dict *arguments)
    460 {
    461 	return 0;
    462 }
    463 
    464 struct lens blind_lens = {
    465 	.format_cb = blind_lens_format_cb,
    466 };
    467 
    468 
    469 static int
    470 octal_lens_format_cb(struct lens *lens, FILE *stream,
    471 		     struct value *value, struct value_dict *arguments)
    472 {
    473 	return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_o);
    474 }
    475 
    476 struct lens octal_lens = {
    477 	.format_cb = octal_lens_format_cb,
    478 };
    479 
    480 
    481 static int
    482 hex_lens_format_cb(struct lens *lens, FILE *stream,
    483 		   struct value *value, struct value_dict *arguments)
    484 {
    485 	return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_x);
    486 }
    487 
    488 struct lens hex_lens = {
    489 	.format_cb = hex_lens_format_cb,
    490 };
    491 
    492 
    493 static int
    494 dec_lens_format_cb(struct lens *lens, FILE *stream,
    495 		   struct value *value, struct value_dict *arguments)
    496 {
    497 	return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_u);
    498 }
    499 
    500 struct lens dec_lens = {
    501 	.format_cb = dec_lens_format_cb,
    502 };
    503 
    504 
    505 static int
    506 guess_lens_format_cb(struct lens *lens, FILE *stream,
    507 		     struct value *value, struct value_dict *arguments)
    508 {
    509 	return toplevel_format_lens(lens, stream, value, arguments,
    510 				    INT_FMT_unknown);
    511 }
    512 
    513 struct lens guess_lens = {
    514 	.format_cb = guess_lens_format_cb,
    515 };
    516 
    517 
    518 static int
    519 bool_lens_format_cb(struct lens *lens, FILE *stream,
    520 		    struct value *value, struct value_dict *arguments)
    521 {
    522 	switch (value->type->type) {
    523 	case ARGTYPE_VOID:
    524 	case ARGTYPE_FLOAT:
    525 	case ARGTYPE_DOUBLE:
    526 	case ARGTYPE_STRUCT:
    527 	case ARGTYPE_POINTER:
    528 	case ARGTYPE_ARRAY:
    529 		return toplevel_format_lens(lens, stream, value,
    530 					    arguments, INT_FMT_default);
    531 
    532 		int zero;
    533 	case ARGTYPE_SHORT:
    534 	case ARGTYPE_INT:
    535 	case ARGTYPE_LONG:
    536 	case ARGTYPE_USHORT:
    537 	case ARGTYPE_UINT:
    538 	case ARGTYPE_ULONG:
    539 	case ARGTYPE_CHAR:
    540 		if ((zero = value_is_zero(value, arguments)) < 0)
    541 			return -1;
    542 		if (zero)
    543 			return fprintf(stream, "false");
    544 		else
    545 			return fprintf(stream, "true");
    546 	}
    547 	abort();
    548 }
    549 
    550 struct lens bool_lens = {
    551 	.format_cb = bool_lens_format_cb,
    552 };
    553 
    554 static int
    555 redispatch_as_array(struct lens *lens, FILE *stream,
    556 		    struct value *value, struct value_dict *arguments,
    557 		    int (*cb)(struct lens *, FILE *,
    558 			      struct value *, struct value_dict *))
    559 {
    560 	struct arg_type_info info[2];
    561 	type_init_array(&info[1], value->type->u.ptr_info.info, 0,
    562 			expr_node_zero(), 0);
    563 	type_init_pointer(&info[0], &info[1], 0);
    564 	info->lens = lens;
    565 	info->own_lens = 0;
    566 	struct value tmp;
    567 	if (value_clone(&tmp, value) < 0)
    568 		return -1;
    569 	value_set_type(&tmp, info, 0);
    570 	int ret = cb(lens, stream, &tmp, arguments);
    571 	type_destroy(&info[0]);
    572 	type_destroy(&info[1]);
    573 	value_destroy(&tmp);
    574 	return ret;
    575 }
    576 
    577 static int
    578 format_wchar(FILE *stream, struct value *value, struct value_dict *arguments)
    579 {
    580 	long l;
    581 	if (value_extract_word(value, &l, arguments) < 0)
    582 		return -1;
    583 	wchar_t wc = (wchar_t) l;
    584 	char buf[MB_CUR_MAX + 1];
    585 
    586 	int c = wctomb(buf, wc);
    587 	if (c < 0)
    588 		return -1;
    589 	if (c == 1)
    590 		return print_char(stream, buf[0]);
    591 
    592 	buf[c] = 0;
    593 	if (fprintf(stream, "%s", buf) < 0)
    594 		return -1;
    595 
    596 	c = wcwidth(wc);
    597 	return c >= 0 ? c : 0;
    598 }
    599 
    600 static int
    601 string_lens_format_cb(struct lens *lens, FILE *stream,
    602 		      struct value *value, struct value_dict *arguments)
    603 {
    604 	switch (value->type->type) {
    605 	case ARGTYPE_POINTER:
    606 		/* This should really be written as either "string",
    607 		 * or, if lens, then string(array(char, zero)*).  But
    608 		 * I suspect people are so used to the char * C idiom,
    609 		 * that string(char *) might actually turn up.  So
    610 		 * let's just support it.  */
    611 		switch ((int) value->type->u.ptr_info.info->type)
    612 		case ARGTYPE_CHAR:
    613 		case ARGTYPE_SHORT:
    614 		case ARGTYPE_USHORT:
    615 		case ARGTYPE_INT:
    616 		case ARGTYPE_UINT:
    617 		case ARGTYPE_LONG:
    618 		case ARGTYPE_ULONG:
    619 			return redispatch_as_array(lens, stream, value,
    620 						   arguments,
    621 						   &string_lens_format_cb);
    622 
    623 		/* Otherwise dispatch to whatever the default for the
    624 		 * pointee is--most likely this will again be us.  */
    625 		/* Fall through.  */
    626 	case ARGTYPE_VOID:
    627 	case ARGTYPE_FLOAT:
    628 	case ARGTYPE_DOUBLE:
    629 	case ARGTYPE_STRUCT:
    630 		return toplevel_format_lens(lens, stream, value,
    631 					    arguments, INT_FMT_default);
    632 
    633 	case ARGTYPE_SHORT:
    634 	case ARGTYPE_INT:
    635 	case ARGTYPE_LONG:
    636 	case ARGTYPE_USHORT:
    637 	case ARGTYPE_UINT:
    638 	case ARGTYPE_ULONG:
    639 		if (value->parent != NULL && value->type->lens == NULL)
    640 			return format_wchar(stream, value, arguments);
    641 		else
    642 			return format_naked(stream, value, arguments,
    643 					    &format_wchar);
    644 
    645 	case ARGTYPE_CHAR:
    646 		return format_char(stream, value, arguments);
    647 
    648 	case ARGTYPE_ARRAY:
    649 		return format_array(stream, value, arguments,
    650 				    value->type->u.array_info.length,
    651 				    options.strlen, 0, "\"", "\"", "");
    652 	}
    653 	abort();
    654 }
    655 
    656 struct lens string_lens = {
    657 	.format_cb = string_lens_format_cb,
    658 };
    659 
    660 static int
    661 out_bits(FILE *stream, size_t low, size_t high)
    662 {
    663 	if (low == high)
    664 		return fprintf(stream, "%zd", low);
    665 	else
    666 		return fprintf(stream, "%zd-%zd", low, high);
    667 }
    668 
    669 static int
    670 bitvect_lens_format_cb(struct lens *lens, FILE *stream,
    671 		       struct value *value, struct value_dict *arguments)
    672 {
    673 	unsigned char *data = value_get_data(value, arguments);
    674 	if (data == NULL)
    675 		return -1;
    676 	size_t sz = type_sizeof(value->inferior, value->type);
    677 	if (sz == (size_t)-1)
    678 		return -1;
    679 
    680 	size_t i;
    681 	unsigned char buf[sz];
    682 	switch ((int)value->type->type) {
    683 		union bitvect_integral_64
    684 		{
    685 			uint8_t u8;
    686 			uint16_t u16;
    687 			uint32_t u32;
    688 			uint64_t u64;
    689 			unsigned char buf[0];
    690 		} bv;
    691 
    692 	case ARGTYPE_POINTER:
    693 		return format_pointer(stream, value, arguments);
    694 
    695 	case ARGTYPE_STRUCT:
    696 	case ARGTYPE_ARRAY:
    697 		break;
    698 
    699 	default:
    700 		assert(sz <= sizeof(bv));
    701 		memmove(bv.buf, data, sz);
    702 
    703 		if (sz == 1)
    704 			bv.u64 = bv.u8;
    705 		else if (sz == 2)
    706 			bv.u64 = bv.u16;
    707 		else if (sz == 4)
    708 			bv.u64 = bv.u32;
    709 
    710 		for (i = 0; i < sz; ++i) {
    711 			buf[i] = bv.u64 & 0xff;
    712 			bv.u64 >>= 8;
    713 		}
    714 		data = buf;
    715 	}
    716 
    717 	size_t bits = 0;
    718 	for (i = 0; i < sz; ++i)
    719 		bits += bitcount(data[i]);
    720 
    721 	/* If there's more 1's than 0's, show inverse.  */
    722 	unsigned neg = bits > sz * 4 ? 0xff : 0x00;
    723 
    724 	int o = 0;
    725 	if (acc_fprintf(&o, stream, "%s<", &"~"[neg == 0x00]) < 0)
    726 		return -1;
    727 
    728 	size_t bitno = 0;
    729 	ssize_t low = -1;
    730 	for (i = 0; i < sz; ++i) {
    731 		unsigned char m;
    732 		unsigned char d = data[i] ^ neg;
    733 		for (m = 0x01; m != 0; m <<= 1) {
    734 			int bit = !!(m & d);
    735 			if (low < 0) {
    736 				if (bit) {
    737 					if (low == -2
    738 					    && acc_fprintf(&o, stream, ",") < 0)
    739 						return -1;
    740 					low = bitno;
    741 				}
    742 			} else if (!bit) {
    743 				if (account_output(&o, out_bits(stream, low,
    744 								bitno-1)) < 0)
    745 					return -1;
    746 				low = -2;
    747 			}
    748 			bitno++;
    749 		}
    750 	}
    751 	if (low >= 0 && account_output(&o, out_bits(stream, low, bitno-1)) < 0)
    752 		return -1;
    753 
    754 	if (fputc('>', stream) < 0)
    755 		return -1;
    756 	o += 1;
    757 
    758 	return o;
    759 }
    760 
    761 struct lens bitvect_lens = {
    762 	.format_cb = bitvect_lens_format_cb,
    763 };
    764