57
57
extern void *(*my_str_malloc)(size_t);
58
58
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);
60
#if defined(HAVE_STPCPY)
61
#define strmov(A,B) stpcpy((A),(B))
63
#define strmov_overlapp(A,B) my_stpcpy(A,B)
64
#ifdef BAD_STRING_COMPILER
65
#define strmov(A,B) (memccpy(A,B,0,INT_MAX)-1)
67
#define strmov_overlapp(A,B) strmov(A,B)
64
68
#define strmake_overlapp(A,B,C) strmake(A,B,C)
71
#if (!defined(USE_BMOVE512) || defined(HAVE_purify)) && !defined(bmove512)
72
#define bmove512(A,B,C) memcpy(A,B,C)
75
/* Prototypes for string functions */
77
extern void bmove512(unsigned char *dst,const unsigned char *src,size_t len);
66
80
extern void bmove_upp(unsigned char *dst,const unsigned char *src,size_t len);
68
82
extern void bchange(unsigned char *dst,size_t old_len,const unsigned char *src,
69
83
size_t new_len,size_t tot_len);
84
extern void strappend(char *s,size_t len,char fill);
85
extern char *strend(const char *s);
86
extern char *strcend(const char *, char);
70
87
extern char *strfield(char *src,int fields,int chars,int blanks,
72
89
extern char *strfill(char * s,size_t len,char fill);
76
93
extern char *strmake_overlapp(char *dst,const char *src, size_t length);
97
extern char *strmov(char *dst,const char *src);
99
extern char *strnmov(char *dst,const char *src,size_t n);
79
100
extern char *strsuff(const char *src,const char *suffix);
101
extern char *strcont(const char *src,const char *set);
80
102
extern char *strxcat(char *dst,const char *src, ...);
81
103
extern char *strxmov(char *dst,const char *src, ...);
82
104
extern char *strxcpy(char *dst,const char *src, ...);
91
113
extern char *strchr(const char *, char);
92
114
extern char *strrchr(const char *, char);
93
115
extern char *strcpy(char *, const char *);
116
extern int strcmp(const char *, const char *);
118
extern size_t strlen(const char *);
122
extern size_t strnlen(const char *s, size_t n);
96
125
#if !defined(__cplusplus)
97
126
#ifndef HAVE_STRPBRK
98
127
extern char *strpbrk(const char *, const char *);
130
extern char *strstr(const char *, const char *);
101
133
extern int is_prefix(const char *, const char *);
136
168
(DBL_DIG + 2) significant digits + sign + "." + ("e-NNN" or
137
169
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))
171
#define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + max(5, MAX_DECPT_FOR_F_FORMAT))
142
174
extern char *llstr(int64_t value,char *buff);
143
175
extern char *ullstr(int64_t value,char *buff);
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);
177
extern char *int2str(long val, char *dst, int radix, int upcase);
178
extern char *int10_to_str(long val,char *dst,int radix);
147
179
extern char *str2int(const char *src,int radix,long lower,long upper,
149
181
int64_t my_strtoll10(const char *nptr, char **endptr, int *error);
182
#if SIZEOF_LONG == SIZEOF_LONG_LONG
183
#define int64_t2str(A,B,C) int2str((A),(B),(C),1)
184
#define int64_t10_to_str(A,B,C) int10_to_str((A),(B),(C))
186
#define strtoll(A,B,C) strtol((A),(B),(C))
187
#define strtoull(A,B,C) strtoul((A),(B),(C))
188
#ifndef HAVE_STRTOULL
189
#define HAVE_STRTOULL
150
195
extern char *int64_t2str(int64_t val,char *dst,int radix);
151
196
extern char *int64_t10_to_str(int64_t val,char *dst,int radix);
197
#if (!defined(HAVE_STRTOULL) || defined(NO_STRTOLL_PROTO))
198
extern int64_t strtoll(const char *str, char **ptr, int base);
199
extern uint64_t strtoull(const char *str, char **ptr, int base);
154
204
#if defined(__cplusplus)
173
223
#define USTRING_WITH_LEN(X) ((unsigned char*) X), ((size_t) (sizeof(X) - 1))
174
224
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
226
/* SPACE_INT is a word that contains only spaces */
228
#define SPACE_INT 0x20202020
229
#elif SIZEOF_INT == 8
230
#define SPACE_INT 0x2020202020202020
232
#error define the appropriate constant for a word full of spaces
177
236
Skip trailing space.
238
On most systems reading memory in larger chunks (ideally equal to the size of
239
the chinks that the machine physically reads from memory) causes fewer memory
240
access loops and hence increased performance.
241
This is why the 'int' type is used : it's closest to that (according to how
243
So when we determine the amount of whitespace at the end of a string we do
245
1. We divide the string into 3 zones :
246
a) from the start of the string (__start) to the first multiple
247
of sizeof(int) (__start_words)
248
b) from the end of the string (__end) to the last multiple of sizeof(int)
250
c) a zone that is aligned to sizeof(int) and can be safely accessed
252
2. We start comparing backwards from (c) char-by-char. If all we find is
253
space then we continue
254
3. If there are elements in zone (b) we compare them as unsigned ints to a
255
int mask (SPACE_INT) consisting of all spaces
256
4. Finally we compare the remaining part (a) of the string char by char.
257
This covers for the last non-space unsigned int from 3. (if any)
259
This algorithm works well for relatively larger strings, but it will slow
260
the things down for smaller strings (because of the additional calculations
261
and checks compared to the naive method). Thus the barrier of length 20
179
264
@param ptr pointer to the input string
180
265
@param len the length of the string
181
266
@return the last non-space character
184
static inline const unsigned char *
185
skip_trailing_space(const unsigned char *ptr,size_t len)
269
static inline const unsigned char *skip_trailing_space(const unsigned char *ptr,size_t len)
187
271
const unsigned char *end= ptr + len;
189
while (end > ptr && isspace(*--end))
275
const unsigned char *end_words= (const unsigned char *)(intptr_t)
276
(((uint64_t)(intptr_t)end) / SIZEOF_INT * SIZEOF_INT);
277
const unsigned char *start_words= (const unsigned char *)(intptr_t)
278
((((uint64_t)(intptr_t)ptr) + SIZEOF_INT - 1) / SIZEOF_INT * SIZEOF_INT);
280
assert(((uint64_t)(intptr_t)ptr) >= SIZEOF_INT);
283
while (end > end_words && end[-1] == 0x20)
285
if (end[-1] == 0x20 && start_words < end_words)
286
while (end > start_words && ((unsigned *)end)[-1] == SPACE_INT)
290
while (end > ptr && end[-1] == 0x20)