636 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			636 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Copyright (c) 1990, 2007 The Regents of the University of California.
 | 
						|
 * All rights reserved.
 | 
						|
 *
 | 
						|
 * Redistribution and use in source and binary forms are permitted
 | 
						|
 * provided that the above copyright notice and this paragraph are
 | 
						|
 * duplicated in all such forms and that any documentation,
 | 
						|
 * advertising materials, and other materials related to such
 | 
						|
 * distribution and use acknowledge that the software was developed
 | 
						|
 * by the University of California, Berkeley.  The name of the
 | 
						|
 * University may not be used to endorse or promote products derived
 | 
						|
 * from this software without specific prior written permission.
 | 
						|
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 | 
						|
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 | 
						|
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 | 
						|
 */
 | 
						|
 | 
						|
/*
 | 
						|
FUNCTION
 | 
						|
<<swprintf>>, <<fwprintf>>, <<wprintf>>---wide character format output
 | 
						|
 | 
						|
INDEX
 | 
						|
	fwprintf
 | 
						|
INDEX
 | 
						|
	_fwprintf_r
 | 
						|
INDEX
 | 
						|
	wprintf
 | 
						|
INDEX
 | 
						|
	_wprintf_r
 | 
						|
INDEX
 | 
						|
	swprintf
 | 
						|
INDEX
 | 
						|
	_swprintf_r
 | 
						|
 | 
						|
ANSI_SYNOPSIS
 | 
						|
        #include <wchar.h>
 | 
						|
 | 
						|
        int wprintf(const wchar_t *<[format]>, ...);
 | 
						|
        int fwprintf(FILE *__restrict <[fd]>,
 | 
						|
        	const wchar_t *__restrict <[format]>, ...);
 | 
						|
        int swprintf(wchar_t *__restrict <[str]>, size_t <[size]>,
 | 
						|
                     const wchar_t *__restrict <[format]>, ...);
 | 
						|
 | 
						|
        int _wprintf_r(struct _reent *<[ptr]>, const wchar_t *<[format]>, ...);
 | 
						|
        int _fwprintf_r(struct _reent *<[ptr]>, FILE *<[fd]>,
 | 
						|
                        const wchar_t *<[format]>, ...);
 | 
						|
        int _swprintf_r(struct _reent *<[ptr]>, wchar_t *<[str]>,
 | 
						|
                        size_t <[size]>, const wchar_t *<[format]>, ...);
 | 
						|
 | 
						|
DESCRIPTION
 | 
						|
        <<wprintf>> accepts a series of arguments, applies to each a
 | 
						|
        format specifier from <<*<[format]>>>, and writes the
 | 
						|
        formatted data to <<stdout>>, without a terminating NUL
 | 
						|
        wide character.  The behavior of <<wprintf>> is undefined if there
 | 
						|
        are not enough arguments for the format or if any argument is not the
 | 
						|
	right type for the corresponding conversion specifier.  <<wprintf>>
 | 
						|
	returns when it reaches the end of the format string.  If there are
 | 
						|
        more arguments than the format requires, excess arguments are
 | 
						|
        ignored.
 | 
						|
 | 
						|
        <<fwprintf>> is like <<wprintf>>, except that output is directed
 | 
						|
        to the stream <[fd]> rather than <<stdout>>.
 | 
						|
 | 
						|
        <<swprintf>> is like <<wprintf>>, except that output is directed
 | 
						|
        to the buffer <[str]> with a terminating wide <<NUL>>, and the
 | 
						|
	resulting string length is limited to at most <[size]> wide characters,
 | 
						|
	including the terminating <<NUL>>.  It is considered an error if the
 | 
						|
	output (including the terminating wide-<<NULL>>) does not fit into
 | 
						|
	<[size]> wide characters.  (This error behavior is not the same as for
 | 
						|
	<<snprintf>>, which <<swprintf>> is otherwise completely analogous to.
 | 
						|
	While <<snprintf>> allows the needed size to be known simply by giving
 | 
						|
	<[size]>=0, <<swprintf>> does not, giving an error instead.)
 | 
						|
 | 
						|
        For <<swprintf>> the behavior is undefined if the output
 | 
						|
	<<*<[str]>>> overlaps with one of the arguments.  Behavior is also
 | 
						|
	undefined if the argument for <<%n>> within <<*<[format]>>>
 | 
						|
	overlaps another argument.
 | 
						|
 | 
						|
        <[format]> is a pointer to a wide character string containing two
 | 
						|
	types of objects: ordinary characters (other than <<%>>),
 | 
						|
	which are copied unchanged to the output, and conversion
 | 
						|
	specifications, each of which is introduced by <<%>>. (To
 | 
						|
	include <<%>> in the output, use <<%%>> in the format string.)
 | 
						|
	A conversion specification has the following form:
 | 
						|
 | 
						|
.       %[<[pos]>][<[flags]>][<[width]>][.<[prec]>][<[size]>]<[type]>
 | 
						|
 | 
						|
        The fields of the conversion specification have the following
 | 
						|
        meanings:
 | 
						|
 | 
						|
        O+
 | 
						|
	o <[pos]>
 | 
						|
 | 
						|
        Conversions normally consume arguments in the order that they
 | 
						|
        are presented.  However, it is possible to consume arguments
 | 
						|
        out of order, and reuse an argument for more than one
 | 
						|
        conversion specification (although the behavior is undefined
 | 
						|
        if the same argument is requested with different types), by
 | 
						|
        specifying <[pos]>, which is a decimal integer followed by
 | 
						|
        '$'.  The integer must be between 1 and <NL_ARGMAX> from
 | 
						|
        limits.h, and if argument <<%n$>> is requested, all earlier
 | 
						|
        arguments must be requested somewhere within <[format]>.  If
 | 
						|
        positional parameters are used, then all conversion
 | 
						|
        specifications except for <<%%>> must specify a position.
 | 
						|
	This positional parameters method is a POSIX extension to the C
 | 
						|
	standard definition for the functions.
 | 
						|
 | 
						|
	o <[flags]>
 | 
						|
 | 
						|
	<[flags]> is an optional sequence of characters which control
 | 
						|
	output justification, numeric signs, decimal points, trailing
 | 
						|
	zeros, and octal and hex prefixes.  The flag characters are
 | 
						|
	minus (<<->>), plus (<<+>>), space ( ), zero (<<0>>), sharp
 | 
						|
	(<<#>>), and quote (<<'>>).  They can appear in any
 | 
						|
	combination, although not all flags can be used for all
 | 
						|
	conversion specification types.
 | 
						|
 | 
						|
		o+
 | 
						|
		o '
 | 
						|
			A POSIX extension to the C standard.  However, this
 | 
						|
			implementation presently treats it as a no-op, which
 | 
						|
			is the default behavior for the C locale, anyway.  (If
 | 
						|
			it did what it is supposed to, when <[type]> were <<i>>,
 | 
						|
			<<d>>, <<u>>, <<f>>, <<F>>, <<g>>, or <<G>>, the
 | 
						|
			integer portion of the conversion would be formatted
 | 
						|
			with thousands' grouping wide characters.)
 | 
						|
 | 
						|
		o -
 | 
						|
			The result of the conversion is left
 | 
						|
			justified, and the right is padded with
 | 
						|
			blanks.  If you do not use this flag, the
 | 
						|
			result is right justified, and padded on the
 | 
						|
			left.
 | 
						|
 | 
						|
	        o +
 | 
						|
			The result of a signed conversion (as
 | 
						|
			determined by <[type]> of <<d>>, <<i>>, <<a>>,
 | 
						|
			<<A>>, <<e>>, <<E>>, <<f>>, <<F>>, <<g>>, or
 | 
						|
			<<G>>) will always begin with a plus or minus
 | 
						|
			sign.  (If you do not use this flag, positive
 | 
						|
			values do not begin with a plus sign.)
 | 
						|
 | 
						|
		o " " (space)
 | 
						|
			If the first character of a signed conversion
 | 
						|
		        specification is not a sign, or if a signed
 | 
						|
		        conversion results in no characters, the
 | 
						|
		        result will begin with a space.  If the space
 | 
						|
		        ( ) flag and the plus (<<+>>) flag both
 | 
						|
		        appear, the space flag is ignored.
 | 
						|
 | 
						|
	        o 0
 | 
						|
			If the <[type]> character is <<d>>, <<i>>,
 | 
						|
			<<o>>, <<u>>, <<x>>, <<X>>, <<a>>, <<A>>,
 | 
						|
			<<e>>, <<E>>, <<f>>, <<F>>, <<g>>, or <<G>>:  leading
 | 
						|
			zeros are used to pad the field width
 | 
						|
			(following any indication of sign or base); no
 | 
						|
			spaces are used for padding.  If the zero
 | 
						|
			(<<0>>) and minus (<<->>) flags both appear,
 | 
						|
			the zero (<<0>>) flag will be ignored.  For
 | 
						|
			<<d>>, <<i>>, <<o>>, <<u>>, <<x>>, and <<X>>
 | 
						|
			conversions, if a precision <[prec]> is
 | 
						|
			specified, the zero (<<0>>) flag is ignored.
 | 
						|
 | 
						|
			Note that <<0>> is interpreted as a flag, not
 | 
						|
		        as the beginning of a field width.
 | 
						|
 | 
						|
	        o #
 | 
						|
			The result is to be converted to an
 | 
						|
			alternative form, according to the <[type]>
 | 
						|
			character.
 | 
						|
		o-
 | 
						|
 | 
						|
	The alternative form output with the # flag depends on the <[type]>
 | 
						|
	character:
 | 
						|
 | 
						|
		o+
 | 
						|
		o o
 | 
						|
			Increases precision to force the first
 | 
						|
			digit of the result to be a zero.
 | 
						|
 | 
						|
		o x
 | 
						|
			A non-zero result will have a <<0x>>
 | 
						|
			prefix.
 | 
						|
 | 
						|
		o X
 | 
						|
			A non-zero result will have a <<0X>>
 | 
						|
			prefix.
 | 
						|
 | 
						|
		o a, A, e, E, f, or F
 | 
						|
			The result will always contain a
 | 
						|
			decimal point even if no digits follow
 | 
						|
			the point.  (Normally, a decimal point
 | 
						|
			appears only if a digit follows it.)
 | 
						|
			Trailing zeros are removed.
 | 
						|
 | 
						|
		o g or G
 | 
						|
			The result will always contain a
 | 
						|
			decimal point even if no digits follow
 | 
						|
			the point.  Trailing zeros are not
 | 
						|
			removed.
 | 
						|
 | 
						|
		o all others
 | 
						|
			Undefined.
 | 
						|
 | 
						|
		o-
 | 
						|
 | 
						|
 | 
						|
	o <[width]>
 | 
						|
 | 
						|
		<[width]> is an optional minimum field width.  You can
 | 
						|
		either specify it directly as a decimal integer, or
 | 
						|
		indirectly by using instead an asterisk (<<*>>), in
 | 
						|
		which case an <<int>> argument is used as the field
 | 
						|
		width.  If positional arguments are used, then the
 | 
						|
		width must also be specified positionally as <<*m$>>,
 | 
						|
		with m as a decimal integer.  Negative field widths
 | 
						|
		are treated as specifying the minus (<<->>) flag for
 | 
						|
		left justfication, along with a positive field width.
 | 
						|
		The resulting format may be wider than the specified
 | 
						|
		width.
 | 
						|
 | 
						|
	o <[prec]>
 | 
						|
 | 
						|
		<[prec]> is an optional field; if present, it is
 | 
						|
		introduced with `<<.>>' (a period). You can specify
 | 
						|
		the precision either directly as a decimal integer or
 | 
						|
		indirectly by using an asterisk (<<*>>), in which case
 | 
						|
		an <<int>> argument is used as the precision.  If
 | 
						|
		positional arguments are used, then the precision must
 | 
						|
		also be specified positionally as <<*m$>>, with m as a
 | 
						|
		decimal integer.  Supplying a negative precision is
 | 
						|
		equivalent to omitting the precision.  If only a
 | 
						|
		period is specified the precision is zero. The effect
 | 
						|
		depends on the conversion <[type]>.
 | 
						|
 | 
						|
		o+
 | 
						|
		o d, i, o, u, x, or X
 | 
						|
			Minimum number of digits to appear.  If no
 | 
						|
			precision is given, defaults to 1.
 | 
						|
 | 
						|
		o a or A
 | 
						|
			Number of digits to appear after the decimal
 | 
						|
			point.  If no precision is given, the
 | 
						|
			precision defaults to the minimum needed for
 | 
						|
			an exact representation.
 | 
						|
 | 
						|
		o e, E, f or F
 | 
						|
			Number of digits to appear after the decimal
 | 
						|
			point.  If no precision is given, the
 | 
						|
			precision defaults to 6.
 | 
						|
 | 
						|
		o g or G
 | 
						|
			Maximum number of significant digits.  A
 | 
						|
			precision of 0 is treated the same as a
 | 
						|
			precision of 1.  If no precision is given, the
 | 
						|
			precision defaults to 6.
 | 
						|
 | 
						|
		o s or S
 | 
						|
			Maximum number of characters to print from the
 | 
						|
			string.  If no precision is given, the entire
 | 
						|
			string is printed.
 | 
						|
 | 
						|
		o all others
 | 
						|
			undefined.
 | 
						|
 | 
						|
		o-
 | 
						|
 | 
						|
	o <[size]>
 | 
						|
 | 
						|
		<[size]> is an optional modifier that changes the data
 | 
						|
		type that the corresponding argument has.  Behavior is
 | 
						|
		unspecified if a size is given that does not match the
 | 
						|
		<[type]>.
 | 
						|
 | 
						|
		o+
 | 
						|
		o hh
 | 
						|
			With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
 | 
						|
			<<X>>, specifies that the argument should be
 | 
						|
			converted to a <<signed char>> or <<unsigned
 | 
						|
			char>> before printing.
 | 
						|
 | 
						|
			With <<n>>, specifies that the argument is a
 | 
						|
			pointer to a <<signed char>>.
 | 
						|
 | 
						|
		o h
 | 
						|
			With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
 | 
						|
			<<X>>, specifies that the argument should be
 | 
						|
			converted to a <<short>> or <<unsigned short>>
 | 
						|
			before printing.
 | 
						|
 | 
						|
			With <<n>>, specifies that the argument is a
 | 
						|
			pointer to a <<short>>.
 | 
						|
 | 
						|
		o l
 | 
						|
			With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
 | 
						|
			<<X>>, specifies that the argument is a
 | 
						|
			<<long>> or <<unsigned long>>.
 | 
						|
 | 
						|
			With <<c>>, specifies that the argument has
 | 
						|
			type <<wint_t>>.
 | 
						|
 | 
						|
			With <<s>>, specifies that the argument is a
 | 
						|
			pointer to <<wchar_t>>.
 | 
						|
 | 
						|
			With <<n>>, specifies that the argument is a
 | 
						|
			pointer to a <<long>>.
 | 
						|
 | 
						|
			With <<a>>, <<A>>, <<e>>, <<E>>, <<f>>, <<F>>,
 | 
						|
			<<g>>, or <<G>>, has no effect (because of
 | 
						|
			vararg promotion rules, there is no need to
 | 
						|
			distinguish between <<float>> and <<double>>).
 | 
						|
 | 
						|
		o ll
 | 
						|
			With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
 | 
						|
			<<X>>, specifies that the argument is a
 | 
						|
			<<long long>> or <<unsigned long long>>.
 | 
						|
 | 
						|
			With <<n>>, specifies that the argument is a
 | 
						|
			pointer to a <<long long>>.
 | 
						|
 | 
						|
		o j
 | 
						|
			With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
 | 
						|
			<<X>>, specifies that the argument is an
 | 
						|
			<<intmax_t>> or <<uintmax_t>>.
 | 
						|
 | 
						|
			With <<n>>, specifies that the argument is a
 | 
						|
			pointer to an <<intmax_t>>.
 | 
						|
 | 
						|
		o z
 | 
						|
			With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
 | 
						|
			<<X>>, specifies that the argument is a <<size_t>>.
 | 
						|
 | 
						|
			With <<n>>, specifies that the argument is a
 | 
						|
			pointer to a <<size_t>>.
 | 
						|
 | 
						|
		o t
 | 
						|
			With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
 | 
						|
			<<X>>, specifies that the argument is a
 | 
						|
			<<ptrdiff_t>>.
 | 
						|
 | 
						|
			With <<n>>, specifies that the argument is a
 | 
						|
			pointer to a <<ptrdiff_t>>.
 | 
						|
 | 
						|
		o L
 | 
						|
			With <<a>>, <<A>>, <<e>>, <<E>>, <<f>>, <<F>>,
 | 
						|
			<<g>>, or <<G>>, specifies that the argument
 | 
						|
			is a <<long double>>.
 | 
						|
 | 
						|
		o-
 | 
						|
 | 
						|
	o   <[type]>
 | 
						|
 | 
						|
		<[type]> specifies what kind of conversion <<wprintf>>
 | 
						|
		performs.  Here is a table of these:
 | 
						|
 | 
						|
		o+
 | 
						|
		o %
 | 
						|
			Prints the percent character (<<%>>).
 | 
						|
 | 
						|
		o c
 | 
						|
			If no <<l>> qualifier is present, the int argument shall
 | 
						|
			be converted to a wide character as if by calling
 | 
						|
			the btowc() function and the resulting wide character
 | 
						|
			shall be written.  Otherwise, the wint_t argument
 | 
						|
			shall be converted to wchar_t, and written.
 | 
						|
 | 
						|
		o C
 | 
						|
			Short for <<%lc>>.  A POSIX extension to the C standard.
 | 
						|
 | 
						|
		o s
 | 
						|
			If no <<l>> qualifier is present, the application
 | 
						|
			shall ensure that the argument is a pointer to a
 | 
						|
			character array containing a character sequence
 | 
						|
			beginning in the initial shift state.  Characters
 | 
						|
			from the array shall be converted as if by repeated
 | 
						|
			calls to the mbrtowc() function, with the conversion
 | 
						|
			state described by an mbstate_t object initialized to
 | 
						|
			zero before the first character is converted, and
 | 
						|
			written up to (but not including) the terminating
 | 
						|
			null wide character. If the precision is specified,
 | 
						|
			no more than that many wide characters shall be
 | 
						|
			written.  If the precision is not specified, or is
 | 
						|
			greater than the size of the array, the application
 | 
						|
			shall ensure that the array contains a null wide
 | 
						|
			character.
 | 
						|
 | 
						|
			If an <<l>> qualifier is present, the application
 | 
						|
			shall ensure that the argument is a pointer to an
 | 
						|
			array of type wchar_t. Wide characters from the array
 | 
						|
			shall be written up to (but not including) a
 | 
						|
			terminating null wide character. If no precision is
 | 
						|
			specified, or is greater than the size of the array,
 | 
						|
			the application shall ensure that the array contains
 | 
						|
			a null wide character. If a precision is specified,
 | 
						|
			no more than that many wide characters shall be
 | 
						|
			written.
 | 
						|
 | 
						|
		o S
 | 
						|
			Short for <<%ls>>.  A POSIX extension to the C standard.
 | 
						|
 | 
						|
		o d or i
 | 
						|
			Prints a signed decimal integer; takes an
 | 
						|
			<<int>>.  Leading zeros are inserted as
 | 
						|
			necessary to reach the precision.  A value of 0 with
 | 
						|
			a precision of 0 produces an empty string.
 | 
						|
 | 
						|
		o o
 | 
						|
			Prints an unsigned octal integer; takes an
 | 
						|
			<<unsigned>>.  Leading zeros are inserted as
 | 
						|
			necessary to reach the precision.  A value of 0 with
 | 
						|
			a precision of 0 produces an empty string.
 | 
						|
 | 
						|
		o u
 | 
						|
			Prints an unsigned decimal integer; takes an
 | 
						|
			<<unsigned>>.  Leading zeros are inserted as
 | 
						|
			necessary to reach the precision.  A value of 0 with
 | 
						|
			a precision of 0 produces an empty string.
 | 
						|
 | 
						|
		o x
 | 
						|
			Prints an unsigned hexadecimal integer (using
 | 
						|
			<<abcdef>> as digits beyond <<9>>); takes an
 | 
						|
			<<unsigned>>.  Leading zeros are inserted as
 | 
						|
			necessary to reach the precision.  A value of 0 with
 | 
						|
			a precision of 0 produces an empty string.
 | 
						|
 | 
						|
		o X
 | 
						|
			Like <<x>>, but uses <<ABCDEF>> as digits
 | 
						|
			beyond <<9>>.
 | 
						|
 | 
						|
		o f
 | 
						|
			Prints a signed value of the form
 | 
						|
			<<[-]9999.9999>>, with the precision
 | 
						|
			determining how many digits follow the decimal
 | 
						|
			point; takes a <<double>> (remember that
 | 
						|
			<<float>> promotes to <<double>> as a vararg).
 | 
						|
			The low order digit is rounded to even.  If
 | 
						|
			the precision results in at most DECIMAL_DIG
 | 
						|
			digits, the result is rounded correctly; if
 | 
						|
			more than DECIMAL_DIG digits are printed, the
 | 
						|
			result is only guaranteed to round back to the
 | 
						|
			original value.
 | 
						|
 | 
						|
			If the value is infinite, the result is
 | 
						|
			<<inf>>, and no zero padding is performed.  If
 | 
						|
			the value is not a number, the result is
 | 
						|
			<<nan>>, and no zero padding is performed.
 | 
						|
 | 
						|
		o F
 | 
						|
			Like <<f>>, but uses <<INF>> and <<NAN>> for
 | 
						|
			non-finite numbers.
 | 
						|
 | 
						|
		o e
 | 
						|
			Prints a signed value of the form
 | 
						|
			<<[-]9.9999e[+|-]999>>; takes a <<double>>.
 | 
						|
			The digit before the decimal point is non-zero
 | 
						|
			if the value is non-zero.  The precision
 | 
						|
			determines how many digits appear between
 | 
						|
			<<.>> and <<e>>, and the exponent always
 | 
						|
			contains at least two digits.  The value zero
 | 
						|
			has an exponent of zero.  If the value is not
 | 
						|
			finite, it is printed like <<f>>.
 | 
						|
 | 
						|
		o E
 | 
						|
			Like <<e>>, but using <<E>> to introduce the
 | 
						|
			exponent, and like <<F>> for non-finite
 | 
						|
			values.
 | 
						|
 | 
						|
		o g
 | 
						|
			Prints a signed value in either <<f>> or <<e>>
 | 
						|
			form, based on the given value and
 | 
						|
			precision---an exponent less than -4 or
 | 
						|
			greater than the precision selects the <<e>>
 | 
						|
			form.  Trailing zeros and the decimal point
 | 
						|
			are printed only if necessary; takes a
 | 
						|
			<<double>>.
 | 
						|
 | 
						|
		o G
 | 
						|
			Like <<g>>, except use <<F>> or <<E>> form.
 | 
						|
 | 
						|
		o a
 | 
						|
			Prints a signed value of the form
 | 
						|
			<<[-]0x1.ffffp[+|-]9>>; takes a <<double>>.
 | 
						|
			The letters <<abcdef>> are used for digits
 | 
						|
			beyond <<9>>.  The precision determines how
 | 
						|
			many digits appear after the decimal point.
 | 
						|
			The exponent contains at least one digit, and
 | 
						|
			is a decimal value representing the power of
 | 
						|
			2; a value of 0 has an exponent of 0.
 | 
						|
			Non-finite values are printed like <<f>>.
 | 
						|
 | 
						|
		o A
 | 
						|
			Like <<a>>, except uses <<X>>, <<P>>, and
 | 
						|
			<<ABCDEF>> instead of lower case.
 | 
						|
 | 
						|
		o n
 | 
						|
			Takes a pointer to <<int>>, and stores a count
 | 
						|
			of the number of bytes written so far.  No
 | 
						|
			output is created.
 | 
						|
 | 
						|
		o p
 | 
						|
			Takes a pointer to <<void>>, and prints it in
 | 
						|
			an implementation-defined format.  This
 | 
						|
			implementation is similar to <<%#tx>>), except
 | 
						|
			that <<0x>> appears even for the NULL pointer.
 | 
						|
 | 
						|
		o m
 | 
						|
			Prints the output of <<strerror(errno)>>; no
 | 
						|
			argument is required.  A GNU extension.
 | 
						|
 | 
						|
		o-
 | 
						|
	O-
 | 
						|
 | 
						|
        <<_wprintf_r>>, <<_fwprintf_r>>, <<_swprintf_r>>, are simply
 | 
						|
        reentrant versions of the functions above.
 | 
						|
 | 
						|
RETURNS
 | 
						|
On success, <<swprintf>> return the number of wide characters in
 | 
						|
the output string, except the concluding <<NUL>> is not counted.
 | 
						|
<<wprintf>> and <<fwprintf>> return the number of characters transmitted.
 | 
						|
 | 
						|
If an error occurs, the result of <<wprintf>>, <<fwprintf>>, and
 | 
						|
<<swprintf>> is a negative value.  For <<wprintf>> and <<fwprintf>>,
 | 
						|
<<errno>> may be set according to <<fputwc>>.  For <<swprintf>>, <<errno>>
 | 
						|
may be set to EOVERFLOW if <[size]> is greater than INT_MAX / sizeof (wchar_t),
 | 
						|
or when the output does not fit into <[size]> wide characters (including the
 | 
						|
terminating wide <<NULL>>).
 | 
						|
 | 
						|
BUGS
 | 
						|
The ``''' (quote) flag does not work when locale's thousands_sep is not empty.
 | 
						|
 | 
						|
PORTABILITY
 | 
						|
POSIX-1.2008 with extensions; C99 (compliant except for POSIX extensions).
 | 
						|
 | 
						|
Depending on how newlib was configured, not all format specifiers are
 | 
						|
supported.
 | 
						|
 | 
						|
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
 | 
						|
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
#include <_ansi.h>
 | 
						|
#include <reent.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <wchar.h>
 | 
						|
#include <stdarg.h>
 | 
						|
#include <limits.h>
 | 
						|
#include <errno.h>
 | 
						|
#include "local.h"
 | 
						|
 | 
						|
/* NOTE:  _swprintf_r() should be identical to swprintf() except for the
 | 
						|
 * former having ptr as a parameter and the latter needing to declare it as
 | 
						|
 * a variable set to _REENT.  */
 | 
						|
 | 
						|
