1*71b3fa15SDavid Xu /*- 2*71b3fa15SDavid Xu * Copyright (c) 2002 Jonathan Mini <mini@freebsd.org> 3*71b3fa15SDavid Xu * All rights reserved. 4*71b3fa15SDavid Xu * 5*71b3fa15SDavid Xu * Redistribution and use in source and binary forms, with or without 6*71b3fa15SDavid Xu * modification, are permitted provided that the following conditions 7*71b3fa15SDavid Xu * are met: 8*71b3fa15SDavid Xu * 1. Redistributions of source code must retain the above copyright 9*71b3fa15SDavid Xu * notice, this list of conditions and the following disclaimer. 10*71b3fa15SDavid Xu * 2. Redistributions in binary form must reproduce the above copyright 11*71b3fa15SDavid Xu * notice, this list of conditions and the following disclaimer in the 12*71b3fa15SDavid Xu * documentation and/or other materials provided with the distribution. 13*71b3fa15SDavid Xu * 14*71b3fa15SDavid Xu * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*71b3fa15SDavid Xu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*71b3fa15SDavid Xu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*71b3fa15SDavid Xu * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*71b3fa15SDavid Xu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*71b3fa15SDavid Xu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*71b3fa15SDavid Xu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*71b3fa15SDavid Xu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*71b3fa15SDavid Xu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*71b3fa15SDavid Xu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*71b3fa15SDavid Xu * SUCH DAMAGE. 25*71b3fa15SDavid Xu * 26*71b3fa15SDavid Xu * $DragonFly: src/lib/libthread_xu/thread/thr_printf.c,v 1.1 2005/02/01 12:38:27 davidxu Exp $ 27*71b3fa15SDavid Xu */ 28*71b3fa15SDavid Xu 29*71b3fa15SDavid Xu #include <sys/cdefs.h> 30*71b3fa15SDavid Xu #include <stdarg.h> 31*71b3fa15SDavid Xu #include <string.h> 32*71b3fa15SDavid Xu #include <unistd.h> 33*71b3fa15SDavid Xu #include <pthread.h> 34*71b3fa15SDavid Xu 35*71b3fa15SDavid Xu #include "thr_private.h" 36*71b3fa15SDavid Xu 37*71b3fa15SDavid Xu static void pchar(int fd, char c); 38*71b3fa15SDavid Xu static void pstr(int fd, const char *s); 39*71b3fa15SDavid Xu 40*71b3fa15SDavid Xu /* 41*71b3fa15SDavid Xu * Write formatted output to stdout, in a thread-safe manner. 42*71b3fa15SDavid Xu * 43*71b3fa15SDavid Xu * Recognises the following conversions: 44*71b3fa15SDavid Xu * %c -> char 45*71b3fa15SDavid Xu * %d -> signed int (base 10) 46*71b3fa15SDavid Xu * %s -> string 47*71b3fa15SDavid Xu * %u -> unsigned int (base 10) 48*71b3fa15SDavid Xu * %x -> unsigned int (base 16) 49*71b3fa15SDavid Xu * %p -> unsigned int (base 16) 50*71b3fa15SDavid Xu */ 51*71b3fa15SDavid Xu void 52*71b3fa15SDavid Xu _thread_printf(int fd, const char *fmt, ...) 53*71b3fa15SDavid Xu { 54*71b3fa15SDavid Xu static const char digits[16] = "0123456789abcdef"; 55*71b3fa15SDavid Xu va_list ap; 56*71b3fa15SDavid Xu char buf[20]; 57*71b3fa15SDavid Xu char *s; 58*71b3fa15SDavid Xu unsigned long r, u; 59*71b3fa15SDavid Xu int c; 60*71b3fa15SDavid Xu long d; 61*71b3fa15SDavid Xu int islong; 62*71b3fa15SDavid Xu 63*71b3fa15SDavid Xu va_start(ap, fmt); 64*71b3fa15SDavid Xu while ((c = *fmt++)) { 65*71b3fa15SDavid Xu islong = 0; 66*71b3fa15SDavid Xu if (c == '%') { 67*71b3fa15SDavid Xu next: c = *fmt++; 68*71b3fa15SDavid Xu if (c == '\0') 69*71b3fa15SDavid Xu goto out; 70*71b3fa15SDavid Xu switch (c) { 71*71b3fa15SDavid Xu case 'c': 72*71b3fa15SDavid Xu pchar(fd, va_arg(ap, int)); 73*71b3fa15SDavid Xu continue; 74*71b3fa15SDavid Xu case 's': 75*71b3fa15SDavid Xu pstr(fd, va_arg(ap, char *)); 76*71b3fa15SDavid Xu continue; 77*71b3fa15SDavid Xu case 'l': 78*71b3fa15SDavid Xu islong = 1; 79*71b3fa15SDavid Xu goto next; 80*71b3fa15SDavid Xu case 'p': 81*71b3fa15SDavid Xu islong = 1; 82*71b3fa15SDavid Xu case 'd': 83*71b3fa15SDavid Xu case 'u': 84*71b3fa15SDavid Xu case 'x': 85*71b3fa15SDavid Xu r = ((c == 'u') || (c == 'd')) ? 10 : 16; 86*71b3fa15SDavid Xu if (c == 'd') { 87*71b3fa15SDavid Xu if (islong) 88*71b3fa15SDavid Xu d = va_arg(ap, unsigned long); 89*71b3fa15SDavid Xu else 90*71b3fa15SDavid Xu d = va_arg(ap, unsigned); 91*71b3fa15SDavid Xu if (d < 0) { 92*71b3fa15SDavid Xu pchar(fd, '-'); 93*71b3fa15SDavid Xu u = (unsigned long)(d * -1); 94*71b3fa15SDavid Xu } else 95*71b3fa15SDavid Xu u = (unsigned long)d; 96*71b3fa15SDavid Xu } else { 97*71b3fa15SDavid Xu if (islong) 98*71b3fa15SDavid Xu u = va_arg(ap, unsigned long); 99*71b3fa15SDavid Xu else 100*71b3fa15SDavid Xu u = va_arg(ap, unsigned); 101*71b3fa15SDavid Xu } 102*71b3fa15SDavid Xu s = buf; 103*71b3fa15SDavid Xu do { 104*71b3fa15SDavid Xu *s++ = digits[u % r]; 105*71b3fa15SDavid Xu } while (u /= r); 106*71b3fa15SDavid Xu while (--s >= buf) 107*71b3fa15SDavid Xu pchar(fd, *s); 108*71b3fa15SDavid Xu continue; 109*71b3fa15SDavid Xu } 110*71b3fa15SDavid Xu } 111*71b3fa15SDavid Xu pchar(fd, c); 112*71b3fa15SDavid Xu } 113*71b3fa15SDavid Xu out: 114*71b3fa15SDavid Xu va_end(ap); 115*71b3fa15SDavid Xu } 116*71b3fa15SDavid Xu 117*71b3fa15SDavid Xu /* 118*71b3fa15SDavid Xu * Write a single character to stdout, in a thread-safe manner. 119*71b3fa15SDavid Xu */ 120*71b3fa15SDavid Xu static void 121*71b3fa15SDavid Xu pchar(int fd, char c) 122*71b3fa15SDavid Xu { 123*71b3fa15SDavid Xu 124*71b3fa15SDavid Xu __sys_write(fd, &c, 1); 125*71b3fa15SDavid Xu } 126*71b3fa15SDavid Xu 127*71b3fa15SDavid Xu /* 128*71b3fa15SDavid Xu * Write a string to stdout, in a thread-safe manner. 129*71b3fa15SDavid Xu */ 130*71b3fa15SDavid Xu static void 131*71b3fa15SDavid Xu pstr(int fd, const char *s) 132*71b3fa15SDavid Xu { 133*71b3fa15SDavid Xu 134*71b3fa15SDavid Xu __sys_write(fd, s, strlen(s)); 135*71b3fa15SDavid Xu } 136*71b3fa15SDavid Xu 137