13
13
along with this program; if not, write to the Free Software
14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
#include "drizzled/internal/m_string.h"
16
#include <my_global.h>
17
#include <my_sys.h> /* Needed for MY_ERRNO_ERANGE */
20
#define MAX_NEGATIVE_NUMBER ((uint64_t) 0x8000000000000000LL)
22
Needed under MetroWerks Compiler, since MetroWerks compiler does not
23
properly handle a constant expression containing a mod operator
25
#if defined(__NETWARE__) && defined(__MWERKS__)
26
static ulonglong ulonglong_max= ~(ulonglong) 0;
27
#define ULONGLONG_MAX ulonglong_max
29
#define ULONGLONG_MAX (~(ulonglong) 0)
30
#endif /* __NETWARE__ && __MWERKS__ */
31
#define MAX_NEGATIVE_NUMBER ((ulonglong) LL(0x8000000000000000))
22
#define LFACTOR 1000000000ULL
23
#define LFACTOR1 10000000000ULL
24
#define LFACTOR2 100000000000ULL
33
#define LFACTOR ULL(1000000000)
34
#define LFACTOR1 ULL(10000000000)
35
#define LFACTOR2 ULL(100000000000)
26
static uint64_t lfactor[9]=
37
static unsigned long lfactor[9]=
28
39
1L, 10L, 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L, 100000000L
32
Convert a string to an to uint64_t integer value
43
Convert a string to an to unsigned long long integer value
36
47
nptr in pointer to the string to be converted
37
48
endptr in/out pointer to the end of the string/
38
49
pointer to the stop character
39
50
error out returned error code
42
53
This function takes the decimal representation of integer number
43
54
from string nptr and converts it to an signed or unsigned
55
long long integer value.
45
56
Space characters and tab are ignored.
46
57
A sign character might precede the digit characters. The number
47
58
may have any number of pre-zero digits.
49
60
The function stops reading the string nptr at the first character
50
61
that is not a decimal digit. If endptr is not NULL then the function
51
62
will not read characters after *endptr.
54
Value of string as a signed/unsigned int64_t integer
65
Value of string as a signed/unsigned longlong integer
56
67
if no error and endptr != NULL, it will be set to point at the character
60
71
-1 Number was an ok negative number
62
73
ERANGE If the the value of the converted number exceeded the
63
maximum negative/uint64_t integer.
64
In this case the return value is UINT64_MAX if value was
65
positive and UINT64_MIN if value was negative.
74
maximum negative/unsigned long long integer.
75
In this case the return value is ~0 if value was
76
positive and LONGLONG_MIN if value was negative.
66
77
EDOM If the string didn't contain any digits. In this case
67
78
the return value is 0.
74
int64_t my_strtoll10(const char *nptr, char **endptr, int *error)
85
longlong my_strtoll10(const char *nptr, char **endptr, int *error)
76
87
const char *s, *end, *start, *n_end, *true_end;
79
90
unsigned long i, j, k;
82
uint64_t cutoff, cutoff2, cutoff3;
93
ulong cutoff, cutoff2, cutoff3;
85
96
/* If fixed length string */
125
cutoff= UINT64_MAX / LFACTOR2;
126
cutoff2= UINT64_MAX % LFACTOR2 / 100;
127
cutoff3= UINT64_MAX % 100;
136
cutoff= ULONGLONG_MAX / LFACTOR2;
137
cutoff2= ULONGLONG_MAX % LFACTOR2 / 100;
138
cutoff3= ULONGLONG_MAX % 100;
130
141
/* Handle case where we have a lot of pre-zero */
196
207
if (i > cutoff || (i == cutoff && ((j > cutoff2 || j == cutoff2) &&
199
li=i*LFACTOR2+ (uint64_t) j*100 + k;
210
li=i*LFACTOR2+ (ulonglong) j*100 + k;
211
return (longlong) li;
202
213
overflow: /* *endptr is set here */
204
return negative ? INT64_MIN: INT64_MAX;
214
*error= MY_ERRNO_ERANGE;
215
return negative ? LONGLONG_MIN : (longlong) ULONGLONG_MAX;
207
218
*endptr= (char*) s;
208
return (negative ? ((int64_t) -(long) i) : (int64_t) i);
219
return (negative ? ((longlong) -(long) i) : (longlong) i);
211
li= (uint64_t) i * lfactor[(unsigned int) (s-start)] + j;
222
li= (ulonglong) i * lfactor[(uint) (s-start)] + j;
212
223
*endptr= (char*) s;
213
return (negative ? -((int64_t) li) : (int64_t) li);
224
return (negative ? -((longlong) li) : (longlong) li);
216
li=(uint64_t) i*LFACTOR+ (uint64_t) j;
227
li=(ulonglong) i*LFACTOR+ (ulonglong) j;
217
228
*endptr= (char*) s;
218
return (negative ? -((int64_t) li) : (int64_t) li);
229
return (negative ? -((longlong) li) : (longlong) li);
221
li=(uint64_t) i*LFACTOR1+ (uint64_t) j * 10 + k;
232
li=(ulonglong) i*LFACTOR1+ (ulonglong) j * 10 + k;
222
233
*endptr= (char*) s;
225
236
if (li > MAX_NEGATIVE_NUMBER)
227
return -((int64_t) li);
238
return -((longlong) li);
240
return (longlong) li;
232
243
/* There was no number to convert. */
244
*error= MY_ERRNO_EDOM;
234
245
*endptr= (char *) nptr;