Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 1990, 2007 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. /*
  19. FUNCTION
  20. <<swprintf>>, <<fwprintf>>, <<wprintf>>---wide character format output
  21.  
  22. INDEX
  23.         fwprintf
  24. INDEX
  25.         _fwprintf_r
  26. INDEX
  27.         wprintf
  28. INDEX
  29.         _wprintf_r
  30. INDEX
  31.         swprintf
  32. INDEX
  33.         _swprintf_r
  34.  
  35. ANSI_SYNOPSIS
  36.         #include <wchar.h>
  37.  
  38.         int wprintf(const wchar_t *<[format]>, ...);
  39.         int fwprintf(FILE *__restrict <[fd]>,
  40.                 const wchar_t *__restrict <[format]>, ...);
  41.         int swprintf(wchar_t *__restrict <[str]>, size_t <[size]>,
  42.                      const wchar_t *__restrict <[format]>, ...);
  43.  
  44.         int _wprintf_r(struct _reent *<[ptr]>, const wchar_t *<[format]>, ...);
  45.         int _fwprintf_r(struct _reent *<[ptr]>, FILE *<[fd]>,
  46.                         const wchar_t *<[format]>, ...);
  47.         int _swprintf_r(struct _reent *<[ptr]>, wchar_t *<[str]>,
  48.                         size_t <[size]>, const wchar_t *<[format]>, ...);
  49.  
  50. DESCRIPTION
  51.         <<wprintf>> accepts a series of arguments, applies to each a
  52.         format specifier from <<*<[format]>>>, and writes the
  53.         formatted data to <<stdout>>, without a terminating NUL
  54.         wide character.  The behavior of <<wprintf>> is undefined if there
  55.         are not enough arguments for the format or if any argument is not the
  56.         right type for the corresponding conversion specifier.  <<wprintf>>
  57.         returns when it reaches the end of the format string.  If there are
  58.         more arguments than the format requires, excess arguments are
  59.         ignored.
  60.  
  61.         <<fwprintf>> is like <<wprintf>>, except that output is directed
  62.         to the stream <[fd]> rather than <<stdout>>.
  63.  
  64.         <<swprintf>> is like <<wprintf>>, except that output is directed
  65.         to the buffer <[str]> with a terminating wide <<NUL>>, and the
  66.         resulting string length is limited to at most <[size]> wide characters,
  67.         including the terminating <<NUL>>.  It is considered an error if the
  68.         output (including the terminating wide-<<NULL>>) does not fit into
  69.         <[size]> wide characters.  (This error behavior is not the same as for
  70.         <<snprintf>>, which <<swprintf>> is otherwise completely analogous to.
  71.         While <<snprintf>> allows the needed size to be known simply by giving
  72.         <[size]>=0, <<swprintf>> does not, giving an error instead.)
  73.  
  74.         For <<swprintf>> the behavior is undefined if the output
  75.         <<*<[str]>>> overlaps with one of the arguments.  Behavior is also
  76.         undefined if the argument for <<%n>> within <<*<[format]>>>
  77.         overlaps another argument.
  78.  
  79.         <[format]> is a pointer to a wide character string containing two
  80.         types of objects: ordinary characters (other than <<%>>),
  81.         which are copied unchanged to the output, and conversion
  82.         specifications, each of which is introduced by <<%>>. (To
  83.         include <<%>> in the output, use <<%%>> in the format string.)
  84.         A conversion specification has the following form:
  85.  
  86. .       %[<[pos]>][<[flags]>][<[width]>][.<[prec]>][<[size]>]<[type]>
  87.  
  88.         The fields of the conversion specification have the following
  89.         meanings:
  90.  
  91.         O+
  92.         o <[pos]>
  93.  
  94.         Conversions normally consume arguments in the order that they
  95.         are presented.  However, it is possible to consume arguments
  96.         out of order, and reuse an argument for more than one
  97.         conversion specification (although the behavior is undefined
  98.         if the same argument is requested with different types), by
  99.         specifying <[pos]>, which is a decimal integer followed by
  100.         '$'.  The integer must be between 1 and <NL_ARGMAX> from
  101.         limits.h, and if argument <<%n$>> is requested, all earlier
  102.         arguments must be requested somewhere within <[format]>.  If
  103.         positional parameters are used, then all conversion
  104.         specifications except for <<%%>> must specify a position.
  105.         This positional parameters method is a POSIX extension to the C
  106.         standard definition for the functions.
  107.  
  108.         o <[flags]>
  109.  
  110.         <[flags]> is an optional sequence of characters which control
  111.         output justification, numeric signs, decimal points, trailing
  112.         zeros, and octal and hex prefixes.  The flag characters are
  113.         minus (<<->>), plus (<<+>>), space ( ), zero (<<0>>), sharp
  114.         (<<#>>), and quote (<<'>>).  They can appear in any
  115.         combination, although not all flags can be used for all
  116.         conversion specification types.
  117.  
  118.                 o+
  119.                 o '
  120.                         A POSIX extension to the C standard.  However, this
  121.                         implementation presently treats it as a no-op, which
  122.                         is the default behavior for the C locale, anyway.  (If
  123.                         it did what it is supposed to, when <[type]> were <<i>>,
  124.                         <<d>>, <<u>>, <<f>>, <<F>>, <<g>>, or <<G>>, the
  125.                         integer portion of the conversion would be formatted
  126.                         with thousands' grouping wide characters.)
  127.  
  128.                 o -
  129.                         The result of the conversion is left
  130.                         justified, and the right is padded with
  131.                         blanks.  If you do not use this flag, the
  132.                         result is right justified, and padded on the
  133.                         left.
  134.  
  135.                 o +
  136.                         The result of a signed conversion (as
  137.                         determined by <[type]> of <<d>>, <<i>>, <<a>>,
  138.                         <<A>>, <<e>>, <<E>>, <<f>>, <<F>>, <<g>>, or
  139.                         <<G>>) will always begin with a plus or minus
  140.                         sign.  (If you do not use this flag, positive
  141.                         values do not begin with a plus sign.)
  142.  
  143.                 o " " (space)
  144.                         If the first character of a signed conversion
  145.                         specification is not a sign, or if a signed
  146.                         conversion results in no characters, the
  147.                         result will begin with a space.  If the space
  148.                         ( ) flag and the plus (<<+>>) flag both
  149.                         appear, the space flag is ignored.
  150.  
  151.                 o 0
  152.                         If the <[type]> character is <<d>>, <<i>>,
  153.                         <<o>>, <<u>>, <<x>>, <<X>>, <<a>>, <<A>>,
  154.                         <<e>>, <<E>>, <<f>>, <<F>>, <<g>>, or <<G>>:  leading
  155.                         zeros are used to pad the field width
  156.                         (following any indication of sign or base); no
  157.                         spaces are used for padding.  If the zero
  158.                         (<<0>>) and minus (<<->>) flags both appear,
  159.                         the zero (<<0>>) flag will be ignored.  For
  160.                         <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, and <<X>>
  161.                         conversions, if a precision <[prec]> is
  162.                         specified, the zero (<<0>>) flag is ignored.
  163.  
  164.                         Note that <<0>> is interpreted as a flag, not
  165.                         as the beginning of a field width.
  166.  
  167.                 o #
  168.                         The result is to be converted to an
  169.                         alternative form, according to the <[type]>
  170.                         character.
  171.                 o-
  172.  
  173.         The alternative form output with the # flag depends on the <[type]>
  174.         character:
  175.  
  176.                 o+
  177.                 o o
  178.                         Increases precision to force the first
  179.                         digit of the result to be a zero.
  180.  
  181.                 o x
  182.                         A non-zero result will have a <<0x>>
  183.                         prefix.
  184.  
  185.                 o X
  186.                         A non-zero result will have a <<0X>>
  187.                         prefix.
  188.  
  189.                 o a, A, e, E, f, or F
  190.                         The result will always contain a
  191.                         decimal point even if no digits follow
  192.                         the point.  (Normally, a decimal point
  193.                         appears only if a digit follows it.)
  194.                         Trailing zeros are removed.
  195.  
  196.                 o g or G
  197.                         The result will always contain a
  198.                         decimal point even if no digits follow
  199.                         the point.  Trailing zeros are not
  200.                         removed.
  201.  
  202.                 o all others
  203.                         Undefined.
  204.  
  205.                 o-
  206.  
  207.  
  208.         o <[width]>
  209.  
  210.                 <[width]> is an optional minimum field width.  You can
  211.                 either specify it directly as a decimal integer, or
  212.                 indirectly by using instead an asterisk (<<*>>), in
  213.                 which case an <<int>> argument is used as the field
  214.                 width.  If positional arguments are used, then the
  215.                 width must also be specified positionally as <<*m$>>,
  216.                 with m as a decimal integer.  Negative field widths
  217.                 are treated as specifying the minus (<<->>) flag for
  218.                 left justfication, along with a positive field width.
  219.                 The resulting format may be wider than the specified
  220.                 width.
  221.  
  222.         o <[prec]>
  223.  
  224.                 <[prec]> is an optional field; if present, it is
  225.                 introduced with `<<.>>' (a period). You can specify
  226.                 the precision either directly as a decimal integer or
  227.                 indirectly by using an asterisk (<<*>>), in which case
  228.                 an <<int>> argument is used as the precision.  If
  229.                 positional arguments are used, then the precision must
  230.                 also be specified positionally as <<*m$>>, with m as a
  231.                 decimal integer.  Supplying a negative precision is
  232.                 equivalent to omitting the precision.  If only a
  233.                 period is specified the precision is zero. The effect
  234.                 depends on the conversion <[type]>.
  235.  
  236.                 o+
  237.                 o d, i, o, u, x, or X
  238.                         Minimum number of digits to appear.  If no
  239.                         precision is given, defaults to 1.
  240.  
  241.                 o a or A
  242.                         Number of digits to appear after the decimal
  243.                         point.  If no precision is given, the
  244.                         precision defaults to the minimum needed for
  245.                         an exact representation.
  246.  
  247.                 o e, E, f or F
  248.                         Number of digits to appear after the decimal
  249.                         point.  If no precision is given, the
  250.                         precision defaults to 6.
  251.  
  252.                 o g or G
  253.                         Maximum number of significant digits.  A
  254.                         precision of 0 is treated the same as a
  255.                         precision of 1.  If no precision is given, the
  256.                         precision defaults to 6.
  257.  
  258.                 o s or S
  259.                         Maximum number of characters to print from the
  260.                         string.  If no precision is given, the entire
  261.                         string is printed.
  262.  
  263.                 o all others
  264.                         undefined.
  265.  
  266.                 o-
  267.  
  268.         o <[size]>
  269.  
  270.                 <[size]> is an optional modifier that changes the data
  271.                 type that the corresponding argument has.  Behavior is
  272.                 unspecified if a size is given that does not match the
  273.                 <[type]>.
  274.  
  275.                 o+
  276.                 o hh
  277.                         With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
  278.                         <<X>>, specifies that the argument should be
  279.                         converted to a <<signed char>> or <<unsigned
  280.                         char>> before printing.
  281.  
  282.                         With <<n>>, specifies that the argument is a
  283.                         pointer to a <<signed char>>.
  284.  
  285.                 o h
  286.                         With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
  287.                         <<X>>, specifies that the argument should be
  288.                         converted to a <<short>> or <<unsigned short>>
  289.                         before printing.
  290.  
  291.                         With <<n>>, specifies that the argument is a
  292.                         pointer to a <<short>>.
  293.  
  294.                 o l
  295.                         With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
  296.                         <<X>>, specifies that the argument is a
  297.                         <<long>> or <<unsigned long>>.
  298.  
  299.                         With <<c>>, specifies that the argument has
  300.                         type <<wint_t>>.
  301.  
  302.                         With <<s>>, specifies that the argument is a
  303.                         pointer to <<wchar_t>>.
  304.  
  305.                         With <<n>>, specifies that the argument is a
  306.                         pointer to a <<long>>.
  307.  
  308.                         With <<a>>, <<A>>, <<e>>, <<E>>, <<f>>, <<F>>,
  309.                         <<g>>, or <<G>>, has no effect (because of
  310.                         vararg promotion rules, there is no need to
  311.                         distinguish between <<float>> and <<double>>).
  312.  
  313.                 o ll
  314.                         With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
  315.                         <<X>>, specifies that the argument is a
  316.                         <<long long>> or <<unsigned long long>>.
  317.  
  318.                         With <<n>>, specifies that the argument is a
  319.                         pointer to a <<long long>>.
  320.  
  321.                 o j
  322.                         With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
  323.                         <<X>>, specifies that the argument is an
  324.                         <<intmax_t>> or <<uintmax_t>>.
  325.  
  326.                         With <<n>>, specifies that the argument is a
  327.                         pointer to an <<intmax_t>>.
  328.  
  329.                 o z
  330.                         With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
  331.                         <<X>>, specifies that the argument is a <<size_t>>.
  332.  
  333.                         With <<n>>, specifies that the argument is a
  334.                         pointer to a <<size_t>>.
  335.  
  336.                 o t
  337.                         With <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, or
  338.                         <<X>>, specifies that the argument is a
  339.                         <<ptrdiff_t>>.
  340.  
  341.                         With <<n>>, specifies that the argument is a
  342.                         pointer to a <<ptrdiff_t>>.
  343.  
  344.                 o L
  345.                         With <<a>>, <<A>>, <<e>>, <<E>>, <<f>>, <<F>>,
  346.                         <<g>>, or <<G>>, specifies that the argument
  347.                         is a <<long double>>.
  348.  
  349.                 o-
  350.  
  351.         o   <[type]>
  352.  
  353.                 <[type]> specifies what kind of conversion <<wprintf>>
  354.                 performs.  Here is a table of these:
  355.  
  356.                 o+
  357.                 o %
  358.                         Prints the percent character (<<%>>).
  359.  
  360.                 o c
  361.                         If no <<l>> qualifier is present, the int argument shall
  362.                         be converted to a wide character as if by calling
  363.                         the btowc() function and the resulting wide character
  364.                         shall be written.  Otherwise, the wint_t argument
  365.                         shall be converted to wchar_t, and written.
  366.  
  367.                 o C
  368.                         Short for <<%lc>>.  A POSIX extension to the C standard.
  369.  
  370.                 o s
  371.                         If no <<l>> qualifier is present, the application
  372.                         shall ensure that the argument is a pointer to a
  373.                         character array containing a character sequence
  374.                         beginning in the initial shift state.  Characters
  375.                         from the array shall be converted as if by repeated
  376.                         calls to the mbrtowc() function, with the conversion
  377.                         state described by an mbstate_t object initialized to
  378.                         zero before the first character is converted, and
  379.                         written up to (but not including) the terminating
  380.                         null wide character. If the precision is specified,
  381.                         no more than that many wide characters shall be
  382.                         written.  If the precision is not specified, or is
  383.                         greater than the size of the array, the application
  384.                         shall ensure that the array contains a null wide
  385.                         character.
  386.  
  387.                         If an <<l>> qualifier is present, the application
  388.                         shall ensure that the argument is a pointer to an
  389.                         array of type wchar_t. Wide characters from the array
  390.                         shall be written up to (but not including) a
  391.                         terminating null wide character. If no precision is
  392.                         specified, or is greater than the size of the array,
  393.                         the application shall ensure that the array contains
  394.                         a null wide character. If a precision is specified,
  395.                         no more than that many wide characters shall be
  396.                         written.
  397.  
  398.                 o S
  399.                         Short for <<%ls>>.  A POSIX extension to the C standard.
  400.  
  401.                 o d or i
  402.                         Prints a signed decimal integer; takes an
  403.                         <<int>>.  Leading zeros are inserted as
  404.                         necessary to reach the precision.  A value of 0 with
  405.                         a precision of 0 produces an empty string.
  406.  
  407.                 o o
  408.                         Prints an unsigned octal integer; takes an
  409.                         <<unsigned>>.  Leading zeros are inserted as
  410.                         necessary to reach the precision.  A value of 0 with
  411.                         a precision of 0 produces an empty string.
  412.  
  413.                 o u
  414.                         Prints an unsigned decimal integer; takes an
  415.                         <<unsigned>>.  Leading zeros are inserted as
  416.                         necessary to reach the precision.  A value of 0 with
  417.                         a precision of 0 produces an empty string.
  418.  
  419.                 o x
  420.                         Prints an unsigned hexadecimal integer (using
  421.                         <<abcdef>> as digits beyond <<9>>); takes an
  422.                         <<unsigned>>.  Leading zeros are inserted as
  423.                         necessary to reach the precision.  A value of 0 with
  424.                         a precision of 0 produces an empty string.
  425.  
  426.                 o X
  427.                         Like <<x>>, but uses <<ABCDEF>> as digits
  428.                         beyond <<9>>.
  429.  
  430.                 o f
  431.                         Prints a signed value of the form
  432.                         <<[-]9999.9999>>, with the precision
  433.                         determining how many digits follow the decimal
  434.                         point; takes a <<double>> (remember that
  435.                         <<float>> promotes to <<double>> as a vararg).
  436.                         The low order digit is rounded to even.  If
  437.                         the precision results in at most DECIMAL_DIG
  438.                         digits, the result is rounded correctly; if
  439.                         more than DECIMAL_DIG digits are printed, the
  440.                         result is only guaranteed to round back to the
  441.                         original value.
  442.  
  443.                         If the value is infinite, the result is
  444.                         <<inf>>, and no zero padding is performed.  If
  445.                         the value is not a number, the result is
  446.                         <<nan>>, and no zero padding is performed.
  447.  
  448.                 o F
  449.                         Like <<f>>, but uses <<INF>> and <<NAN>> for
  450.                         non-finite numbers.
  451.  
  452.                 o e
  453.                         Prints a signed value of the form
  454.                         <<[-]9.9999e[+|-]999>>; takes a <<double>>.
  455.                         The digit before the decimal point is non-zero
  456.                         if the value is non-zero.  The precision
  457.                         determines how many digits appear between
  458.                         <<.>> and <<e>>, and the exponent always
  459.                         contains at least two digits.  The value zero
  460.                         has an exponent of zero.  If the value is not
  461.                         finite, it is printed like <<f>>.
  462.  
  463.                 o E
  464.                         Like <<e>>, but using <<E>> to introduce the
  465.                         exponent, and like <<F>> for non-finite
  466.                         values.
  467.  
  468.                 o g
  469.                         Prints a signed value in either <<f>> or <<e>>
  470.                         form, based on the given value and
  471.                         precision---an exponent less than -4 or
  472.                         greater than the precision selects the <<e>>
  473.                         form.  Trailing zeros and the decimal point
  474.                         are printed only if necessary; takes a
  475.                         <<double>>.
  476.  
  477.                 o G
  478.                         Like <<g>>, except use <<F>> or <<E>> form.
  479.  
  480.                 o a
  481.                         Prints a signed value of the form
  482.                         <<[-]0x1.ffffp[+|-]9>>; takes a <<double>>.
  483.                         The letters <<abcdef>> are used for digits
  484.                         beyond <<9>>.  The precision determines how
  485.                         many digits appear after the decimal point.
  486.                         The exponent contains at least one digit, and
  487.                         is a decimal value representing the power of
  488.                         2; a value of 0 has an exponent of 0.
  489.                         Non-finite values are printed like <<f>>.
  490.  
  491.                 o A
  492.                         Like <<a>>, except uses <<X>>, <<P>>, and
  493.                         <<ABCDEF>> instead of lower case.
  494.  
  495.                 o n
  496.                         Takes a pointer to <<int>>, and stores a count
  497.                         of the number of bytes written so far.  No
  498.                         output is created.
  499.  
  500.                 o p
  501.                         Takes a pointer to <<void>>, and prints it in
  502.                         an implementation-defined format.  This
  503.                         implementation is similar to <<%#tx>>), except
  504.                         that <<0x>> appears even for the NULL pointer.
  505.  
  506.                 o m
  507.                         Prints the output of <<strerror(errno)>>; no
  508.                         argument is required.  A GNU extension.
  509.  
  510.                 o-
  511.         O-
  512.  
  513.         <<_wprintf_r>>, <<_fwprintf_r>>, <<_swprintf_r>>, are simply
  514.         reentrant versions of the functions above.
  515.  
  516. RETURNS
  517. On success, <<swprintf>> return the number of wide characters in
  518. the output string, except the concluding <<NUL>> is not counted.
  519. <<wprintf>> and <<fwprintf>> return the number of characters transmitted.
  520.  
  521. If an error occurs, the result of <<wprintf>>, <<fwprintf>>, and
  522. <<swprintf>> is a negative value.  For <<wprintf>> and <<fwprintf>>,
  523. <<errno>> may be set according to <<fputwc>>.  For <<swprintf>>, <<errno>>
  524. may be set to EOVERFLOW if <[size]> is greater than INT_MAX / sizeof (wchar_t),
  525. or when the output does not fit into <[size]> wide characters (including the
  526. terminating wide <<NULL>>).
  527.  
  528. BUGS
  529. The ``''' (quote) flag does not work when locale's thousands_sep is not empty.
  530.  
  531. PORTABILITY
  532. POSIX-1.2008 with extensions; C99 (compliant except for POSIX extensions).
  533.  
  534. Depending on how newlib was configured, not all format specifiers are
  535. supported.
  536.  
  537. Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
  538. <<lseek>>, <<read>>, <<sbrk>>, <<write>>.
  539. */
  540.  
  541.  
  542. #include <_ansi.h>
  543. #include <reent.h>
  544. #include <stdio.h>
  545. #include <wchar.h>
  546. #include <stdarg.h>
  547. #include <limits.h>
  548. #include <errno.h>
  549. #include "local.h"
  550.  
  551. /* NOTE:  _swprintf_r() should be identical to swprintf() except for the
  552.  * former having ptr as a parameter and the latter needing to declare it as
  553.  * a variable set to _REENT.  */
  554.  
  555. int
  556. _DEFUN(_swprintf_r, (ptr, str, size, fmt),
  557.        struct _reent *ptr _AND
  558.        wchar_t *str          _AND
  559.        size_t size        _AND
  560.        _CONST wchar_t *fmt _DOTS)
  561. {
  562.   int ret;
  563.   va_list ap;
  564.   FILE f;
  565.  
  566.   if (size > INT_MAX / sizeof (wchar_t))
  567.     {
  568.       ptr->_errno = EOVERFLOW;  /* POSIX extension */
  569.       return EOF;
  570.     }
  571.   f._flags = __SWR | __SSTR;
  572.   f._bf._base = f._p = (unsigned char *) str;
  573.   f._bf._size = f._w = (size > 0 ? (size - 1) * sizeof (wchar_t) : 0);
  574.   f._file = -1;  /* No file. */
  575.   va_start (ap, fmt);
  576.   ret = _svfwprintf_r (ptr, &f, fmt, ap);
  577.   va_end (ap);
  578.   /* _svfwprintf_r() does not put in a terminating NUL, so add one if
  579.    * appropriate, which is whenever size is > 0.  _svfwprintf_r() stops
  580.    * after n-1, so always just put at the end.  */
  581.   if (size > 0)  {
  582.     *(wchar_t *)f._p = L'\0';   /* terminate the string */
  583.   }
  584.   if(ret >= size)  {
  585.     /* _svfwprintf_r() returns how many wide characters it would have printed
  586.      * if there were enough space.  Return an error if too big to fit in str,
  587.      * unlike snprintf, which returns the size needed.  */
  588.     ptr->_errno = EOVERFLOW;    /* POSIX extension */
  589.     ret = -1;
  590.   }
  591.   return (ret);
  592. }
  593.  
  594. #ifndef _REENT_ONLY
  595.  
  596. int
  597. _DEFUN(swprintf, (str, size, fmt),
  598.        wchar_t *__restrict str   _AND
  599.        size_t size _AND
  600.        _CONST wchar_t *__restrict fmt _DOTS)
  601. {
  602.   int ret;
  603.   va_list ap;
  604.   FILE f;
  605.   struct _reent *ptr = _REENT;
  606.  
  607.   if (size > INT_MAX / sizeof (wchar_t))
  608.     {
  609.       ptr->_errno = EOVERFLOW;  /* POSIX extension */
  610.       return EOF;
  611.     }
  612.   f._flags = __SWR | __SSTR;
  613.   f._bf._base = f._p = (unsigned char *) str;
  614.   f._bf._size = f._w = (size > 0 ? (size - 1) * sizeof (wchar_t) : 0);
  615.   f._file = -1;  /* No file. */
  616.   va_start (ap, fmt);
  617.   ret = _svfwprintf_r (ptr, &f, fmt, ap);
  618.   va_end (ap);
  619.   /* _svfwprintf_r() does not put in a terminating NUL, so add one if
  620.    * appropriate, which is whenever size is > 0.  _svfwprintf_r() stops
  621.    * after n-1, so always just put at the end.  */
  622.   if (size > 0)  {
  623.     *(wchar_t *)f._p = L'\0';   /* terminate the string */
  624.   }
  625.   if(ret >= size)  {
  626.     /* _svfwprintf_r() returns how many wide characters it would have printed
  627.      * if there were enough space.  Return an error if too big to fit in str,
  628.      * unlike snprintf, which returns the size needed.  */
  629.     ptr->_errno = EOVERFLOW;    /* POSIX extension */
  630.     ret = -1;
  631.   }
  632.   return (ret);
  633. }
  634.  
  635. #endif
  636.