Annotation of prex-old/usr/lib/libsa/vsprintf.c, Revision 1.1.1.1
1.1 nbrk 1: /*-
2: * Copyright (c) 2005, Kohsuke Ohtani
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. Neither the name of the author nor the names of any co-contributors
14: * may be used to endorse or promote products derived from this software
15: * without specific prior written permission.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27: * SUCH DAMAGE.
28: */
29:
30: /*
31: * vsprintf.c - Format and output data to buffer
32: */
33:
34: #include <limits.h>
35: #include <stdarg.h>
36: #include <string.h>
37: #include <stdio.h>
38:
39: #define isdigit(c) ((unsigned)((c) - '0') < 10)
40:
41: static int
42: divide(long *n, int base)
43: {
44: int res;
45:
46: /*
47: * Note: Optimized for ARM processor which does not support
48: * divide instructions.
49: *
50: * res = ((unsigned long)*n) % (unsigned int)base;
51: * *n = ((unsigned long)*n) / (unsigned int)base;
52: */
53:
54: if (base == 10) {
55: res = ((unsigned long)*n) % 10U;
56: *n = ((unsigned long)*n) / 10U;
57: } else {
58: res = ((unsigned long)*n) % 16U;
59: *n = ((unsigned long)*n) / 16U;
60: }
61: return res;
62: }
63:
64: static int
65: atoi(const char **s)
66: {
67: int i = 0;
68: while (isdigit((int)**s))
69: i = i * 10 + *((*s)++) - '0';
70: return i;
71: }
72:
73: /*
74: * Print formatted output - scaled down version
75: *
76: * Identifiers:
77: * %d - Decimal signed int
78: * %x - Hex integer
79: * %u - Unsigned integer
80: * %c - Character
81: * %s - String
82: *
83: * Flags:
84: * 0 - Zero pad
85: */
86: int
87: vsprintf(char *buf, const char *fmt, va_list args)
88: {
89: char *p, *str;
90: const char *digits = "0123456789abcdef";
91: char pad, tmp[16];
92: int width, base, sign, i, size;
93: long num;
94:
95: size = 0;
96: for (p = buf; *fmt && (size < LINE_MAX); fmt++, size++) {
97: if (*fmt != '%') {
98: *p++ = *fmt;
99: continue;
100: }
101: /* get flags */
102: ++fmt;
103: pad = ' ';
104: if (*fmt == '0') {
105: pad = '0';
106: fmt++;
107: }
108: /* get width */
109: width = -1;
110: if (isdigit((int)*fmt)) {
111: width = atoi(&fmt);
112: }
113: base = 10;
114: sign = 0;
115: switch (*fmt) {
116: case 'c':
117: *p++ = (unsigned char)va_arg(args, int);
118: continue;
119: case 's':
120: str = va_arg(args, char *);
121: if (str == NULL)
122: str = "<NULL>";
123: for (; *str; str++) {
124: *p++ = *str;
125: if (size++ >= LINE_MAX)
126: break;
127: }
128: continue;
129: case 'X':
130: case 'x':
131: base = 16;
132: break;
133: case 'd':
134: sign = 1;
135: break;
136: case 'u':
137: break;
138: default:
139: continue;
140: }
141: num = va_arg(args, long);
142: if (sign && num < 0) {
143: num = -num;
144: *p++ = '-';
145: width--;
146: }
147: i = 0;
148: if (num == 0)
149: tmp[i++] = '0';
150: else
151: while (num != 0)
152: tmp[i++] = digits[divide(&num, base)];
153: width -= i;
154: while (width-- > 0)
155: *p++ = pad;
156: while (i-- > 0)
157: *p++ = tmp[i];
158: }
159: *p = '\0';
160: return (p - buf);
161: }
162:
163: int
164: sprintf(char *buf, const char *fmt, ...)
165: {
166: va_list args;
167: int i;
168:
169: va_start(args, fmt);
170: i = vsprintf(buf, fmt, args);
171: va_end(args);
172: return i;
173: }
CVSweb