~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mystrings/m_string.h

Merge of Jay

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include <drizzled/global.h>
26
26
 
27
27
#ifndef __USE_GNU
28
 
#define __USE_GNU                               /* We want to use stpcpy */
 
28
#define __USE_GNU                               /* We want to use my_stpcpy */
29
29
#endif
30
30
#if defined(HAVE_STRINGS_H)
31
31
#include <strings.h>
36
36
 
37
37
#include <stdlib.h>
38
38
#include <stddef.h>
39
 
#include <stdbool.h>
40
39
#include <assert.h>
41
40
#include <limits.h>
 
41
#include <ctype.h>
42
42
 
43
43
/*  This is needed for the definitions of memcpy... on solaris */
44
44
#if defined(HAVE_MEMORY_H) && !defined(__cplusplus)
49
49
extern "C" {
50
50
#endif
51
51
 
52
 
/*
53
 
  my_str_malloc() and my_str_free() are assigned to implementations in
54
 
  strings/alloc.c, but can be overridden in the calling program.
55
 
 */
56
 
extern void *(*my_str_malloc)(size_t);
57
 
extern void (*my_str_free)(void *);
58
 
 
59
 
#define strmov_overlapp(A,B) stpcpy(A,B)
 
52
#define strmov_overlapp(A,B) my_stpcpy(A,B)
60
53
#define strmake_overlapp(A,B,C) strmake(A,B,C)
61
54
 
62
55
extern void bmove_upp(unsigned char *dst,const unsigned char *src,size_t len);
63
56
 
64
57
extern  void bchange(unsigned char *dst,size_t old_len,const unsigned char *src,
65
58
                     size_t new_len,size_t tot_len);
66
 
extern  char *strend(const char *s);
67
59
extern  char *strfield(char *src,int fields,int chars,int blanks,
68
60
                           int tabch);
69
61
extern  char *strfill(char * s,size_t len,char fill);
78
70
extern  char *strxmov(char *dst,const char *src, ...);
79
71
extern  char *strxcpy(char *dst,const char *src, ...);
80
72
extern  char *strxncat(char *dst,size_t len, const char *src, ...);
81
 
extern  char *strxnmov(char *dst,size_t len, const char *src, ...);
82
73
extern  char *strxncpy(char *dst,size_t len, const char *src, ...);
83
74
 
84
75
/* Prototypes of normal stringfunctions (with may ours) */
90
81
extern char *strcpy(char *, const char *);
91
82
#endif
92
83
 
93
 
#ifndef HAVE_STPNCPY
94
 
char *stpncpy(register char *dst, register const char *src, size_t n);
95
 
#endif
96
 
 
97
 
#if !defined(__cplusplus)
98
 
#ifndef HAVE_STRPBRK
99
 
extern char *strpbrk(const char *, const char *);
100
 
#endif
101
 
#ifndef HAVE_STRSTR
102
 
extern char *strstr(const char *, const char *);
103
 
#endif
104
 
#endif
105
84
extern int is_prefix(const char *, const char *);
106
85
 
107
86
/* Conversion routines */
116
95
size_t my_gcvt(double x, my_gcvt_arg_type type, int width, char *to,
117
96
               bool *error);
118
97
 
119
 
#define NOT_FIXED_DEC 31
 
98
#define NOT_FIXED_DEC (uint8_t)31
120
99
 
121
100
/*
122
101
  The longest string my_fcvt can return is 311 + "precision" bytes.
140
119
  (DBL_DIG + 2) significant digits + sign + "." + ("e-NNN" or
141
120
  MAX_DECPT_FOR_F_FORMAT zeros for cases when |x|<1 and the 'f' format is used).
142
121
*/
143
 
#define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + max(5, MAX_DECPT_FOR_F_FORMAT))
144
 
  
 
122
#define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + cmax(5, MAX_DECPT_FOR_F_FORMAT))
 
123
 
145
124
 
146
125
extern char *llstr(int64_t value,char *buff);
147
126
extern char *ullstr(int64_t value,char *buff);
148
127
 
149
 
extern char *int2str(long val, char *dst, int radix, int upcase);
150
 
extern char *int10_to_str(long val,char *dst,int radix);
151
 
extern char *str2int(const char *src,int radix,long lower,long upper,
152
 
                         long *val);
 
128
extern char *int2str(int32_t val, char *dst, int radix, int upcase);
 
129
extern char *int10_to_str(int32_t val,char *dst,int radix);
153
130
int64_t my_strtoll10(const char *nptr, char **endptr, int *error);
154
 
#if SIZEOF_LONG == SIZEOF_LONG_LONG
155
 
#define int64_t2str(A,B,C) int2str((A),(B),(C),1)
156
 
#define int64_t10_to_str(A,B,C) int10_to_str((A),(B),(C))
157
 
#undef strtoll
158
 
#define strtoll(A,B,C) strtol((A),(B),(C))
159
 
#define strtoull(A,B,C) strtoul((A),(B),(C))
160
 
#ifndef HAVE_STRTOULL
161
 
#define HAVE_STRTOULL
162
 
#endif
163
 
#ifndef HAVE_STRTOLL
164
 
#define HAVE_STRTOLL
165
 
#endif
166
 
#else
167
131
extern char *int64_t2str(int64_t val,char *dst,int radix);
168
132
extern char *int64_t10_to_str(int64_t val,char *dst,int radix);
169
 
#if (!defined(HAVE_STRTOULL) || defined(NO_STRTOLL_PROTO))
170
 
extern int64_t strtoll(const char *str, char **ptr, int base);
171
 
extern uint64_t strtoull(const char *str, char **ptr, int base);
172
 
#endif
173
 
#endif
174
133
 
175
134
 
176
135
#if defined(__cplusplus)
177
136
}
178
137
#endif
179
138
 
