~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to include/m_string.h

  • Committer: Brian Aker
  • Date: 2008-07-15 06:45:16 UTC
  • Revision ID: brian@tangent.org-20080715064516-fnbq7kowh7w57bxj
Merge Monty's code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
/*  This is needed for the definitions of strchr... on solaris */
20
20
 
21
 
 
22
21
#ifndef _m_string_h
23
22
#define _m_string_h
24
 
 
25
 
#include <drizzled/global.h>
26
 
 
27
23
#ifndef __USE_GNU
28
 
#define __USE_GNU                               /* We want to use my_stpcpy */
 
24
#define __USE_GNU                               /* We want to use stpcpy */
29
25
#endif
30
26
#if defined(HAVE_STRINGS_H)
31
27
#include <strings.h>
34
30
#include <string.h>
35
31
#endif
36
32
 
37
 
#include <stdlib.h>
38
 
#include <stddef.h>
39
 
#include <stdbool.h>
40
 
#include <assert.h>
41
 
#include <limits.h>
42
 
#include <ctype.h>
 
33
#ifdef _AIX
 
34
#undef HAVE_BCMP
 
35
#endif
 
36
 
 
37
/*  This is needed for the definitions of bzero... on solaris */
 
38
#if defined(HAVE_STRINGS_H)
 
39
#include <strings.h>
 
40
#endif
43
41
 
44
42
/*  This is needed for the definitions of memcpy... on solaris */
45
43
#if defined(HAVE_MEMORY_H) && !defined(__cplusplus)
46
44
#include <memory.h>
47
45
#endif
48
46
 
 
47
#if !defined(HAVE_MEMCPY) && !defined(HAVE_MEMMOVE)
 
48
# define memcpy(d, s, n)        bcopy ((s), (d), (n))
 
49
# define memset(A,C,B)          bfill((A),(B),(C))
 
50
# define memmove(d, s, n)       bmove ((d), (s), (n))
 
51
#elif defined(HAVE_MEMMOVE)
 
52
# define bmove(d, s, n)         memmove((d), (s), (n))
 
53
#else
 
54
# define memmove(d, s, n)       bmove((d), (s), (n)) /* our bmove */
 
55
#endif
 
56
 
 
57
/* Unixware 7 */
 
58
#if !defined(HAVE_BFILL)
 
59
# define bfill(A,B,C)           memset((A),(C),(B))
 
60
# define bmove_align(A,B,C)    memcpy((A),(B),(C))
 
61
#endif
 
62
 
 
63
#if !defined(HAVE_BCMP)
 
64
# define bcopy(s, d, n)         memcpy((d), (s), (n))
 
65
# define bcmp(A,B,C)            memcmp((A),(B),(C))
 
66
# define bzero(A,B)             memset((A),0,(B))
 
67
# define bmove_align(A,B,C)     memcpy((A),(B),(C))
 
68
#endif
 
69
 
49
70
#if defined(__cplusplus)
50
71
extern "C" {
51
72
#endif
57
78
extern void *(*my_str_malloc)(size_t);
58
79
extern void (*my_str_free)(void *);
59
80
 
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);
62
 
 
63
 
#define strmov_overlapp(A,B) my_stpcpy(A,B)
 
81
#if defined(HAVE_STPCPY)
 
82
#define strmov(A,B) stpcpy((A),(B))
 
83
#endif
 
84
 
 
85
/* Declared in int2str() */
 
86
extern char _dig_vec_upper[];
 
87
extern char _dig_vec_lower[];
 
88
 
 
89
#ifdef BAD_STRING_COMPILER
 
90
#define strmov(A,B)  (memccpy(A,B,0,INT_MAX)-1)
 
91
#else
 
92
#define strmov_overlapp(A,B) strmov(A,B)
64
93
#define strmake_overlapp(A,B,C) strmake(A,B,C)
65
 
 
66
 
extern void bmove_upp(unsigned char *dst,const unsigned char *src,size_t len);
67
 
 
68
 
