~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2002 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1 by brian
clean slate
15
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
16
#include "config.h"
1130.3.26 by Monty Taylor
Removed global.h from headers.
17
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
18
#include "drizzled/internal/m_string.h"
1241.9.61 by Monty Taylor
No more mystrings in drizzled/
19
#include "drizzled/charset_info.h"
20
#include <cerrno>
21
#include <cstdio>
22
#include <cstdlib>
1 by brian
clean slate
23
1241.9.61 by Monty Taylor
No more mystrings in drizzled/
24
#include <stdarg.h>
1 by brian
clean slate
25
1067.4.9 by Nathan Williams
Converted all usages of cmin/cmax in mystrings directory to use std::min/max
26
#include <algorithm>
27
28
using namespace std;
29
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
30
namespace drizzled
31
{
1067.4.9 by Nathan Williams
Converted all usages of cmin/cmax in mystrings directory to use std::min/max
32
1 by brian
clean slate
33
/*
34
  Returns the number of bytes required for strnxfrm().
35
*/
36
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
37
size_t my_strnxfrmlen_simple(const CHARSET_INFO * const cs, size_t len)
1 by brian
clean slate
38
{
39
  return len * (cs->strxfrm_multiply ? cs->strxfrm_multiply : 1);
40
}
41
42
43
/*
44
   We can't use vsprintf here as it's not guaranteed to return
45
   the length on all operating systems.
46
   This function is also not called in a safe environment, so the
47
   end buffer must be checked.
48
*/
49
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
50
size_t my_snprintf_8bit(const CHARSET_INFO * const,
51
                        char* to, size_t n,
1 by brian
clean slate
52
		     const char* fmt, ...)
53
{
54
  va_list args;
55
  int result;
56
  va_start(args,fmt);
77.1.18 by Monty Taylor
Removed my_vsnprintf and my_snprintf.
57
  result= vsnprintf(to, n, fmt, args);
1 by brian
clean slate
58
  va_end(args);
59
  return result;
60
}
61
62
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
63
long my_strntol_8bit(const CHARSET_INFO * const cs,
1 by brian
clean slate
64
		     const char *nptr, size_t l, int base,
65
		     char **endptr, int *err)
66
{
67
  int negative;
163 by Brian Aker
Merge Monty's code.
68
  register uint32_t cutoff;
482 by Brian Aker
Remove uint.
69
  register uint32_t cutlim;
163 by Brian Aker
Merge Monty's code.
70
  register uint32_t i;
1 by brian
clean slate
71
  register const char *s;
481 by Brian Aker
Remove all of uchar.
72
  register unsigned char c;
1 by brian
clean slate
73
  const char *save, *e;
74
  int overflow;
75
76
  *err= 0;				/* Initialize error indicator */
77
#ifdef NOT_USED
78
  if (base < 0 || base == 1 || base > 36)
79
    base = 10;
80
#endif
81
82
  s = nptr;
83
  e = nptr+l;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
84
575.3.1 by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found.
85
  for ( ; s<e && my_isspace(cs, *s) ; s++) {}
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
86
1 by brian
clean slate
87
  if (s == e)
88
  {
89
    goto noconv;
90
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
91
1 by brian
clean slate
92
  /* Check for a sign.	*/
93
  if (*s == '-')
94
  {
95
    negative = 1;
96
    ++s;
97
  }
98
  else if (*s == '+')
99
  {
100
    negative = 0;
101
    ++s;
102
  }
103
  else
104
    negative = 0;
105
106
#ifdef NOT_USED
107
  if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
108
    s += 2;
109
#endif
110
111
#ifdef NOT_USED
112
  if (base == 0)
113
  {
114
    if (*s == '0')
115
    {
116
      if (s[1]=='X' || s[1]=='x')
117
      {
118
	s += 2;
119
	base = 16;
120
      }
121
      else
122
	base = 8;
123
    }
124
    else
125
      base = 10;
126
  }
127
#endif
128
129
  save = s;
365.2.9 by Monty Taylor
Got rid of all instances of ~0
130
  cutoff = (UINT32_MAX) / (uint32_t) base;
895 by Brian Aker
Completion (?) of uint conversion.
131
  cutlim = (uint32_t) ((UINT32_MAX) % (uint32_t) base);
1 by brian
clean slate
132
133
  overflow = 0;
134
  i = 0;
135
  for (c = *s; s != e; c = *++s)
136
  {
137
    if (c>='0' && c<='9')
138
      c -= '0';
139
    else if (c>='A' && c<='Z')
140
      c = c - 'A' + 10;
141
    else if (c>='a' && c<='z')
142
      c = c - 'a' + 10;
143
    else
144
      break;
145
    if (c >= base)
146
      break;
147
    if (i > cutoff || (i == cutoff && c > cutlim))
148
      overflow = 1;
149
    else
150
    {
163 by Brian Aker
Merge Monty's code.
151
      i *= (uint32_t) base;
1 by brian
clean slate
152
      i += c;
153
    }
154
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
155
1 by brian
clean slate
156
  if (s == save)
157
    goto noconv;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
158
1 by brian
clean slate
159
  if (endptr != NULL)
160
    *endptr = (char *) s;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
161
1 by brian
clean slate
162
  if (negative)
163
  {
163 by Brian Aker
Merge Monty's code.
164
    if (i  > (uint32_t) INT32_MIN)
1 by brian
clean slate
165
      overflow = 1;
166
  }
163 by Brian Aker
Merge Monty's code.
167
  else if (i > INT32_MAX)
1 by brian
clean slate
168
    overflow = 1;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
169
1 by brian
clean slate
170
  if (overflow)
171
  {
172
    err[0]= ERANGE;
163 by Brian Aker
Merge Monty's code.
173
    return negative ? INT32_MIN : INT32_MAX;
1 by brian
clean slate
174
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
175
1 by brian
clean slate
176
  return (negative ? -((long) i) : (long) i);
177
178
noconv:
179
  err[0]= EDOM;
180
  if (endptr != NULL)
181
    *endptr = (char *) nptr;
182
  return 0L;
183
}
184
185
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
186
ulong my_strntoul_8bit(const CHARSET_INFO * const cs,
1 by brian
clean slate
187
		       const char *nptr, size_t l, int base,
188
		       char **endptr, int *err)
189
{
190
  int negative;
163 by Brian Aker
Merge Monty's code.
191
  register uint32_t cutoff;
482 by Brian Aker
Remove uint.
192
  register uint32_t cutlim;
163 by Brian Aker
Merge Monty's code.
193
  register uint32_t i;
1 by brian
clean slate
194
  register const char *s;
481 by Brian Aker
Remove all of uchar.
195
  register unsigned char c;
1 by brian
clean slate
196
  const char *save, *e;
197
  int overflow;
198
199
  *err= 0;				/* Initialize error indicator */
200
#ifdef NOT_USED
201
  if (base < 0 || base == 1 || base > 36)
202
    base = 10;
203
#endif
204
205
  s = nptr;
206
  e = nptr+l;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
207
575.3.1 by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found.
208
  for( ; s<e && my_isspace(cs, *s); s++) {}
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
209
1 by brian
clean slate
210
  if (s==e)
211
  {
212
    goto noconv;
213
  }
214
215
  if (*s == '-')
216
  {
217
    negative = 1;
218
    ++s;
219
  }
220
  else if (*s == '+')
221
  {
222
    negative = 0;
223
    ++s;
224
  }
225
  else
226
    negative = 0;
227
228
#ifdef NOT_USED
229
  if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
230
    s += 2;
231
#endif
232
233
#ifdef NOT_USED
234
  if (base == 0)
235
  {
236
    if (*s == '0')
237
    {
238
      if (s[1]=='X' || s[1]=='x')
239
      {
240
	s += 2;
241
	base = 16;
242
      }
243
      else
244
	base = 8;
245
    }
246
    else
247
      base = 10;
248
  }
249
#endif
250
251
  save = s;
365.2.9 by Monty Taylor
Got rid of all instances of ~0
252
  cutoff = (UINT32_MAX) / (uint32_t) base;
895 by Brian Aker
Completion (?) of uint conversion.
253
  cutlim = (uint32_t) ((UINT32_MAX) % (uint32_t) base);
1 by brian
clean slate
254
  overflow = 0;
255
  i = 0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
256
1 by brian
clean slate
257
  for (c = *s; s != e; c = *++s)
258
  {
259
    if (c>='0' && c<='9')
260
      c -= '0';
261
    else if (c>='A' && c<='Z')
262
      c = c - 'A' + 10;
263
    else if (c>='a' && c<='z')
264
      c = c - 'a' + 10;
265
    else
266
      break;
267
    if (c >= base)
268
      break;
269
    if (i > cutoff || (i == cutoff && c > cutlim))
270
      overflow = 1;
271
    else
272
    {
163 by Brian Aker
Merge Monty's code.
273
      i *= (uint32_t) base;
1 by brian
clean slate
274
      i += c;
275
    }
276
  }
277
278
  if (s == save)
279
    goto noconv;
280
281
  if (endptr != NULL)
282
    *endptr = (char *) s;
283
284
  if (overflow)
285
  {
286
    err[0]= ERANGE;
1816.2.4 by Monty Taylor
Cleaned up a bunch more warnings.
287
    return UINT32_MAX;
1 by brian
clean slate
288
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
289
1 by brian
clean slate
290
  return (negative ? -((long) i) : (long) i);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
291
1 by brian
clean slate
292
noconv:
293
  err[0]= EDOM;
294
  if (endptr != NULL)
295
    *endptr = (char *) nptr;
296
  return 0L;
297
}
298
299
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
300
int64_t my_strntoll_8bit(const CHARSET_INFO * const cs,
1 by brian
clean slate
301
			  const char *nptr, size_t l, int base,
302
			  char **endptr,int *err)
303
{
304
  int negative;
151 by Brian Aker
Ulonglong to uint64_t
305
  register uint64_t cutoff;
482 by Brian Aker
Remove uint.
306
  register uint32_t cutlim;
151 by Brian Aker
Ulonglong to uint64_t
307
  register uint64_t i;
1 by brian
clean slate
308
  register const char *s, *e;
309
  const char *save;
310
  int overflow;
311
312
  *err= 0;				/* Initialize error indicator */
313
#ifdef NOT_USED
314
  if (base < 0 || base == 1 || base > 36)
315
    base = 10;
316
#endif
317
318
  s = nptr;
319
  e = nptr+l;
320
575.3.1 by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found.
321
  for(; s<e && my_isspace(cs,*s); s++) {}
1 by brian
clean slate
322
323
  if (s == e)
324
  {
325
    goto noconv;
326
  }
327
328
  if (*s == '-')
329
  {
330
    negative = 1;
331
    ++s;
332
  }
333
  else if (*s == '+')
334
  {
335
    negative = 0;
336
    ++s;
337
  }
338
  else
339
    negative = 0;
340
341
#ifdef NOT_USED
342
  if (base == 16 && s[0] == '0' && (s[1]=='X'|| s[1]=='x'))
343
    s += 2;
344
#endif
345
346
#ifdef NOT_USED
347
  if (base == 0)
348
  {
349
    if (*s == '0')
350
    {
351
      if (s[1]=='X' || s[1]=='x')
352
      {
353
	s += 2;
354
	base = 16;
355
      }
356
      else
357
	base = 8;
358
    }
359
    else
360
      base = 10;
361
  }
362
#endif
363
364
  save = s;
365
151 by Brian Aker
Ulonglong to uint64_t
366
  cutoff = (~(uint64_t) 0) / (unsigned long int) base;
895 by Brian Aker
Completion (?) of uint conversion.
367
  cutlim = (uint32_t) ((~(uint64_t) 0) % (unsigned long int) base);
1 by brian
clean slate
368
369
  overflow = 0;
370
  i = 0;
371
  for ( ; s != e; s++)
372
  {
481 by Brian Aker
Remove all of uchar.
373
    register unsigned char c= *s;
1 by brian
clean slate
374
    if (c>='0' && c<='9')
375
      c -= '0';
376
    else if (c>='A' && c<='Z')
377
      c = c - 'A' + 10;
378
    else if (c>='a' && c<='z')
379
      c = c - 'a' + 10;
380
    else
381
      break;
382
    if (c >= base)
383
      break;
384
    if (i > cutoff || (i == cutoff && c > cutlim))
385
      overflow = 1;
386
    else
387
    {
151 by Brian Aker
Ulonglong to uint64_t
388
      i *= (uint64_t) base;
1 by brian
clean slate
389
      i += c;
390
    }
391
  }
392
393
  if (s == save)
394
    goto noconv;
395
396
  if (endptr != NULL)
397
    *endptr = (char *) s;
398
399
  if (negative)
400
  {
163 by Brian Aker
Merge Monty's code.
401
    if (i  > (uint64_t) INT64_MIN)
1 by brian
clean slate
402
      overflow = 1;
403
  }
163 by Brian Aker
Merge Monty's code.
404
  else if (i > (uint64_t) INT64_MAX)
1 by brian
clean slate
405
    overflow = 1;
406
407
  if (overflow)
408
  {
409
    err[0]= ERANGE;
163 by Brian Aker
Merge Monty's code.
410
    return negative ? INT64_MIN : INT64_MAX;
1 by brian
clean slate
411
  }
412
152 by Brian Aker
longlong replacement
413
  return (negative ? -((int64_t) i) : (int64_t) i);
1 by brian
clean slate
414
415
noconv:
416
  err[0]= EDOM;
417
  if (endptr != NULL)
418
    *endptr = (char *) nptr;
419
  return 0L;
420
}
421
422
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
423
uint64_t my_strntoull_8bit(const CHARSET_INFO * const cs,
1 by brian
clean slate
424
			   const char *nptr, size_t l, int base,
425
			   char **endptr, int *err)
426
{
427
  int negative;
151 by Brian Aker
Ulonglong to uint64_t
428
  register uint64_t cutoff;
482 by Brian Aker
Remove uint.
429
  register uint32_t cutlim;
151 by Brian Aker
Ulonglong to uint64_t
430
  register uint64_t i;
1 by brian
clean slate
431
  register const char *s, *e;
432
  const char *save;
433
  int overflow;
434
435
  *err= 0;				/* Initialize error indicator */
436
#ifdef NOT_USED
437
  if (base < 0 || base == 1 || base > 36)
438
    base = 10;
439
#endif
440
441
  s = nptr;
442
  e = nptr+l;
443
575.3.1 by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found.
444
  for(; s<e && my_isspace(cs,*s); s++) {}
1 by brian
clean slate
445
446
  if (s == e)
447
  {
448
    goto noconv;
449
  }
450
451
  if (*s == '-')
452
  {
453
    negative = 1;
454
    ++s;
455
  }
456
  else if (*s == '+')
457
  {
458
    negative = 0;
459
    ++s;
460
  }
461
  else
462
    negative = 0;
463
464
#ifdef NOT_USED
465
  if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
466
    s += 2;
467
#endif
468
469
#ifdef NOT_USED
470
  if (base == 0)
471
  {
472
    if (*s == '0')
473
    {
474
      if (s[1]=='X' || s[1]=='x')
475
      {
476
	s += 2;
477
	base = 16;
478
      }
479
      else
480
	base = 8;
481
    }
482
    else
483
      base = 10;
484
  }
485
#endif
486
487
  save = s;
488
151 by Brian Aker
Ulonglong to uint64_t
489
  cutoff = (~(uint64_t) 0) / (unsigned long int) base;
895 by Brian Aker
Completion (?) of uint conversion.
490
  cutlim = (uint32_t) ((~(uint64_t) 0) % (unsigned long int) base);
1 by brian
clean slate
491
492
  overflow = 0;
493
  i = 0;
494
  for ( ; s != e; s++)
495
  {
481 by Brian Aker
Remove all of uchar.
496
    register unsigned char c= *s;
1 by brian
clean slate
497
498
    if (c>='0' && c<='9')
499
      c -= '0';
500
    else if (c>='A' && c<='Z')
501
      c = c - 'A' + 10;
502
    else if (c>='a' && c<='z')
503
      c = c - 'a' + 10;
504
    else
505
      break;
506
    if (c >= base)
507
      break;
508
    if (i > cutoff || (i == cutoff && c > cutlim))
509
      overflow = 1;
510
    else
511
    {
151 by Brian Aker
Ulonglong to uint64_t
512
      i *= (uint64_t) base;
1 by brian
clean slate
513
      i += c;
514
    }
515
  }
516
517
  if (s == save)
518
    goto noconv;
519
520
  if (endptr != NULL)
521
    *endptr = (char *) s;
522
523
  if (overflow)
524
  {
525
    err[0]= ERANGE;
151 by Brian Aker
Ulonglong to uint64_t
526
    return (~(uint64_t) 0);
1 by brian
clean slate
527
  }
528
152 by Brian Aker
longlong replacement
529
  return (negative ? -((int64_t) i) : (int64_t) i);
1 by brian
clean slate
530
531
noconv:
532
  err[0]= EDOM;
533
  if (endptr != NULL)
534
    *endptr = (char *) nptr;
535
  return 0L;
536
}
537
538
539
/*
540
  Read double from string
541
542
  SYNOPSIS:
543
    my_strntod_8bit()
544
    cs		Character set information
545
    str		String to convert to double
546
    length	Optional length for string.
547
    end		result pointer to end of converted string
548
    err		Error number if failed conversion
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
549
1 by brian
clean slate
550
  NOTES:
163 by Brian Aker
Merge Monty's code.
551
    If length is not INT32_MAX or str[length] != 0 then the given str must
1 by brian
clean slate
552
    be writeable
163 by Brian Aker
Merge Monty's code.
553
    If length == INT32_MAX the str must be \0 terminated.
1 by brian
clean slate
554
555
    It's implemented this way to save a buffer allocation and a memory copy.
556
557
  RETURN
558
    Value of number in string
559
*/
560
561
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
562
double my_strntod_8bit(const CHARSET_INFO * const,
1 by brian
clean slate
563
		       char *str, size_t length,
564
		       char **end, int *err)
565
{
163 by Brian Aker
Merge Monty's code.
566
  if (length == INT32_MAX)
1 by brian
clean slate
567
    length= 65535;                          /* Should be big enough */
568
  *end= str + length;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
569
  return internal::my_strtod(str, end, err);
1 by brian
clean slate
570
}
571
572
573
/*
574
  This is a fast version optimized for the case of radix 10 / -10
575
576
  Assume len >= 1
577
*/
578
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
579
size_t my_long10_to_str_8bit(const CHARSET_INFO * const,
1 by brian
clean slate
580
                             char *dst, size_t len, int radix, long int val)
581
{
582
  char buffer[66];
583
  register char *p, *e;
584
  long int new_val;
482 by Brian Aker
Remove uint.
585
  uint32_t sign=0;
1 by brian
clean slate
586
  unsigned long int uval = (unsigned long int) val;
587
588
  e = p = &buffer[sizeof(buffer)-1];
589
  *p= 0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
590
1 by brian
clean slate
591
  if (radix < 0)
592
  {
593
    if (val < 0)
594
    {
163 by Brian Aker
Merge Monty's code.
595
      /* Avoid integer overflow in (-val) for INT64_MIN (BUG#31799). */
1 by brian
clean slate
596
      uval= (unsigned long int)0 - uval;
597
      *dst++= '-';
598
      len--;
599
      sign= 1;
600
    }
601
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
602
1 by brian
clean slate
603
  new_val = (long) (uval / 10);
604
  *--p    = '0'+ (char) (uval - (unsigned long) new_val * 10);
605
  val     = new_val;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
606
1 by brian
clean slate
607
  while (val != 0)
608
  {
609
    new_val=val/10;
610
    *--p = '0' + (char) (val-new_val*10);
611
    val= new_val;
612
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
613
1067.4.9 by Nathan Williams
Converted all usages of cmin/cmax in mystrings directory to use std::min/max
614
  len= min(len, (size_t) (e-p));
1 by brian
clean slate
615
  memcpy(dst, p, len);
616
  return len+sign;
617
}
618
619
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
620
size_t my_int64_t10_to_str_8bit(const CHARSET_INFO * const,
621
                                char *dst, size_t len, int radix,
622
                                int64_t val)
1 by brian
clean slate
623
{
624
  char buffer[65];
625
  register char *p, *e;
626
  long long_val;
482 by Brian Aker
Remove uint.
627
  uint32_t sign= 0;
151 by Brian Aker
Ulonglong to uint64_t
628
  uint64_t uval = (uint64_t)val;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
629
1 by brian
clean slate
630
  if (radix < 0)
631
  {
632
    if (val < 0)
633
    {
163 by Brian Aker
Merge Monty's code.
634
      /* Avoid integer overflow in (-val) for INT64_MIN (BUG#31799). */
151 by Brian Aker
Ulonglong to uint64_t
635
      uval = (uint64_t)0 - uval;
1 by brian
clean slate
636
      *dst++= '-';
637
      len--;
638
      sign= 1;
639
    }
640
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
641
1 by brian
clean slate
642
  e = p = &buffer[sizeof(buffer)-1];
643
  *p= 0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
644
1 by brian
clean slate
645
  if (uval == 0)
646
  {
647
    *--p= '0';
648
    len= 1;
649
    goto cnv;
650
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
651
151 by Brian Aker
Ulonglong to uint64_t
652
  while (uval > (uint64_t) LONG_MAX)
1 by brian
clean slate
653
  {
895 by Brian Aker
Completion (?) of uint conversion.
654
    uint64_t quo= uval/(uint32_t) 10;
655
    uint32_t rem= (uint32_t) (uval- quo* (uint32_t) 10);
1 by brian
clean slate
656
    *--p = '0' + rem;
657
    uval= quo;
658
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
659
1 by brian
clean slate
660
  long_val= (long) uval;
661
  while (long_val != 0)
662
  {
663
    long quo= long_val/10;
664
    *--p = (char) ('0' + (long_val - quo*10));
665
    long_val= quo;
666
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
667
1067.4.9 by Nathan Williams
Converted all usages of cmin/cmax in mystrings directory to use std::min/max
668
  len= min(len, (size_t) (e-p));
1 by brian
clean slate
669
cnv:
670
  memcpy(dst, p, len);
671
  return len+sign;
672
}
673
674
675
/*
676
** Compare string against string with wildcard
677
**	0 if matched
678
**	-1 if not matched with wildcard
679
**	 1 if matched with wildcard
680
*/
681
1892.6.1 by Gustaf Thorslund
Replaced some more macro functions.
682
inline static int likeconv(const charset_info_st *cs, const char c) 
683
{
1 by brian
clean slate
684
#ifdef LIKE_CMP_TOUPPER
1892.6.1 by Gustaf Thorslund
Replaced some more macro functions.
685
  return (unsigned char) my_toupper(cs, c);
1 by brian
clean slate
686
#else
1892.6.1 by Gustaf Thorslund
Replaced some more macro functions.
687
  return cs->sort_order[(unsigned char)c];
688
#endif    
689
}
690
691
692
inline static const char* inc_ptr(const charset_info_st *cs, const char *str, const char *str_end)
693
{
694
  // (Strange this macro have been used. If str_end would actually
695
  // have been used it would have made sense. /Gustaf)
696
  (void)cs;
697
  (void)str_end;
698
  return str++; 
699
}
1 by brian
clean slate
700
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
701
int my_wildcmp_8bit(const CHARSET_INFO * const cs,
1 by brian
clean slate
702
		    const char *str,const char *str_end,
703
		    const char *wildstr,const char *wildend,
704
		    int escape, int w_one, int w_many)
705
{
706
  int result= -1;			/* Not found, using wildcards */
707
708
  while (wildstr != wildend)
709
  {
710
    while (*wildstr != w_many && *wildstr != w_one)
711
    {
712
      if (*wildstr == escape && wildstr+1 != wildend)
713
	wildstr++;
714
715
      if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++))
716
	return(1);				/* No match */
717
      if (wildstr == wildend)
718
	return(str != str_end);		/* Match if both are at end */
719
      result=1;					/* Found an anchor char     */
720
    }
721
    if (*wildstr == w_one)
722
    {
723
      do
724
      {
725
	if (str == str_end)			/* Skip one char if possible */
726
	  return(result);
1892.6.1 by Gustaf Thorslund
Replaced some more macro functions.
727
	inc_ptr(cs,str,str_end);
1 by brian
clean slate
728
      } while (++wildstr < wildend && *wildstr == w_one);
729
      if (wildstr == wildend)
730
	break;
731
    }
732
    if (*wildstr == w_many)
733
    {						/* Found w_many */
481 by Brian Aker
Remove all of uchar.
734
      unsigned char cmp;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
735
1 by brian
clean slate
736
      wildstr++;
737
      /* Remove any '%' and '_' from the wild search string */
738
      for (; wildstr != wildend ; wildstr++)
739
      {
740
	if (*wildstr == w_many)
741
	  continue;
742
	if (*wildstr == w_one)
743
	{
744
	  if (str == str_end)
745
	    return(-1);
1892.6.1 by Gustaf Thorslund
Replaced some more macro functions.
746
	  inc_ptr(cs,str,str_end);
1 by brian
clean slate
747
	  continue;
748
	}
749
	break;					/* Not a wild character */
750
      }
751
      if (wildstr == wildend)
752
	return(0);				/* Ok if w_many is last */
753
      if (str == str_end)
754
	return(-1);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
755
1 by brian
clean slate
756
      if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
757
	cmp= *++wildstr;
758
1892.6.1 by Gustaf Thorslund
Replaced some more macro functions.
759
      inc_ptr(cs,wildstr,wildend);	/* This is compared trough cmp */
1 by brian
clean slate
760
      cmp=likeconv(cs,cmp);
761
      do
762
      {
481 by Brian Aker
Remove all of uchar.
763
	while (str != str_end && (unsigned char) likeconv(cs,*str) != cmp)
1 by brian
clean slate
764
	  str++;
765
	if (str++ == str_end) return(-1);
766
	{
767
	  int tmp=my_wildcmp_8bit(cs,str,str_end,wildstr,wildend,escape,w_one,
768
				  w_many);
769
	  if (tmp <= 0)
770
	    return(tmp);
771
	}
772
      } while (str != str_end && wildstr[0] != w_many);
773
      return(-1);
774
    }
775
  }
776
  return(str != str_end ? 1 : 0);
777
}
778
779
780
/*
781
** Calculate min_str and max_str that ranges a LIKE string.
782
** Arguments:
783
** ptr		Pointer to LIKE string.
784
** ptr_length	Length of LIKE string.
785
** escape	Escape character in LIKE.  (Normally '\').
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
786
**		All escape characters should be removed from
77.1.95 by Monty Taylor
Fixed silly my_bool==char nonsense.
787
**              min_str and max_str
1 by brian
clean slate
788
** res_length	Length of min_str and max_str.
789
** min_str	Smallest case sensitive string that ranges LIKE.
790
**		Should be space padded to res_length.
791
** max_str	Largest case sensitive string that ranges LIKE.
792
**		Normally padded with the biggest character sort value.
793
**
794
** The function should return 0 if ok and 1 if the LIKE string can't be
795
** optimized !
796
*/
797
276 by Brian Aker
Cleaned out my_bool from strings.
798
bool my_like_range_simple(const CHARSET_INFO * const cs,
77.1.95 by Monty Taylor
Fixed silly my_bool==char nonsense.
799
                             const char *ptr, size_t ptr_length,
800
                             char escape, char w_one, char w_many,
801
                             size_t res_length,
802
                             char *min_str,char *max_str,
803
                             size_t *min_length, size_t *max_length)
1 by brian
clean slate
804
{
805
  const char *end= ptr + ptr_length;
806
  char *min_org=min_str;
807
  char *min_end=min_str+res_length;
808
  size_t charlen= res_length / cs->mbmaxlen;
809
810
  for (; ptr != end && min_str != min_end && charlen > 0 ; ptr++, charlen--)
811
  {
812
    if (*ptr == escape && ptr+1 != end)
813
    {
814
      ptr++;					/* Skip escape */
815
      *min_str++= *max_str++ = *ptr;
816
      continue;
817
    }
818
    if (*ptr == w_one)				/* '_' in SQL */
819
    {
820
      *min_str++='\0';				/* This should be min char */
821
      *max_str++= (char) cs->max_sort_char;
822
      continue;
823
    }
824
    if (*ptr == w_many)				/* '%' in SQL */
825
    {
826
      /* Calculate length of keys */
827
      *min_length= ((cs->state & MY_CS_BINSORT) ?
828
                    (size_t) (min_str - min_org) :
829
                    res_length);
830
      *max_length= res_length;
831
      do
832
      {
833
	*min_str++= 0;
834
	*max_str++= (char) cs->max_sort_char;
835
      } while (min_str != min_end);
836
      return 0;
837
    }
838
    *min_str++= *max_str++ = *ptr;
839
  }
840
841
 *min_length= *max_length = (size_t) (min_str - min_org);
842
  while (min_str != min_end)
843
    *min_str++= *max_str++ = ' ';      /* Because if key compression */
844
  return 0;
845
}
846
847
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
848
size_t my_scan_8bit(const CHARSET_INFO * const cs, const char *str, const char *end, int sq)
1 by brian
clean slate
849
{
850
  const char *str0= str;
851
  switch (sq)
852
  {
853
  case MY_SEQ_INTTAIL:
854
    if (*str == '.')
855
    {
575.3.1 by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found.
856
      for(str++ ; str != end && *str == '0' ; str++) {}
1 by brian
clean slate
857
      return (size_t) (str - str0);
858
    }
859
    return 0;
860
861
  case MY_SEQ_SPACES:
862
    for ( ; str < end ; str++)
863
    {
864
      if (!my_isspace(cs,*str))
865
        break;
866
    }
867
    return (size_t) (str - str0);
868
  default:
869
    return 0;
870
  }
871
}
872
873
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
874
void my_fill_8bit(const CHARSET_INFO * const,
875
		  char *s, size_t l, int fill)
1 by brian
clean slate
876
{
212.6.15 by Mats Kindahl
Removing redundant use of casts in mystrings/ for memcmp(), memcpy(), memset(), and memmove().
877
  memset(s, fill, l);
1 by brian
clean slate
878
}
879
880
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
881
size_t my_numchars_8bit(const CHARSET_INFO * const,
882
		        const char *b, const char *e)
1 by brian
clean slate
883
{
884
  return (size_t) (e - b);
885
}
886
887
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
888
size_t my_numcells_8bit(const CHARSET_INFO * const,
1 by brian
clean slate
889
                        const char *b, const char *e)
890
{
891
  return (size_t) (e - b);
892
}
893
894
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
895
size_t my_charpos_8bit(const CHARSET_INFO * const,
896
                       const char *, const char *, size_t pos)
1 by brian
clean slate
897
{
898
  return pos;
899
}
900
901
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
902
size_t my_well_formed_len_8bit(const CHARSET_INFO * const,
1 by brian
clean slate
903
                               const char *start, const char *end,
904
                               size_t nchars, int *error)
905
{
906
  size_t nbytes= (size_t) (end-start);
907
  *error= 0;
1067.4.9 by Nathan Williams
Converted all usages of cmin/cmax in mystrings directory to use std::min/max
908
  return min(nbytes, nchars);
1 by brian
clean slate
909
}
910
911
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
912
size_t my_lengthsp_8bit(const CHARSET_INFO * const,
1 by brian
clean slate
913
                        const char *ptr, size_t length)
914
{
915
  const char *end;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
916
  end= (const char *) internal::skip_trailing_space((const unsigned char *)ptr, length);
1 by brian
clean slate
917
  return (size_t) (end-ptr);
918
}
919
920
482 by Brian Aker
Remove uint.
921
uint32_t my_instr_simple(const CHARSET_INFO * const cs,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
922
                     const char *b, size_t b_length,
1 by brian
clean slate
923
                     const char *s, size_t s_length,
482 by Brian Aker
Remove uint.
924
                     my_match_t *match, uint32_t nmatch)
1 by brian
clean slate
925
{
481 by Brian Aker
Remove all of uchar.
926
  register const unsigned char *str, *search, *end, *search_end;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
927
1 by brian
clean slate
928
  if (s_length <= b_length)
929
  {
930
    if (!s_length)
931
    {
932
      if (nmatch)
933
      {
934
        match->beg= 0;
935
        match->end= 0;
936
        match->mb_len= 0;
937
      }
938
      return 1;		/* Empty string is always found */
939
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
940
481 by Brian Aker
Remove all of uchar.
941
    str= (const unsigned char*) b;
942
    search= (const unsigned char*) s;
943
    end= (const unsigned char*) b+b_length-s_length+1;
944
    search_end= (const unsigned char*) s + s_length;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
945
1 by brian
clean slate
946
skip:
947
    while (str != end)
948
    {
949
      if (cs->sort_order[*str++] == cs->sort_order[*search])
950
      {
481 by Brian Aker
Remove all of uchar.
951
	register const unsigned char *i,*j;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
952
953
	i= str;
1 by brian
clean slate
954
	j= search+1;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
955
1 by brian
clean slate
956
	while (j != search_end)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
957
	  if (cs->sort_order[*i++] != cs->sort_order[*j++])
1 by brian
clean slate
958
            goto skip;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
959
1 by brian
clean slate
960
	if (nmatch > 0)
961
	{
962
	  match[0].beg= 0;
481 by Brian Aker
Remove all of uchar.
963
	  match[0].end= (size_t) (str- (const unsigned char*)b-1);
1 by brian
clean slate
964
	  match[0].mb_len= match[0].end;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
965
1 by brian
clean slate
966
	  if (nmatch > 1)
967
	  {
968
	    match[1].beg= match[0].end;
969
	    match[1].end= match[0].end+s_length;
970
	    match[1].mb_len= match[1].end-match[1].beg;
971
	  }
972
	}
973
	return 2;
974
      }
975
    }
976
  }
977
  return 0;
978
}
979
980
981
typedef struct
982
{
983
  int		nchars;
984
  MY_UNI_IDX	uidx;
985
} uni_idx;
986
987
#define PLANE_SIZE	0x100
988
#define PLANE_NUM	0x100
1892.6.1 by Gustaf Thorslund
Replaced some more macro functions.
989
inline static int plane_number(uint16_t x)
990
{
991
  return ((x >> 8) % PLANE_NUM);
992
}
1 by brian
clean slate
993
994
static int pcmp(const void * f, const void * s)
995
{
996
  const uni_idx *F= (const uni_idx*) f;
997
  const uni_idx *S= (const uni_idx*) s;
998
  int res;
999
1000
  if (!(res=((S->nchars)-(F->nchars))))
1001
    res=((F->uidx.from)-(S->uidx.to));
1002
  return res;
1003
}
1004
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
1005
static bool create_fromuni(CHARSET_INFO *cs, cs_alloc_func alloc)
1 by brian
clean slate
1006
{
1007
  uni_idx	idx[PLANE_NUM];
1008
  int		i,n;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1009
1 by brian
clean slate
1010
  /*
1011
    Check that Unicode map is loaded.
1012
    It can be not loaded when the collation is
1013
    listed in Index.xml but not specified
1014
    in the character set specific XML file.
1015
  */
1016
  if (!cs->tab_to_uni)
163 by Brian Aker
Merge Monty's code.
1017
    return true;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1018
1 by brian
clean slate
1019
  /* Clear plane statistics */
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
1020
  memset(idx, 0, sizeof(idx));
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1021
1 by brian
clean slate
1022
  /* Count number of characters in each plane */
1023
  for (i=0; i< 0x100; i++)
1024
  {
206 by Brian Aker
Removed final uint dead types.
1025
    uint16_t wc=cs->tab_to_uni[i];
1892.6.1 by Gustaf Thorslund
Replaced some more macro functions.
1026
    int pl= plane_number(wc);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1027
1 by brian
clean slate
1028
    if (wc || !i)
1029
    {
1030
      if (!idx[pl].nchars)
1031
      {
1032
        idx[pl].uidx.from=wc;
1033
        idx[pl].uidx.to=wc;
1034
      }else
1035
      {
1036
        idx[pl].uidx.from=wc<idx[pl].uidx.from?wc:idx[pl].uidx.from;
1037
        idx[pl].uidx.to=wc>idx[pl].uidx.to?wc:idx[pl].uidx.to;
1038
      }
1039
      idx[pl].nchars++;
1040
    }
1041
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1042
1 by brian
clean slate
1043
  /* Sort planes in descending order */
1044
  qsort(&idx,PLANE_NUM,sizeof(uni_idx),&pcmp);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1045
1 by brian
clean slate
1046
  for (i=0; i < PLANE_NUM; i++)
1047
  {
1048
    int ch,numchars;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1049
1 by brian
clean slate
1050
    /* Skip empty plane */
1051
    if (!idx[i].nchars)
1052
      break;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1053
1 by brian
clean slate
1054
    numchars=idx[i].uidx.to-idx[i].uidx.from+1;
481 by Brian Aker
Remove all of uchar.
1055
    if (!(idx[i].uidx.tab=(unsigned char*) alloc(numchars * sizeof(*idx[i].uidx.tab))))
163 by Brian Aker
Merge Monty's code.
1056
      return true;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1057
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
1058
    memset(idx[i].uidx.tab, 0, numchars*sizeof(*idx[i].uidx.tab));
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1059
1 by brian
clean slate
1060
    for (ch=1; ch < PLANE_SIZE; ch++)
1061
    {
206 by Brian Aker
Removed final uint dead types.
1062
      uint16_t wc=cs->tab_to_uni[ch];
1 by brian
clean slate
1063
      if (wc >= idx[i].uidx.from && wc <= idx[i].uidx.to && wc)
1064
      {
1065
        int ofs= wc - idx[i].uidx.from;
1066
        idx[i].uidx.tab[ofs]= ch;
1067
      }
1068
    }
1069
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1070
1 by brian
clean slate
1071
  /* Allocate and fill reverse table for each plane */
1072
  n=i;
1073
  if (!(cs->tab_from_uni= (MY_UNI_IDX*) alloc(sizeof(MY_UNI_IDX)*(n+1))))
163 by Brian Aker
Merge Monty's code.
1074
    return true;
1 by brian
clean slate
1075
1076
  for (i=0; i< n; i++)
1077
    cs->tab_from_uni[i]= idx[i].uidx;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1078
1 by brian
clean slate
1079
  /* Set end-of-list marker */
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
1080
  memset(&cs->tab_from_uni[i], 0, sizeof(MY_UNI_IDX));
163 by Brian Aker
Merge Monty's code.
1081
  return false;
1 by brian
clean slate
1082
}
1083
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
1084
bool my_cset_init_8bit(CHARSET_INFO *cs, cs_alloc_func alloc)
1 by brian
clean slate
1085
{
1086
  cs->caseup_multiply= 1;
1087
  cs->casedn_multiply= 1;
1088
  cs->pad_char= ' ';
1089
  return create_fromuni(cs, alloc);
1090
}
1091
1092
static void set_max_sort_char(CHARSET_INFO *cs)
1093
{
481 by Brian Aker
Remove all of uchar.
1094
  unsigned char max_char;
482 by Brian Aker
Remove uint.
1095
  uint32_t  i;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1096
1 by brian
clean slate
1097
  if (!cs->sort_order)
1098
    return;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1099
481 by Brian Aker
Remove all of uchar.
1100
  max_char=cs->sort_order[(unsigned char) cs->max_sort_char];
1 by brian
clean slate
1101
  for (i= 0; i < 256; i++)
1102
  {
481 by Brian Aker
Remove all of uchar.
1103
    if ((unsigned char) cs->sort_order[i] > max_char)
1 by brian
clean slate
1104
    {
481 by Brian Aker
Remove all of uchar.
1105
      max_char=(unsigned char) cs->sort_order[i];
1 by brian
clean slate
1106
      cs->max_sort_char= i;
1107
    }
1108
  }
1109
}
1110
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
1111
bool my_coll_init_simple(CHARSET_INFO *cs, cs_alloc_func)
1 by brian
clean slate
1112
{
1113
  set_max_sort_char(cs);
163 by Brian Aker
Merge Monty's code.
1114
  return false;
1 by brian
clean slate
1115
}
1116
1117
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
1118
int64_t my_strtoll10_8bit(const CHARSET_INFO * const,
1119
                          const char *nptr, char **endptr, int *error)
1 by brian
clean slate
1120
{
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1121
  return internal::my_strtoll10(nptr, endptr, error);
1 by brian
clean slate
1122
}
1123
1124
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
1125
int my_mb_ctype_8bit(const CHARSET_INFO * const cs, int *ctype,
481 by Brian Aker
Remove all of uchar.
1126
                   const unsigned char *s, const unsigned char *e)
1 by brian
clean slate
1127
{
1128
  if (s >= e)
1129
  {
1130
    *ctype= 0;
1131
    return MY_CS_TOOSMALL;
1132
  }
1133
  *ctype= cs->ctype[*s + 1];
1134
  return 1;
1135
}
1136
1137
163 by Brian Aker
Merge Monty's code.
1138
#undef  UINT64_MAX
1139
#define UINT64_MAX           (~(uint64_t) 0)
1 by brian
clean slate
1140
163 by Brian Aker
Merge Monty's code.
1141
#define CUTOFF  (UINT64_MAX / 10)
1142
#define CUTLIM  (UINT64_MAX % 10)
1 by brian
clean slate
1143
#define DIGITS_IN_ULONGLONG 20
1144
151 by Brian Aker
Ulonglong to uint64_t
1145
static uint64_t d10[DIGITS_IN_ULONGLONG]=
1 by brian
clean slate
1146
{
1147
  1,
1148
  10,
1149
  100,
1150
  1000,
1151
  10000,
1152
  100000,
1153
  1000000,
1154
  10000000,
1155
  100000000,
1156
  1000000000,
1157
  10000000000ULL,
1158
  100000000000ULL,
1159
  1000000000000ULL,
1160
  10000000000000ULL,
1161
  100000000000000ULL,
1162
  1000000000000000ULL,
1163
  10000000000000000ULL,
1164
  100000000000000000ULL,
1165
  1000000000000000000ULL,
1166
  10000000000000000000ULL
1167
};
1168
1169
1170
/*
1171
481.1.2 by Monty Taylor
Replaced all unsigned long long with uint64_t.
1172
  Convert a string to uint64_t integer value
1 by brian
clean slate
1173
  with rounding.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1174
1 by brian
clean slate
1175
  SYNOPSYS
1176
    my_strntoull10_8bit()
1177
      cs              in      pointer to character set
1178
      str             in      pointer to the string to be converted
1179
      length          in      string length
1180
      unsigned_flag   in      whether the number is unsigned
1181
      endptr          out     pointer to the stop character
1182
      error           out     returned error code
1183
1184
  DESCRIPTION
1185
    This function takes the decimal representation of integer number
1186
    from string str and converts it to an signed or unsigned
481.1.3 by Monty Taylor
Replaced long long with int64_t.
1187
    int64_t value.
1 by brian
clean slate
1188
    Space characters and tab are ignored.
1189
    A sign character might precede the digit characters.
1190
    The number may have any number of pre-zero digits.
1191
    The number may have decimal point and exponent.
1192
    Rounding is always done in "away from zero" style:
1193
      0.5  ->   1
1194
     -0.5  ->  -1
1195
1196
    The function stops reading the string str after "length" bytes
1197
    or at the first character that is not a part of correct number syntax:
1198
1199
    <signed numeric literal> ::=
1200
      [ <sign> ] <exact numeric literal> [ E [ <sign> ] <unsigned integer> ]
1201
1202
    <exact numeric literal> ::=
1203
                        <unsigned integer> [ <period> [ <unsigned integer> ] ]
1204
                      | <period> <unsigned integer>
1205
    <unsigned integer>   ::= <digit>...
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1206
1 by brian
clean slate
1207
  RETURN VALUES
152 by Brian Aker
longlong replacement
1208
    Value of string as a signed/unsigned int64_t integer
1 by brian
clean slate
1209
1210
    endptr cannot be NULL. The function will store the end pointer
1211
    to the stop character here.
1212
1213
    The error parameter contains information how things went:
1214
    0	     ok
1215
    ERANGE   If the the value of the converted number is out of range
1216
    In this case the return value is:
163 by Brian Aker
Merge Monty's code.
1217
    - UINT64_MAX if unsigned_flag and the number was too big
1 by brian
clean slate
1218
    - 0 if unsigned_flag and the number was negative
163 by Brian Aker
Merge Monty's code.
1219
    - INT64_MAX if no unsigned_flag and the number is too big
1220
    - INT64_MIN if no unsigned_flag and the number it too big negative
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1221
1 by brian
clean slate
1222
    EDOM If the string didn't contain any digits.
1223
    In this case the return value is 0.
1224
*/
1225
151 by Brian Aker
Ulonglong to uint64_t
1226
uint64_t
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
1227
my_strntoull10rnd_8bit(const CHARSET_INFO * const,
1 by brian
clean slate
1228
                       const char *str, size_t length, int unsigned_flag,
1229
                       char **endptr, int *error)
1230
{
1231
  const char *dot, *end9, *beg, *end= str + length;
151 by Brian Aker
Ulonglong to uint64_t
1232
  uint64_t ull;
1 by brian
clean slate
1233
  ulong ul;
481 by Brian Aker
Remove all of uchar.
1234
  unsigned char ch;
1 by brian
clean slate
1235
  int shift= 0, digits= 0, negative, addon;
1236
1237
  /* Skip leading spaces and tabs */
575.3.1 by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found.
1238
  for ( ; str < end && (*str == ' ' || *str == '\t') ; str++) {}
1 by brian
clean slate
1239
1240
  if (str >= end)
1241
    goto ret_edom;
1242
1243
  if ((negative= (*str == '-')) || *str=='+') /* optional sign */
1244
  {
1245
    if (++str == end)
1246
      goto ret_edom;
1247
  }
1248
1249
  beg= str;
1250
  end9= (str + 9) > end ? end : (str + 9);
1251
  /* Accumulate small number into ulong, for performance purposes */
481 by Brian Aker
Remove all of uchar.
1252
  for (ul= 0 ; str < end9 && (ch= (unsigned char) (*str - '0')) < 10; str++)
1 by brian
clean slate
1253
  {
1254
    ul= ul * 10 + ch;
1255
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1256
1 by brian
clean slate
1257
  if (str >= end) /* Small number without dots and expanents */
1258
  {
1259
    *endptr= (char*) str;
1260
    if (negative)
1261
    {
1262
      if (unsigned_flag)
1263
      {
236.1.31 by Monty Taylor
Re-remove mysys header from mystrings.
1264
        *error= ul ? ERANGE : 0;
1 by brian
clean slate
1265
        return 0;
1266
      }
1267
      else
1268
      {
1269
        *error= 0;
152 by Brian Aker
longlong replacement
1270
        return (uint64_t) (int64_t) -(long) ul;
1 by brian
clean slate
1271
      }
1272
    }
1273
    else
1274
    {
1275
      *error=0;
151 by Brian Aker
Ulonglong to uint64_t
1276
      return (uint64_t) ul;
1 by brian
clean slate
1277
    }
1278
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1279
1 by brian
clean slate
1280
  digits= str - beg;
1281
151 by Brian Aker
Ulonglong to uint64_t
1282
  /* Continue to accumulate into uint64_t */
1 by brian
clean slate
1283
  for (dot= NULL, ull= ul; str < end; str++)
1284
  {
481 by Brian Aker
Remove all of uchar.
1285
    if ((ch= (unsigned char) (*str - '0')) < 10)
1 by brian
clean slate
1286
    {
1287
      if (ull < CUTOFF || (ull == CUTOFF && ch <= CUTLIM))
1288
      {
1289
        ull= ull * 10 + ch;
1290
        digits++;
1291
        continue;
1292
      }
1293
      /*
1294
        Adding the next digit would overflow.
1295
        Remember the next digit in "addon", for rounding.
1296
        Scan all digits with an optional single dot.
1297
      */
1298
      if (ull == CUTOFF)
1299
      {
163 by Brian Aker
Merge Monty's code.
1300
        ull= UINT64_MAX;
1 by brian
clean slate
1301
        addon= 1;
1302
        str++;
1303
      }
1304
      else
1305
        addon= (*str >= '5');
1306
      if (!dot)
1307
      {
575.3.1 by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found.
1308
        for ( ; str < end && (ch= (unsigned char) (*str - '0')) < 10; shift++, str++) {}
1 by brian
clean slate
1309
        if (str < end && *str == '.')
1310
        {
1311
          str++;
575.3.1 by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found.
1312
          for ( ; str < end && (ch= (unsigned char) (*str - '0')) < 10; str++) {}
1 by brian
clean slate
1313
        }
1314
      }
1315
      else
1316
      {
1317
        shift= dot - str;
575.3.1 by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found.
1318
        for ( ; str < end && (ch= (unsigned char) (*str - '0')) < 10; str++) {}
1 by brian
clean slate
1319
      }
1320
      goto exp;
1321
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1322
1 by brian
clean slate
1323
    if (*str == '.')
1324
    {
1325
      if (dot)
1326
      {
1327
        /* The second dot character */
1328
        addon= 0;
1329
        goto exp;
1330
      }
1331
      else
1332
      {
1333
        dot= str + 1;
1334
      }
1335
      continue;
1336
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1337
1 by brian
clean slate
1338
    /* Unknown character, exit the loop */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1339
    break;
1 by brian
clean slate
1340
  }
1341
  shift= dot ? dot - str : 0; /* Right shift */
1342
  addon= 0;
1343
1344
exp:    /* [ E [ <sign> ] <unsigned integer> ] */
1345
1346
  if (!digits)
1347
  {
1348
    str= beg;
1349
    goto ret_edom;
1350
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1351
1 by brian
clean slate
1352
  if (str < end && (*str == 'e' || *str == 'E'))
1353
  {
1354
    str++;
1355
    if (str < end)
1356
    {
1357
      int negative_exp, exponent;
1358
      if ((negative_exp= (*str == '-')) || *str=='+')
1359
      {
1360
        if (++str == end)
1361
          goto ret_sign;
1362
      }
1363
      for (exponent= 0 ;
481 by Brian Aker
Remove all of uchar.
1364
           str < end && (ch= (unsigned char) (*str - '0')) < 10;
1 by brian
clean slate
1365
           str++)
1366
      {
1367
        exponent= exponent * 10 + ch;
1368
      }
1369
      shift+= negative_exp ? -exponent : exponent;
1370
    }
1371
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1372
1 by brian
clean slate
1373
  if (shift == 0) /* No shift, check addon digit */
1374
  {
1375
    if (addon)
1376
    {
163 by Brian Aker
Merge Monty's code.
1377
      if (ull == UINT64_MAX)
1 by brian
clean slate
1378
        goto ret_too_big;
1379
      ull++;
1380
    }
1381
    goto ret_sign;
1382
  }
1383
1384
  if (shift < 0) /* Right shift */
1385
  {
151 by Brian Aker
Ulonglong to uint64_t
1386
    uint64_t d, r;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1387
1 by brian
clean slate
1388
    if (-shift >= DIGITS_IN_ULONGLONG)
1389
      goto ret_zero; /* Exponent is a big negative number, return 0 */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1390
1 by brian
clean slate
1391
    d= d10[-shift];
1392
    r= (ull % d) * 2;
1393
    ull /= d;
1394
    if (r >= d)
1395
      ull++;
1396
    goto ret_sign;
1397
  }
1398
1399
  if (shift > DIGITS_IN_ULONGLONG) /* Huge left shift */
1400
  {
1401
    if (!ull)
1402
      goto ret_sign;
1403
    goto ret_too_big;
1404
  }
1405
1406
  for ( ; shift > 0; shift--, ull*= 10) /* Left shift */
1407
  {
1408
    if (ull > CUTOFF)
1409
      goto ret_too_big; /* Overflow, number too big */
1410
  }
1411
1412
ret_sign:
1413
  *endptr= (char*) str;
1414
1415
  if (!unsigned_flag)
1416
  {
1417
    if (negative)
1418
    {
163 by Brian Aker
Merge Monty's code.
1419
      if (ull > (uint64_t) INT64_MIN)
1 by brian
clean slate
1420
      {
236.1.31 by Monty Taylor
Re-remove mysys header from mystrings.
1421
        *error= ERANGE;
163 by Brian Aker
Merge Monty's code.
1422
        return (uint64_t) INT64_MIN;
1 by brian
clean slate
1423
      }
1424
      *error= 0;
152 by Brian Aker
longlong replacement
1425
      return (uint64_t) -(int64_t) ull;
1 by brian
clean slate
1426
    }
1427
    else
1428
    {
163 by Brian Aker
Merge Monty's code.
1429
      if (ull > (uint64_t) INT64_MAX)
1 by brian
clean slate
1430
      {
236.1.31 by Monty Taylor
Re-remove mysys header from mystrings.
1431
        *error= ERANGE;
163 by Brian Aker
Merge Monty's code.
1432
        return (uint64_t) INT64_MAX;
1 by brian
clean slate
1433
      }
1434
      *error= 0;
1435
      return ull;
1436
    }
1437
  }
1438
1439
  /* Unsigned number */
1440
  if (negative && ull)
1441
  {
236.1.31 by Monty Taylor
Re-remove mysys header from mystrings.
1442
    *error= ERANGE;
1 by brian
clean slate
1443
    return 0;
1444
  }
1445
  *error= 0;
1446
  return ull;
1447
1448
ret_zero:
1449
  *endptr= (char*) str;
1450
  *error= 0;
1451
  return 0;
1452
1453
ret_edom:
1454
  *endptr= (char*) str;
236.1.31 by Monty Taylor
Re-remove mysys header from mystrings.
1455
  *error= EDOM;
1 by brian
clean slate
1456
  return 0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1457
1 by brian
clean slate
1458
ret_too_big:
1459
  *endptr= (char*) str;
236.1.31 by Monty Taylor
Re-remove mysys header from mystrings.
1460
  *error= ERANGE;
1 by brian
clean slate
1461
  return unsigned_flag ?
163 by Brian Aker
Merge Monty's code.
1462
         UINT64_MAX :
1463
         negative ? (uint64_t) INT64_MIN : (uint64_t) INT64_MAX;
1 by brian
clean slate
1464
}
1465
1466
1467
/*
1468
  Check if a constant can be propagated
1469
1470
  SYNOPSIS:
1471
    my_propagate_simple()
1472
    cs		Character set information
1473
    str		String to convert to double
1474
    length	Optional length for string.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1475
1 by brian
clean slate
1476
  NOTES:
1477
   Takes the string in the given charset and check
1478
   if it can be safely propagated in the optimizer.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1479
1 by brian
clean slate
1480
   create table t1 (
1481
     s char(5) character set latin1 collate latin1_german2_ci);
1482
   insert into t1 values (0xf6); -- o-umlaut
1483
   select * from t1 where length(s)=1 and s='oe';
1484
1485
   The above query should return one row.
1486
   We cannot convert this query into:
1487
   select * from t1 where length('oe')=1 and s='oe';
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1488
1 by brian
clean slate
1489
   Currently we don't check the constant itself,
1490
   and decide not to propagate a constant
1491
   just if the collation itself allows tricky things
1492
   like expansions and contractions. In the future
1493
   we can write a more sophisticated functions to
1494
   check the constants. For example, 'oa' can always
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1495
   be safety propagated in German2 because unlike
1 by brian
clean slate
1496
   'oe' it does not have any special meaning.
1497
1498
  RETURN
1499
    1 if constant can be safely propagated
1500
    0 if it is not safe to propagate the constant
1501
*/
1502
1503
1504
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
1505
bool my_propagate_simple(const CHARSET_INFO * const, const unsigned char *,
1506
                         size_t)
1 by brian
clean slate
1507
{
1508
  return 1;
1509
}
1510
1511
632.1.10 by Monty Taylor
Got rid of Sun Studio warnings.
1512
bool my_propagate_complex(const CHARSET_INFO * const, const unsigned char *,
1513
                          size_t)
1 by brian
clean slate
1514
{
1515
  return 0;
1516
}
1517
1518
1519
1520
/*
1521
  Normalize strxfrm flags
1522
1523
  SYNOPSIS:
1524
    my_strxfrm_flag_normalize()
1525
    flags    - non-normalized flags
1526
    nlevels  - number of levels
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1527
1 by brian
clean slate
1528
  NOTES:
1529
    If levels are omitted, then 1-maximum is assumed.
1530
    If any level number is greater than the maximum,
1531
    it is treated as the maximum.
1532
1533
  RETURN
1534
    normalized flags
1535
*/
1536
482 by Brian Aker
Remove uint.
1537
uint32_t my_strxfrm_flag_normalize(uint32_t flags, uint32_t maximum)
1 by brian
clean slate
1538
{
51.3.9 by Jay Pipes
Removal of DBUG from strings/ library
1539
  assert(maximum >= 1 && maximum <= MY_STRXFRM_NLEVELS);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1540
1 by brian
clean slate
1541
  /* If levels are omitted, then 1-maximum is assumed*/
1542
  if (!(flags & MY_STRXFRM_LEVEL_ALL))
1543
  {
482 by Brian Aker
Remove uint.
1544
    static uint32_t def_level_flags[]= {0, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F };
1545
    uint32_t flag_pad= flags & MY_STRXFRM_PAD_WITH_SPACE;
1 by brian
clean slate
1546
    flags= def_level_flags[maximum] | flag_pad;
1547
  }
1548
  else
1549
  {
482 by Brian Aker
Remove uint.
1550
    uint32_t i;
1551
    uint32_t flag_lev= flags & MY_STRXFRM_LEVEL_ALL;
1552
    uint32_t flag_dsc= (flags >> MY_STRXFRM_DESC_SHIFT) & MY_STRXFRM_LEVEL_ALL;
1553
    uint32_t flag_rev= (flags >> MY_STRXFRM_REVERSE_SHIFT) & MY_STRXFRM_LEVEL_ALL;
1554
    uint32_t flag_pad= flags & MY_STRXFRM_PAD_WITH_SPACE;
1 by brian
clean slate
1555
1556
    /*
1557
      If any level number is greater than the maximum,
1558
      it is treated as the maximum.
1559
    */
1560
    for (maximum--, flags= 0, i= 0; i < MY_STRXFRM_NLEVELS; i++)
1561
    {
482 by Brian Aker
Remove uint.
1562
      uint32_t src_bit= 1 << i;
1067.4.9 by Nathan Williams
Converted all usages of cmin/cmax in mystrings directory to use std::min/max
1563
      uint32_t dst_bit= 1 << min(i, maximum);
1 by brian
clean slate
1564
      if (flag_lev & src_bit)
1565
      {
1566
        flags|= dst_bit;
1567
        flags|= (flag_dsc & dst_bit) << MY_STRXFRM_DESC_SHIFT;
1568
        flags|= (flag_rev & dst_bit) << MY_STRXFRM_REVERSE_SHIFT;
1569
      }
1570
      else
1571
      {
1572
        /* Check that there are no DESC or REVERSE flag for skipped level */
51.3.9 by Jay Pipes
Removal of DBUG from strings/ library
1573
        assert(!(flag_dsc & src_bit) && !(flag_rev & src_bit));
1 by brian
clean slate
1574
      }
1575
    }
1576
    flags|= flag_pad;
1577
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1578
1 by brian
clean slate
1579
  return flags;
1580
}
1581
1582
/*
1583
  Apply DESC and REVERSE collation rules.
1584
1585
  SYNOPSIS:
1586
    my_strxfrm_desc_and_reverse()
1587
    str      - pointer to string
1588
    strend   - end of string
1589
    flags    - flags
1590
    level    - which level, starting from 0.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1591
1 by brian
clean slate
1592
  NOTES:
1593
    Apply DESC or REVERSE or both flags.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1594
1 by brian
clean slate
1595
    If DESC flag is given, then the weights
1596
    come out NOTed or negated for that level.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1597
1 by brian
clean slate
1598
    If REVERSE flags is given, then the weights come out in
1599
    reverse order for that level, that is, starting with
1600
    the last character and ending with the first character.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1601
1 by brian
clean slate
1602
    If nether DESC nor REVERSE flags are give,
1603
    the string is not changed.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1604
1 by brian
clean slate
1605
*/
481 by Brian Aker
Remove all of uchar.
1606
void my_strxfrm_desc_and_reverse(unsigned char *str, unsigned char *strend,
482 by Brian Aker
Remove uint.
1607
                                 uint32_t flags, uint32_t level)
1 by brian
clean slate
1608
{
1609
  if (flags & (MY_STRXFRM_DESC_LEVEL1 << level))
1610
  {
1611
    if (flags & (MY_STRXFRM_REVERSE_LEVEL1 << level))
1612
    {
1613
      for (strend--; str <= strend;)
1614
      {
481 by Brian Aker
Remove all of uchar.
1615
        unsigned char tmp= *str;
1 by brian
clean slate
1616
        *str++= ~*strend;
1617
        *strend--= ~tmp;
1618
      }
1619
    }
1620
    else
1621
    {
1622
      for (; str < strend; str++)
1623
        *str= ~*str;
1624
    }
1625
  }
1626
  else if (flags & (MY_STRXFRM_REVERSE_LEVEL1 << level))
1627
  {
1628
    for (strend--; str < strend;)
1629
    {
481 by Brian Aker
Remove all of uchar.
1630
      unsigned char tmp= *str;
1 by brian
clean slate
1631
      *str++= *strend;
1632
      *strend--= tmp;
1633
    }
1634
  }
1635
}
1636
1637
1638
size_t
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
1639
my_strxfrm_pad_desc_and_reverse(const CHARSET_INFO * const cs,
481 by Brian Aker
Remove all of uchar.
1640
                                unsigned char *str, unsigned char *frmend, unsigned char *strend,
482 by Brian Aker
Remove uint.
1641
                                uint32_t nweights, uint32_t flags, uint32_t level)
1 by brian
clean slate
1642
{
1643
  if (nweights && frmend < strend && (flags & MY_STRXFRM_PAD_WITH_SPACE))
1644
  {
1067.4.9 by Nathan Williams
Converted all usages of cmin/cmax in mystrings directory to use std::min/max
1645
    uint32_t fill_length= min((uint32_t) (strend - frmend), nweights * cs->mbminlen);
1 by brian
clean slate
1646
    cs->cset->fill(cs, (char*) frmend, fill_length, cs->pad_char);
1647
    frmend+= fill_length;
1648
  }
1649
  my_strxfrm_desc_and_reverse(str, frmend, flags, level);
1650
  return frmend - str;
1651
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1652
1653
} /* namespace drizzled */