aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/vsprintf.c80
1 files changed, 42 insertions, 38 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 4c6674a41ed9..1a9c6b9b4944 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -32,6 +32,18 @@
32/* Works only for digits and letters, but small and fast */ 32/* Works only for digits and letters, but small and fast */
33#define TOLOWER(x) ((x) | 0x20) 33#define TOLOWER(x) ((x) | 0x20)
34 34
35static unsigned int simple_guess_base(const char *cp)
36{
37 if (cp[0] == '0') {
38 if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
39 return 16;
40 else
41 return 8;
42 } else {
43 return 10;
44 }
45}
46
35/** 47/**
36 * simple_strtoul - convert a string to an unsigned long 48 * simple_strtoul - convert a string to an unsigned long
37 * @cp: The start of the string 49 * @cp: The start of the string
@@ -40,32 +52,28 @@
40 */ 52 */
41unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) 53unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
42{ 54{
43 unsigned long result = 0,value; 55 unsigned long result = 0;
44 56
45 if (!base) { 57 if (!base)
46 base = 10; 58 base = simple_guess_base(cp);
47 if (*cp == '0') { 59
48 base = 8; 60 if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
49 cp++; 61 cp += 2;
50 if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) { 62
51 cp++; 63 while (isxdigit(*cp)) {
52 base = 16; 64 unsigned int value;
53 } 65
54 } 66 value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
55 } else if (base == 16) { 67 if (value >= base)
56 if (cp[0] == '0' && TOLOWER(cp[1]) == 'x') 68 break;
57 cp += 2; 69 result = result * base + value;
58 }
59 while (isxdigit(*cp) &&
60 (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
61 result = result*base + value;
62 cp++; 70 cp++;
63 } 71 }
72
64 if (endp) 73 if (endp)
65 *endp = (char *)cp; 74 *endp = (char *)cp;
66 return result; 75 return result;
67} 76}
68
69EXPORT_SYMBOL(simple_strtoul); 77EXPORT_SYMBOL(simple_strtoul);
70 78
71/** 79/**
@@ -91,32 +99,28 @@ EXPORT_SYMBOL(simple_strtol);
91 */ 99 */
92unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base) 100unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
93{ 101{
94 unsigned long long result = 0,value; 102 unsigned long long result = 0;
95 103
96 if (!base) { 104 if (!base)
97 base = 10; 105 base = simple_guess_base(cp);
98 if (*cp == '0') { 106
99 base = 8; 107 if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
100 cp++; 108 cp += 2;
101 if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) { 109
102 cp++; 110 while (isxdigit(*cp)) {
103 base = 16; 111 unsigned int value;
104 } 112
105 } 113 value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
106 } else if (base == 16) { 114 if (value >= base)
107 if (cp[0] == '0' && TOLOWER(cp[1]) == 'x') 115 break;
108 cp += 2; 116 result = result * base + value;
109 }
110 while (isxdigit(*cp)
111 && (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
112 result = result*base + value;
113 cp++; 117 cp++;
114 } 118 }
119
115 if (endp) 120 if (endp)
116 *endp = (char *)cp; 121 *endp = (char *)cp;
117 return result; 122 return result;
118} 123}
119
120EXPORT_SYMBOL(simple_strtoull); 124EXPORT_SYMBOL(simple_strtoull);
121 125
122/** 126/**