d0421f64ace265e4393f2c223f01022db4d0b538
1 /* $Id: sprintf.c,v 1.5 2001/11/05 20:59:57 jimtabor Exp $
7 * Copyright 1996 Alexandre Julliard
9 * 1999-05-01 (Emanuele Aliberti)
10 * Adapted from Wine to ReactOS
18 #define WPRINTF_LEFTALIGN 0x0001 /* Align output on the left ('-' prefix) */
19 #define WPRINTF_PREFIX_HEX 0x0002 /* Prefix hex with 0x ('#' prefix) */
20 #define WPRINTF_ZEROPAD 0x0004 /* Pad with zeros ('0' prefix) */
21 #define WPRINTF_LONG 0x0008 /* Long arg ('l' prefix) */
22 #define WPRINTF_SHORT 0x0010 /* Short arg ('h' prefix) */
23 #define WPRINTF_UPPER_HEX 0x0020 /* Upper-case hex ('X' specifier) */
24 #define WPRINTF_WIDE 0x0040 /* Wide arg ('w' prefix) */
50 static const LPSTR null_stringA
= "(null)";
51 static const LPWSTR null_stringW
= L
"(null)";
57 /***********************************************************************
80 WPRINTF_FORMAT
*format
,
88 if (format
->flags
& WPRINTF_LEFTALIGN
)
90 format
->flags
&= ~WPRINTF_ZEROPAD
;
92 if (format
->width
> maxlen
)
94 format
->width
= maxlen
;
100 return (format
->precision
= 1);
105 *(LPCSTR
*)arg
= null_stringA
;
108 (!format
->precision
|| (len
< format
->precision
));
112 if (!*(*(LPCSTR
*)arg
+ len
))
121 return (format
->precision
= len
);
124 if (!*(LPCWSTR
*)arg
)
126 *(LPCWSTR
*)arg
= null_stringW
;
129 (!format
->precision
|| (len
< format
->precision
));
133 if (!*(*(LPCWSTR
*)arg
+ len
))
140 return (format
->precision
= len
);
161 ((format
->flags
& WPRINTF_UPPER_HEX
)
166 if (format
->flags
& WPRINTF_PREFIX_HEX
)
179 if (format
->precision
< len
)
181 format
->precision
= len
;
183 if (format
->precision
> maxlen
)
185 format
->precision
= maxlen
;
187 if ( (format
->flags
& WPRINTF_ZEROPAD
)
188 && (format
->width
> format
->precision
)
191 format
->precision
= format
->width
;
197 /* === ANSI VERSION === */
200 /***********************************************************************
202 * WPRINTF_ParseFormatA
205 * Parse a format specification. A format specification has the
208 * [-][#][0][width][.precision]type
217 * The length of the format specification in characters.
221 WPRINTF_ParseFormatA(
233 res
->flags
|= WPRINTF_LEFTALIGN
;
238 res
->flags
|= WPRINTF_PREFIX_HEX
;
243 res
->flags
|= WPRINTF_ZEROPAD
;
246 while ((*p
>= '0') && (*p
<= '9')) /* width field */
253 if (*p
== '.') /* precision field */
256 while ((*p
>= '0') && (*p
<= '9'))
259 (res
->precision
* 10)
266 res
->flags
|= WPRINTF_LONG
;
271 res
->flags
|= WPRINTF_SHORT
;
276 res
->flags
|= WPRINTF_WIDE
;
284 (res
->flags
& WPRINTF_LONG
)
291 (res
->flags
& WPRINTF_SHORT
)
298 res
->type
= WPR_SIGNED
;
303 (res
->flags
& (WPRINTF_LONG
|WPRINTF_WIDE
))
310 (res
->flags
& (WPRINTF_SHORT
|WPRINTF_WIDE
))
316 res
->type
= WPR_UNSIGNED
;
320 res
->flags
|= WPRINTF_UPPER_HEX
;
324 res
->type
= WPR_HEXA
;
327 default: /* unknown format char */
328 res
->type
= WPR_UNKNOWN
;
329 p
--; /* print format as normal char */
334 return (INT
) (p
- format
) + 1;
338 /***********************************************************************
340 * wvsnprintfA (Not a Windows API)
351 WPRINTF_FORMAT format
;
357 while (*spec
&& (maxlen
> 1))
372 spec
+= WPRINTF_ParseFormatA(
376 len
= WPRINTF_GetLen(
382 if (!(format
.flags
& WPRINTF_LEFTALIGN
))
384 for ( i
= format
.precision
;
395 if ((*p
= (CHAR
) (WCHAR
) va_arg( args
, int)))
399 else if (format
.width
> 1)
410 if ((*p
= (CHAR
) va_arg( args
, int )))
414 else if (format
.width
> 1)
427 va_arg( args
, LPCSTR
),
435 LPCWSTR ptr
= va_arg( args
, LPCWSTR
);
442 *p
++ = (CHAR
) *ptr
++;
448 if ( (format
.flags
& WPRINTF_PREFIX_HEX
)
453 *p
++ = (format
.flags
& WPRINTF_UPPER_HEX
)
458 format
.precision
-= 2;
466 (i
< format
.precision
);
478 (void) va_arg( args
, INT
); /* Go to the next arg */
485 if (format
.flags
& WPRINTF_LEFTALIGN
)
487 for ( i
= format
.precision
;
505 /***********************************************************************
507 * wsprintfA (USER32.585)
526 va_start( valist
, spec
);
538 /***********************************************************************
540 * wvsprintfA (USER32.587)
565 /* === UNICODE VERSION === */
568 /***********************************************************************
570 * WPRINTF_ParseFormatW
573 * Parse a format specification. A format specification has
576 * [-][#][0][width][.precision]type
585 * The length of the format specification in characters.
589 WPRINTF_ParseFormatW(
601 res
->flags
|= WPRINTF_LEFTALIGN
;
606 res
->flags
|= WPRINTF_PREFIX_HEX
;
611 res
->flags
|= WPRINTF_ZEROPAD
;
615 while ((*p
>= L
'0') && (*p
<= L
'9')) /* width field */
623 if (*p
== L
'.') /* precision field */
626 while ((*p
>= L
'0') && (*p
<= L
'9'))
629 (res
->precision
* 10)
636 res
->flags
|= WPRINTF_LONG
;
641 res
->flags
|= WPRINTF_SHORT
;
646 res
->flags
|= WPRINTF_WIDE
;
654 (res
->flags
& WPRINTF_SHORT
)
661 (res
->flags
& WPRINTF_LONG
)
668 res
->type
= WPR_SIGNED
;
673 ((res
->flags
& WPRINTF_SHORT
)
674 && !(res
->flags
& WPRINTF_WIDE
)
682 (res
->flags
& (WPRINTF_LONG
| WPRINTF_WIDE
))
688 res
->type
= WPR_UNSIGNED
;
692 res
->flags
|= WPRINTF_UPPER_HEX
;
696 res
->type
= WPR_HEXA
;
700 res
->type
= WPR_UNKNOWN
;
701 p
--; /* print format as normal char */
705 return (INT
) (p
- format
) + 1;
709 /***********************************************************************
711 * wvsnprintfW (Not a Windows API)
721 WPRINTF_FORMAT format
;
727 while (*spec
&& (maxlen
> 1))
742 spec
+= WPRINTF_ParseFormatW(
746 len
= WPRINTF_GetLen(
752 if (!(format
.flags
& WPRINTF_LEFTALIGN
))
754 for ( i
= format
.precision
;
765 if ((*p
= (WCHAR
) va_arg( args
, int)))
769 else if (format
.width
> 1)
780 if ((*p
= (WCHAR
)(CHAR
) va_arg( args
, int )))
784 else if (format
.width
> 1)
796 LPCSTR ptr
= va_arg( args
, LPCSTR
);
803 *p
++ = (WCHAR
) *ptr
++;
813 va_arg( args
, LPCWSTR
),
814 (len
* sizeof (WCHAR
))
821 if ( (format
.flags
& WPRINTF_PREFIX_HEX
)
826 *p
++ = (format
.flags
& WPRINTF_UPPER_HEX
)
831 format
.precision
-= 2;
839 (i
< format
.precision
);
850 *p
++ = (WCHAR
) number
[i
];
852 (void) va_arg( args
, INT
); /* Go to the next arg */
859 if (format
.flags
& WPRINTF_LEFTALIGN
)
861 for ( i
= format
.precision
;
879 /***********************************************************************
881 * wsprintfW (USER32.586)
900 va_start( valist
, spec
);
912 /***********************************************************************
914 * wvsprintfW (USER32.588)