Sun Jan 23 02:08:24 2011 UTC ()
fix a failure in the sign extension consideration.


(nisimura)
diff -r1.2 -r1.3 src/sys/arch/sandpoint/stand/altboot/printf.c

cvs diff -r1.2 -r1.3 src/sys/arch/sandpoint/stand/altboot/Attic/printf.c (switch to unified diff)

--- src/sys/arch/sandpoint/stand/altboot/Attic/printf.c 2011/01/23 01:32:08 1.2
+++ src/sys/arch/sandpoint/stand/altboot/Attic/printf.c 2011/01/23 02:08:24 1.3
@@ -1,271 +1,272 @@ @@ -1,271 +1,272 @@
1/* $NetBSD: printf.c,v 1.2 2011/01/23 01:32:08 nisimura Exp $ */ 1/* $NetBSD: printf.c,v 1.3 2011/01/23 02:08:24 nisimura Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 2007 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Tohru Nishimura. 8 * by Tohru Nishimura.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * printf -- format and write output using 'func' to write characters 33 * printf -- format and write output using 'func' to write characters
34 */ 34 */
35 35
36#include <sys/types.h> 36#include <sys/types.h>
37#include <machine/stdarg.h> 37#include <machine/stdarg.h>
38#include <lib/libsa/stand.h> 38#include <lib/libsa/stand.h>
39 39
40#define MAXSTR 80 40#define MAXSTR 80
41 41
42static int _doprnt(void (*)(int), const char *, va_list); 42static int _doprnt(void (*)(int), const char *, va_list);
43static void mkdigit(unsigned long long, int, char *); 43static void mkdigit(unsigned long long, int, char *);
44static void sputchar(int); 44static void sputchar(int);
45 45
46static char *sbuf, *ebuf; 46static char *sbuf, *ebuf;
47 47
48void 48void
49printf(const char *fmt, ...) 49printf(const char *fmt, ...)
50{ 50{
51 va_list ap; 51 va_list ap;
52 52
53 va_start(ap, fmt); 53 va_start(ap, fmt);
54 _doprnt(putchar, fmt, ap); 54 _doprnt(putchar, fmt, ap);
55 va_end(ap); 55 va_end(ap);
56} 56}
57 57
58void 58void
59vprintf(const char *fmt, va_list ap) 59vprintf(const char *fmt, va_list ap)
60{ 60{
61 61
62 _doprnt(putchar, fmt, ap); 62 _doprnt(putchar, fmt, ap);
63} 63}
64 64
65int 65int
66sprintf(char *buf, const char *fmt, ...) 66sprintf(char *buf, const char *fmt, ...)
67{ 67{
68 va_list ap; 68 va_list ap;
69 69
70 sbuf = buf; 70 sbuf = buf;
71 ebuf = buf + -(size_t)buf - 1; 71 ebuf = buf + -(size_t)buf - 1;
72 va_start(ap, fmt); 72 va_start(ap, fmt);
73 _doprnt(sputchar, fmt, ap); 73 _doprnt(sputchar, fmt, ap);
74 *sbuf = '\0'; 74 *sbuf = '\0';
75 return (sbuf - buf); 75 return (sbuf - buf);
76} 76}
77 77
78int 78int
79snprintf(char *buf, size_t size, const char *fmt, ...) 79snprintf(char *buf, size_t size, const char *fmt, ...)
80{ 80{
81 va_list ap; 81 va_list ap;
82 82
83 sbuf = buf; 83 sbuf = buf;
84 ebuf = buf + size - 1; 84 ebuf = buf + size - 1;
85 va_start(ap, fmt); 85 va_start(ap, fmt);
86 _doprnt(sputchar, fmt, ap); 86 _doprnt(sputchar, fmt, ap);
87 *sbuf = '\0'; 87 *sbuf = '\0';
88 return (sbuf - buf); 88 return (sbuf - buf);
89} 89}
90 90
91static int 91static int
92_doprnt(void (*func)(int), const char *fmt, va_list ap) 92_doprnt(void (*func)(int), const char *fmt, va_list ap)
93{ 93{
94 int i, outcnt; 94 int i, outcnt;
95 char buf[23], *str; /* requires 23 digits in octal at most */ 95 char buf[23], *str; /* requires 23 digits in octal at most */
96 int length, fmax, fmin, leading; 96 int length, fmax, fmin, leading;
97 int leftjust, llflag; 97 int leftjust, llflag;
98 char fill, sign; 98 char fill, sign;
99 long long v; 99 long long d;
 100 unsigned long long v;
100 101
101 outcnt = 0; 102 outcnt = 0;
102 while ((i = *fmt++) != '\0') { 103 while ((i = *fmt++) != '\0') {
103 if (i != '%') { 104 if (i != '%') {
104 (*func)(i); 105 (*func)(i);
105 outcnt += 1; 106 outcnt += 1;
106 continue; 107 continue;
107 } 108 }
108 if (*fmt == '%') { 109 if (*fmt == '%') {
109 (*func)(*fmt++); 110 (*func)(*fmt++);
110 outcnt += 1; 111 outcnt += 1;
111 continue; 112 continue;
112 } 113 }
113 leftjust = (*fmt == '-'); 114 leftjust = (*fmt == '-');
114 if (leftjust) 115 if (leftjust)
115 fmt++; 116 fmt++;
116 fill = (*fmt == '0') ? *fmt++ : ' '; 117 fill = (*fmt == '0') ? *fmt++ : ' ';
117 if (*fmt == '*') 118 if (*fmt == '*')
118 fmin = va_arg(ap, int); 119 fmin = va_arg(ap, int);
119 else { 120 else {
120 fmin = 0; 121 fmin = 0;
121 while ('0' <= *fmt && *fmt <= '9') 122 while ('0' <= *fmt && *fmt <= '9')
122 fmin = fmin * 10 + *fmt++ - '0'; 123 fmin = fmin * 10 + *fmt++ - '0';
123 } 124 }
124 if (*fmt != '.') 125 if (*fmt != '.')
125 fmax = 0; 126 fmax = 0;
126 else { 127 else {
127 fmt++; 128 fmt++;
128 if (*fmt == '*') 129 if (*fmt == '*')
129 fmax = va_arg(ap, int); 130 fmax = va_arg(ap, int);
130 else { 131 else {
131 fmax = 0; 132 fmax = 0;
132 while ('0' <= *fmt && *fmt <= '9') 133 while ('0' <= *fmt && *fmt <= '9')
133 fmax = fmax * 10 + *fmt++ - '0'; 134 fmax = fmax * 10 + *fmt++ - '0';
134 } 135 }
135 } 136 }
136 llflag = 0; 137 llflag = 0;
137 if (*fmt == 'l' && *++fmt == 'l') { 138 if (*fmt == 'l' && *++fmt == 'l') {
138 llflag = 1; 139 llflag = 1;
139 fmt += 1; 140 fmt += 1;
140 } 141 }
141 if ((i = *fmt++) == '\0') { 142 if ((i = *fmt++) == '\0') {
142 (*func)('%'); 143 (*func)('%');
143 outcnt += 1; 144 outcnt += 1;
144 break; 145 break;
145 } 146 }
146 str = buf; 147 str = buf;
147 sign = ' '; 148 sign = ' ';
148 switch (i) { 149 switch (i) {
149 case 'c': 150 case 'c':
150 str[0] = va_arg(ap, int); 151 str[0] = va_arg(ap, int);
151 str[1] = '\0'; 152 str[1] = '\0';
152 fmax = 0; 153 fmax = 0;
153 fill = ' '; 154 fill = ' ';
154 break; 155 break;
155 156
156 case 's': 157 case 's':
157 str = va_arg(ap, char *); 158 str = va_arg(ap, char *);
158 fill = ' '; 159 fill = ' ';
159 break; 160 break;
160 161
161 case 'd': 162 case 'd':
162 if (llflag) 163 if (llflag)
163 v = va_arg(ap, long long); 164 d = va_arg(ap, long long);
164 else 165 else
165 v = va_arg(ap, int); 166 d = va_arg(ap, int);
166 if (v < 0) { 167 if (d < 0) {
167 sign = '-' ; v = -v; 168 sign = '-' ; d = -d;
168 } 169 }
169 mkdigit((unsigned long long)v, 10, str); 170 mkdigit((unsigned long long)d, 10, str);
170 break; 171 break;
171 172
172 case 'u': 173 case 'u':
173 if (llflag) 174 if (llflag)
174 v = va_arg(ap, long long); 175 v = va_arg(ap, unsigned long long);
175 else 176 else
176 v = va_arg(ap, int); 177 v = va_arg(ap, unsigned int);
177 mkdigit((unsigned long long)v, 10, str); 178 mkdigit(v, 10, str);
178 break; 179 break;
179 180
180 case 'o': 181 case 'o':
181 if (llflag) 182 if (llflag)
182 v = va_arg(ap, long long); 183 v = va_arg(ap, unsigned long long);
183 else 184 else
184 v = va_arg(ap, int); 185 v = va_arg(ap, unsigned int);
185 mkdigit((unsigned long long)v, 8, str); 186 mkdigit(v, 8, str);
186 fmax = 0; 187 fmax = 0;
187 break; 188 break;
188 189
189 case 'X': 190 case 'X':
190 case 'x': 191 case 'x':
191 if (llflag) 192 if (llflag)
192 v = va_arg(ap, long long); 193 v = va_arg(ap, unsigned long long);
193 else 194 else
194 v = va_arg(ap, int); 195 v = va_arg(ap, unsigned int);
195 mkdigit((unsigned long long)v, 16, str); 196 mkdigit(v, 16, str);
196 fmax = 0; 197 fmax = 0;
197 break; 198 break;
198 199
199 case 'p': 200 case 'p':
200 mkdigit(va_arg(ap, unsigned int), 16, str); 201 mkdigit(va_arg(ap, unsigned int), 16, str);
201 fill = '0'; 202 fill = '0';
202 fmin = 8; 203 fmin = 8;
203 fmax = 0; 204 fmax = 0;
204 (*func)('0'); (*func)('x'); 205 (*func)('0'); (*func)('x');
205 outcnt += 2; 206 outcnt += 2;
206 break; 207 break;
207 208
208 default: 209 default:
209 (*func)(i); 210 (*func)(i);
210 break; 211 break;
211 } 212 }
212 for (i = 0; str[i] != '\0'; i++) 213 for (i = 0; str[i] != '\0'; i++)
213 ; 214 ;
214 length = i; 215 length = i;
215 if (fmin > MAXSTR || fmin < 0) 216 if (fmin > MAXSTR || fmin < 0)
216 fmin = 0; 217 fmin = 0;
217 if (fmax > MAXSTR || fmax < 0) 218 if (fmax > MAXSTR || fmax < 0)
218 fmax = 0; 219 fmax = 0;
219 leading = 0; 220 leading = 0;
220 if (fmax != 0 || fmin != 0) { 221 if (fmax != 0 || fmin != 0) {
221 if (fmax != 0 && length > fmax) 222 if (fmax != 0 && length > fmax)
222 length = fmax; 223 length = fmax;
223 if (fmin != 0) 224 if (fmin != 0)
224 leading = fmin - length; 225 leading = fmin - length;
225 if (sign == '-') 226 if (sign == '-')
226 --leading; 227 --leading;
227 } 228 }
228 outcnt += leading + length; 229 outcnt += leading + length;
229 if (sign == '-') 230 if (sign == '-')
230 outcnt += 1; 231 outcnt += 1;
231 if (sign == '-' && fill == '0') 232 if (sign == '-' && fill == '0')
232 (*func)(sign); 233 (*func)(sign);
233 if (leftjust == 0) 234 if (leftjust == 0)
234 for (i = 0; i < leading; i++) (*func)(fill); 235 for (i = 0; i < leading; i++) (*func)(fill);
235 if (sign == '-' && fill == ' ') 236 if (sign == '-' && fill == ' ')
236 (*func)(sign); 237 (*func)(sign);
237 for (i = 0; i < length; i++) 238 for (i = 0; i < length; i++)
238 (*func)(str[i]); 239 (*func)(str[i]);
239 if (leftjust != 0) 240 if (leftjust != 0)
240 for (i = 0; i < leading; i++) (*func)(fill); 241 for (i = 0; i < leading; i++) (*func)(fill);
241 } 242 }
242 return outcnt; 243 return outcnt;
243} 244}
244 245
245 246
246static void 247static void
247mkdigit(unsigned long long llval, int base, char *s) 248mkdigit(unsigned long long llval, int base, char *s)
248{ 249{
249 char ptmp[23], *t; /* requires 22 digit in octal at most */ 250 char ptmp[23], *t; /* requires 22 digit in octal at most */
250 int n; 251 int n;
251 static const char hexdigit[] = "0123456789abcdef"; 252 static const char hexdigit[] = "0123456789abcdef";
252 253
253 n = 1; 254 n = 1;
254 t = ptmp; 255 t = ptmp;
255 *t++ = '\0'; 256 *t++ = '\0';
256 do { 257 do {
257 int d = (int)llval % base; 258 int d = (int)llval % base;
258 *t++ = hexdigit[d]; 259 *t++ = hexdigit[d];
259 llval /= base; 260 llval /= base;
260 } while (llval != 0 && ++n < sizeof(ptmp)); 261 } while (llval != 0 && ++n < sizeof(ptmp));
261 while ((*s++ = *--t) != '\0') 262 while ((*s++ = *--t) != '\0')
262 /* copy reserved digits */ ; 263 /* copy reserved digits */ ;
263} 264}
264 265
265static void 266static void
266sputchar(int c) 267sputchar(int c)
267{ 268{
268 269
269 if (sbuf < ebuf) 270 if (sbuf < ebuf)
270 *sbuf++ = c; 271 *sbuf++ = c;
271} 272}