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 */
16
#include <my_global.h>
17
#include <my_sys.h> /* Needed for MY_ERRNO_ERANGE */
16
18
#include <m_string.h>
19
#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))
21
#define LFACTOR 1000000000ULL
22
#define LFACTOR1 10000000000ULL
23
#define LFACTOR2 100000000000ULL
33
#define LFACTOR ULL(1000000000)
34
#define LFACTOR1 ULL(10000000000)
35
#define LFACTOR2 ULL(100000000000)
25
static uint64_t lfactor[9]=
37
static unsigned long lfactor[9]=
27
39
1L, 10L, 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L, 100000000L
31
Convert a string to an to uint64_t integer value
43
Convert a string to an to unsigned long long integer value
41
53
This function takes the decimal representation of integer number
42
54
from string nptr and converts it to an signed or unsigned
55
long long integer value.
44
56
Space characters and tab are ignored.
45
57
A sign character might precede the digit characters. The number
46
58
may have any number of pre-zero digits.
50
62
will not read characters after *endptr.
53
Value of string as a signed/unsigned int64_t integer
65
Value of string as a signed/unsigned longlong integer
55
67
if no error and endptr != NULL, it will be set to point at the character
59
71
-1 Number was an ok negative number
61
73
ERANGE If the the value of the converted number exceeded the
62
maximum negative/uint64_t integer.
63
In this case the return value is UINT64_MAX if value was
64
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.
65
77
EDOM If the string didn't contain any digits. In this case
66
78
the return value is 0.
73
int64_t my_strtoll10(const char *nptr, char **endptr, int *error)
85
longlong my_strtoll10(const char *nptr, char **endptr, int *error)
75
87
const char *s, *end, *start, *n_end, *true_end;
78
90
unsigned long i, j, k;
81
unsigned long cutoff, cutoff2, cutoff3;
93
ulong cutoff, cutoff2, cutoff3;
84
96
/* If fixed length string */
124
cutoff= UINT64_MAX / LFACTOR2;
125
cutoff2= UINT64_MAX % LFACTOR2 / 100;
126
cutoff3= UINT64_MAX % 100;
136
cutoff= ULONGLONG_MAX / LFACTOR2;
137
cutoff2= ULONGLONG_MAX % LFACTOR2 / 100;
138
cutoff3= ULONGLONG_MAX % 100;
129
141
/* Handle case where we have a lot of pre-zero */
195
207
if (i > cutoff || (i == cutoff && ((j > cutoff2 || j == cutoff2) &&
198
li=i*LFACTOR2+ (uint64_t) j*100 + k;
210
li=i*LFACTOR2+ (ulonglong) j*100 + k;
211
return (longlong) li;
201
213
overflow: /* *endptr is set here */
203
return negative ? INT64_MIN: INT64_MAX;
214
*error= MY_ERRNO_ERANGE;
215
return negative ? LONGLONG_MIN : (longlong) ULONGLONG_MAX;
206
218
*endptr= (char*) s;
207
return (negative ? ((int64_t) -(long) i) : (int64_t) i);
219
return (negative ? ((longlong) -(long) i) : (longlong) i);
210
li= (uint64_t) i * lfactor[(unsigned int) (s-start)] + j;
222
li= (ulonglong) i * lfactor[(uint) (s-start)] + j;
211
223
*endptr= (char*) s;
212
return (negative ? -((int64_t) li) : (int64_t) li);
224
return (negative ? -((longlong) li) : (longlong) li);
215
li=(uint64_t) i*LFACTOR+ (uint64_t) j;
227
li=(ulonglong) i*LFACTOR+ (ulonglong) j;
216
228
*endptr= (char*) s;
217
return (negative ? -((int64_t) li) : (int64_t) li);
229
return (negative ? -((longlong) li) : (longlong) li);
220
li=(uint64_t) i*LFACTOR1+ (uint64_t) j * 10 + k;
232
li=(ulonglong) i*LFACTOR1+ (ulonglong) j * 10 + k;
221
233
*endptr= (char*) s;
224
236
if (li > MAX_NEGATIVE_NUMBER)
226
return -((int64_t) li);
238
return -((longlong) li);
240
return (longlong) li;
231
243
/* There was no number to convert. */
244
*error= MY_ERRNO_EDOM;
233
245
*endptr= (char *) nptr;