~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to strings/my_strtoll10.c

Removed/replaced DBUG symbols and standardized TRUE/FALSE

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 */
15
15
 
 
16
#include <my_global.h>
 
17
#include <my_sys.h>            /* Needed for MY_ERRNO_ERANGE */
16
18
#include <m_string.h>
17
 
#include <errno.h>
18
19
 
19
 
#define MAX_NEGATIVE_NUMBER     ((uint64_t) 0x8000000000000000LL)
 
20
#undef  ULONGLONG_MAX
 
21
/*
 
22
  Needed under MetroWerks Compiler, since MetroWerks compiler does not
 
23
  properly handle a constant expression containing a mod operator
 
24
*/
 
25
#if defined(__NETWARE__) && defined(__MWERKS__) 
 
26
static ulonglong ulonglong_max= ~(ulonglong) 0;
 
27
#define ULONGLONG_MAX ulonglong_max
 
28
#else
 
29
#define ULONGLONG_MAX           (~(ulonglong) 0)
 
30
#endif /* __NETWARE__ && __MWERKS__ */
 
31
#define MAX_NEGATIVE_NUMBER     ((ulonglong) 0x8000000000000000LL)
20
32
#define INIT_CNT  9
21
33
#define LFACTOR   1000000000ULL
22
34
#define LFACTOR1  10000000000ULL
23
35
#define LFACTOR2  100000000000ULL
24
36
 
25
 
static uint64_t lfactor[9]=
 
37
static unsigned long lfactor[9]=
26
38
{
27
39
  1L, 10L, 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L, 100000000L
28
40
};
29
41
 
30
42
/*
31
 
  Convert a string to an to uint64_t integer value
 
43
  Convert a string to an to unsigned long long integer value
32
44
  
33
45
  SYNOPSYS
34
46
    my_strtoll10()
40
52
  DESCRIPTION
41
53
    This function takes the decimal representation of integer number
42
54
    from string nptr and converts it to an signed or unsigned
43
 
    int64_t value.
 
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.
51
63
 
52
64
  RETURN VALUES
53
 
    Value of string as a signed/unsigned int64_t integer
 
65
    Value of string as a signed/unsigned longlong integer
54
66
 
55
67
    if no error and endptr != NULL, it will be set to point at the character
56
68
    after the number
59
71
    -1          Number was an ok negative number
60
72
    0           ok
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.
67
79
 
70
82
*/
71
83
 
72
84
 
73
 
int64_t my_strtoll10(const char *nptr, char **endptr, int *error)
 
85
longlong my_strtoll10(const char *nptr, char **endptr, int *error)
74
86
{
75
87
  const char *s, *end, *start, *n_end, *true_end;
76
88
  char *dummy;
77
 
  unsigned char c;
 
89
  uchar c;
78
90
  unsigned long i, j, k;
79
 
  uint64_t li;
 
91
  ulonglong li;
80
92
  int negative;
81
 
  unsigned long cutoff, cutoff2, cutoff3;
 
93
  ulong cutoff, cutoff2, cutoff3;
82
94
 
83
95
  s= nptr;
84
96
  /* If fixed length string */
121
133
      if (++s == end)
122
134
        goto no_conv;
123
135
    }
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;
127
139
  }
128
140
 
129
141
  /* Handle case where we have a lot of pre-zero */
195
207
  if (i > cutoff || (i == cutoff && ((j > cutoff2 || j == cutoff2) &&
196
208
                                     k > cutoff3)))
197
209
    goto overflow;
198
 
  li=i*LFACTOR2+ (uint64_t) j*100 + k;
199
 
  return (int64_t) li;
 
210
  li=i*LFACTOR2+ (ulonglong) j*100 + k;
 
211
  return (longlong) li;
200
212
 
201
213
overflow:                                       /* *endptr is set here */
202
 
  *error= ERANGE;
203
 
  return negative ? INT64_MIN: INT64_MAX;
 
214
  *error= MY_ERRNO_ERANGE;
 
215
  return negative ? LONGLONG_MIN : (longlong) ULONGLONG_MAX;
204
216
 
205
217
end_i:
206
218
  *endptr= (char*) s;
207
 
  return (negative ? ((int64_t) -(long) i) : (int64_t) i);
 
219
  return (negative ? ((longlong) -(long) i) : (longlong) i);
208
220
 
209
221
end_i_and_j:
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);
213
225
 
214
226
end3:
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);
218
230
 
219
231
end4:
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;
222
234
  if (negative)
223
235
  {
224
236
   if (li > MAX_NEGATIVE_NUMBER)
225
237
     goto overflow;
226
 
   return -((int64_t) li);
 
238
   return -((longlong) li);
227
239
  }
228
 
  return (int64_t) li;
 
240
  return (longlong) li;
229
241
 
230
242
no_conv:
231
243
  /* There was no number to convert.  */
232
 
  *error= EDOM;
 
244
  *error= MY_ERRNO_EDOM;
233
245
  *endptr= (char *) nptr;
234
246
  return 0;
235
247
}