Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /****************************************************************************
  2. *
  3. *                            Open Watcom Project
  4. *
  5. *    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
  6. *
  7. *  ========================================================================
  8. *
  9. *    This file contains Original Code and/or Modifications of Original
  10. *    Code as defined in and that are subject to the Sybase Open Watcom
  11. *    Public License version 1.0 (the 'License'). You may not use this file
  12. *    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
  13. *    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
  14. *    provided with the Original Code and Modifications, and is also
  15. *    available at www.sybase.com/developer/opensource.
  16. *
  17. *    The Original Code and all software distributed under the License are
  18. *    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  19. *    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
  20. *    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
  21. *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
  22. *    NON-INFRINGEMENT. Please see the License for the specific language
  23. *    governing rights and limitations under the License.
  24. *
  25. *  ========================================================================
  26. *
  27. * Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
  28. *               DESCRIBE IT HERE!
  29. *
  30. ****************************************************************************/
  31.  
  32.  
  33. #include "variety.h"
  34. #include "widechar.h"
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #ifdef __WIDECHAR__
  38.     #include <wctype.h>
  39. #else
  40.     #include <ctype.h>
  41. #endif
  42. #include <errno.h>
  43. #include <limits.h>
  44. #include "seterrno.h"
  45.  
  46. /*
  47.  * this table is the largest value that can safely be multiplied
  48.  * by the associated base without overflowing
  49.  */
  50. static unsigned long nearly_overflowing[] = {
  51.     ULONG_MAX / 2,  ULONG_MAX / 3,  ULONG_MAX / 4,  ULONG_MAX / 5,
  52.     ULONG_MAX / 6,  ULONG_MAX / 7,  ULONG_MAX / 8,  ULONG_MAX / 9,
  53.     ULONG_MAX / 10, ULONG_MAX / 11, ULONG_MAX / 12, ULONG_MAX / 13,
  54.     ULONG_MAX / 14, ULONG_MAX / 15, ULONG_MAX / 16, ULONG_MAX / 17,
  55.     ULONG_MAX / 18, ULONG_MAX / 19, ULONG_MAX / 20, ULONG_MAX / 21,
  56.     ULONG_MAX / 22, ULONG_MAX / 23, ULONG_MAX / 24, ULONG_MAX / 25,
  57.     ULONG_MAX / 26, ULONG_MAX / 27, ULONG_MAX / 28, ULONG_MAX / 29,
  58.     ULONG_MAX / 30, ULONG_MAX / 31, ULONG_MAX / 32, ULONG_MAX / 33,
  59.     ULONG_MAX / 34, ULONG_MAX / 35, ULONG_MAX / 36
  60. };
  61.  
  62. #define hexstr(p) (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
  63.  
  64.  
  65. static int radix_value( CHAR_TYPE c )
  66.     {
  67.         if( c >= '0'  &&  c <= '9' ) return( c - '0' );
  68.         c = __F_NAME(tolower,towlower)(c);
  69.         if( c >= 'a'  &&  c <= 'i' ) return( c - 'a' + 10 );
  70.         if( c >= 'j'  &&  c <= 'r' ) return( c - 'j' + 19 );
  71.         if( c >= 's'  &&  c <= 'z' ) return( c - 's' + 28 );
  72.         return( 37 );
  73.     }
  74.  
  75.  
  76. static unsigned long int _stol( const CHAR_TYPE *nptr,CHAR_TYPE **endptr,int base,int who)
  77.     {
  78.         const CHAR_TYPE *p;
  79.         const CHAR_TYPE *startp;
  80.         int digit;
  81.         unsigned long int value;
  82.         unsigned long int prev_value;
  83.         CHAR_TYPE sign;
  84.         char overflow;          /*overflow is used as a flag so it does not
  85.                                  *need to be of type CHAR_TYPE */
  86.  
  87.         if( endptr != NULL ) *endptr = (CHAR_TYPE *)nptr;
  88.         p = nptr;
  89.         while( __F_NAME(isspace,iswspace)(*p) ) ++p;
  90.         sign = *p;
  91.         if( sign == '+'  ||  sign == '-' ) ++p;
  92.         if( base == 0 ) {
  93.             if( hexstr(p) )      base = 16;
  94.             else if( *p == '0' ) base = 8;
  95.             else                 base = 10;
  96.         }
  97.         if( base < 2  ||  base > 36 ) {
  98.             __set_errno( EDOM );
  99.             return( 0 );
  100.         }
  101.         if( base == 16 ) {
  102.             if( hexstr(p) )  p += 2;    /* skip over '0x' */
  103.         }
  104.         startp = p;
  105.         overflow = 0;
  106.         value = 0;
  107.         for(;;) {
  108.             digit = radix_value( *p );
  109.             if( digit >= base ) break;
  110.             if( value > nearly_overflowing[base-2] ) overflow = 1;
  111.             prev_value = value;
  112.             value = value * base + digit;
  113.             if( value < prev_value ) overflow = 1;
  114.             ++p;
  115.         }
  116.         if( p == startp )  p = nptr;
  117.         if( endptr != NULL ) *endptr = (CHAR_TYPE *)p;
  118.         if( who == 1 ) {
  119.             if( value >= 0x80000000 ) {
  120.                 if( value == 0x80000000  &&  sign == '-' ) {
  121.                     ;  /* OK */
  122.                 } else {
  123.                     overflow = 1;
  124.                 }
  125.             }
  126.         }
  127.         if( overflow ) {
  128.             __set_errno( ERANGE );
  129.             if( who == 0 )     return( ULONG_MAX );
  130.             if( sign == '-' )  return( LONG_MIN );
  131.             return( LONG_MAX );
  132.         }
  133.         if( sign == '-' )  value = - value;
  134.         return( value );
  135.     }
  136.  
  137.  
  138. _WCRTLINK unsigned long int __F_NAME(strtoul,wcstoul)( const CHAR_TYPE *nptr,
  139.                 CHAR_TYPE **endptr, int base )
  140.     {
  141.         return( _stol( nptr, endptr, base, 0 ) );
  142.     }
  143.  
  144.  
  145. _WCRTLINK long int __F_NAME(strtol,wcstol)( const CHAR_TYPE *nptr, CHAR_TYPE **endptr, int base )
  146.     {
  147.         return( _stol( nptr, endptr, base, 1 ) );
  148.     }
  149.