uboot/lib/strto.c
<<
>>
Prefs
   1/*
   2 *  linux/lib/vsprintf.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 */
   6
   7/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
   8/*
   9 * Wirzenius wrote this portably, Torvalds fucked it up :-)
  10 */
  11
  12#include <common.h>
  13#include <errno.h>
  14#include <linux/ctype.h>
  15
  16unsigned long simple_strtoul(const char *cp, char **endp,
  17                                unsigned int base)
  18{
  19        unsigned long result = 0;
  20        unsigned long value;
  21
  22        if (*cp == '0') {
  23                cp++;
  24                if ((*cp == 'x') && isxdigit(cp[1])) {
  25                        base = 16;
  26                        cp++;
  27                }
  28
  29                if (!base)
  30                        base = 8;
  31        }
  32
  33        if (!base)
  34                base = 10;
  35
  36        while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
  37            ? toupper(*cp) : *cp)-'A'+10) < base) {
  38                result = result*base + value;
  39                cp++;
  40        }
  41
  42        if (endp)
  43                *endp = (char *)cp;
  44
  45        return result;
  46}
  47
  48int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
  49{
  50        char *tail;
  51        unsigned long val;
  52        size_t len;
  53
  54        *res = 0;
  55        len = strlen(cp);
  56        if (len == 0)
  57                return -EINVAL;
  58
  59        val = simple_strtoul(cp, &tail, base);
  60        if (tail == cp)
  61                return -EINVAL;
  62
  63        if ((*tail == '\0') ||
  64                ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
  65                *res = val;
  66                return 0;
  67        }
  68
  69        return -EINVAL;
  70}
  71
  72long simple_strtol(const char *cp, char **endp, unsigned int base)
  73{
  74        if (*cp == '-')
  75                return -simple_strtoul(cp + 1, endp, base);
  76
  77        return simple_strtoul(cp, endp, base);
  78}
  79
  80unsigned long ustrtoul(const char *cp, char **endp, unsigned int base)
  81{
  82        unsigned long result = simple_strtoul(cp, endp, base);
  83        switch (**endp) {
  84        case 'G':
  85                result *= 1024;
  86                /* fall through */
  87        case 'M':
  88                result *= 1024;
  89                /* fall through */
  90        case 'K':
  91        case 'k':
  92                result *= 1024;
  93                if ((*endp)[1] == 'i') {
  94                        if ((*endp)[2] == 'B')
  95                                (*endp) += 3;
  96                        else
  97                                (*endp) += 2;
  98                }
  99        }
 100        return result;
 101}
 102
 103unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base)
 104{
 105        unsigned long long result = simple_strtoull(cp, endp, base);
 106        switch (**endp) {
 107        case 'G':
 108                result *= 1024;
 109                /* fall through */
 110        case 'M':
 111                result *= 1024;
 112                /* fall through */
 113        case 'K':
 114        case 'k':
 115                result *= 1024;
 116                if ((*endp)[1] == 'i') {
 117                        if ((*endp)[2] == 'B')
 118                                (*endp) += 3;
 119                        else
 120                                (*endp) += 2;
 121                }
 122        }
 123        return result;
 124}
 125
 126unsigned long long simple_strtoull(const char *cp, char **endp,
 127                                        unsigned int base)
 128{
 129        unsigned long long result = 0, value;
 130
 131        if (*cp == '0') {
 132                cp++;
 133                if ((*cp == 'x') && isxdigit(cp[1])) {
 134                        base = 16;
 135                        cp++;
 136                }
 137
 138                if (!base)
 139                        base = 8;
 140        }
 141
 142        if (!base)
 143                base = 10;
 144
 145        while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp - '0'
 146                : (islower(*cp) ? toupper(*cp) : *cp) - 'A' + 10) < base) {
 147                result = result * base + value;
 148                cp++;
 149        }
 150
 151        if (endp)
 152                *endp = (char *) cp;
 153
 154        return result;
 155}
 156
 157long trailing_strtoln(const char *str, const char *end)
 158{
 159        const char *p;
 160
 161        if (!end)
 162                end = str + strlen(str);
 163        for (p = end - 1; p > str; p--) {
 164                if (!isdigit(*p))
 165                        return simple_strtoul(p + 1, NULL, 10);
 166        }
 167
 168        return -1;
 169}
 170
 171long trailing_strtol(const char *str)
 172{
 173        return trailing_strtoln(str, NULL);
 174}
 175