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