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