home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c065 / 1.ddi / CLIB1.ZIP / STRTOUL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-07  |  4.7 KB  |  142 lines

  1. /*-----------------------------------------------------------------------*
  2.  * filename - strtoul.c
  3.  *
  4.  * function(s)
  5.  *        Get     - gets the next character in a string
  6.  *        UnGet   - moves a character pointer one position forward
  7.  *        strtoul - convert a string to an unsigned long integer
  8.  *-----------------------------------------------------------------------*/
  9.  
  10. /*[]------------------------------------------------------------[]*/
  11. /*|                                                              |*/
  12. /*|     Turbo C Run Time Library - Version 3.0                   |*/
  13. /*|                                                              |*/
  14. /*|                                                              |*/
  15. /*|     Copyright (c) 1987,1988,1990 by Borland International    |*/
  16. /*|     All Rights Reserved.                                     |*/
  17. /*|                                                              |*/
  18. /*[]------------------------------------------------------------[]*/
  19.  
  20. #include <stdlib.h>
  21. #include <limits.h>
  22. #include <ctype.h>
  23. #include <errno.h>
  24. #include <_scanf.h>
  25. #include <stddef.h>
  26.  
  27.  
  28. /*---------------------------------------------------------------------*
  29.  
  30. Name            Get - gets the next character in a string
  31.  
  32. Usage           static int Get(char **strPP);
  33.  
  34. Return value    the next character in a string.  It return -1 if the next
  35.                 character is the null character.
  36.  
  37. *---------------------------------------------------------------------*/
  38.  
  39. static int near Get(char **strPP)
  40. {
  41.         register unsigned       c;
  42.  
  43.         return ((c = *((*strPP) ++)) == 0) ? -1 : c;
  44. }
  45.  
  46.  
  47. /*---------------------------------------------------------------------*
  48.  
  49. Name            UnGet - moves a character pointer one position forward
  50.  
  51. Usage           static void UnGet(char c, char **strPP);
  52.  
  53. Description     decrements a character pointer
  54.  
  55. *---------------------------------------------------------------------*/
  56. #pragma argsused
  57. static void near UnGet(char c, char **strPP)
  58. {
  59.         --(*strPP);     /* ignore c, we don't allow the string to change */
  60. }
  61.  
  62.  
  63. /*-------------------------------------------------------------------------*
  64.  
  65. Name            strtoul - convert a string to an unsigned long integer
  66.  
  67. Usage           unsigned long strtoul(const char *strP, char **suffixPP,
  68.                                       int radix);
  69.  
  70. Prototype in    stdlib.h
  71.  
  72. Description     Convert a string to an unsigned long integer. The syntax of
  73.                 the string must be:
  74.  
  75.                 unsigned long   ::= [isspace]* [+] numeral;
  76.  
  77.                 numeral         ::= { '0' ['x'|'X'] digit [digit]* } |
  78.                                     { digit [digit] }
  79.  
  80.                 "strP"  is a  pointer to  the ASCII  string to  be scanned.
  81.                 "suffixPP" is a pointer to  a string pointer to be updated.
  82.                 If suffixPP  is not NULL  then the updated  pointer will be
  83.                 set to point  to the first character following  the section
  84.                 of  the string  which was   consumed. Thus  the caller  can
  85.                 easily analyze subsequent contents of the string.
  86.  
  87.                 The radix may be zero, or any number 2..36. If the radix is
  88.                 zero, then a radix will be chosen from the possibilities 8,
  89.                 10, or 16, by the usual "C" rules for distinguishing octal,
  90.                 decimal, and hex numerals.
  91.  
  92.                 If radix > 10 then the  letters of the alphabet "A..Z" form
  93.                 the extended set of valid digits.
  94.  
  95. Return value    If the  radix is invalid or  no number could be  found then
  96.                 the result  value is zero   and the next  char pointer will
  97.                 equal the starting string pointer.
  98.  
  99.                 If  the  number  overflows,  LONG_MAX  or  LONG_MIN will be
  100.                 returned and errno will be set to ERANGE.
  101.  
  102. ----------------------------------------------------------------------------*/
  103. unsigned long strtoul(const char *strP, char **suffixPP, int radix)
  104. {
  105.         int     charCt = 0;
  106.         int     status = 0;
  107.         long    result = 0L;
  108.  
  109.  
  110.         while (isspace(*strP))
  111.         {
  112.                 strP++;
  113.                 charCt++;
  114.         }
  115.  
  116.         if (*strP != '-')
  117.         {
  118.                 errno = 0;
  119.                 result = _scantol (
  120.             (int near (*)(void *))Get,
  121.             (void near (*)(int, void *))UnGet,
  122.             &strP,
  123.             radix,
  124.             0x7FFF,
  125.             &charCt,
  126.             &status
  127.             );
  128.         }
  129.  
  130.         if (status <= 0)
  131.                 strP -= charCt;
  132.         else if (status == 2)
  133.     {
  134.         result = ULONG_MAX;
  135.                 errno = ERANGE;
  136.     }
  137.         if (NULL != suffixPP)
  138.                 *suffixPP = (char *)strP;
  139.  
  140.         return (result);
  141. }
  142.