34
30
#include <string.h>
33
/* need by my_vsnprintf */
40
/* This is needed for the definitions of bzero... on solaris */
41
#if defined(HAVE_STRINGS_H)
44
45
/* This is needed for the definitions of memcpy... on solaris */
45
46
#if defined(HAVE_MEMORY_H) && !defined(__cplusplus)
46
47
#include <memory.h>
50
#if !defined(HAVE_MEMCPY) && !defined(HAVE_MEMMOVE)
51
# define memcpy(d, s, n) bcopy ((s), (d), (n))
52
# define memset(A,C,B) bfill((A),(B),(C))
53
# define memmove(d, s, n) bmove ((d), (s), (n))
54
#elif defined(HAVE_MEMMOVE)
55
# define bmove(d, s, n) memmove((d), (s), (n))
57
# define memmove(d, s, n) bmove((d), (s), (n)) /* our bmove */
61
#if !defined(HAVE_BFILL)
62
# define bfill(A,B,C) memset((A),(C),(B))
63
# define bmove_align(A,B,C) memcpy((A),(B),(C))
66
#if !defined(HAVE_BCMP)
67
# define bcopy(s, d, n) memcpy((d), (s), (n))
68
# define bcmp(A,B,C) memcmp((A),(B),(C))
69
# define bzero(A,B) memset((A),0,(B))
70
# define bmove_align(A,B,C) memcpy((A),(B),(C))
49
73
#if defined(__cplusplus)
57
81
extern void *(*my_str_malloc)(size_t);
58
82
extern void (*my_str_free)(void *);
60
char *my_stpncpy(register char *dst, register const char *src, size_t n);
61
char *my_stpcpy(register char *dst, register const char *src);
63
#define strmov_overlapp(A,B) my_stpcpy(A,B)
84
#if defined(HAVE_STPCPY)
85
#define strmov(A,B) stpcpy((A),(B))
88
/* Declared in int2str() */
89
extern char _dig_vec_upper[];
90
extern char _dig_vec_lower[];
92
#ifdef BAD_STRING_COMPILER
93
#define strmov(A,B) (memccpy(A,B,0,INT_MAX)-1)
95
#define strmov_overlapp(A,B) strmov(A,B)
64
96
#define strmake_overlapp(A,B,C) strmake(A,B,C)
66
extern void bmove_upp(unsigned char *dst,const unsigned char *src,size_t len);
68
extern void bchange(unsigned char *dst,size_t old_len,const unsigned char *src,
99
#ifdef BAD_MEMCPY /* Problem with gcc on Alpha */
100
#define memcpy_fixed(A,B,C) bmove((A),(B),(C))
102
#define memcpy_fixed(A,B,C) memcpy((A),(B),(C))
105
#if (!defined(USE_BMOVE512) || defined(HAVE_purify)) && !defined(bmove512)
106
#define bmove512(A,B,C) memcpy(A,B,C)
109
/* Prototypes for string functions */
111
#if !defined(bfill) && !defined(HAVE_BFILL)
112
extern void bfill(uchar *dst,size_t len,pchar fill);
115
#if !defined(bzero) && !defined(HAVE_BZERO)
116
extern void bzero(uchar * dst,size_t len);
119
#if !defined(bcmp) && !defined(HAVE_BCMP)
120
extern size_t bcmp(const uchar *s1,const uchar *s2,size_t len);
123
extern size_t my_bcmp(const uchar *s1,const uchar *s2,size_t len);
125
#define bcmp(A,B,C) my_bcmp((A),(B),(C))
126
#define bzero_if_purify(A,B) bzero(A,B)
128
#define bzero_if_purify(A,B)
129
#endif /* HAVE_purify */
132
extern void bmove512(uchar *dst,const uchar *src,size_t len);
135
#if !defined(HAVE_BMOVE) && !defined(bmove)
136
extern void bmove(uuchar *dst, const uchar *src,size_t len);
139
extern void bmove_upp(uchar *dst,const uchar *src,size_t len);
140
extern void bchange(uchar *dst,size_t old_len,const uchar *src,
69
141
size_t new_len,size_t tot_len);
142
extern void strappend(char *s,size_t len,pchar fill);
143
extern char *strend(const char *s);
144
extern char *strcend(const char *, pchar);
70
145
extern char *strfield(char *src,int fields,int chars,int blanks,
72
extern char *strfill(char * s,size_t len,char fill);
147
extern char *strfill(char * s,size_t len,pchar fill);
148
extern size_t strinstr(const char *str,const char *search);
149
extern size_t r_strinstr(const char *str, size_t from, const char *search);
73
150
extern char *strkey(char *dst,char *head,char *tail,char *flags);
74
151
extern char *strmake(char *dst,const char *src,size_t length);
75
152
#ifndef strmake_overlapp
76
153
extern char *strmake_overlapp(char *dst,const char *src, size_t length);
157
extern char *strmov(char *dst,const char *src);
159
extern char *strnmov(char *dst,const char *src,size_t n);
79
160
extern char *strsuff(const char *src,const char *suffix);
80
extern char *strxcat(char *dst,const char *src, ...);
81
extern char *strxmov(char *dst,const char *src, ...);
82
extern char *strxcpy(char *dst,const char *src, ...);
83
extern char *strxncat(char *dst,size_t len, const char *src, ...);
84
extern char *strxnmov(char *dst,size_t len, const char *src, ...);
85
extern char *strxncpy(char *dst,size_t len, const char *src, ...);
161
extern char *strcont(const char *src,const char *set);
162
extern char *strxcat _VARARGS((char *dst,const char *src, ...));
163
extern char *strxmov _VARARGS((char *dst,const char *src, ...));
164
extern char *strxcpy _VARARGS((char *dst,const char *src, ...));
165
extern char *strxncat _VARARGS((char *dst,size_t len, const char *src, ...));
166
extern char *strxnmov _VARARGS((char *dst,size_t len, const char *src, ...));
167
extern char *strxncpy _VARARGS((char *dst,size_t len, const char *src, ...));
87
169
/* Prototypes of normal stringfunctions (with may ours) */
89
171
#ifdef WANT_STRING_PROTOTYPES
90
172
extern char *strcat(char *, const char *);
91
extern char *strchr(const char *, char);
92
extern char *strrchr(const char *, char);
173
extern char *strchr(const char *, pchar);
174
extern char *strrchr(const char *, pchar);
93
175
extern char *strcpy(char *, const char *);
176
extern int strcmp(const char *, const char *);
178
extern size_t strlen(const char *);
182
extern size_t strnlen(const char *s, size_t n);
96
185
#if !defined(__cplusplus)
97
186
#ifndef HAVE_STRPBRK
98
187
extern char *strpbrk(const char *, const char *);
190
extern char *strstr(const char *, const char *);
101
193
extern int is_prefix(const char *, const char *);
136
228
(DBL_DIG + 2) significant digits + sign + "." + ("e-NNN" or
137
229
MAX_DECPT_FOR_F_FORMAT zeros for cases when |x|<1 and the 'f' format is used).
139
#define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + cmax(5, MAX_DECPT_FOR_F_FORMAT))
231
#define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + max(5, MAX_DECPT_FOR_F_FORMAT))
142
extern char *llstr(int64_t value,char *buff);
143
extern char *ullstr(int64_t value,char *buff);
234
extern char *llstr(longlong value,char *buff);
235
extern char *ullstr(longlong value,char *buff);
237
extern long strtol(const char *str, char **ptr, int base);
238
extern ulong strtoul(const char *str, char **ptr, int base);
145
extern char *int2str(int32_t val, char *dst, int radix, int upcase);
146
extern char *int10_to_str(int32_t val,char *dst,int radix);
241
extern char *int2str(long val, char *dst, int radix, int upcase);
242
extern char *int10_to_str(long val,char *dst,int radix);
147
243
extern char *str2int(const char *src,int radix,long lower,long upper,
149
int64_t my_strtoll10(const char *nptr, char **endptr, int *error);
150
extern char *int64_t2str(int64_t val,char *dst,int radix);
151
extern char *int64_t10_to_str(int64_t val,char *dst,int radix);
245
longlong my_strtoll10(const char *nptr, char **endptr, int *error);
246
#if SIZEOF_LONG == SIZEOF_LONG_LONG
247
#define longlong2str(A,B,C) int2str((A),(B),(C),1)
248
#define longlong10_to_str(A,B,C) int10_to_str((A),(B),(C))
250
#define strtoll(A,B,C) strtol((A),(B),(C))
251
#define strtoull(A,B,C) strtoul((A),(B),(C))
252
#ifndef HAVE_STRTOULL
253
#define HAVE_STRTOULL
259
#ifdef HAVE_LONG_LONG
260
extern char *longlong2str(longlong val,char *dst,int radix);
261
extern char *longlong10_to_str(longlong val,char *dst,int radix);
262
#if (!defined(HAVE_STRTOULL) || defined(NO_STRTOLL_PROTO))
263
extern longlong strtoll(const char *str, char **ptr, int base);
264
extern ulonglong strtoull(const char *str, char **ptr, int base);
271
extern size_t my_vsnprintf(char *str, size_t n,
272
const char *format, va_list ap);
273
extern size_t my_snprintf(char *to, size_t n, const char *fmt, ...)
274
ATTRIBUTE_FORMAT(printf, 3, 4);
154
276
#if defined(__cplusplus)
170
292
typedef struct st_mysql_lex_string LEX_STRING;
172
294
#define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1))
173
#define USTRING_WITH_LEN(X) ((unsigned char*) X), ((size_t) (sizeof(X) - 1))
295
#define USTRING_WITH_LEN(X) ((uchar*) X), ((size_t) (sizeof(X) - 1))
174
296
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
298
/* SPACE_INT is a word that contains only spaces */
300
#define SPACE_INT 0x20202020
301
#elif SIZEOF_INT == 8
302
#define SPACE_INT 0x2020202020202020
304
#error define the appropriate constant for a word full of spaces
177
308
Skip trailing space.
310
On most systems reading memory in larger chunks (ideally equal to the size of
311
the chinks that the machine physically reads from memory) causes fewer memory
312
access loops and hence increased performance.
313
This is why the 'int' type is used : it's closest to that (according to how
315
So when we determine the amount of whitespace at the end of a string we do
317
1. We divide the string into 3 zones :
318
a) from the start of the string (__start) to the first multiple
319
of sizeof(int) (__start_words)
320
b) from the end of the string (__end) to the last multiple of sizeof(int)
322
c) a zone that is aligned to sizeof(int) and can be safely accessed
324
2. We start comparing backwards from (c) char-by-char. If all we find is
325
space then we continue
326
3. If there are elements in zone (b) we compare them as unsigned ints to a
327
int mask (SPACE_INT) consisting of all spaces
328
4. Finally we compare the remaining part (a) of the string char by char.
329
This covers for the last non-space unsigned int from 3. (if any)
331
This algorithm works well for relatively larger strings, but it will slow
332
the things down for smaller strings (because of the additional calculations
333
and checks compared to the naive method). Thus the barrier of length 20
179
336
@param ptr pointer to the input string
180
337
@param len the length of the string
181
338
@return the last non-space character
184
static inline const unsigned char *
185
skip_trailing_space(const unsigned char *ptr,size_t len)
341
static inline const uchar *skip_trailing_space(const uchar *ptr,size_t len)
187
const unsigned char *end= ptr + len;
189
while (end > ptr && isspace(*--end))
343
const uchar *end= ptr + len;
347
const uchar *end_words= (const uchar *)(intptr)
348
(((ulonglong)(intptr)end) / SIZEOF_INT * SIZEOF_INT);
349
const uchar *start_words= (const uchar *)(intptr)
350
((((ulonglong)(intptr)ptr) + SIZEOF_INT - 1) / SIZEOF_INT * SIZEOF_INT);
352
DBUG_ASSERT(((ulonglong)(intptr)ptr) >= SIZEOF_INT);
355
while (end > end_words && end[-1] == 0x20)
357
if (end[-1] == 0x20 && start_words < end_words)
358
while (end > start_words && ((unsigned *)end)[-1] == SPACE_INT)
362
while (end > ptr && end[-1] == 0x20)