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