int
 | 
						|
_DEFUN(_swprintf_r, (ptr, str, size, fmt),
 | 
						|
       struct _reent *ptr _AND
 | 
						|
       wchar_t *str          _AND
 | 
						|
       size_t size        _AND
 | 
						|
       _CONST wchar_t *fmt _DOTS)
 | 
						|
{
 | 
						|
  int ret;
 | 
						|
  va_list ap;
 | 
						|
  FILE f;
 | 
						|
 | 
						|
  if (size > INT_MAX / sizeof (wchar_t))
 | 
						|
    {
 | 
						|
      ptr->_errno = EOVERFLOW;	/* POSIX extension */
 | 
						|
      return EOF;
 | 
						|
    }
 | 
						|
  f._flags = __SWR | __SSTR;
 | 
						|
  f._bf._base = f._p = (unsigned char *) str;
 | 
						|
  f._bf._size = f._w = (size > 0 ? (size - 1) * sizeof (wchar_t) : 0);
 | 
						|
  f._file = -1;  /* No file. */
 | 
						|
  va_start (ap, fmt);
 | 
						|
  ret = _svfwprintf_r (ptr, &f, fmt, ap);
 | 
						|
  va_end (ap);
 | 
						|
  /* _svfwprintf_r() does not put in a terminating NUL, so add one if
 | 
						|
   * appropriate, which is whenever size is > 0.  _svfwprintf_r() stops
 | 
						|
   * after n-1, so always just put at the end.  */
 | 
						|
  if (size > 0)  {
 | 
						|
    *(wchar_t *)f._p = L'\0';	/* terminate the string */
 | 
						|
  }
 | 
						|
  if(ret >= size)  {
 | 
						|
    /* _svfwprintf_r() returns how many wide characters it would have printed
 | 
						|
     * if there were enough space.  Return an error if too big to fit in str,
 | 
						|
     * unlike snprintf, which returns the size needed.  */
 | 
						|
    ptr->_errno = EOVERFLOW;	/* POSIX extension */
 | 
						|
    ret = -1;
 | 
						|
  }
 | 
						|
  return (ret);
 | 
						|
}
 | 
						|
 | 
						|