180
 
/*
181
 
  LEX_STRING -- a pair of a C-string and its length.
182
 
*/
183
 
 
184
 
#ifndef _my_plugin_h
185
 
/* This definition must match the one given in mysql/plugin.h */
186
 
struct st_mysql_lex_string
187
 
{
188
 
  char *str;
189
 
  size_t length;
190
 
};
191
 
#endif
192
 
typedef struct st_mysql_lex_string LEX_STRING;
193
 
 
194
 
#define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1))
195
 
#define USTRING_WITH_LEN(X) ((unsigned char*) X), ((size_t) (sizeof(X) - 1))
196
 
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
197
 
 
198
 
/* SPACE_INT is a word that contains only spaces */
199
 
#if SIZEOF_INT == 4
200
 
#define SPACE_INT 0x20202020
201
 
#elif SIZEOF_INT == 8
202
 
#define SPACE_INT 0x2020202020202020
203
 
#else
204
 
#error define the appropriate constant for a word full of spaces
205
 
#endif
206
139
 
207
140
/**
208
141
  Skip trailing space.
209
142
 
210
 
  On most systems reading memory in larger chunks (ideally equal to the size of
211
 
  the chinks that the machine physically reads from memory) causes fewer memory
212
 
  access loops and hence increased performance.
213
 
  This is why the 'int' type is used : it's closest to that (according to how
214
 
  it's defined in C).
215
 
  So when we determine the amount of whitespace at the end of a string we do
216
 
  the following :
217
 
    1. We divide the string into 3 zones :
218
 
      a) from the start of the string (__start) to the first multiple
219
 
        of sizeof(int)  (__start_words)
220
 
      b) from the end of the string (__end) to the last multiple of sizeof(int)
221
 
        (__end_words)
222
 
      c) a zone that is aligned to sizeof(int) and can be safely accessed
223
 
        through an int *
224
 
    2. We start comparing backwards from (c) char-by-char. If all we find is
225
 
       space then we continue
226
 
    3. If there are elements in zone (b) we compare them as unsigned ints to a
227
 
       int mask (SPACE_INT) consisting of all spaces
228
 
    4. Finally we compare the remaining part (a) of the string char by char.
229
 
       This covers for the last non-space unsigned int from 3. (if any)
230
 
 
231
 
   This algorithm works well for relatively larger strings, but it will slow
232
 
   the things down for smaller strings (because of the additional calculations
233
 
   and checks compared to the naive method). Thus the barrier of length 20
234
 
   is added.
235
 
 
236
143
   @param     ptr   pointer to the input string
237
144
   @param     len   the length of the string
238
145
   @return          the last non-space character
239
146
*/
240
147
 
241
 
static inline const unsigned char *skip_trailing_space(const unsigned char *ptr,size_t len)
 
148
static inline const unsigned char *
 
149
skip_trailing_space(const unsigned char *ptr, size_t len)
242
150
{
243
151
  const unsigned char *end= ptr + len;
244
152
 
245
 
  if (len > 20)
246
 
  {
247
 
    const unsigned char *end_words= (const unsigned char *)(intptr_t)
248
 
      (((uint64_t)(intptr_t)end) / SIZEOF_INT * SIZEOF_INT);
249
 
    const unsigned char *start_words= (const unsigned char *)(intptr_t)
250
 
       ((((uint64_t)(intptr_t)ptr) + SIZEOF_INT - 1) / SIZEOF_INT * SIZEOF_INT);
251
 
 
252
 
    assert(((uint64_t)(intptr_t)ptr) >= SIZEOF_INT);
253
 
    if (end_words > ptr)
254
 
    {
255
 
      while (end > end_words && end[-1] == 0x20)
256
 
        end--;
257
 
      if (end[-1] == 0x20 && start_words < end_words)
258
 
        while (end > start_words && ((const unsigned *)end)[-1] == SPACE_INT)
259
 
          end -= SIZEOF_INT;
260
 
    }
261
 
  }
262
 
  while (end > ptr && end[-1] == 0x20)
263
 
    end--;
264
 
  return (end);
 
153
  while (end > ptr && isspace(*--end))
 
154
    continue;
 
155
  return end+1;
265
156
}
266
157
 
267
158
#endif