xref: /original-bsd/sys/netiso/clnp_sprintf.c (revision e59fb703)
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