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

VxWorks

开发平台:

C/C++

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