1 /*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)clnp_sprintf.c 7.1 (Berkeley) 05/08/91 8 */ 9 10 /* 11 * CLNP needs a version of sprintf in the kernel. If anything else 12 * ever needs it, this can trivially be dropped into kern/subr_prf.c. 13 */ 14 #include "param.h" 15 16 /* 17 * Note that stdarg.h and the ANSI style va_start macro is used for both 18 * ANSI and traditional C compilers. 19 */ 20 #include <machine/stdarg.h> 21 22 int sprintf __P((char *, const char *, ...)); 23 24 /* 25 * Scaled down version of sprintf(3). 26 */ 27 #ifdef __STDC__ 28 sprintf(char *buf, const char *fmt, ...) 29 #else 30 sprintf(buf, fmt /*, va_alist */) 31 char *buf, *fmt; 32 #endif 33 { 34 register char *p, *bp; 35 register int ch, base; 36 u_long ul; 37 int lflag; /* hold a long in base 8 */ 38 char num[(sizeof(long) * NBBY / 3) + 1]; 39 va_list ap; 40 41 va_start(ap, fmt); 42 for (bp = buf;;) { 43 while ((ch = *fmt++) != '%') { 44 if ((*bp = ch) == '\0') 45 return(bp - buf); 46 *bp++ = ch; 47 } 48 lflag = 0; 49 reswitch: switch (ch = *fmt++) { 50 case 'l': 51 lflag = 1; 52 goto reswitch; 53 case 'c': 54 *bp++ = va_arg(ap, int); 55 break; 56 case 's': 57 p = va_arg(ap, char *); 58 while (*bp++ = *p++); 59 --bp; 60 break; 61 case 'D': 62 lflag = 1; 63 /* FALLTHROUGH */ 64 case 'd': 65 ul = lflag ? 66 va_arg(ap, long) : va_arg(ap, int); 67 if ((long)ul < 0) { 68 *bp++ = '-'; 69 ul = -(long)ul; 70 } 71 base = 10; 72 goto number; 73 break; 74 case 'O': 75 lflag = 1; 76 /* FALLTHROUGH */ 77 case 'o': 78 ul = lflag ? 79 va_arg(ap, u_long) : va_arg(ap, u_int); 80 base = 8; 81 goto number; 82 break; 83 case 'U': 84 lflag = 1; 85 /* FALLTHROUGH */ 86 case 'u': 87 ul = lflag ? 88 va_arg(ap, u_long) : va_arg(ap, u_int); 89 base = 10; 90 goto number; 91 break; 92 case 'X': 93 lflag = 1; 94 /* FALLTHROUGH */ 95 case 'x': 96 ul = lflag ? 97 va_arg(ap, u_long) : va_arg(ap, u_int); 98 base = 16; 99 number: p = num; 100 do { 101 *p++ = "0123456789abcdef"[ul % base]; 102 } while (ul /= base); 103 do { 104 *bp++ = *--p; 105 } while (p > num); 106 break; 107 default: 108 *bp++ = '%'; 109 if (lflag) 110 *bp++ = 'l'; 111 *bp++ = ch; 112 } 113 } 114 va_end(ap); 115 } 116