Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include <ctype.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <limits.h>
  5. #include <inttypes.h>
  6.  
  7. #define __expect(foo,bar) (foo)
  8. #define __likely(foo) __expect((foo),1)
  9. #define __unlikely(foo) __expect((foo),0)
  10.  
  11. unsigned long long int strtoull(const char *ptr, char **endptr, int base)
  12. {
  13.   int neg = 0, overflow = 0;
  14.   long long int v=0;
  15.   const char* orig;
  16.   const char* nptr=ptr;
  17.  
  18.   while(isspace(*nptr)) ++nptr;
  19.  
  20.   if (*nptr == '-') { neg=1; nptr++; }
  21.   else if (*nptr == '+') ++nptr;
  22.   orig=nptr;
  23.   if (base==16 && nptr[0]=='0') goto skip0x;
  24.   if (base) {
  25.     register unsigned int b=base-2;
  26.     if (__unlikely(b>34)) { errno=EINVAL; return 0; }
  27.   } else {
  28.     if (*nptr=='0') {
  29.       base=8;
  30. skip0x:
  31.       if (((*(nptr+1)=='x')||(*(nptr+1)=='X')) && isxdigit(nptr[2])) {
  32.         nptr+=2;
  33.         base=16;
  34.       }
  35.     } else
  36.       base=10;
  37.   }
  38.   while(__likely(*nptr)) {
  39.     register unsigned char c=*nptr;
  40.     c=(c>='a'?c-'a'+10:c>='A'?c-'A'+10:c<='9'?c-'0':0xff);
  41.     if (__unlikely(c>=base)) break;     /* out of base */
  42.     {
  43.       register unsigned long x=(v&0xff)*base+c;
  44.       register unsigned long long w=(v>>8)*base+(x>>8);
  45.       if (w>(ULLONG_MAX>>8)) overflow=1;
  46.       v=(w<<8)+(x&0xff);
  47.     }
  48.     ++nptr;
  49.   }
  50.   if (__unlikely(nptr==orig)) {         /* no conversion done */
  51.     nptr=ptr;
  52.     errno=EINVAL;
  53.     v=0;
  54.   }
  55.   if (endptr) *endptr=(char *)nptr;
  56.   if (overflow) {
  57.     errno=ERANGE;
  58.     return ULLONG_MAX;
  59.   }
  60.   return (neg?-v:v);
  61. }
  62.  
  63. /* die, BSD, die!!! */
  64. unsigned long long int strtouq(const char *nptr, char **endptr, int base)
  65.         __attribute__((alias("strtoull")));
  66.  
  67. uintmax_t strtoumax(const char *nptr, char **endptr, int base)
  68.         __attribute__((alias("strtoull")));
  69.