extern  void bchange(unsigned char *dst,size_t old_len,const unsigned char *src,
 
94
#endif
 
95
 
 
96
#ifdef BAD_MEMCPY                       /* Problem with gcc on Alpha */
 
97
#define memcpy_fixed(A,B,C) bmove((A),(B),(C))
 
98
#else
 
99
#define memcpy_fixed(A,B,C) memcpy((A),(B),(C))
 
100
#endif
 
101
 
 
102
#if (!defined(USE_BMOVE512) || defined(HAVE_purify)) && !defined(bmove512)
 
103
#define bmove512(A,B,C) memcpy(A,B,C)
 
104
#endif
 
105
 
 
106
        /* Prototypes for string functions */
 
107
 
 
108
#if !defined(bfill) && !defined(HAVE_BFILL)
 
109
extern  void bfill(uchar *dst,size_t len,char fill);
 
110
#endif
 
111
 
 
112
#if !defined(bzero) && !defined(HAVE_BZERO)
 
113
extern  void bzero(uchar * dst,size_t len);
 
114
#endif
 
115
 
 
116
#if !defined(bcmp) && !defined(HAVE_BCMP)
 
117
extern  size_t bcmp(const uchar *s1,const uchar *s2,size_t len);
 
118
#endif
 
119
#ifdef HAVE_purify
 
120
extern  size_t my_bcmp(const uchar *s1,const uchar *s2,size_t len);
 
121
#undef bcmp
 
122
#define bcmp(A,B,C) my_bcmp((A),(B),(C))
 
123
#define bzero_if_purify(A,B) bzero(A,B)
 
124
#else
 
125
#define bzero_if_purify(A,B)
 
126
#endif /* HAVE_purify */
 
127
 
 
128
#ifndef bmove512
 
129
extern  void bmove512(uchar *dst,const uchar *src,size_t len);
 
130
#endif
 
131
 
 
132
#if !defined(HAVE_BMOVE) && !defined(bmove)
 
133
extern  void bmove(uuchar *dst, const uchar *src,size_t len);
 
134
#endif
 
135
 
 
136
extern  void bmove_upp(uchar *dst,const uchar *src,size_t len);
 
137
extern  void bchange(uchar *dst,size_t old_len,const uchar *src,
69
138
                     size_t new_len,size_t tot_len);
 
139
extern  void strappend(char *s,size_t len,char fill);
 
140
extern  char *strend(const char *s);
 
141
extern  char *strcend(const char *, char);
70
142
extern  char *strfield(char *src,int fields,int chars,int blanks,
71
143
                           int tabch);
72
144
extern  char *strfill(char * s,size_t len,char fill);
76
148
extern  char *strmake_overlapp(char *dst,const char *src, size_t length);
77
149
#endif
78
150
 
 
151
#ifndef strmov
 
152
extern  char *strmov(char *dst,const char *src);
 
153
#endif
 
154
extern  char *strnmov(char *dst,const char *src,size_t n);
79
155
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, ...);
 
156
extern  char *strcont(const char *src,const char *set);
 
157
extern  char *strxcat _VARARGS((char *dst,const char *src, ...));
 
158
extern  char *strxmov _VARARGS((char *dst,const char *src, ...));
 
159
extern  char *strxcpy _VARARGS((char *dst,const char *src, ...));
 
160
extern  char *strxncat _VARARGS((char *dst,size_t len, const char *src, ...));
 
161
extern  char *strxnmov _VARARGS((char *dst,size_t len, const char *src, ...));
 
162
extern  char *strxncpy _VARARGS((char *dst,size_t len, const char *src, ...));
86
163
 
87
164
/* Prototypes of normal stringfunctions (with may ours) */
88
165
 
91
168
extern char *strchr(const char *, char);
92
169
extern char *strrchr(const char *, char);
93
170
extern char *strcpy(char *, const char *);
 
171
extern int strcmp(const char *, const char *);
 
172
#ifndef __GNUC__
 
173
extern size_t strlen(const char *);
 
174
#endif
 
175
#endif
 
176
#ifndef HAVE_STRNLEN
 
177
extern size_t strnlen(const char *s, size_t n);
94
178
#endif
95
179
 
96
180
#if !defined(__cplusplus)
97
181
#ifndef HAVE_STRPBRK
98
182
extern char *strpbrk(const char *, const char *);
99
183
#endif
 
184
#ifndef HAVE_STRSTR
 
185
extern char *strstr(const char *, const char *);
 
186
#endif
100
187
#endif
101
188
extern int is_prefix(const char *, const char *);
102
189
 
108
195
 
109
196
double my_strtod(const char *str, char **end, int *error);
110
197
double my_atof(const char *nptr);
111
 
size_t my_fcvt(double x, int precision, char *to, bool *error);
 
198
size_t my_fcvt(double x, int precision, char *to, my_bool *error);
112
199
size_t my_gcvt(double x, my_gcvt_arg_type type, int width, char *to,
113
 
               bool *error);
 
200
               my_bool *error);
114
201
 
115
202
#define NOT_FIXED_DEC 31
116
203
 
136
223
  (DBL_DIG + 2) significant digits + sign + "." + ("e-NNN" or
137
224
  MAX_DECPT_FOR_F_FORMAT zeros for cases when |x|<1 and the 'f' format is used).
138
225
*/
139
 
#define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + cmax(5, MAX_DECPT_FOR_F_FORMAT))
 
226
#define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + max(5, MAX_DECPT_FOR_F_FORMAT))
140
227
  
141
228
 
142
229
extern char *llstr(int64_t value,char *buff);
143
230
extern char *ullstr(int64_t value,char *buff);
 
231
#ifndef HAVE_STRTOUL
 
232
extern long strtol(const char *str, char **ptr, int base);
 
233
extern ulong strtoul(const char *str, char **ptr, int base);
 
234
#endif
144
235
 
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);
 
236
extern char *int2str(long val, char *dst, int radix, int upcase);
 
237
extern char *int10_to_str(long val,char *dst,int radix);
147
238
extern char *str2int(const char *src,int radix,long lower,long upper,
148
239
                         long *val);
149
240
int64_t my_strtoll10(const char *nptr, char **endptr, int *error);
 
