1 /* $NetBSD: xprintf.c,v 1.21 2010/12/16 22:52:32 joerg Exp $ */
4 * Copyright 1996 Matt Thomas <matt@3am-software.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: xprintf.c,v 1.21 2010/12/16 22:52:32 joerg Exp $");
45 #define SZ_UNSIGNED 0x02
46 #define SZ_SIZE_T 0x04
49 * Non-mallocing printf, for use by malloc and rtld itself.
50 * This avoids putting in most of stdio.
52 * deals withs formats %x, %p, %s, and %d.
55 xvsnprintf(char *buf
, size_t buflen
, const char *fmt
, va_list ap
)
58 char *const ep
= buf
+ buflen
- 4;
61 while (*fmt
!= '\0' && bp
< ep
) {
71 rflag
: switch (fmt
[1]) {
73 prec
= va_arg(ap
, int);
92 char digits
[sizeof(int) * 3], *dp
= digits
;
94 (size & SZ_LONG ? va_arg(ap, long) : \
95 ((size & SZ_SIZE_T ? (long)va_arg(ap, size_t) : \
98 (size & SZ_LONG ? va_arg(ap, unsigned long) : \
99 ((size & SZ_SIZE_T ? va_arg(ap, size_t) : \
100 va_arg(ap, unsigned int))))
103 if (size
& SZ_UNSIGNED
)
108 if ((sval
<< 1) == 0) {
119 * since it is now not
122 *dp
++ = '0'-(sval
% 10);
131 if (size
& SZ_UNSIGNED
)
137 *dp
++ = '0' + (uval
% 10);
142 } while (dp
!= digits
&& bp
< ep
);
148 unsigned long val
= va_arg(ap
, unsigned long);
149 unsigned long mask
= ~(~0UL >> 4);
150 int bits
= sizeof(val
) * 8 - 4;
151 const char hexdigits
[] = "0123456789abcdef";
156 /* handle the border case */
163 while ((val
& mask
) == 0)
164 bits
-= 4, mask
>>= 4;
166 /* emit the hex digits */
167 while (bits
>= 0 && bp
< ep
) {
168 *bp
++ = hexdigits
[(val
& mask
) >> bits
];
169 bits
-= 4, mask
>>= 4;
175 const char *str
= va_arg(ap
, const char *);
187 memcpy(bp
, str
, len
);
193 int c
= va_arg(ap
, int);
215 xvprintf(const char *fmt
, va_list ap
)
219 (void) write(2, buf
, xvsnprintf(buf
, sizeof(buf
), fmt
, ap
));
223 xprintf(const char *fmt
, ...)
235 xsnprintf(char *buf
, size_t buflen
, const char *fmt
, ...)
241 xvsnprintf(buf
, buflen
, fmt
, ap
);
246 #include "errlist_concat.h"
252 if (error
>= concat_nerr
|| error
< 0) {
253 static char buf
[128];
254 xsnprintf(buf
, sizeof(buf
), "Unknown error: %d", error
);
257 return concat_errlist
+ concat_offset
[error
];
261 xerrx(int eval
, const char *fmt
, ...)
268 (void) write(2, "\n", 1);
274 xerr(int eval
, const char *fmt
, ...)
276 int saved_errno
= errno
;
283 xprintf(": %s\n", xstrerror(saved_errno
));
288 xwarn(const char *fmt
, ...)
290 int saved_errno
= errno
;
297 xprintf(": %s\n", xstrerror(saved_errno
));
302 xwarnx(const char *fmt
, ...)
309 (void) write(2, "\n", 1);
314 xassert(const char *file
, int line
, const char *failedexpr
)
317 xprintf("assertion \"%s\" failed: file \"%s\", line %d\n",
318 failedexpr
, file
, line
);