1 | /*␊ |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.␊ |
7 | * ␊ |
8 | * This file contains Original Code and/or Modifications of Original Code␊ |
9 | * as defined in and that are subject to the Apple Public Source License␊ |
10 | * Version 2.0 (the 'License'). You may not use this file except in␊ |
11 | * compliance with the License. Please obtain a copy of the License at␊ |
12 | * http://www.opensource.apple.com/apsl/ and read it before using this␊ |
13 | * file.␊ |
14 | * ␊ |
15 | * The Original Code and all software distributed under the License are␊ |
16 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
17 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
18 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
19 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.␊ |
20 | * Please see the License for the specific language governing rights and␊ |
21 | * limitations under the License.␊ |
22 | * ␊ |
23 | * @APPLE_LICENSE_HEADER_END@␊ |
24 | */␊ |
25 | /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */␊ |
26 | /*-␊ |
27 | * Copyright (c) 1986, 1988, 1991, 1993␊ |
28 | * The Regents of the University of California. All rights reserved.␊ |
29 | * (c) UNIX System Laboratories, Inc.␊ |
30 | * All or some portions of this file are derived from material licensed␊ |
31 | * to the University of California by American Telephone and Telegraph␊ |
32 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with␊ |
33 | * the permission of UNIX System Laboratories, Inc.␊ |
34 | *␊ |
35 | * Redistribution and use in source and binary forms, with or without␊ |
36 | * modification, are permitted provided that the following conditions␊ |
37 | * are met:␊ |
38 | * 1. Redistributions of source code must retain the above copyright␊ |
39 | * notice, this list of conditions and the following disclaimer.␊ |
40 | * 2. Redistributions in binary form must reproduce the above copyright␊ |
41 | * notice, this list of conditions and the following disclaimer in the␊ |
42 | * documentation and/or other materials provided with the distribution.␊ |
43 | * 3. All advertising materials mentioning features or use of this software␊ |
44 | * must display the following acknowledgement:␊ |
45 | * This product includes software developed by the University of␊ |
46 | * California, Berkeley and its contributors.␊ |
47 | * 4. Neither the name of the University nor the names of its contributors␊ |
48 | * may be used to endorse or promote products derived from this software␊ |
49 | * without specific prior written permission.␊ |
50 | *␊ |
51 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND␊ |
52 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE␊ |
53 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE␊ |
54 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE␊ |
55 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL␊ |
56 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS␊ |
57 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)␊ |
58 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT␊ |
59 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY␊ |
60 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF␊ |
61 | * SUCH DAMAGE.␊ |
62 | *␊ |
63 | * @(#)subr_prf.c 8.4 (Berkeley) 5/4/95␊ |
64 | */␊ |
65 | /*␊ |
66 | * @OSF_COPYRIGHT@␊ |
67 | */␊ |
68 | ␊ |
69 | /* ␊ |
70 | * Mach Operating System␊ |
71 | * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University␊ |
72 | * All Rights Reserved.␊ |
73 | * ␊ |
74 | * Permission to use, copy, modify and distribute this software and its␊ |
75 | * documentation is hereby granted, provided that both the copyright␊ |
76 | * notice and this permission notice appear in all copies of the␊ |
77 | * software, derivative works or modified versions, and any portions␊ |
78 | * thereof, and that both notices appear in supporting documentation.␊ |
79 | * ␊ |
80 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"␊ |
81 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR␊ |
82 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.␊ |
83 | * ␊ |
84 | * Carnegie Mellon requests users of this software to return to␊ |
85 | * ␊ |
86 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU␊ |
87 | * School of Computer Science␊ |
88 | * Carnegie Mellon University␊ |
89 | * Pittsburgh PA 15213-3890␊ |
90 | * ␊ |
91 | * any improvements or extensions that they make and grant Carnegie Mellon␊ |
92 | * the rights to redistribute these changes.␊ |
93 | */␊ |
94 | ␊ |
95 | ␊ |
96 | #include "libsa.h"␊ |
97 | ␊ |
98 | struct snprintf_arg {␊ |
99 | char *str;␊ |
100 | size_t remain;␊ |
101 | };␊ |
102 | ␊ |
103 | static void␊ |
104 | dummy_putc(int ch, void *arg)␊ |
105 | {␊ |
106 | void (*real_putc)() = arg;␊ |
107 | ␊ |
108 | if (real_putc) real_putc(ch);␊ |
109 | }␊ |
110 | ␊ |
111 | #if 0␊ |
112 | void ␊ |
113 | _doprnt(␊ |
114 | register const char *fmt,␊ |
115 | va_list argp,␊ |
116 | /* character output routine */␊ |
117 | void (*putc)(),␊ |
118 | int radix) /* default radix - for '%r' */␊ |
119 | {␊ |
120 | __doprnt(fmt, argp, dummy_putc, putc, radix);␊ |
121 | }␊ |
122 | #endif␊ |
123 | #if 1␊ |
124 | #define Ctod(c) ((c) - '0')␊ |
125 | ␊ |
126 | #define MAXBUF (sizeof(long long int) * 8)␉/* enough for binary */␊ |
127 | static char digs[] = "0123456789abcdef";␊ |
128 | static int␊ |
129 | printnum(␊ |
130 | unsigned long long int␉u,␉/* number to print */␊ |
131 | int␉␉base,␊ |
132 | void␉␉␉(*putc)(int, void *),␊ |
133 | void *arg)␊ |
134 | {␊ |
135 | ␉char␉buf[MAXBUF];␉/* build number here */␊ |
136 | ␉char *␉p = &buf[MAXBUF-1];␊ |
137 | ␉int nprinted = 0;␊ |
138 | ␊ |
139 | ␉do {␊ |
140 | ␉ *p-- = digs[u % base];␊ |
141 | ␉ u /= base;␊ |
142 | ␉} while (u != 0);␊ |
143 | ␊ |
144 | ␉while (++p != &buf[MAXBUF]) {␊ |
145 | ␉ if (putc) (*putc)(*p, arg);␊ |
146 | ␉ nprinted++;␊ |
147 | ␉}␊ |
148 | ␊ |
149 | ␉return nprinted;␊ |
150 | }␊ |
151 | ␊ |
152 | bool␉_doprnt_truncates = false;␊ |
153 | ␊ |
154 | int␊ |
155 | __doprnt(␊ |
156 | const char␉*fmt,␊ |
157 | va_list␉␉␉argp,␊ |
158 | /* character output routine */␊ |
159 | void␉␉␉(*putc)(int ch, void *arg),␊ |
160 | void *arg,␊ |
161 | int␉␉␉radix)␉␉/* default radix - for '%r' */␊ |
162 | {␊ |
163 | ␉int␉␉length;␊ |
164 | ␉int␉␉prec;␊ |
165 | ␉bool␉ladjust;␊ |
166 | ␉char␉␉padc;␊ |
167 | ␉long long␉␉n;␊ |
168 | ␉unsigned long long␉u;␊ |
169 | ␉int␉␉plus_sign;␊ |
170 | ␉int␉␉sign_char;␊ |
171 | ␉bool␉altfmt, truncate;␊ |
172 | ␉int␉␉base;␊ |
173 | ␉char␉c;␊ |
174 | ␉int␉␉capitals;␊ |
175 | ␉int␉␉long_long;␊ |
176 | ␉int nprinted = 0;␊ |
177 | ␊ |
178 | ␉while ((c = *fmt) != '\0') {␊ |
179 | ␉ if (c != '%') {␊ |
180 | if (putc) {␊ |
181 | (*putc)(c, arg);␊ |
182 | }␊ |
183 | nprinted++;␊ |
184 | fmt++;␊ |
185 | continue;␊ |
186 | ␉ }␊ |
187 | ␊ |
188 | ␉ fmt++;␊ |
189 | ␊ |
190 | ␉ long_long = 0;␊ |
191 | ␉ length = 0;␊ |
192 | ␉ prec = -1;␊ |
193 | ␉ ladjust = false;␊ |
194 | ␉ padc = ' ';␊ |
195 | ␉ plus_sign = 0;␊ |
196 | ␉ sign_char = 0;␊ |
197 | ␉ altfmt = false;␊ |
198 | ␊ |
199 | ␉ while (true) {␊ |
200 | c = *fmt;␊ |
201 | if (c == '#') {␊ |
202 | altfmt = true;␊ |
203 | }␊ |
204 | else if (c == '-') {␊ |
205 | ladjust = true;␊ |
206 | }␊ |
207 | else if (c == '+') {␊ |
208 | plus_sign = '+';␊ |
209 | }␊ |
210 | else if (c == ' ') {␊ |
211 | if (plus_sign == 0)␊ |
212 | plus_sign = ' ';␊ |
213 | }␊ |
214 | else␊ |
215 | break;␊ |
216 | fmt++;␊ |
217 | ␉ }␊ |
218 | ␊ |
219 | ␉ if (c == '0') {␊ |
220 | padc = '0';␊ |
221 | c = *++fmt;␊ |
222 | ␉ }␊ |
223 | ␊ |
224 | ␉ if (isdigit(c)) {␊ |
225 | while(isdigit(c)) {␊ |
226 | length = 10 * length + Ctod(c);␊ |
227 | c = *++fmt;␊ |
228 | }␊ |
229 | ␉ }␊ |
230 | ␉ else if (c == '*') {␊ |
231 | length = va_arg(argp, int);␊ |
232 | c = *++fmt;␊ |
233 | if (length < 0) {␊ |
234 | ladjust = !ladjust;␊ |
235 | length = -length;␊ |
236 | }␊ |
237 | ␉ }␊ |
238 | ␊ |
239 | ␉ if (c == '.') {␊ |
240 | c = *++fmt;␊ |
241 | if (isdigit(c)) {␊ |
242 | prec = 0;␊ |
243 | while(isdigit(c)) {␊ |
244 | prec = 10 * prec + Ctod(c);␊ |
245 | c = *++fmt;␊ |
246 | }␊ |
247 | }␊ |
248 | else if (c == '*') {␊ |
249 | prec = va_arg(argp, int);␊ |
250 | c = *++fmt;␊ |
251 | }␊ |
252 | ␉ }␊ |
253 | ␊ |
254 | ␉ if (c == 'l') {␊ |
255 | c = *++fmt;␉/* need it if sizeof(int) < sizeof(long) */␊ |
256 | if (sizeof(int)<sizeof(long))␊ |
257 | long_long = 1;␊ |
258 | if (c == 'l') {␊ |
259 | long_long = 1;␊ |
260 | c = *++fmt;␊ |
261 | }␉␊ |
262 | ␉ } else if (c == 'q' || c == 'L') {␊ |
263 | ␉ ␉long_long = 1;␊ |
264 | c = *++fmt;␊ |
265 | ␉ } ␊ |
266 | ␊ |
267 | ␉ truncate = false;␊ |
268 | ␉ capitals=0;␉␉/* Assume lower case printing */␊ |
269 | ␊ |
270 | ␉ switch(c) {␊ |
271 | case 'b':␊ |
272 | case 'B':␊ |
273 | {␊ |
274 | register char *p;␊ |
275 | boolean_t␉ any;␊ |
276 | register int i;␊ |
277 | ␊ |
278 | if (long_long) {␊ |
279 | u = va_arg(argp, unsigned long long);␊ |
280 | } else {␊ |
281 | u = va_arg(argp, unsigned int);␊ |
282 | }␊ |
283 | p = va_arg(argp, char *);␊ |
284 | base = *p++;␊ |
285 | nprinted += printnum(u, base, putc, arg);␊ |
286 | ␊ |
287 | if (u == 0)␊ |
288 | break;␊ |
289 | ␊ |
290 | any = false;␊ |
291 | while ((i = *p++) != '\0') {␊ |
292 | if (*fmt == 'B')␊ |
293 | i = 33 - i;␊ |
294 | if (*p <= 32) {␊ |
295 | /*␊ |
296 | * Bit field␊ |
297 | */␊ |
298 | register int j;␊ |
299 | if (any) {␊ |
300 | if (putc) (*putc)(',', arg);␊ |
301 | } else {␊ |
302 | if (putc) (*putc)('<', arg);␊ |
303 | any = true;␊ |
304 | }␊ |
305 | nprinted++;␊ |
306 | j = *p++;␊ |
307 | if (*fmt == 'B')␊ |
308 | j = 32 - j;␊ |
309 | for (; (c = *p) > 32; p++) {␊ |
310 | if (putc) (*putc)(c, arg);␊ |
311 | nprinted++;␊ |
312 | }␊ |
313 | nprinted += printnum((unsigned)( (u>>(j-1)) & ((2<<(i-j))-1)),␊ |
314 | base, putc, arg);␊ |
315 | }␊ |
316 | else if (u & (1<<(i-1))) {␊ |
317 | if (any) {␊ |
318 | if (putc) (*putc)(',', arg);␊ |
319 | } else {␊ |
320 | if (putc) (*putc)('<', arg);␊ |
321 | any = true;␊ |
322 | }␊ |
323 | nprinted++;␊ |
324 | for (; (c = *p) > 32; p++) {␊ |
325 | if (putc) (*putc)(c, arg);␊ |
326 | nprinted++;␊ |
327 | }␊ |
328 | }␊ |
329 | else {␊ |
330 | for (; *p > 32; p++)␊ |
331 | continue;␊ |
332 | }␊ |
333 | }␊ |
334 | if (any) {␊ |
335 | if (putc) (*putc)('>', arg);␊ |
336 | nprinted++;␊ |
337 | }␊ |
338 | break;␊ |
339 | }␊ |
340 | ␊ |
341 | case 'c':␊ |
342 | c = va_arg(argp, int);␊ |
343 | if (putc) (*putc)(c, arg);␊ |
344 | nprinted++;␊ |
345 | break;␊ |
346 | ␊ |
347 | case 's':␊ |
348 | {␊ |
349 | register const char *p;␊ |
350 | register const char *p2;␊ |
351 | ␊ |
352 | if (prec == -1)␊ |
353 | prec = 0x7fffffff;␉/* MAXINT */␊ |
354 | ␊ |
355 | p = va_arg(argp, char *);␊ |
356 | ␊ |
357 | if (p == NULL)␊ |
358 | p = "";␊ |
359 | ␊ |
360 | if (length > 0 && !ladjust) {␊ |
361 | n = 0;␊ |
362 | p2 = p;␊ |
363 | ␊ |
364 | for (; *p != '\0' && n < prec; p++)␊ |
365 | n++;␊ |
366 | ␊ |
367 | p = p2;␊ |
368 | ␊ |
369 | while (n < length) {␊ |
370 | if (putc) (*putc)(' ', arg);␊ |
371 | n++;␊ |
372 | nprinted++;␊ |
373 | }␊ |
374 | }␊ |
375 | ␊ |
376 | n = 0;␊ |
377 | ␊ |
378 | while ((n < prec) && (!(length > 0 && n >= length))) {␊ |
379 | if (*p == '\0') {␊ |
380 | break;␊ |
381 | }␊ |
382 | if (putc) (*putc)(*p++, arg);␊ |
383 | nprinted++;␊ |
384 | n++;␊ |
385 | }␊ |
386 | ␊ |
387 | if (n < length && ladjust) {␊ |
388 | while (n < length) {␊ |
389 | if (putc) (*putc)(' ', arg);␊ |
390 | n++;␊ |
391 | nprinted++;␊ |
392 | }␊ |
393 | }␊ |
394 | ␊ |
395 | break;␊ |
396 | }␊ |
397 | ␊ |
398 | case 'o':␊ |
399 | truncate = _doprnt_truncates;␊ |
400 | case 'O':␊ |
401 | base = 8;␊ |
402 | goto print_unsigned;␊ |
403 | ␊ |
404 | case 'D': {␊ |
405 | unsigned char *up;␊ |
406 | char *q, *p;␊ |
407 | ␊ |
408 | up = (unsigned char *)va_arg(argp, unsigned char *);␊ |
409 | p = (char *)va_arg(argp, char *);␊ |
410 | if (length == -1)␊ |
411 | length = 16;␊ |
412 | while(length--) {␊ |
413 | if (putc) (*putc)(digs[(*up >> 4)], arg);␊ |
414 | if (putc) (*putc)(digs[(*up & 0x0f)], arg);␊ |
415 | nprinted += 2;␊ |
416 | up++;␊ |
417 | if (length) {␊ |
418 | for (q=p;*q;q++) {␊ |
419 | if (putc) (*putc)(*q, arg);␊ |
420 | nprinted++;␊ |
421 | }␊ |
422 | }␊ |
423 | }␊ |
424 | break;␊ |
425 | }␊ |
426 | ␊ |
427 | case 'd':␊ |
428 | truncate = _doprnt_truncates;␊ |
429 | base = 10;␊ |
430 | goto print_signed;␊ |
431 | ␊ |
432 | case 'u':␊ |
433 | truncate = _doprnt_truncates;␊ |
434 | case 'U':␊ |
435 | base = 10;␊ |
436 | goto print_unsigned;␊ |
437 | ␊ |
438 | case 'p':␊ |
439 | altfmt = true;␊ |
440 | if (sizeof(int)<sizeof(void *)) {␊ |
441 | long_long = 1;␊ |
442 | }␊ |
443 | case 'x':␊ |
444 | truncate = _doprnt_truncates;␊ |
445 | base = 16;␊ |
446 | goto print_unsigned;␊ |
447 | ␊ |
448 | case 'X':␊ |
449 | base = 16;␊ |
450 | capitals=16;␉/* Print in upper case */␊ |
451 | goto print_unsigned;␊ |
452 | ␊ |
453 | case 'z':␊ |
454 | truncate = _doprnt_truncates;␊ |
455 | base = 16;␊ |
456 | goto print_signed;␊ |
457 | ␊ |
458 | case 'Z':␊ |
459 | base = 16;␊ |
460 | capitals=16;␉/* Print in upper case */␊ |
461 | goto print_signed;␊ |
462 | ␊ |
463 | case 'r':␊ |
464 | truncate = _doprnt_truncates;␊ |
465 | case 'R':␊ |
466 | base = radix;␊ |
467 | goto print_signed;␊ |
468 | ␊ |
469 | case 'n':␊ |
470 | truncate = _doprnt_truncates;␊ |
471 | case 'N':␊ |
472 | base = radix;␊ |
473 | goto print_unsigned;␊ |
474 | ␊ |
475 | print_signed:␊ |
476 | if (long_long) {␊ |
477 | n = va_arg(argp, long long);␊ |
478 | } else {␊ |
479 | n = va_arg(argp, int);␊ |
480 | }␊ |
481 | if (n >= 0) {␊ |
482 | u = n;␊ |
483 | sign_char = plus_sign;␊ |
484 | }␊ |
485 | else {␊ |
486 | u = -n;␊ |
487 | sign_char = '-';␊ |
488 | }␊ |
489 | goto print_num;␊ |
490 | ␊ |
491 | print_unsigned:␊ |
492 | if (long_long) {␊ |
493 | u = va_arg(argp, unsigned long long);␊ |
494 | } else { ␊ |
495 | u = va_arg(argp, unsigned int);␊ |
496 | }␊ |
497 | goto print_num;␊ |
498 | ␊ |
499 | print_num:␊ |
500 | {␊ |
501 | char␉buf[MAXBUF];␉/* build number here */␊ |
502 | register char *␉p = &buf[MAXBUF-1];␊ |
503 | static char digits[] = "0123456789abcdef0123456789ABCDEF";␊ |
504 | const char *prefix = NULL;␊ |
505 | ␊ |
506 | if (truncate) u = (long long)((int)(u));␊ |
507 | ␊ |
508 | if (u != 0 && altfmt) {␊ |
509 | if (base == 8)␊ |
510 | prefix = "0";␊ |
511 | else if (base == 16)␊ |
512 | prefix = "0x";␊ |
513 | }␊ |
514 | ␊ |
515 | do {␊ |
516 | /* Print in the correct case */␊ |
517 | *p-- = digits[(u % base)+capitals];␊ |
518 | u /= base;␊ |
519 | } while (u != 0);␊ |
520 | ␊ |
521 | length -= (int)(&buf[MAXBUF-1] - p);␊ |
522 | if (sign_char)␊ |
523 | length--;␊ |
524 | if (prefix)␊ |
525 | length -= (int)strlen(prefix);␊ |
526 | ␊ |
527 | if (padc == ' ' && !ladjust) {␊ |
528 | /* blank padding goes before prefix */␊ |
529 | while (--length >= 0) {␊ |
530 | if (putc) (*putc)(' ', arg);␊ |
531 | nprinted++;␊ |
532 | }␉␉␉ ␊ |
533 | }␊ |
534 | if (sign_char) {␊ |
535 | if (putc) (*putc)(sign_char, arg);␊ |
536 | nprinted++;␊ |
537 | }␊ |
538 | if (prefix) {␊ |
539 | while (*prefix) {␊ |
540 | if (putc) (*putc)(*prefix++, arg);␊ |
541 | nprinted++;␊ |
542 | }␊ |
543 | }␊ |
544 | if (padc == '0') {␊ |
545 | /* zero padding goes after sign and prefix */␊ |
546 | while (--length >= 0) {␊ |
547 | if (putc) (*putc)('0', arg);␊ |
548 | nprinted++;␊ |
549 | }␉␉␉ ␊ |
550 | }␊ |
551 | while (++p != &buf[MAXBUF]) {␊ |
552 | if (putc) (*putc)(*p, arg);␊ |
553 | nprinted++;␊ |
554 | }␊ |
555 | ␊ |
556 | if (ladjust) {␊ |
557 | while (--length >= 0) {␊ |
558 | if (putc) (*putc)(' ', arg);␊ |
559 | nprinted++;␊ |
560 | }␊ |
561 | }␊ |
562 | break;␊ |
563 | }␊ |
564 | ␊ |
565 | case '\0':␊ |
566 | fmt--;␊ |
567 | break;␊ |
568 | ␊ |
569 | default:␊ |
570 | if (putc) (*putc)(c, arg);␊ |
571 | nprinted++;␊ |
572 | ␉ }␊ |
573 | fmt++;␊ |
574 | ␉}␊ |
575 | ␊ |
576 | ␉return nprinted;␊ |
577 | }␊ |
578 | #endif␊ |
579 | ␊ |
580 | int␊ |
581 | prf(␊ |
582 | const char␉*fmt,␊ |
583 | va_list␉␉␉ap,␊ |
584 | /* character output routine */␊ |
585 | void␉␉␉(*putc)(char))␉␉␊ |
586 | {␊ |
587 | return __doprnt(fmt, ap, dummy_putc, putc, 10); ␊ |
588 | }␊ |
589 | ␊ |
590 | ␊ |
591 | static char *copybyte_str;␊ |
592 | ␊ |
593 | static void␊ |
594 | copybyte(␊ |
595 | char byte)␊ |
596 | {␊ |
597 | *copybyte_str++ = byte;␊ |
598 | *copybyte_str = '\0';␊ |
599 | }␊ |
600 | ␊ |
601 | int␊ |
602 | sprintf(char *buf, const char *fmt, ...)␊ |
603 | {␊ |
604 | va_list listp;␊ |
605 | ␊ |
606 | va_start(listp, fmt);␊ |
607 | copybyte_str = buf;␊ |
608 | prf(fmt, listp, copybyte);␊ |
609 | va_end(listp);␊ |
610 | return strlen(buf);␊ |
611 | }␊ |
612 | ␊ |
613 | static void␊ |
614 | snprintf_func(int ch, void *arg)␊ |
615 | {␊ |
616 | struct snprintf_arg *const info = arg;␊ |
617 | ␊ |
618 | if (info->remain >= 2) {␊ |
619 | *info->str++ = ch;␊ |
620 | info->remain--;␊ |
621 | }␊ |
622 | }␊ |
623 | ␊ |
624 | /*␊ |
625 | * Scaled down version of vsnprintf(3).␊ |
626 | */␊ |
627 | int␊ |
628 | vsnprintf(char *str, size_t size, const char *format, va_list ap)␊ |
629 | {␊ |
630 | struct snprintf_arg info;␊ |
631 | int retval;␊ |
632 | ␊ |
633 | info.str = str;␊ |
634 | info.remain = size;␊ |
635 | retval = __doprnt(format, ap, snprintf_func, &info, 10);␊ |
636 | if (info.remain >= 1)␊ |
637 | *info.str++ = '\0';␊ |
638 | return retval;␊ |
639 | }␊ |
640 | ␊ |
641 | /*␊ |
642 | * Scaled down version of snprintf(3).␊ |
643 | */␊ |
644 | int␊ |
645 | snprintf(char *str, size_t size, const char *format, ...)␊ |
646 | {␊ |
647 | int retval;␊ |
648 | va_list ap;␊ |
649 | ␊ |
650 | va_start(ap, format);␊ |
651 | retval = vsnprintf(str, size, format, ap);␊ |
652 | va_end(ap);␊ |
653 | return(retval);␊ |
654 | } |