Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2. FUNCTION
  3.         <<wcstod>>, <<wcstof>>---wide char string to double or float
  4.  
  5. INDEX
  6.         wcstod
  7. INDEX
  8.         _wcstod_r
  9. INDEX
  10.         wcstof
  11. INDEX
  12.         _wcstof_r
  13.  
  14. ANSI_SYNOPSIS
  15.         #include <stdlib.h>
  16.         double wcstod(const wchar_t *__restrict <[str]>,
  17.             wchar_t **__restrict <[tail]>);
  18.         float wcstof(const wchar_t *__restrict <[str]>,
  19.             wchar_t **__restrict <[tail]>);
  20.  
  21.         double _wcstod_r(void *<[reent]>,
  22.                          const wchar_t *<[str]>, wchar_t **<[tail]>);
  23.         float _wcstof_r(void *<[reent]>,
  24.                          const wchar_t *<[str]>, wchar_t **<[tail]>);
  25.  
  26. TRAD_SYNOPSIS
  27.         #include <stdlib.h>
  28.         double wcstod(<[str]>,<[tail]>)
  29.         wchar_t *__restrict <[str]>;
  30.         wchar_t **__restrict <[tail]>;
  31.  
  32.         float wcstof(<[str]>,<[tail]>)
  33.         wchar_t *__restrict <[str]>;
  34.         wchar_t **__restrict <[tail]>;
  35.  
  36.         double _wcstod_r(<[reent]>,<[str]>,<[tail]>)
  37.         wchar_t *<[reent]>;
  38.         wchar_t *<[str]>;
  39.         wchar_t **<[tail]>;
  40.  
  41.         float _wcstof_r(<[reent]>,<[str]>,<[tail]>)
  42.         wchar_t *<[reent]>;
  43.         wchar_t *<[str]>;
  44.         wchar_t **<[tail]>;
  45.  
  46. DESCRIPTION
  47.         The function <<wcstod>> parses the wide character string <[str]>,
  48.         producing a substring which can be converted to a double
  49.         value.  The substring converted is the longest initial
  50.         subsequence of <[str]>, beginning with the first
  51.         non-whitespace character, that has one of these formats:
  52.         .[+|-]<[digits]>[.[<[digits]>]][(e|E)[+|-]<[digits]>]
  53.         .[+|-].<[digits]>[(e|E)[+|-]<[digits]>]
  54.         .[+|-](i|I)(n|N)(f|F)[(i|I)(n|N)(i|I)(t|T)(y|Y)]
  55.         .[+|-](n|N)(a|A)(n|N)[<(>[<[hexdigits]>]<)>]
  56.         .[+|-]0(x|X)<[hexdigits]>[.[<[hexdigits]>]][(p|P)[+|-]<[digits]>]
  57.         .[+|-]0(x|X).<[hexdigits]>[(p|P)[+|-]<[digits]>]
  58.         The substring contains no characters if <[str]> is empty, consists
  59.         entirely of whitespace, or if the first non-whitespace
  60.         character is something other than <<+>>, <<->>, <<.>>, or a
  61.         digit, and cannot be parsed as infinity or NaN. If the platform
  62.         does not support NaN, then NaN is treated as an empty substring.
  63.         If the substring is empty, no conversion is done, and
  64.         the value of <[str]> is stored in <<*<[tail]>>>.  Otherwise,
  65.         the substring is converted, and a pointer to the final string
  66.         (which will contain at least the terminating null character of
  67.         <[str]>) is stored in <<*<[tail]>>>.  If you want no
  68.         assignment to <<*<[tail]>>>, pass a null pointer as <[tail]>.
  69.         <<wcstof>> is identical to <<wcstod>> except for its return type.
  70.  
  71.         This implementation returns the nearest machine number to the
  72.         input decimal string.  Ties are broken by using the IEEE
  73.         round-even rule.  However, <<wcstof>> is currently subject to
  74.         double rounding errors.
  75.  
  76.         The alternate functions <<_wcstod_r>> and <<_wcstof_r>> are
  77.         reentrant versions of <<wcstod>> and <<wcstof>>, respectively.
  78.         The extra argument <[reent]> is a pointer to a reentrancy structure.
  79.  
  80. RETURNS
  81.         Return the converted substring value, if any.  If
  82.         no conversion could be performed, 0 is returned.  If the
  83.         correct value is out of the range of representable values,
  84.         plus or minus <<HUGE_VAL>> is returned, and <<ERANGE>> is
  85.         stored in errno. If the correct value would cause underflow, 0
  86.         is returned and <<ERANGE>> is stored in errno.
  87.  
  88. Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
  89. <<lseek>>, <<read>>, <<sbrk>>, <<write>>.
  90. */
  91.  
  92. /*-
  93.  * Copyright (c) 2002 Tim J. Robbins
  94.  * All rights reserved.
  95.  *
  96.  * Redistribution and use in source and binary forms, with or without
  97.  * modification, are permitted provided that the following conditions
  98.  * are met:
  99.  * 1. Redistributions of source code must retain the above copyright
  100.  *    notice, this list of conditions and the following disclaimer.
  101.  * 2. Redistributions in binary form must reproduce the above copyright
  102.  *    notice, this list of conditions and the following disclaimer in the
  103.  *    documentation and/or other materials provided with the distribution.
  104.  *
  105.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  106.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  107.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  108.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  109.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  110.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  111.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  112.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  113.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  114.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  115.  * SUCH DAMAGE.
  116.  */
  117.  
  118. #include <_ansi.h>
  119. #include <errno.h>
  120. #include <stdlib.h>
  121. #include <string.h>
  122. #include <wchar.h>
  123. #include <wctype.h>
  124. #include <locale.h>
  125. #include <math.h>
  126.  
  127. double
  128. _DEFUN (_wcstod_r, (ptr, nptr, endptr),
  129.         struct _reent *ptr _AND
  130.         _CONST wchar_t *nptr _AND
  131.         wchar_t **endptr)
  132. {
  133.         static const mbstate_t initial;
  134.         mbstate_t mbs;
  135.         double val;
  136.         char *buf, *end;
  137.         const wchar_t *wcp;
  138.         size_t len;
  139.  
  140.         while (iswspace(*nptr))
  141.                 nptr++;
  142.  
  143.         /*
  144.          * Convert the supplied numeric wide char. string to multibyte.
  145.          *
  146.          * We could attempt to find the end of the numeric portion of the
  147.          * wide char. string to avoid converting unneeded characters but
  148.          * choose not to bother; optimising the uncommon case where
  149.          * the input string contains a lot of text after the number
  150.          * duplicates a lot of strtod()'s functionality and slows down the
  151.          * most common cases.
  152.          */
  153.         wcp = nptr;
  154.         mbs = initial;
  155.         if ((len = _wcsrtombs_r(ptr, NULL, &wcp, 0, &mbs)) == (size_t)-1) {
  156.                 if (endptr != NULL)
  157.                         *endptr = (wchar_t *)nptr;
  158.                 return (0.0);
  159.         }
  160.         if ((buf = _malloc_r(ptr, len + 1)) == NULL)
  161.                 return (0.0);
  162.         mbs = initial;
  163.         _wcsrtombs_r(ptr, buf, &wcp, len + 1, &mbs);
  164.  
  165.         /* Let strtod() do most of the work for us. */
  166.         val = _strtod_r(ptr, buf, &end);
  167.  
  168.         /*
  169.          * We only know where the number ended in the _multibyte_
  170.          * representation of the string. If the caller wants to know
  171.          * where it ended, count multibyte characters to find the
  172.          * corresponding position in the wide char string.
  173.          */
  174.         if (endptr != NULL) {
  175.                 /* The only valid multibyte char in a float converted by
  176.                    strtod/wcstod is the radix char.  What we do here is,
  177.                    figure out if the radix char was in the valid leading
  178.                    float sequence in the incoming string.  If so, the
  179.                    multibyte float string is strlen(radix char) - 1 bytes
  180.                    longer than the incoming wide char string has characters.
  181.                    To fix endptr, reposition end as if the radix char was
  182.                    just one byte long.  The resulting difference (end - buf)
  183.                    is then equivalent to the number of valid wide characters
  184.                    in the input string. */
  185.                 len = strlen (_localeconv_r (ptr)->decimal_point);
  186.                 if (len > 1) {
  187.                         char *d = strstr (buf,
  188.                                           _localeconv_r (ptr)->decimal_point);
  189.                         if (d && d < end)
  190.                                 end -= len - 1;
  191.                 }
  192.                 *endptr = (wchar_t *)nptr + (end - buf);
  193.         }
  194.  
  195.         _free_r(ptr, buf);
  196.  
  197.         return (val);
  198. }
  199.  
  200. float
  201. _DEFUN (_wcstof_r, (ptr, nptr, endptr),
  202.         struct _reent *ptr _AND
  203.         _CONST wchar_t *nptr _AND
  204.         wchar_t **endptr)
  205. {
  206.   double retval = _wcstod_r (ptr, nptr, endptr);
  207.   if (isnan (retval))
  208.     return nanf (NULL);
  209.   return (float)retval;
  210. }
  211.  
  212. #ifndef _REENT_ONLY
  213.  
  214. double
  215. _DEFUN (wcstod, (nptr, endptr),
  216.         _CONST wchar_t *__restrict nptr _AND wchar_t **__restrict endptr)
  217. {
  218.   return _wcstod_r (_REENT, nptr, endptr);
  219. }
  220.  
  221. float
  222. _DEFUN (wcstof, (nptr, endptr),
  223.         _CONST wchar_t *__restrict nptr _AND
  224.         wchar_t **__restrict endptr)
  225. {
  226.   double retval = _wcstod_r (_REENT, nptr, endptr);
  227.   if (isnan (retval))
  228.     return nanf (NULL);
  229.   return (float)retval;
  230. }
  231.  
  232. #endif
  233.