#ifndef _REENT_ONLY
 | 
						|
 | 
						|
int
 | 
						|
_DEFUN(swprintf, (str, size, fmt),
 | 
						|
       wchar_t *__restrict str   _AND
 | 
						|
       size_t size _AND
 | 
						|
       _CONST wchar_t *__restrict fmt _DOTS)
 | 
						|
{
 | 
						|
  int ret;
 | 
						|
  va_list ap;
 | 
						|
  FILE f;
 | 
						|
  struct _reent *ptr = _REENT;
 | 
						|
 | 
						|
  if (size > INT_MAX / sizeof (wchar_t))
 | 
						|
    {
 | 
						|
      ptr->_errno = EOVERFLOW;	/* POSIX extension */
 | 
						|
      return EOF;
 | 
						|
    }
 | 
						|
  f._flags = __SWR | __SSTR;
 | 
						|
  f._bf._base = f._p = (unsigned char *) str;
 | 
						|
  f._bf._size = f._w = (size > 0 ? (size - 1) * sizeof (wchar_t) : 0);
 | 
						|
  f._file = -1;  /* No file. */
 | 
						|
  va_start (ap, fmt);
 | 
						|
  ret = _svfwprintf_r (ptr, &f, fmt, ap);
 | 
						|
  va_end (ap);
 | 
						|
  /* _svfwprintf_r() does not put in a terminating NUL, so add one if
 | 
						|
   * appropriate, which is whenever size is > 0.  _svfwprintf_r() stops
 | 
						|
   * after n-1, so always just put at the end.  */
 | 
						|
  if (size > 0)  {
 | 
						|
    *(wchar_t *)f._p = L'\0';	/* terminate the string */
 | 
						|
  }
 | 
						|
  if(ret >= size)  {
 | 
						|
    /* _svfwprintf_r() returns how many wide characters it would have printed
 | 
						|
     * if there were enough space.  Return an error if too big to fit in str,
 | 
						|
     * unlike snprintf, which returns the size needed.  */
 | 
						|
    ptr->_errno = EOVERFLOW;	/* POSIX extension */
 | 
						|
    ret = -1;
 | 
						|
  }
 | 
						|
  return (ret);
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |