strtoul.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:7k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* strtoul.c - strtoul file for stdlib  */
  2. /* Copyright 1992-1993 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01d,08feb93,jdi  documentation cleanup for 5.1.
  7. 01c,21sep92,smb  tweaks for mg
  8. 01b,20sep92,smb  documentation additions.
  9. 01a,10jul92,smb  documented.
  10. */
  11. /*
  12. DESCRIPTION
  13.  * Copyright (c) 1990 Regents of the University of California.
  14.  * All rights reserved.
  15.  *
  16.  * Redistribution and use in source and binary forms, with or without
  17.  * modification, are permitted provided that the following conditions
  18.  * are met:
  19.  * 1. Redistributions of source code must retain the above copyright
  20.  *    notice, this list of conditions and the following disclaimer.
  21.  * 2. Redistributions in binary form must reproduce the above copyright
  22.  *    notice, this list of conditions and the following disclaimer in the
  23.  *    documentation and/or other materials provided with the distribution.
  24.  * 3. All advertising materials mentioning features or use of this software
  25.  *    must display the following acknowledgement:
  26.  * This product includes software developed by the University of
  27.  * California, Berkeley and its contributors.
  28.  * 4. Neither the name of the University nor the names of its contributors
  29.  *    may be used to endorse or promote products derived from this software
  30.  *    without specific prior written permission.
  31.  *
  32.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  33.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  34.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  35.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  36.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  37.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  38.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  40.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  41.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  42.  * SUCH DAMAGE.
  43. INCLUDE FILES: stdlib.h, limits.h, ctype.h, errno.h
  44. SEE ALSO: American National Standard X3.159-1989
  45. NOMANUAL
  46. */
  47. #include "vxWorks.h"
  48. #include "limits.h"
  49. #include "ctype.h"
  50. #include "errno.h"
  51. #include "stdlib.h"
  52. /*****************************************************************************
  53. *
  54. * strtoul - convert a string to an unsigned long integer (ANSI)
  55. *
  56. * This routine converts the initial portion of a string <nptr> to
  57. * `unsigned long int' representation.  First, it decomposes the input
  58. * string into three parts:  an initial, possibly empty, sequence of
  59. * white-space characters (as specified by isspace()); a subject sequence
  60. * resembling an unsigned integer represented in some radix determined by
  61. * the value <base>; and a final string of one or more unrecognized
  62. * characters, including the terminating null character of the input string.
  63. * Then, it attempts to convert the subject sequence to an unsigned integer,
  64. * and returns the result.
  65. *
  66. * If the value of <base> is zero, the expected form of the subject sequence
  67. * is that of an integer constant, optionally preceded by a plus or minus
  68. * sign, but not including an integer suffix.  If the value of <base> is
  69. * between 2 and 36, the expected form of the subject sequence is a sequence
  70. * of letters and digits representing an integer with the radix specified by
  71. * letters from a (or A) through z (or Z) which are ascribed the values 10 to
  72. * 35; only letters whose ascribed values are less than <base> are
  73. * premitted.  If the value of <base> is 16, the characters 0x or 0X may
  74. * optionally precede the sequence of letters and digits, following the sign
  75. * if present.
  76. *
  77. * The subject sequence is defined as the longest initial subsequence of the
  78. * input string, starting with the first non-white-space character, that is
  79. * of the expected form.  The subject sequence contains no characters if the
  80. * input string is empty or consists entirely of white space, or if the first
  81. * non-white-space character is other than a sign or a permissible letter or
  82. * digit.
  83. *
  84. * If the subject sequence has the expected form and the value of <base> is
  85. * zero, the sequence of characters starting with the first digit is
  86. * interpreted as an integer constant.  If the subject sequence has the
  87. * expected form and the value of <base> is between 2 and 36, it is used as
  88. * the <base> for conversion, ascribing to each letter its value as given
  89. * above.  If the subject sequence begins with a minus sign, the value
  90. * resulting from the conversion is negated.  A pointer to the final string
  91. * is stored in the object pointed to by <endptr>, provided that <endptr> is
  92. * not a null pointer.
  93. *
  94. * In other than the "C" locale, additional implementation-defined subject
  95. * sequence forms may be accepted.  VxWorks supports only the "C" locale;
  96. * it assumes that the upper- and lower-case alphabets and digits are
  97. * each contiguous.
  98. *
  99. * If the subject sequence is empty or does not have the expected form, no
  100. * conversion is performed; the value of <nptr> is stored in the object
  101. * pointed to by <endptr>, provided that <endptr> is not a null pointer.
  102. *
  103. * INCLUDE FILES: stdlib.h 
  104. *
  105. * RETURNS:
  106. * The converted value, if any.  If no conversion could be performed it
  107. * returns zero.  If the correct value is outside the range of representable
  108. * values, it returns ULONG_MAX, and stores the value of the macro ERANGE in
  109. * <errno>.
  110. */
  111. ulong_t strtoul
  112.     (
  113.     const char *     nptr, /* string to convert */
  114.     char **          endptr, /* ptr to final string */
  115.     FAST int         base /* radix */
  116.     )
  117.     {
  118.     FAST const char *s = nptr;
  119.     FAST ulong_t     acc;
  120.     FAST int         c;
  121.     FAST ulong_t     cutoff;
  122.     FAST int         neg = 0;
  123.     FAST int       any;
  124.     FAST int       cutlim;
  125.     /*
  126.      * See strtol for comments as to the logic used.
  127.      */
  128.     do 
  129.         {
  130.      c = *s++;
  131.         } while (isspace (c));
  132.     if (c == '-') 
  133.         {
  134.      neg = 1;
  135.      c = *s++;
  136.         } 
  137.     else if (c == '+')
  138.      c = *s++;
  139.     if (((base == 0) || (base == 16)) &&
  140.         (c == '0') && 
  141.         ((*s == 'x') || (*s == 'X'))) 
  142.         {
  143.      c = s[1];
  144.      s += 2;
  145.      base = 16;
  146.         }
  147.     if (base == 0)
  148.      base = (c == '0' ? 8 : 10);
  149.     cutoff = (ulong_t)ULONG_MAX / (ulong_t)base;
  150.     cutlim = (ulong_t)ULONG_MAX % (ulong_t)base;
  151.     for (acc = 0, any = 0;; c = *s++) 
  152.         {
  153.      if (isdigit (c))
  154.          c -= '0';
  155.      else if (isalpha (c))
  156.          c -= (isupper (c) ? 'A' - 10 : 'a' - 10);
  157.      else
  158.          break;
  159.      if (c >= base)
  160.          break;
  161.      if ((any < 0) || (acc > cutoff) || (acc == cutoff) && (c > cutlim))
  162.          any = -1;
  163.      else 
  164.             {
  165.          any = 1;
  166.          acc *= base;
  167.          acc += c;
  168.          }
  169.         }
  170.     if (any < 0) 
  171.         {
  172.      acc = ULONG_MAX;
  173.      errno = ERANGE;
  174.         } 
  175.     else if (neg)
  176.      acc = -acc;
  177.     if (endptr != 0)
  178.      *endptr = (any ? CHAR_FROM_CONST (s - 1) : CHAR_FROM_CONST (nptr));
  179.     return (acc);
  180.     }