~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mystrings/m_string.h

  • Committer: Mats Kindahl
  • Date: 2008-08-07 06:24:22 UTC
  • mfrom: (265 drizzle)
  • mto: (264.1.19 codestyle)
  • mto: This revision was merged to the branch mainline in revision 266.
  • Revision ID: mats@mysql.com-20080807062422-20kyv6ssp4grfm0s
Manual merge of lp:drizzle into ~mkindahl/remove-mem-casts.

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 my_stpcpy */
 
28
#define __USE_GNU                               /* We want to use 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 <stdint.h>
39
40
#include <stdbool.h>
40
41
#include <assert.h>
41
42
#include <limits.h>
42
 
#include <ctype.h>
43
43
 
44
44
/*  This is needed for the definitions of memcpy... on solaris */
45
45
#if defined(HAVE_MEMORY_H) && !defined(__cplusplus)
57
57
extern void *(*my_str_malloc)(size_t);
58
58
extern void (*my_str_free)(void *);
59
59
 
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))
 
62
#endif
62
63
 
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)
 
66
#else
 
67
#define strmov_overlapp(A,B) strmov(A,B)
64
68
#define strmake_overlapp(A,B,C) strmake(A,B,C)
 
69
#endif
 
70
 
 
71
#if (!defined(USE_BMOVE512) || defined(HAVE_purify)) && !defined(bmove512)
 
72
#define bmove512(A,B,C) memcpy(A,B,C)
 
73
#endif
 
74
 
 
75
        /* Prototypes for string functions */
 
76
#ifndef bmove512
 
77
extern void bmove512(unsigned char *dst,const unsigned char *src,size_t len);
 
78
#endif
65
79
 
66
80
extern void bmove_upp(unsigned char *dst,const unsigned char *src,size_t len);
67
81
 
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,
71
88
                           int tabch);
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);
77
94
#endif
78
95
 
 
96
#ifndef strmov
 
97
extern  char *strmov(char *dst,const char *src);
 
98
#endif
 
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 *);
 
117
#ifndef __GNUC__
 
118
extern size_t strlen(const char *);
 
119
#endif
 
120
#endif
 
121
#ifndef HAVE_STRNLEN
 
122
extern size_t strnlen(const char *s, size_t n);
94
123
#endif
95
124
 
96
125
#if !defined(__cplusplus)
97
126
#ifndef HAVE_STRPBRK
98
127
extern char *strpbrk(const char *, const char *);
99
128
#endif
 
129
#ifndef HAVE_STRSTR
 
130
extern char *strstr(const char *, const char *);
 
131
#endif
100
132
#endif
101
133
extern int is_prefix(const char *, const char *);
102
134
 
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).
138
170
*/
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))
140
172
  
141
173
 
142
174
extern char *llstr(int64_t value,char *buff);
143
175
extern char *ullstr(int64_t value,char *buff);
144
176
 
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,
148
180
                         long *val);
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))
 
185
#undef strtoll
 
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
 
190
#endif
 
191
#ifndef HAVE_STRTOLL
 
192
#define HAVE_STRTOLL
 
193
#endif
 
194
#else
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);
 
200
#endif
 
201
#endif
152
202
 
153
203
 
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))
175
225
 
 
226
/* SPACE_INT is a word that contains only spaces */
 
227
#if SIZEOF_INT == 4
 
228
#define SPACE_INT 0x20202020
 
229
#elif SIZEOF_INT == 8
 
230
#define SPACE_INT 0x2020202020202020
 
231
#else
 
232
#error define the appropriate constant for a word full of spaces
 
233
#endif
 
234
 
176
235
/**
177
236
  Skip trailing space.
178
237
 
 
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
 
242
  it's defined in C).
 
243
  So when we determine the amount of whitespace at the end of a string we do
 
244
  the following :
 
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)
 
249
        (__end_words)
 
250
      c) a zone that is aligned to sizeof(int) and can be safely accessed
 
251
        through an int *
 
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)
 
258
 
 
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
 
262
   is added.
 
263
 
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
182
267
*/
183
268
 
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)
186
270
{
187
271
  const unsigned char *end= ptr + len;
188
272
 
189
 
  while (end > ptr && isspace(*--end))
190
 
    continue;
191
 
  return end+1;
 
273
  if (len > 20)
 
274
  {
 
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);
 
279
 
 
280
    assert(((uint64_t)(intptr_t)ptr) >= SIZEOF_INT);
 
281
    if (end_words > ptr)
 
282
    {
 
283
      while (end > end_words && end[-1] == 0x20)
 
284
        end--;
 
285
      if (end[-1] == 0x20 && start_words < end_words)
 
286
        while (end > start_words && ((unsigned *)end)[-1] == SPACE_INT)
 
287
          end -= SIZEOF_INT;
 
288
    }
 
289
  }
 
290
  while (end > ptr && end[-1] == 0x20)
 
291
    end--;
 
292
  return (end);
192
293
}
193
294
 
194
295
#endif