241
#if SIZEOF_LONG == SIZEOF_LONG_LONG
 
242
#define int64_t2str(A,B,C) int2str((A),(B),(C),1)
 
243
#define int64_t10_to_str(A,B,C) int10_to_str((A),(B),(C))
 
244
#undef strtoll
 
245
#define strtoll(A,B,C) strtol((A),(B),(C))
 
246
#define strtoull(A,B,C) strtoul((A),(B),(C))
 
247
#ifndef HAVE_STRTOULL
 
248
#define HAVE_STRTOULL
 
249
#endif
 
250
#ifndef HAVE_STRTOLL
 
251
#define HAVE_STRTOLL
 
252
#endif
 
253
#else
150
254
extern char *int64_t2str(int64_t val,char *dst,int radix);
151
255
extern char *int64_t10_to_str(int64_t val,char *dst,int radix);
 
256
#if (!defined(HAVE_STRTOULL) || defined(NO_STRTOLL_PROTO))
 
257
extern int64_t strtoll(const char *str, char **ptr, int base);
 
258
extern uint64_t strtoull(const char *str, char **ptr, int base);
 
259
#endif
 
260
#endif
152
261
 
153
262
 
154
263
#if defined(__cplusplus)
170
279
typedef struct st_mysql_lex_string LEX_STRING;
171
280
 
172
281
#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))
 
282
#define USTRING_WITH_LEN(X) ((uchar*) X), ((size_t) (sizeof(X) - 1))
174
283
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
175
284
 
 
285
/* SPACE_INT is a word that contains only spaces */
 
286
#if SIZEOF_INT == 4
 
287
#define SPACE_INT 0x20202020
 
288
#elif SIZEOF_INT == 8
 
289
#define SPACE_INT 0x2020202020202020
 
290
#else
 
291
#error define the appropriate constant for a word full of spaces
 
292
#endif
 
293
 
176
294
/**
177
295
  Skip trailing space.
178
296
 
 
297
  On most systems reading memory in larger chunks (ideally equal to the size of
 
298
  the chinks that the machine physically reads from memory) causes fewer memory
 
299
  access loops and hence increased performance.
 
300
  This is why the 'int' type is used : it's closest to that (according to how
 
301
  it's defined in C).
 
302
  So when we determine the amount of whitespace at the end of a string we do
 
303
  the following :
 
304
    1. We divide the string into 3 zones :
 
305
      a) from the start of the string (__start) to the first multiple
 
306
        of sizeof(int)  (__start_words)
 
307
      b) from the end of the string (__end) to the last multiple of sizeof(int)
 
308
        (__end_words)
 
309
      c) a zone that is aligned to sizeof(int) and can be safely accessed
 
310
        through an int *
 
311
    2. We start comparing backwards from (c) char-by-char. If all we find is
 
312
       space then we continue
 
313
    3. If there are elements in zone (b) we compare them as unsigned ints to a
 
314
       int mask (SPACE_INT) consisting of all spaces
 
315
    4. Finally we compare the remaining part (a) of the string char by char.
 
316
       This covers for the last non-space unsigned int from 3. (if any)
 
317
 
 
318
   This algorithm works well for relatively larger strings, but it will slow
 
319
   the things down for smaller strings (because of the additional calculations
 
320
   and checks compared to the naive method). Thus the barrier of length 20
 
321
   is added.
 
322
 
179
323
   @param     ptr   pointer to the input string
180
324
   @param     len   the length of the string
181
325
   @return          the last non-space character
182
326
*/
183
327
 
184
 
static inline const unsigned char *
185
 
skip_trailing_space(const unsigned char *ptr,size_t len)
 
328
static inline const uchar *skip_trailing_space(const uchar *ptr,size_t len)
186
329
{
187
 
  const unsigned char *end= ptr + len;
188
 
 
189
 
  while (end > ptr && isspace(*--end))
190
 
    continue;
191
 
  return end+1;
 
330
  const uchar *end= ptr + len;
 
331
 
 
332
  if (len > 20)
 
333
  {
 
334
    const uchar *end_words= (const uchar *)(intptr_t)
 
335
      (((uint64_t)(intptr_t)end) / SIZEOF_INT * SIZEOF_INT);
 
336
    const uchar *start_words= (const uchar *)(intptr_t)
 
337
       ((((uint64_t)(intptr_t)ptr) + SIZEOF_INT - 1) / SIZEOF_INT * SIZEOF_INT);
 
338
 
 
339
    DBUG_ASSERT(((uint64_t)(intptr_t)ptr) >= SIZEOF_INT);
 
340
    if (end_words > ptr)
 
341
    {
 
342
      while (end > end_words && end[-1] == 0x20)
 
343
        end--;
 
344
      if (end[-1] == 0x20 && start_words < end_words)
 
345
        while (end > start_words && ((unsigned *)end)[-1] == SPACE_INT)
 
346
          end -= SIZEOF_INT;
 
347
    }
 
348
  }
 
349
  while (end > ptr && end[-1] == 0x20)
 
350
    end--;
 
351
  return (end);
192
352
}
193
353
 
194
354
#endif