881acb0a5db88f91287be3949a9b199f4e99bc38
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: lib/ntdll/stdio/sprintf.c
6 * PURPOSE: Single byte sprintf functions
7 * PROGRAMMERS: David Welch
13 * linux/lib/vsprintf.c
15 * Copyright (C) 1991, 1992 Linus Torvalds
18 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
20 * Wirzenius wrote this portably, Torvalds fucked it up :-)
23 #define __NO_CTYPE_INLINES
32 #define ZEROPAD 1 /* pad with zero */
33 #define SIGN 2 /* unsigned/signed long */
34 #define PLUS 4 /* show plus */
35 #define SPACE 8 /* space if plus */
36 #define LEFT 16 /* left justified */
37 #define SPECIAL 32 /* 0x */
38 #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
41 #define do_div(n,base) ({ \
43 __res = ((unsigned long long) n) % (unsigned) base; \
44 n = ((unsigned long long) n) / (unsigned) base; \
48 static int skip_atoi(const char **s
)
53 i
= i
*10 + *((*s
)++) - '0';
59 number(char * buf
, char * end
, long long num
, int base
, int size
, int precision
, int type
)
63 const char *small_digits
= "0123456789abcdefghijklmnopqrstuvwxyz";
64 const char *large_digits
= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
67 digits
= (type
& LARGE
) ? large_digits
: small_digits
;
70 if (base
< 2 || base
> 36)
72 c
= (type
& ZEROPAD
) ? '0' : ' ';
79 } else if (type
& PLUS
) {
82 } else if (type
& SPACE
) {
97 tmp
[i
++] = digits
[do_div(num
,base
)];
101 if (!(type
&(ZEROPAD
+LEFT
))) {
113 if (type
& SPECIAL
) {
118 } else if (base
==16) {
127 if (!(type
& LEFT
)) {
134 while (i
< precision
--) {
153 string(char* buf
, char* end
, const char* s
, int len
, int field_width
, int precision
, int flags
)
166 while ((unsigned int)len
< (unsigned int)precision
&& s
[len
])
171 if ((unsigned int)len
> (unsigned int)precision
)
176 while (len
< field_width
--)
182 for (i
= 0; i
< len
; ++i
)
188 while (len
< field_width
--)
198 stringw(char* buf
, char* end
, const wchar_t* sw
, int len
, int field_width
, int precision
, int flags
)
211 while ((unsigned int)len
< (unsigned int)precision
&& sw
[len
])
216 if ((unsigned int)len
> (unsigned int)precision
)
221 while (len
< field_width
--)
227 for (i
= 0; i
< len
; ++i
)
230 *buf
= (unsigned char)(*sw
++);
233 while (len
< field_width
--)
245 int _vsnprintf(char *buf
, size_t cnt
, const char *fmt
, va_list args
)
248 unsigned long long num
;
254 int flags
; /* flags to number() */
256 int field_width
; /* width of output field */
257 int precision
; /* min. # of digits for integers; max
258 number of chars for from string */
259 int qualifier
; /* 'h', 'l', 'L', 'I' or 'w' for integer fields */
268 for ( ; *fmt
; ++fmt
) {
279 ++fmt
; /* this also skips first '%' */
281 case '-': flags
|= LEFT
; goto repeat
;
282 case '+': flags
|= PLUS
; goto repeat
;
283 case ' ': flags
|= SPACE
; goto repeat
;
284 case '#': flags
|= SPECIAL
; goto repeat
;
285 case '0': flags
|= ZEROPAD
; goto repeat
;
288 /* get field width */
291 field_width
= skip_atoi(&fmt
);
292 else if (*fmt
== '*') {
294 /* it's the next argument */
295 field_width
= va_arg(args
, int);
296 if (field_width
< 0) {
297 field_width
= -field_width
;
302 /* get the precision */
307 precision
= skip_atoi(&fmt
);
308 else if (*fmt
== '*') {
310 /* it's the next argument */
311 precision
= va_arg(args
, int);
317 /* get the conversion qualifier */
319 if (*fmt
== 'h' || *fmt
== 'l' || *fmt
== 'L' || *fmt
== 'w') {
322 } else if (*fmt
== 'I' && *(fmt
+1) == '6' && *(fmt
+2) == '4') {
331 case 'c': /* finished */
333 while (--field_width
> 0) {
338 if (qualifier
== 'l' || qualifier
== 'w') {
340 *str
= (unsigned char)(wchar_t) va_arg(args
, int);
344 *str
= (unsigned char) va_arg(args
, int);
347 while (--field_width
> 0) {
354 case 'C': /* finished */
356 while (--field_width
> 0) {
361 if (qualifier
== 'h') {
363 *str
= (unsigned char) va_arg(args
, int);
367 *str
= (unsigned char)(wchar_t) va_arg(args
, int);
370 while (--field_width
> 0) {
377 case 's': /* finished */
378 if (qualifier
== 'l' || qualifier
== 'w') {
379 /* print unicode string */
380 sw
= va_arg(args
, wchar_t *);
381 str
= stringw(str
, end
, sw
, -1, field_width
, precision
, flags
);
383 /* print ascii string */
384 s
= va_arg(args
, char *);
385 str
= string(str
, end
, s
, -1, field_width
, precision
, flags
);
390 if (qualifier
== 'h') {
391 /* print ascii string */
392 s
= va_arg(args
, char *);
393 str
= string(str
, end
, s
, -1, field_width
, precision
, flags
);
395 /* print unicode string */
396 sw
= va_arg(args
, wchar_t *);
397 str
= stringw(str
, end
, sw
, -1, field_width
, precision
, flags
);
402 if (qualifier
== 'w') {
403 /* print counted unicode string */
404 PUNICODE_STRING pus
= va_arg(args
, PUNICODE_STRING
);
405 if ((pus
== NULL
) || (pus
->Buffer
== NULL
)) {
410 len
= pus
->Length
/ sizeof(WCHAR
);
412 str
= stringw(str
, end
, sw
, len
, field_width
, precision
, flags
);
414 /* print counted ascii string */
415 PANSI_STRING pus
= va_arg(args
, PANSI_STRING
);
416 if ((pus
== NULL
) || (pus
->Buffer
== NULL
)) {
423 str
= string(str
, end
, s
, len
, field_width
, precision
, flags
);
428 if (field_width
== -1) {
429 field_width
= 2 * sizeof(void *);
432 str
= number(str
, end
,
433 (unsigned long) va_arg(args
, void *), 16,
434 field_width
, precision
, flags
);
438 /* FIXME: What does C99 say about the overflow case here? */
439 if (qualifier
== 'l') {
440 long * ip
= va_arg(args
, long *);
443 int * ip
= va_arg(args
, int *);
448 /* integer number formats - set up the flags and "break" */
484 if (qualifier
== 'I')
485 num
= va_arg(args
, unsigned long long);
486 else if (qualifier
== 'l') {
488 num
= va_arg(args
, long);
490 num
= va_arg(args
, unsigned long);
492 else if (qualifier
== 'h') {
494 num
= va_arg(args
, int);
496 num
= va_arg(args
, unsigned int);
500 num
= va_arg(args
, int);
502 num
= va_arg(args
, unsigned int);
504 str
= number(str
, end
, num
, base
, field_width
, precision
, flags
);
509 /* don't write out a null byte if the buf size is zero */
518 int sprintf(char * buf
, const char *fmt
, ...)
524 i
=_vsnprintf(buf
,INT_MAX
,fmt
,args
);
533 int _snprintf(char * buf
, size_t cnt
, const char *fmt
, ...)
539 i
=_vsnprintf(buf
,cnt
,fmt
,args
);
548 int vsprintf(char *buf
, const char *fmt
, va_list args
)
550 return _vsnprintf(buf
,INT_MAX
,fmt
,args
);