xref: /freebsd/lib/libc/stdio/xprintf_hexdump.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
175067f4fSPoul-Henning Kamp /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3d915a14eSPedro F. Giffuni  *
475067f4fSPoul-Henning Kamp  * Copyright (c) 2005 Poul-Henning Kamp
575067f4fSPoul-Henning Kamp  * All rights reserved.
675067f4fSPoul-Henning Kamp  *
775067f4fSPoul-Henning Kamp  * Redistribution and use in source and binary forms, with or without
875067f4fSPoul-Henning Kamp  * modification, are permitted provided that the following conditions
975067f4fSPoul-Henning Kamp  * are met:
1075067f4fSPoul-Henning Kamp  * 1. Redistributions of source code must retain the above copyright
1175067f4fSPoul-Henning Kamp  *    notice, this list of conditions and the following disclaimer.
1275067f4fSPoul-Henning Kamp  * 2. Redistributions in binary form must reproduce the above copyright
1375067f4fSPoul-Henning Kamp  *    notice, this list of conditions and the following disclaimer in the
1475067f4fSPoul-Henning Kamp  *    documentation and/or other materials provided with the distribution.
1575067f4fSPoul-Henning Kamp  *
1675067f4fSPoul-Henning Kamp  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1775067f4fSPoul-Henning Kamp  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1875067f4fSPoul-Henning Kamp  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1975067f4fSPoul-Henning Kamp  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2075067f4fSPoul-Henning Kamp  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2175067f4fSPoul-Henning Kamp  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2275067f4fSPoul-Henning Kamp  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2375067f4fSPoul-Henning Kamp  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2475067f4fSPoul-Henning Kamp  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2575067f4fSPoul-Henning Kamp  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2675067f4fSPoul-Henning Kamp  * SUCH DAMAGE.
2775067f4fSPoul-Henning Kamp  */
2875067f4fSPoul-Henning Kamp 
2975067f4fSPoul-Henning Kamp #include <namespace.h>
3075067f4fSPoul-Henning Kamp #include <stdio.h>
3175067f4fSPoul-Henning Kamp #include <wchar.h>
3275067f4fSPoul-Henning Kamp #include <stdint.h>
3375067f4fSPoul-Henning Kamp #include <assert.h>
3475067f4fSPoul-Henning Kamp #include <sys/time.h>
3575067f4fSPoul-Henning Kamp #include "printf.h"
3675067f4fSPoul-Henning Kamp 
3775067f4fSPoul-Henning Kamp int
__printf_arginfo_hexdump(const struct printf_info * pi,size_t n,int * argt)3875067f4fSPoul-Henning Kamp __printf_arginfo_hexdump(const struct printf_info *pi, size_t n, int *argt)
3975067f4fSPoul-Henning Kamp {
4075067f4fSPoul-Henning Kamp 
4175067f4fSPoul-Henning Kamp 	assert(n >= 2);
4275067f4fSPoul-Henning Kamp 	argt[0] = PA_POINTER;
4375067f4fSPoul-Henning Kamp 	argt[1] = PA_INT;
4475067f4fSPoul-Henning Kamp 	return (2);
4575067f4fSPoul-Henning Kamp }
4675067f4fSPoul-Henning Kamp 
4775067f4fSPoul-Henning Kamp int
__printf_render_hexdump(struct __printf_io * io,const struct printf_info * pi,const void * const * arg)4875067f4fSPoul-Henning Kamp __printf_render_hexdump(struct __printf_io *io, const struct printf_info *pi, const void *const *arg)
4975067f4fSPoul-Henning Kamp {
5075067f4fSPoul-Henning Kamp 	unsigned char *p;
5122adaea1SPoul-Henning Kamp 	int i;
5275067f4fSPoul-Henning Kamp 	unsigned u, l, j, a;
5375067f4fSPoul-Henning Kamp 	char buf[100], *q;
5475067f4fSPoul-Henning Kamp 	int ret;
5575067f4fSPoul-Henning Kamp 
5675067f4fSPoul-Henning Kamp 	if (pi->width > 0 && pi->width < 16)
5775067f4fSPoul-Henning Kamp 		l = pi->width;
5875067f4fSPoul-Henning Kamp 	else
5975067f4fSPoul-Henning Kamp 		l = 16;
6075067f4fSPoul-Henning Kamp 	p = *((unsigned char **)arg[0]);
6122adaea1SPoul-Henning Kamp 	i = *((int *)arg[1]);
6222adaea1SPoul-Henning Kamp 	if (i < 0)
6322adaea1SPoul-Henning Kamp 		i = 0;
6422adaea1SPoul-Henning Kamp 	u = i;
6575067f4fSPoul-Henning Kamp 
6675067f4fSPoul-Henning Kamp 	ret = 0;
6775067f4fSPoul-Henning Kamp 	a = 0;
6875067f4fSPoul-Henning Kamp 	while (u > 0) {
6975067f4fSPoul-Henning Kamp 		q = buf;
7075067f4fSPoul-Henning Kamp 		if (pi->showsign)
7175067f4fSPoul-Henning Kamp 			q += sprintf(q, " %04x", a);
7275067f4fSPoul-Henning Kamp 		for (j = 0; j < l && j < u; j++)
7375067f4fSPoul-Henning Kamp 			q += sprintf(q, " %02x", p[j]);
7475067f4fSPoul-Henning Kamp 		if (pi->alt) {
7575067f4fSPoul-Henning Kamp 			for (; j < l; j++)
7675067f4fSPoul-Henning Kamp 				q += sprintf(q, "   ");
7775067f4fSPoul-Henning Kamp 			q += sprintf(q, "  |");
7875067f4fSPoul-Henning Kamp 			for (j = 0; j < l && j < u; j++) {
7975067f4fSPoul-Henning Kamp 				if (p[j] < ' ' || p[j] > '~')
8075067f4fSPoul-Henning Kamp 					*q++ = '.';
8175067f4fSPoul-Henning Kamp 				else
8275067f4fSPoul-Henning Kamp 					*q++ = p[j];
8375067f4fSPoul-Henning Kamp 			}
8475067f4fSPoul-Henning Kamp 			for (; j < l; j++)
8575067f4fSPoul-Henning Kamp 				*q++ = ' ';
8675067f4fSPoul-Henning Kamp 			*q++ = '|';
8775067f4fSPoul-Henning Kamp 		}
8875067f4fSPoul-Henning Kamp 		if (l < u)
8975067f4fSPoul-Henning Kamp 			j = l;
9075067f4fSPoul-Henning Kamp 		else
9175067f4fSPoul-Henning Kamp 			j = u;
9275067f4fSPoul-Henning Kamp 		p += j;
9375067f4fSPoul-Henning Kamp 		u -= j;
9475067f4fSPoul-Henning Kamp 		a += j;
9575067f4fSPoul-Henning Kamp 		if (u > 0)
9675067f4fSPoul-Henning Kamp 			*q++ = '\n';
9775067f4fSPoul-Henning Kamp 		ret += __printf_puts(io, buf + 1, q - (buf + 1));
9875067f4fSPoul-Henning Kamp 		__printf_flush(io);
9975067f4fSPoul-Henning Kamp 	}
10075067f4fSPoul-Henning Kamp 	return (ret);
10175067f4fSPoul-Henning Kamp }
102